Loading...
Searching...
No Matches
axesRotation.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2017-2022 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "axesRotation.H"
30#include "dictionary.H"
32
33// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34
35namespace Foam
37namespace coordinateRotations
38{
39
41
42 // Standard short name
44 (
46 axes,
48 axes
49 );
50
51 // Long name - Compat 1806
53 (
55 axes,
57 axes,
59 1806
60 );
62} // End namespace coordinateRotations
63} // End namespace Foam
64
65
66// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
67
69(
70 const vector& axis1,
71 const vector& axis2,
72 axisOrder order
73)
74{
75 const scalar magAxis1(mag(axis1));
76 scalar magAxis2(mag(axis2));
77
78 if (magAxis1 < ROOTVSMALL)
79 {
81 << "Dominant coordinate axis cannot have zero length"
82 << nl << endl
83 << abort(FatalError);
84 }
85
86 const vector ax1(axis1 / magAxis1); // normalise
87 vector ax2(axis2);
88
89 if (magAxis2 < ROOTVSMALL)
90 {
91 // axis2 == Zero : Use best-guess for the second axis.
92 ax2 = findOrthogonal(axis1);
93 }
94
95 ax2.removeCollinear(ax1);
96
97 magAxis2 = mag(ax2);
98
99 if (magAxis2 < SMALL)
100 {
102 << "axis1, axis2 appear to be co-linear: "
103 << axis1 << ", " << axis2 << " Revert to guessing axis2"
104 << nl << endl;
105
106 ax2 = findOrthogonal(axis1);
107
108 ax2.removeCollinear(ax1);
109
110 magAxis2 = mag(ax2);
111
112 if (magAxis2 < SMALL)
113 {
115 << "Could not find an appropriate second axis"
116 << nl << endl
117 << abort(FatalError);
118 }
119 }
120
121 ax2 /= magAxis2; // normalise
122
123
124 // The local axes are columns of the rotation matrix
125
126 tensor rotTensor;
127
128 switch (order)
129 {
130 case E1_E2:
131 {
132 rotTensor.col<0>(ax1);
133 rotTensor.col<1>(ax2);
134 rotTensor.col<2>(ax1^ax2);
135 break;
136 }
137 case E2_E3:
138 {
139 rotTensor.col<0>(ax1^ax2);
140 rotTensor.col<1>(ax1);
141 rotTensor.col<2>(ax2);
142 break;
143 }
144 case E3_E1:
145 case E3_E1_COMPAT:
146 {
147 rotTensor.col<0>(ax2);
148 rotTensor.col<1>(ax1^ax2);
149 rotTensor.col<2>(ax1);
150 break;
151 }
152 }
154 return rotTensor;
155}
156
157
158// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
159
161{
162 if
163 (
164 dict.readIfPresent("e1", axis1_)
165 && dict.readIfPresent("e2", axis2_)
166 )
167 {
168 order_ = E1_E2;
169 }
170 else if
171 (
172 dict.readIfPresent("e2", axis1_)
173 && dict.readIfPresent("e3", axis2_)
174 )
175 {
176 order_ = E2_E3;
177 }
178 else if
179 (
180 dict.readIfPresent("e3", axis1_)
181 && dict.readIfPresent("e1", axis2_)
182 )
183 {
184 order_ = E3_E1;
185 }
186 else if
187 (
188 dict.readIfPresent("axis", axis1_)
189 && dict.readIfPresent("direction", axis2_)
190 )
191 {
192 order_ = E3_E1_COMPAT;
193 }
194 else
195 {
197 << "No entries of the type (e1, e2) or (e2, e3) or (e3, e1) found"
199 }
200}
201
202
203// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
204
206:
208 axis1_(0,0,1), // e3 = global Z
209 axis2_(1,0,0), // e1 = global X
211{}
212
213
215:
217 axis1_(crot.axis1_),
218 axis2_(crot.axis2_),
219 order_(crot.order_)
220{}
221
222
224(
225 const vector& axis1,
226 const vector& axis2,
227 axisOrder order
228)
229:
231 axis1_(axis1),
232 axis2_(axis2),
233 order_(order)
234{}
235
238:
239 coordinateRotations::axes(axis, Zero, E3_E1_COMPAT) // Guess second axis
240{}
241
242
244:
247 read(dict);
248}
249
250
251// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
252
255 axis1_ = vector(0,0,1); // primary axis (e3, global Z)
256 axis2_ = vector(1,0,0); // secondary axis (e1, global X)
257 order_ = E3_E1;
258}
259
260
264}
265
266
267// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
268
270{
271 switch (order_)
272 {
273 case E1_E2:
274 os << "e1: " << axis1_ << " e2: " << axis2_;
275 break;
276 case E2_E3:
277 os << "e2: " << axis1_ << " e3: " << axis2_;
278 break;
279 case E3_E1:
280 os << "e1: " << axis2_ << " e3: " << axis1_;
281 break;
283 os << "axis: " << axis1_ << " direction: " << axis2_;
284 break;
285 }
286}
287
288
290(
291 const word& keyword,
292 Ostream& os
293) const
294{
295 // We permit direct embedding of the axes specification without
296 // requiring a sub-dictionary.
297
298 const bool subDict = !keyword.empty();
299
300 if (subDict)
301 {
302 os.beginBlock(keyword);
303 os.writeEntry("type", type());
304 }
305
306 switch (order_)
307 {
308 case E1_E2:
309 {
310 os.writeEntry("e1", axis1_);
311 os.writeEntry("e2", axis2_);
312 break;
313 }
314 case E2_E3:
315 {
316 os.writeEntry("e2", axis1_);
317 os.writeEntry("e3", axis2_);
318 break;
319 }
320 case E3_E1:
321 {
322 os.writeEntry("e1", axis2_);
323 os.writeEntry("e3", axis1_);
324 break;
325 }
326 case E3_E1_COMPAT:
327 {
328 os.writeEntry("axis", axis1_);
329 os.writeEntry("direction", axis2_);
330 break;
331 }
332 }
333
334 if (subDict)
335 {
336 os.endBlock();
337 }
338}
339
340
341// ************************************************************************* //
Macros for easy insertion into run-time selection tables.
#define addAliasToRunTimeSelectionTable(baseType, thisType, argNames, lookup, other, ver)
Add lookup alias for runTime selection.
#define addNamedToRunTimeSelectionTable(baseType, thisType, argNames, lookupName)
Add to construction table with 'lookupName' as the key.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
Vector< Cmpt > col() const
Extract vector for given column: compile-time check of index.
Vector< Cmpt > & removeCollinear(const Vector< Cmpt > &unitVec)
Inplace removal of components that are collinear to the given unit vector.
Definition VectorI.H:136
User specification of a coordinate rotation.
static vector findOrthogonal(const vector &axis)
Determine best-guess for an orthogonal axis.
A coordinateRotation specified using global axes.
axes()
Default construct - an identity transform.
virtual tensor R() const
The rotation tensor calculated from the specified axes and order.
void read(const dictionary &dict)
Read from dictionary.
virtual void write(Ostream &os) const
Write information.
virtual void writeEntry(const word &keyword, Ostream &os) const
Write dictionary entry.
axisOrder order_
The axis order.
vector axis1_
The primary axis.
axisOrder
The order/combination of local axes for the axes-rotation definition.
@ E2_E3
The axis1 (dominant) is local Y, axis2 is local Z.
@ E1_E2
The axis1 (dominant) is local X, axis2 is local Y.
@ E3_E1_COMPAT
E3_E1 specified as axis/direction.
@ E3_E1
The axis1 (dominant) is local Z, axis2 is local X.
virtual void clear()
Reset specification.
vector axis2_
The secondary axis.
static tensor rotation(const vector &axis1, const vector &axis2, axisOrder order=E3_E1)
The rotation tensor calculated from two axes and their order.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeName(Type)
Define the typeName.
Definition className.H:113
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
OBJstream os(runTime.globalPath()/outputName)
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for coordinate system rotations.
Namespace for OpenFOAM.
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition int32.H:127
coordinateRotations::axes axesRotation
Tensor< scalar > tensor
Definition symmTensor.H:57
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition POSIX.C:801
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
errorManip< error > abort(error &err)
Definition errorManip.H:139
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
Vector< scalar > vector
Definition vector.H:57
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
dictionary dict