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-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 
35 namespace Foam
36 {
37  namespace coordinateRotations
38  {
40 
41  // Standard short name
43  (
45  axes,
46  dictionary,
47  axes
48  );
49 
50  // Longer name - Compat 1806
52  (
54  axes,
55  dictionary,
57  );
58  }
59 }
60 
61 
62 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
63 
65 (
66  const vector& axis1,
67  const vector& axis2,
68  axisOrder order
69 )
70 {
71  const scalar magAxis1(mag(axis1));
72  scalar magAxis2(mag(axis2));
73 
74  if (magAxis1 < ROOTVSMALL)
75  {
77  << "Dominant coordinate axis cannot have zero length"
78  << nl << endl
79  << abort(FatalError);
80  }
81 
82  const vector ax1(axis1 / magAxis1); // normalise
83  vector ax2(axis2);
84 
85  if (magAxis2 < ROOTVSMALL)
86  {
87  // axis2 == Zero : Use best-guess for the second axis.
88  ax2 = findOrthogonal(axis1);
89  }
90 
91  // Remove colinear component
92  ax2 -= ((ax1 & ax2) * ax1);
93 
94  magAxis2 = mag(ax2);
95 
96  if (magAxis2 < SMALL)
97  {
99  << "axis1, axis2 appear to be co-linear: "
100  << axis1 << ", " << axis2 << " Revert to guessing axis2"
101  << nl << endl;
102 
103  ax2 = findOrthogonal(axis1);
104 
105  // Remove colinear component
106  ax2 -= ((ax1 & ax2) * ax1);
107 
108  magAxis2 = mag(ax2);
109 
110  if (magAxis2 < SMALL)
111  {
113  << "Could not find an appropriate second axis"
114  << nl << endl
115  << abort(FatalError);
116  }
117  }
118 
119  ax2 /= magAxis2; // normalise
120 
121 
122  // The local axes are columns of the rotation matrix
123 
124  tensor rotTensor;
125 
126  switch (order)
127  {
128  case E1_E2:
129  {
130  rotTensor.col<0>(ax1);
131  rotTensor.col<1>(ax2);
132  rotTensor.col<2>(ax1^ax2);
133  break;
134  }
135  case E2_E3:
136  {
137  rotTensor.col<0>(ax1^ax2);
138  rotTensor.col<1>(ax1);
139  rotTensor.col<2>(ax2);
140  break;
141  }
142  case E3_E1:
143  case E3_E1_COMPAT:
144  {
145  rotTensor.col<0>(ax2);
146  rotTensor.col<1>(ax1^ax2);
147  rotTensor.col<2>(ax1);
148  break;
149  }
150  }
151 
152  return rotTensor;
153 }
154 
155 
156 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
157 
159 {
160  if
161  (
162  dict.readIfPresent("e1", axis1_)
163  && dict.readIfPresent("e2", axis2_)
164  )
165  {
166  order_ = E1_E2;
167  }
168  else if
169  (
170  dict.readIfPresent("e2", axis1_)
171  && dict.readIfPresent("e3", axis2_)
172  )
173  {
174  order_ = E2_E3;
175  }
176  else if
177  (
178  dict.readIfPresent("e3", axis1_)
179  && dict.readIfPresent("e1", axis2_)
180  )
181  {
182  order_ = E3_E1;
183  }
184  else if
185  (
186  dict.readIfPresent("axis", axis1_)
187  && dict.readIfPresent("direction", axis2_)
188  )
189  {
191  }
192  else
193  {
195  << "No entries of the type (e1, e2) or (e2, e3) or (e3, e1) found"
196  << exit(FatalIOError);
197  }
198 }
199 
200 
201 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
202 
204 :
206  axis1_(0,0,1), // e3 = global Z
207  axis2_(1,0,0), // e1 = global X
208  order_(E3_E1)
209 {}
210 
211 
213 :
215  axis1_(crot.axis1_),
216  axis2_(crot.axis2_),
217  order_(crot.order_)
218 {}
219 
220 
222 (
223  const vector& axis1,
224  const vector& axis2,
225  axisOrder order
226 )
227 :
229  axis1_(axis1),
230  axis2_(axis2),
231  order_(order)
232 {}
233 
234 
236 :
237  coordinateRotations::axes(axis, Zero, E3_E1_COMPAT) // Guess second axis
238 {}
239 
240 
242 :
243  coordinateRotations::axes()
244 {
245  read(dict);
246 }
247 
248 
249 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
250 
252 {
253  axis1_ = vector(0,0,1); // primary axis (e3, global Z)
254  axis2_ = vector(1,0,0); // secondary axis (e1, global X)
255  order_ = E3_E1;
256 }
257 
258 
260 {
261  return axes::rotation(axis1_, axis2_, order_);
262 }
263 
264 
265 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
266 
268 {
269  switch (order_)
270  {
271  case E1_E2:
272  os << "e1: " << axis1_ << " e2: " << axis2_;
273  break;
274  case E2_E3:
275  os << "e2: " << axis1_ << " e3: " << axis2_;
276  break;
277  case E3_E1:
278  os << "e1: " << axis2_ << " e3: " << axis1_;
279  break;
280  case E3_E1_COMPAT:
281  os << "axis: " << axis1_ << " direction: " << axis2_;
282  break;
283  }
284 }
285 
286 
288 (
289  const word& keyword,
290  Ostream& os
291 ) const
292 {
293  // We permit direct embedding of the axes specification without
294  // requiring a sub-dictionary.
295 
296  const bool subDict = !keyword.empty();
297 
298  if (subDict)
299  {
300  os.beginBlock(keyword);
301  os.writeEntry("type", type());
302  }
303 
304  switch (order_)
305  {
306  case E1_E2:
307  {
308  os.writeEntry("e1", axis1_);
309  os.writeEntry("e2", axis2_);
310  break;
311  }
312  case E2_E3:
313  {
314  os.writeEntry("e2", axis1_);
315  os.writeEntry("e3", axis2_);
316  break;
317  }
318  case E3_E1:
319  {
320  os.writeEntry("e1", axis2_);
321  os.writeEntry("e3", axis1_);
322  break;
323  }
324  case E3_E1_COMPAT:
325  {
326  os.writeEntry("axis", axis1_);
327  os.writeEntry("direction", axis2_);
328  break;
329  }
330  }
331 
332  if (subDict)
333  {
334  os.endBlock();
335  }
336 }
337 
338 
339 // ************************************************************************* //
Foam::Tensor< scalar >
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::coordinateRotations::axes::axis1_
vector axis1_
The primary axis.
Definition: axesRotation.H:126
Foam::coordinateRotations::axes::read
void read(const dictionary &dict)
Read from dictionary.
Definition: axesRotation.C:158
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::coordinateRotations::axes::axis2_
vector axis2_
The secondary axis.
Definition: axesRotation.H:129
Foam::coordinateRotations::axes::order_
axisOrder order_
The axis order.
Definition: axesRotation.H:132
Foam::coordinateRotations::axes::R
virtual tensor R() const
The rotation tensor calculated from the specified axes and order.
Definition: axesRotation.C:259
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::coordinateRotations::axes
A coordinateRotation specified using global axes.
Definition: axesRotation.H:104
Foam::coordinateRotations::axes::write
virtual void write(Ostream &os) const
Write information.
Definition: axesRotation.C:267
Foam::coordinateRotations::axes::clear
virtual void clear()
Reset specification.
Definition: axesRotation.C:251
Foam::coordinateRotations::axes::axes
axes()
Default construct - an identity transform.
Definition: axesRotation.C:203
Foam::coordinateRotations::axes::axisOrder
axisOrder
The order/combination of local axes for the axes-rotation definition.
Definition: axesRotation.H:112
Foam::coordinateRotation
User specification of a coordinate rotation.
Definition: coordinateRotation.H:78
Foam::coordinateRotations::defineTypeName
defineTypeName(axes)
Foam::coordinateRotations::axes::writeEntry
virtual void writeEntry(const word &keyword, Ostream &os) const
Write dictionary entry.
Definition: axesRotation.C:288
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
os
OBJstream os(runTime.globalPath()/outputName)
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::coordinateRotations::axes::E1_E2
The axis1 (dominant) is local X, axis2 is local Y.
Definition: axesRotation.H:114
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::coordinateRotations::addNamedToRunTimeSelectionTable
addNamedToRunTimeSelectionTable(coordinateRotation, axes, dictionary, axes)
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::coordinateRotations::axes::E2_E3
The axis1 (dominant) is local Y, axis2 is local Z.
Definition: axesRotation.H:115
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::coordinateRotations::axes::E3_E1_COMPAT
E3_E1 specified as axis/direction.
Definition: axesRotation.H:117
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::Vector< scalar >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
dictionary.H
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::coordinateRotations::axes::E3_E1
The axis1 (dominant) is local Z, axis2 is local X.
Definition: axesRotation.H:116
Foam::coordinateRotations::axes::rotation
static tensor rotation(const vector &axis1, const vector &axis2, axisOrder order=E3_E1)
The rotation tensor calculated from two axes and their order.
Definition: axesRotation.C:65
Foam::Tensor::col
Vector< Cmpt > col() const
Extract vector for given column.
axesRotation.H
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328