OpenLB 1.8.1
Loading...
Searching...
No Matches
vectorHelpers.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2013, 2014 Lukas Baron, Mathias J. Krause
4 * 2023 Julius Jessberger
5 * E-mail contact: info@openlb.net
6 * The most recent release of OpenLB can be downloaded at
7 * <http://www.openlb.net/>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23*/
24
25#ifndef VECTOR_HELPERS_H
26#define VECTOR_HELPERS_H
27
28#include <assert.h>
29#include <vector>
30#include <string>
31#include <sstream>
32#include <limits>
33
34#include "io/ostreamManager.h"
35#include "utilities/omath.h"
36#include "core/vector.h"
37#include "utilities/aDiff.h"
38
39namespace olb {
40
41template<typename T, unsigned Size> class Vector;
42
43namespace util {
44
45template <class T, unsigned DIM> class ADf;
46
47template <class T, unsigned DIM> inline ADf<T,DIM> sqrt (const ADf<T,DIM>& a);
48
49template<typename S>
50using StdVector = std::vector<S,std::allocator<S>>;
51
52template <class T>
53inline void copyN(T c[], const T a[], const unsigned dim) any_platform
54{
55 for (unsigned i=0; i<dim; i++) {
56 c[i] = a[i];
57 }
58}
59
60template <class S, class T>
61inline void copyN(S c[], const T a[], const unsigned dim) any_platform
62{
63 for (unsigned i=0; i<dim; i++) {
64 c[i] = a[i];
65 }
66}
67
68template <class T>
69inline void copy3(T c[], const T a[])
70{
71 for (unsigned i=0; i<3; i++) {
72 c[i] = a[i];
73 }
74}
75
76
77template <typename T>
78std::vector<T> fromVector3(const Vector<T,3>& vec)
79{
80 std::vector<T> v;
81 v.push_back(vec[0]);
82 v.push_back(vec[1]);
83 v.push_back(vec[2]);
84 return v;
85}
86template <typename T>
87std::vector<T> fromVector2(const Vector<T,2>& vec)
88{
89 std::vector<T> v;
90 v.push_back(vec[0]);
91 v.push_back(vec[1]);
92 return v;
93}
94
96template <typename T>
97T norm2(const T* a, unsigned size)
98{
99 T v{};
100 for (unsigned iD=0; iD<size; ++iD) {
101 v += a[iD]*a[iD];
102 }
103 return v;
104}
105
107template <typename T>
108T norm2(const std::vector<T>& a)
109{
110 return norm2(a.data(), a.size());
111}
112
114template <typename T>
115T norm(const T* a, unsigned size)
116{
117 return util::sqrt(norm2(a, size));
118}
119
121template <typename T>
122T norm(const std::vector<T>& a)
123{
124 return norm(a.data(), a.size());
125}
126
128template <typename T>
130{
131 return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
132}
133
135template <typename T>
137{
138 return a[0]*b[0] + a[1]*b[1];
139}
140
142template <typename T,unsigned D>
143T dotProduct(const Vector<T,D>& a, const Vector<T,D>& b)
144{
145 if constexpr (D==2){
146 return dotProduct2D(a, b);
147 } else {
148 return dotProduct3D(a, b);
149 }
150}
151
152template <typename T, unsigned D>
154{
155 return a / norm(a);
156}
157
159template <typename T>
160std::vector<T> normalize(const std::vector<T>& a)
161{
162 std::vector<T> out(a);
163 T scale = norm(a);
164 assert(scale>0);
165 for (unsigned int iDim=0; iDim<a.size(); iDim++) {
166 out[iDim] /= scale;
167 }
168 return out;
169}
170
172template <typename T, unsigned Size>
174{
175 Vector<T,Size> out;
176 for (unsigned int iDim=0; iDim < Size; ++iDim) {
177 out[iDim] = util::floor(a[iDim]);
178 }
179 return out;
180}
181
183template <typename T, unsigned Size>
185{
186 Vector<T,Size> out;
187 for (unsigned int iDim=0; iDim < Size; ++iDim) {
188 out[iDim] = util::ceil(a[iDim]);
189 }
190 return out;
191}
192
194template <typename T, typename S, unsigned Size>
196{
197 Vector<T,Size> out;
198 for (unsigned int iDim=0; iDim < Size; ++iDim) {
199 out[iDim] = util::fmod(a[iDim], b);
200 }
201 return out;
202}
203
205template <typename T, unsigned Size>
207{
208 T sum = a[0];
209 for (unsigned int iDim=1; iDim < Size; ++iDim) {
210 sum += a[iDim];
211 }
212 return sum/Size;
213}
214
216template <typename T, unsigned Size>
218{
219 T max = a[0];
220 for (unsigned int iDim=1; iDim < Size; ++iDim) {
221 max = std::max(max,a[iDim]);
222 }
223 return max;
224}
225
227template <typename T, unsigned Size>
229{
230 T min = a[0];
231 for (unsigned int iDim=1; iDim < Size; ++iDim) {
232 min = std::min(min,a[iDim]);
233 }
234 return min;
235}
236
238template <typename T, unsigned Size>
240{
241 unsigned maxPos = 0;
242 for (unsigned int iDim=1; iDim < Size; ++iDim) {
243 if (a[iDim]>a[maxPos]){
244 maxPos = iDim;
245 }
246 }
247 return maxPos;
248}
249
251template <typename T, unsigned Size>
253{
254 unsigned minPos = 0;
255 for (unsigned int iDim=1; iDim < Size; ++iDim) {
256 if (a[iDim]<a[minPos]){
257 minPos = iDim;
258 }
259 }
260 return minPos;
261}
262
264template <typename T, unsigned Size>
266{
267 T maxAbs = a[0];
268 for (unsigned int iDim=1; iDim < Size; ++iDim) {
269 if (abs(a[iDim])>abs(maxAbs)){
270 maxAbs = a[iDim];
271 }
272 }
273 return maxAbs;
274}
275
277template <typename T, unsigned Size>
279{
280 unsigned maxAbsPos = 0;
281 for (unsigned int iDim=1; iDim < Size; ++iDim) {
282 if (abs(a[iDim])>abs(a[maxAbsPos])){
283 maxAbsPos = iDim;
284 }
285 }
286 return maxAbsPos;
287}
288
290template <typename T, bool ensureAngularBounds=true>
292{
293 if constexpr(ensureAngularBounds){
294 return std::fmod(util::atan2(b[1]*a[0]-b[0]*a[1], a[0]*b[0]+a[1]*b[1]), M_PI);
295 } else {
296 return util::atan2(b[1]*a[0]-b[0]*a[1], a[0]*b[0]+a[1]*b[1]);
297 }
298}
299
301template <typename T, bool ensureAngularBounds=true>
303{
304 Vector<T,3> angles;
305 angles[0] = angleBetweenVectors<T,ensureAngularBounds>(Vector<T,2>(a[1], a[2]), Vector<T,2>(b[1], b[2]));
306 angles[1] = angleBetweenVectors<T,ensureAngularBounds>(Vector<T,2>(a[0], a[2]), Vector<T,2>(b[0], b[2]));
307 angles[2] = angleBetweenVectors<T,ensureAngularBounds>(Vector<T,2>(a[0], a[1]), Vector<T,2>(b[0], b[1]));
308 return angles;
309}
310
311template <typename T>
312constexpr T determinant(const Vector<T,2>& v0, const Vector<T,2>& v1)
313{
314 return crossProduct2D(v0, v1);
315}
316
317template <typename T>
318constexpr T determinant(const Vector<T,3>& v0, const Vector<T,3>& v1,
319 const Vector<T,3>& v2)
320{
321 return v0[0]*v1[1]*v2[2] + v1[0]*v2[1]*v0[2] + v2[0]*v0[1]*v1[2]
322 - v0[2]*v1[1]*v2[0] - v1[2]*v2[1]*v0[0] - v2[2]*v0[1]*v1[0];
323}
324
325
327// Returns +-inf if a0, a1 are linearly dependent and rhs is not (no solution)
328// Returns nan if a0, a1, rhs are linearly dependent (infinitely many solutions)
329template <typename T>
331 const Vector<T,2>& a1, const Vector<T,2>& rhs)
332{
333 const T det = crossProduct2D(a0, a1);
334 return Vector<T,2> (crossProduct2D(rhs, a1) / det, crossProduct2D(a0, rhs) / det);
335}
336
337template <typename T>
339 const Vector<T,3>& a1, const Vector<T,3>& a2, const Vector<T,3>& rhs,
340 T det)
341{
342 Vector<T,3> res;
343 res[0] = determinant(rhs, a1, a2) / det;
344 res[1] = determinant(a0, rhs, a2) / det;
345 res[2] = determinant(a0, a1, rhs) / det;
346 return res;
347}
348
350// Returns +-inf if a0, a1, a2 are linearly dependent and rhs is not (no solution)
351// Returns nan if a0, a1, a2, rhs are linearly dependent (infinitely many solutions)
352// Cf. https://danceswithcode.net/engineeringnotes/linear_equations/linear_equations.html
353// for formula
354template <typename T>
356 const Vector<T,3>& a1, const Vector<T,3>& a2, const Vector<T,3>& rhs)
357{
358 const T det = determinant(a0, a1, a2);
359 return solveLinearSystem_help(a0, a1, a2, rhs, det);
360}
361
362
363/*
366template <typename T>
367bool triangleIntersectionWithNormalDirection(const std::vector<T>& point0,
368 const std::vector<T>& point1, const std::vector<T>& point2,
369 const std::vector<T>& origin, const std::vector<T>& normalDirection,
370 T& distance)
371{
372 T EPSILON = std::numeric_limits<T>::epsilon();
373 std::vector<T> e1, e2;
374 std::vector<T> P, Q, TT;
375 T det, inv_det;
376 T t, u, v;
377 e1 = point1 - point0;
378 e2 = point2 - point0;
379 P = crossProduct3D(normalDirection, e2);
380 det = dotProduct3D(P, e1);
381 if (det > -EPSILON && det < EPSILON) {
382 return false;
383 }
384 inv_det = T(1) / det;
385 TT = origin - point0;
386 u = dotProduct3D(TT, P)*inv_det;
387 if (u < T() || u > T(1)) {
388 return false;
389 }
390 Q = crossProduct3D(TT, e1);
391 v = dotProduct3D(normalDirection, Q) * inv_det;
392 if (v < T() || u + v > T(1)) {
393 return false;
394 }
395 t = dotProduct3D(e2, Q)*inv_det;
396 if (t > EPSILON) {
397 distance = t;
398 return true;
399 }
400 return false;
401}
402
403template <typename T>
404bool triangleIntersection(const std::vector<T>& point0, const std::vector<T>& point1, const std::vector<T>& point2, const std::vector<T>& origin, const std::vector<T>& direction, T& distance)
405{
406 std::vector<T> normalDirection(normalize(direction) );
407 return triangleIntersectionWithNormalDirection(point0, point1, point2, origin, normalDirection, distance );
408}
409*/
410template <typename T>
411std::vector<T> assign(T a, T b)
412{
413 std::vector<T> v1;
414 v1.push_back(a);
415 v1.push_back(b);
416 return v1;
417}
418
419template <typename T>
420std::vector<T> assign(T a, T b, T c)
421{
422 std::vector<T> v1;
423 v1.push_back(a);
424 v1.push_back(b);
425 v1.push_back(c);
426 return v1;
427}
428
429
430template<typename U>
431void print(U data, const std::string& name="", OstreamManager clout = OstreamManager(std::cout,"print"),
432 const char delimiter=',')
433{
434 static_assert(!std::is_integral<U>::value && !std::is_floating_point<U>::value, "passed integral or floating_point value to function print()");
435 if (name != "") {
436 clout << name << " = ";
437 }
438 for ( auto& element : data ) {
439 clout << std::fixed << element << delimiter << ' ';
440 }
441 clout << std::endl;
442}
443
445// U must provide equality 'operator==' and this has to fit the elements of c.
446template<typename C, typename U>
447bool isContained(const C& c, U object) {
448 return (std::find(c.begin(), c.end(), object) != c.end());
449}
450
452// See below for template specializations.
453template<typename C>
455
456template<typename T>
457struct ContainerCreator<std::vector<T>> {
458 using C = std::vector<T>;
459
460 static constexpr C create(std::size_t size) {
461 return C(size);
462 }
463};
464
465template<typename T, std::size_t SIZE>
466struct ContainerCreator<std::array<T,SIZE>> {
467 using C = std::array<T,SIZE>;
468
469 static constexpr C create(std::size_t size) {
470 OLB_PRECONDITION(SIZE == size);
471 return C{};
472 }
473};
474
475template<typename T, unsigned SIZE>
476struct ContainerCreator<Vector<T,SIZE>> {
478
479 static constexpr C create(std::size_t size) {
480 OLB_PRECONDITION(SIZE == size);
481 return C{};
482 }
483};
484
490template<unsigned DIM>
491unsigned serialSymmetricTensorIndex(unsigned i, unsigned j) any_platform
492{
493 OLB_PRECONDITION(DIM > 1);
494 OLB_PRECONDITION(DIM < 4);
495 if constexpr (DIM==2) {
496 return i+j;
497 }
498 else if constexpr (DIM==3) {
499 const unsigned res = i+j;
500 if ((i>0) && (j>0)) {
501 return res+1;
502 } else {
503 return res;
504 }
505 }
506 else {
507 // other dimensions are not implemented
508 exit(1);
509 }
510}
511
512} // namespace util
513
514} // namespace olb
515
516#endif
The description of a algoritmic differentiation data type using the forward method – header file.
#define M_PI
class for marking output with some text
Plain old scalar vector.
Definition of a description of a algoritmic differentiation data type using the forward method.
Vector< T, 3 > solveLinearSystem_help(const Vector< T, 3 > &a0, const Vector< T, 3 > &a1, const Vector< T, 3 > &a2, const Vector< T, 3 > &rhs, T det)
ADf< T, DIM > abs(const ADf< T, DIM > &a)
Definition aDiff.h:1019
ADf< T, DIM > ceil(const ADf< T, DIM > &a)
Definition aDiff.h:900
ADf< T, DIM > floor(const ADf< T, DIM > &a)
Definition aDiff.h:869
Expr sqrt(Expr x)
Definition expr.cpp:225
std::vector< T > fromVector3(const Vector< T, 3 > &vec)
std::vector< S, std::allocator< S > > StdVector
ADf< T, DIM > fmod(const ADf< T, DIM > &a, const ADf< T, DIM > &b)
Definition aDiff.h:703
auto solveLinearSystem(const Matrix< T, 2, 2 > &a, const Vector< T, 2 > &rhs)
Solve a * x = rhs.
Definition matrix.h:158
ADf< T, DIM > atan2(const T &y, const ADf< T, DIM > &x)
Definition aDiff.h:623
bool isContained(const C &c, U object)
Check, if object is contained in iteratable container c.
Expr min(Expr a, Expr b)
Definition expr.cpp:249
void copyN(T c[], const T a[], const unsigned dim) any_platform
Expr max(Expr a, Expr b)
Definition expr.cpp:245
T angleBetweenVectors(const Vector< T, 2 > &a, const Vector< T, 2 > &b)
Calculates angles between two 2D vectors.
T norm2(const T *a, unsigned size)
l2 norm to the power of 2 of a vector of arbitrary length
T average(const Vector< T, Size > &a)
computes the average of all elements
std::vector< T > fromVector2(const Vector< T, 2 > &vec)
T max_element(const Vector< T, Size > &a)
finds maximum element of all elements
T min_element(const Vector< T, Size > &a)
finds minimum element of all elements
constexpr auto determinant(const Matrix< T, 2, 2 > &m)
Definition matrix.h:143
T dotProduct(const Vector< T, D > &a, const Vector< T, D > &b)
dot product
T maxElementAbs(const Vector< T, Size > &a)
finds maximum element of all absolute elements
unsigned maxElementAbsPos(const Vector< T, Size > &a)
finds position of maximum element of all absolute elements
T norm(const std::vector< T > &a)
l2 norm of a vector of arbitrary length
unsigned minElementPos(const Vector< T, Size > &a)
finds position of minimum element of all elements
unsigned maxElementPos(const Vector< T, Size > &a)
finds position of maximum element of all elements
T dotProduct3D(const Vector< T, 3 > &a, const Vector< T, 3 > &b)
dot product, only valid in 3d
Vector< T, D > normalize(const Vector< T, D > &a)
unsigned serialSymmetricTensorIndex(unsigned i, unsigned j) any_platform
Compute serial index of symmetric tensor.
void print(U data, const std::string &name="", OstreamManager clout=OstreamManager(std::cout,"print"), const char delimiter=',')
std::vector< T > assign(T a, T b)
T dotProduct2D(const Vector< T, 2 > &a, const Vector< T, 2 > &b)
dot product, only valid in 2d
void copy3(T c[], const T a[])
Top level namespace for all of OpenLB.
constexpr T crossProduct2D(const ScalarVector< T, 2, IMPL > &a, const ScalarVector< T, 2, IMPL_ > &b)
Definition vector.h:256
#define OLB_PRECONDITION(COND)
Definition olbDebug.h:46
#define any_platform
Define preprocessor macros for device-side functions, constant storage.
Definition platform.h:77
static constexpr C create(std::size_t size)
static constexpr C create(std::size_t size)
static constexpr C create(std::size_t size)
Creates a container of type C.
efficient implementation of a vector class