OpenLB 1.7
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 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24#ifndef VECTOR_HELPERS_H
25#define VECTOR_HELPERS_H
26
27#include <assert.h>
28#include <vector>
29#include <string>
30#include <sstream>
31#include <limits>
32
33#include "io/ostreamManager.h"
34#include "utilities/omath.h"
35#include "core/vector.h"
36#include "aDiff.h"
37
38namespace olb {
39
40template<typename T, unsigned Size> class Vector;
41
42namespace util {
43
44template <class T, unsigned DIM> class ADf;
45
46template <class T, unsigned DIM> inline ADf<T,DIM> sqrt (const ADf<T,DIM>& a);
47
48template<typename S>
49using StdVector = std::vector<S,std::allocator<S>>;
50
52template <typename T>
53inline bool nearZero(T a)
54{
55 if (a==T()) {
56 return true;
57 }
58 T EPSILON = std::numeric_limits<T>::epsilon();
59 if (a > -EPSILON && a < EPSILON) {
60 return true;
61 }
62 else {
63 return false;
64 }
65}
66
67template <typename T>
68inline bool nearZero(T a, T epsilon)
69{
70 if (a > -epsilon && a < epsilon) {
71 return true;
72 }
73 else {
74 return false;
75 }
76}
77
78template<typename T, typename U=T, typename W=T>
79inline bool approxEqual(T a, U b, W epsilon)
80{
81 if (a==b) {
82 return true;
83 }
84 return nearZero<T>(a - b, epsilon);
85}
86
87template<typename T, typename U=T>
88inline bool approxEqual(T a, U b)
89{
90 if (a==b) {
91 return true;
92 }
93 if (nearZero(a) && nearZero(b)) {
94 return true;
95 }
96 T EPSILON = std::numeric_limits<T>::epsilon()*4.*util::fabs(a);
97 return approxEqual(a,b,EPSILON);
98}
99
100template <class T>
101inline void copyN(T c[], const T a[], const unsigned dim) any_platform
102{
103 for (unsigned i=0; i<dim; i++) {
104 c[i] = a[i];
105 }
106}
107
108template <class S, class T>
109inline void copyN(S c[], const T a[], const unsigned dim) any_platform
110{
111 for (unsigned i=0; i<dim; i++) {
112 c[i] = a[i];
113 }
114}
115
116template <class T>
117inline void copy3(T c[], const T a[])
118{
119 for (unsigned i=0; i<3; i++) {
120 c[i] = a[i];
121 }
122}
123
124
125template <typename T>
126std::vector<T> fromVector3(const Vector<T,3>& vec)
127{
128 std::vector<T> v;
129 v.push_back(vec[0]);
130 v.push_back(vec[1]);
131 v.push_back(vec[2]);
132 return v;
133}
134template <typename T>
135std::vector<T> fromVector2(const Vector<T,2>& vec)
136{
137 std::vector<T> v;
138 v.push_back(vec[0]);
139 v.push_back(vec[1]);
140 return v;
141}
142
143
145template <typename T>
146T norm(const std::vector<T>& a)
147{
148 T v(0);
149 for (unsigned iD=0; iD<a.size(); iD++) {
150 v += a[iD]*a[iD];
151 }
152 v = util::sqrt(v);
153 return v;
154}
155
157template <typename T>
158T norm2(const std::vector<T>& a)
159{
160 T v = T();
161 for (unsigned iD=0; iD<a.size(); iD++) {
162 v += a[iD]*a[iD];
163 }
164 return v;
165}
166
168template <typename T>
170{
171 return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
172}
173
175template <typename T>
177{
178 return a[0]*b[0] + a[1]*b[1];
179}
180
182template <typename T,unsigned D>
183T dotProduct(const Vector<T,D>& a, const Vector<T,D>& b)
184{
185 if constexpr (D==2){
186 return dotProduct2D(a, b);
187 } else {
188 return dotProduct3D(a, b);
189 }
190}
191
192template <typename T, unsigned D>
194{
195 return a / norm(a);
196}
197
199template <typename T>
200std::vector<T> normalize(const std::vector<T>& a)
201{
202 std::vector<T> out(a);
203 T scale = norm(a);
204 assert(scale>0);
205 for (unsigned int iDim=0; iDim<a.size(); iDim++) {
206 out[iDim] /= scale;
207 }
208 return out;
209}
210
212template <typename T, unsigned Size>
214{
215 Vector<T,Size> out;
216 for (unsigned int iDim=0; iDim < Size; ++iDim) {
217 out[iDim] = util::floor(a[iDim]);
218 }
219 return out;
220}
221
223template <typename T, unsigned Size>
225{
226 Vector<T,Size> out;
227 for (unsigned int iDim=0; iDim < Size; ++iDim) {
228 out[iDim] = util::ceil(a[iDim]);
229 }
230 return out;
231}
232
234template <typename T, typename S, unsigned Size>
236{
237 Vector<T,Size> out;
238 for (unsigned int iDim=0; iDim < Size; ++iDim) {
239 out[iDim] = util::fmod(a[iDim], b);
240 }
241 return out;
242}
243
245template <typename T, unsigned Size>
247{
248 T sum = a[0];
249 for (unsigned int iDim=1; iDim < Size; ++iDim) {
250 sum += a[iDim];
251 }
252 return sum/Size;
253}
254
256template <typename T, unsigned Size>
258{
259 T max = a[0];
260 for (unsigned int iDim=1; iDim < Size; ++iDim) {
261 max = std::max(max,a[iDim]);
262 }
263 return max;
264}
265
267template <typename T, unsigned Size>
269{
270 T min = a[0];
271 for (unsigned int iDim=1; iDim < Size; ++iDim) {
272 min = std::min(min,a[iDim]);
273 }
274 return min;
275}
276
278template <typename T, unsigned Size>
280{
281 unsigned maxPos = 0;
282 for (unsigned int iDim=1; iDim < Size; ++iDim) {
283 if (a[iDim]>a[maxPos]){
284 maxPos = iDim;
285 }
286 }
287 return maxPos;
288}
289
291template <typename T, unsigned Size>
293{
294 unsigned minPos = 0;
295 for (unsigned int iDim=1; iDim < Size; ++iDim) {
296 if (a[iDim]<a[minPos]){
297 minPos = iDim;
298 }
299 }
300 return minPos;
301}
302
304template <typename T, unsigned Size>
306{
307 T maxAbs = a[0];
308 for (unsigned int iDim=1; iDim < Size; ++iDim) {
309 if (abs(a[iDim])>abs(maxAbs)){
310 maxAbs = a[iDim];
311 }
312 }
313 return maxAbs;
314}
315
317template <typename T, unsigned Size>
319{
320 unsigned maxAbsPos = 0;
321 for (unsigned int iDim=1; iDim < Size; ++iDim) {
322 if (abs(a[iDim])>abs(a[maxAbsPos])){
323 maxAbsPos = iDim;
324 }
325 }
326 return maxAbsPos;
327}
328
330template <typename T, bool ensureAngularBounds=true>
332{
333 if constexpr(ensureAngularBounds){
334 return std::fmod(util::atan2(b[1]*a[0]-b[0]*a[1], a[0]*b[0]+a[1]*b[1]), M_PI);
335 } else {
336 return util::atan2(b[1]*a[0]-b[0]*a[1], a[0]*b[0]+a[1]*b[1]);
337 }
338}
339
341template <typename T, bool ensureAngularBounds=true>
343{
344 Vector<T,3> angles;
345 angles[0] = angleBetweenVectors<T,ensureAngularBounds>(Vector<T,2>(a[1], a[2]), Vector<T,2>(b[1], b[2]));
346 angles[1] = angleBetweenVectors<T,ensureAngularBounds>(Vector<T,2>(a[0], a[2]), Vector<T,2>(b[0], b[2]));
347 angles[2] = angleBetweenVectors<T,ensureAngularBounds>(Vector<T,2>(a[0], a[1]), Vector<T,2>(b[0], b[1]));
348 return angles;
349}
350
351/*
354template <typename T>
355bool triangleIntersectionWithNormalDirection(const std::vector<T>& point0,
356 const std::vector<T>& point1, const std::vector<T>& point2,
357 const std::vector<T>& origin, const std::vector<T>& normalDirection,
358 T& distance)
359{
360 T EPSILON = std::numeric_limits<T>::epsilon();
361 std::vector<T> e1, e2;
362 std::vector<T> P, Q, TT;
363 T det, inv_det;
364 T t, u, v;
365 e1 = point1 - point0;
366 e2 = point2 - point0;
367 P = crossProduct3D(normalDirection, e2);
368 det = dotProduct3D(P, e1);
369 if (det > -EPSILON && det < EPSILON) {
370 return false;
371 }
372 inv_det = T(1) / det;
373 TT = origin - point0;
374 u = dotProduct3D(TT, P)*inv_det;
375 if (u < T() || u > T(1)) {
376 return false;
377 }
378 Q = crossProduct3D(TT, e1);
379 v = dotProduct3D(normalDirection, Q) * inv_det;
380 if (v < T() || u + v > T(1)) {
381 return false;
382 }
383 t = dotProduct3D(e2, Q)*inv_det;
384 if (t > EPSILON) {
385 distance = t;
386 return true;
387 }
388 return false;
389}
390
391template <typename T>
392bool 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)
393{
394 std::vector<T> normalDirection(normalize(direction) );
395 return triangleIntersectionWithNormalDirection(point0, point1, point2, origin, normalDirection, distance );
396}
397*/
398template <typename T>
399std::vector<T> assign(T a, T b)
400{
401 std::vector<T> v1;
402 v1.push_back(a);
403 v1.push_back(b);
404 return v1;
405}
406
407template <typename T>
408std::vector<T> assign(T a, T b, T c)
409{
410 std::vector<T> v1;
411 v1.push_back(a);
412 v1.push_back(b);
413 v1.push_back(c);
414 return v1;
415}
416
417
418template<typename U>
419void print(U data, const std::string& name="", OstreamManager clout = OstreamManager(std::cout,"print"),
420 const char delimiter=',')
421{
422 static_assert(!std::is_integral<U>::value && !std::is_floating_point<U>::value, "passed integral or floating_point value to function print()");
423 if (name != "") {
424 clout << name << " = ";
425 }
426 for ( auto& element : data ) {
427 clout << std::fixed << element << delimiter << ' ';
428 }
429 clout << std::endl;
430}
431
433// U must provide equality 'operator==' and this has to fit the elements of c.
434template<typename C, typename U>
435bool isContained(const C& c, U object) {
436 return (std::find(c.begin(), c.end(), object) != c.end());
437}
438
440// See below for template specializations.
441template<typename C>
443
444template<typename T>
445struct ContainerCreator<std::vector<T>> {
446 using C = std::vector<T>;
447
448 static constexpr C create(std::size_t size) {
449 return C(size);
450 }
451};
452
453template<typename T, std::size_t SIZE>
454struct ContainerCreator<std::array<T,SIZE>> {
455 using C = std::array<T,SIZE>;
456
457 static constexpr C create(std::size_t size) {
458 OLB_PRECONDITION(SIZE == size);
459 return C{};
460 }
461};
462
463template<typename T, unsigned SIZE>
464struct ContainerCreator<Vector<T,SIZE>> {
466
467 static constexpr C create(std::size_t size) {
468 OLB_PRECONDITION(SIZE == size);
469 return C{};
470 }
471};
472
473} // namespace util
474
475} // namespace olb
476
477#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 vector.h:47
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
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
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
cpu::simd::Pack< T > min(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
Definition pack.h:124
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.
void copyN(T c[], const T a[], const unsigned dim) any_platform
T angleBetweenVectors(const Vector< T, 2 > &a, const Vector< T, 2 > &b)
Calculates angles between two 2D vectors.
T average(const Vector< T, Size > &a)
computes the average of all elements
std::vector< T > fromVector2(const Vector< T, 2 > &vec)
bool approxEqual(T a, U b, W epsilon)
T max_element(const Vector< T, Size > &a)
finds maximum element of all elements
cpu::simd::Pack< T > max(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
Definition pack.h:130
T min_element(const Vector< T, Size > &a)
finds minimum element of all elements
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
cpu::simd::Pack< T > fabs(cpu::simd::Pack< T > value)
Definition pack.h:106
T dotProduct3D(const Vector< T, 3 > &a, const Vector< T, 3 > &b)
dot product, only valid in 3d
T norm2(const std::vector< T > &a)
l2 norm to the power of 2 of a vector of arbitrary length
Vector< T, D > normalize(const Vector< T, D > &a)
bool nearZero(const ADf< T, DIM > &a)
Definition aDiff.h:1087
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.
#define OLB_PRECONDITION(COND)
Definition olbDebug.h:46
#define any_platform
Define preprocessor macros for device-side functions, constant storage.
Definition platform.h:78
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