OpenLB 1.8.1
Loading...
Searching...
No Matches
geometricOperations.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2021 Julius Jessberger
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
28#ifndef GEOMETRIC_OPERATIONS_H
29#define GEOMETRIC_OPERATIONS_H
30
31#include "core/vector.h"
32#include "dimensionConverter.h"
33#include "matrix.h"
34
35namespace olb {
36
37namespace util {
38
39// angle conversions
40template <typename T, unsigned D>
43{
44 constexpr BaseType<decltype(util::sqrt(T()))> conversionFactor = M_PI / 180.;
45 return conversionFactor * angle;
46}
47
48template <typename T>
49decltype(util::sqrt(T())) degreeToRadian(T angle)
50{
51 return degreeToRadian(Vector<T, 1>(angle))[0];
52}
53
54template <typename T, unsigned D>
57{
58 constexpr BaseType<decltype(util::sqrt(T()))> conversionFactor = 180. / M_PI;
59 return conversionFactor * angle;
60}
61
62template <typename T>
63decltype(util::sqrt(T())) radianToDegree(T angle)
64{
65 return radianToDegree(Vector<T, 1>(angle))[0];
66}
67
68template <typename T, unsigned D>
71{
73
74 if constexpr (D == 2) {
75 T const cos = util::cos(angle[0]);
76 T const sin = util::sin(angle[0]);
77
78 // row 1
79 rotationMatrix[0] = cos;
80 rotationMatrix[1] = -sin;
81 // row 2
82 rotationMatrix[2] = sin;
83 rotationMatrix[3] = cos;
84 }
85 else {
86 T const cos[3] = {util::cos(angle[0]), util::cos(angle[1]),
87 util::cos(angle[2])};
88 T const sin[3] = {util::sin(angle[0]), util::sin(angle[1]),
89 util::sin(angle[2])};
90
91 // |x0| / 0 1 2 \ |x1|
92 // |y0| | 3 4 5 | = |x1|
93 // |z0| \ 6 7 8 / |x1|
94
95 // row 1
96 rotationMatrix[0] = cos[1] * cos[2];
97 rotationMatrix[1] = sin[0] * sin[1] * cos[2] - cos[0] * sin[2];
98 rotationMatrix[2] = cos[0] * sin[1] * cos[2] + sin[0] * sin[2];
99 // row 2
100 rotationMatrix[3] = cos[1] * sin[2];
101 rotationMatrix[4] = sin[0] * sin[1] * sin[2] + cos[0] * cos[2];
102 rotationMatrix[5] = cos[0] * sin[1] * sin[2] - sin[0] * cos[2];
103 // row 3
104 rotationMatrix[6] = -sin[1];
105 rotationMatrix[7] = sin[0] * cos[1];
106 rotationMatrix[8] = cos[0] * cos[1];
107 }
108
109 return rotationMatrix;
110}
111
112template <typename T>
114 return Vector{m[0], m[2],
115 m[1], m[3]};
116}
117
118template <typename T>
120 return Vector{m[0], m[3], m[6],
121 m[1], m[4], m[7],
122 m[2], m[5], m[8]};
123}
124
126template <typename T, unsigned D>
129 const Vector<T,D>& b) any_platform
130{
131 return Vector<T,D>([&](unsigned iD) -> T {
132 T element{};
133 for (unsigned jD=0; jD < D; ++jD) {
134 element += M[iD*D + jD] * b[jD];
135 }
136 return element;
137 });
138}
139
141template <typename T, unsigned D>
145{
147 for (unsigned i=0; i < D; ++i) {
148 for (unsigned j=0; j < D; ++j) {
149 for (unsigned k=0; k < D; ++k) {
150 C[i*D + j] += A[i*D + k] * B[k*D + j];
151 }
152 }
153 }
154 return C;
155}
156
157template <typename T, unsigned D>
159 const Vector<T, utilities::dimensions::convert<D>::matrix>& rotationMatrix)
160{
161 if constexpr (D == 2) {
162 return Vector<T, 4>(rotationMatrix[0], rotationMatrix[2], rotationMatrix[1],
163 rotationMatrix[3]);
164 }
165 else {
166
167 //Individual Entries ( source: https://doi.org/10.1016/j.compfluid.2018.02.027 )
168 // |x0| / 0 3 6 \ |x1|
169 // |y0| | 1 4 7 | = |x1|
170 // |z0| \ 2 5 8 / |x1|
171
172 return Vector<T, 9>(rotationMatrix[0], rotationMatrix[3], rotationMatrix[6],
173 rotationMatrix[1], rotationMatrix[4], rotationMatrix[7],
174 rotationMatrix[2], rotationMatrix[5],
175 rotationMatrix[8]);
176 }
177 __builtin_unreachable();
178}
179
180template <typename T, unsigned D>
187
189template <typename T, unsigned D,
190 bool OUTPUT_USES_ROTATION_CENTER_AS_ORIGIN = false>
192 const Vector<T, D>& input,
193 const Vector<T, utilities::dimensions::convert<D>::matrix>& rotationMatrix,
194 const Vector<T, D>& rotationCenter = Vector<T, D>(0.))
195{
196 const Vector<T, D> dist = input - rotationCenter;
197 Vector<T, D> rotated;
198
199 if constexpr (D == 2) {
200 rotated =
201 Vector<T, 2>(dist[0] * rotationMatrix[0] + dist[1] * rotationMatrix[1],
202 dist[0] * rotationMatrix[2] + dist[1] * rotationMatrix[3]);
203 }
204 else {
205 rotated =
206 Vector<T, 3>(rotationMatrix[0] * dist[0] + rotationMatrix[1] * dist[1] +
207 rotationMatrix[2] * dist[2],
208 rotationMatrix[3] * dist[0] + rotationMatrix[4] * dist[1] +
209 rotationMatrix[5] * dist[2],
210 rotationMatrix[6] * dist[0] + rotationMatrix[7] * dist[1] +
211 rotationMatrix[8] * dist[2]);
212 }
213
214 if constexpr (!OUTPUT_USES_ROTATION_CENTER_AS_ORIGIN) {
215 return rotationCenter + rotated;
216 }
217 else {
218 return rotated;
219 }
220
221 __builtin_unreachable();
222}
223
225template <typename T, unsigned D,
226 bool OUTPUT_USES_ROTATION_CENTER_AS_ORIGIN = false>
228 const Vector<T, D>& input,
229 const Vector<T, utilities::dimensions::convert<D>::matrix>& rotationMatrix,
230 const Vector<T, D>& rotationCenter = Vector<T, D>(0.))
231{
233 invertRotationMatrix<T, D>(rotationMatrix);
234 return executeRotation(input, invRotationMatrix, rotationCenter);
235}
236
238template <typename T, unsigned D>
240 const Vector<T, D>& rotationCenter, const Vector<T, D>& velocity,
242 angularVelocity,
243 const Vector<T, D>& position)
244{
245 if constexpr (D == 2) {
246 // two dimensions: u = U + w x r = (Ux, Uy, 0) + (0,0,w) x (X,Y,0) = (Ux, Uy, 0) + (-w*Y, w*X, 0)
247 return Vector<T, 2>(
248 velocity[0] - angularVelocity[0] * (position[1] - rotationCenter[1]),
249 velocity[1] + angularVelocity[0] * (position[0] - rotationCenter[0]));
250 }
251 else {
252 // three dimensions: u = U + w x r = (Ux, Uy, Uz) + (wx,wy,wz) x (X,Y,Z) = (Ux, Uy, Uz) + (wy*Z-wz*Y, wz*X-wx*Z, wx*Y-wy*X)
253 return velocity +
254 crossProduct3D(angularVelocity, position - rotationCenter);
255 }
256 __builtin_unreachable();
257}
258
260template <typename T>
262 const Vector<T, 9>& rotationMatrix)
263{
264 // I' = R(angle) * I * R(angle)^T
265 // TODO: The inertia tensor is symmetric - make use of it
266 T data[3][3] = {
267 {mofi[0], T {}, T {}},
268 { T {}, mofi[1], T {}},
269 { T {}, T {}, mofi[2]}
270 };
271 Matrix<T, 3, 3> inertiaTensor(data);
272 const Matrix<T, 3, 3> _rotationMatrix(rotationMatrix);
273 inertiaTensor =
274 _rotationMatrix * inertiaTensor * (_rotationMatrix.transpose());
275
276 return inertiaTensor;
277}
278
279} // namespace util
280
281} // namespace olb
282
283#endif
#define M_PI
Matrix with a defined number of ROWS and columns (COLS)
Definition matrix.h:33
constexpr Matrix< T, COLS, ROWS > transpose() const
Definition matrix.h:127
Plain old scalar vector.
decltype(Vector< decltype(util::sqrt(T())), D >()) radianToDegree(const Vector< T, D > &angle)
Vector< T, D > invertRotation(const Vector< T, D > &input, const Vector< T, utilities::dimensions::convert< D >::matrix > &rotationMatrix, const Vector< T, D > &rotationCenter=Vector< T, D >(0.))
Rotates the input around the rotationCenter with a given rotationMatrix in the opposite direction.
Expr sqrt(Expr x)
Definition expr.cpp:225
Vector< T, utilities::dimensions::convert< D >::matrix > matrixMatrixProduct(const Vector< T, utilities::dimensions::convert< D >::matrix > &A, const Vector< T, utilities::dimensions::convert< D >::matrix > &B) any_platform
Compute C=AB for square matrices.
constexpr Matrix< T, 3, 3 > rotateMofi(const Vector< T, 3 > &mofi, const Vector< T, 9 > &rotationMatrix)
Rotate moment of inertia (mofi)
ADf< T, DIM > sin(const ADf< T, DIM > &a)
Definition aDiff.h:569
decltype(Vector< decltype(util::sqrt(T())), D >()) degreeToRadian(const Vector< T, D > &angle)
Vector< T, D > executeRotation(const Vector< T, D > &input, const Vector< T, utilities::dimensions::convert< D >::matrix > &rotationMatrix, const Vector< T, D > &rotationCenter=Vector< T, D >(0.))
Rotates the input around the rotationCenter with a given rotationMatrix.
Vector< T, utilities::dimensions::convert< D >::matrix > calculateRotationMatrix(const Vector< T, utilities::dimensions::convert< D >::rotation > &angle) any_platform
constexpr Vector< T, D > calculateLocalVelocity(const Vector< T, D > &rotationCenter, const Vector< T, D > &velocity, const Vector< T, utilities::dimensions::convert< D >::rotation > &angularVelocity, const Vector< T, D > &position)
Calculate local velocity.
Vector< T, 4 > inverseRotation(const Vector< T, 4 > &m) any_platform
Vector< T, D > matrixVectorProduct(const Vector< T, utilities::dimensions::convert< D >::matrix > &M, const Vector< T, D > &b) any_platform
Compute v=M b.
Vector< T, utilities::dimensions::convert< D >::matrix > invertRotationMatrix(const Vector< T, utilities::dimensions::convert< D >::matrix > &rotationMatrix)
Vector< T, utilities::dimensions::convert< D >::matrix > calculateInverseRotationMatrix(const Vector< T, utilities::dimensions::convert< D >::rotation > &angle)
ADf< T, DIM > cos(const ADf< T, DIM > &a)
Definition aDiff.h:578
Top level namespace for all of OpenLB.
Vector(T &&t, Ts &&... ts) -> Vector< std::remove_cvref_t< T >, 1+sizeof...(Ts)>
typename util::BaseTypeHelper< T >::type BaseType
Definition baseType.h:59
constexpr Vector< T, 3 > crossProduct3D(const ScalarVector< T, 3, IMPL > &a, const ScalarVector< T, 3, IMPL_ > &b) any_platform
Definition vector.h:263
#define any_platform
Define preprocessor macros for device-side functions, constant storage.
Definition platform.h:77
Converts dimensions by deriving from given cartesian dimension D.
efficient implementation of a vector class