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-2018 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 :
214  coordinateRotation(crot),
215  axis1_(crot.axis1_),
216  axis2_(crot.axis2_),
217  order_(crot.order_)
218 {}
219 
220 
222 :
223  coordinateRotation(std::move(crot)),
224  axis1_(std::move(crot.axis1_)),
225  axis2_(std::move(crot.axis2_)),
226  order_(crot.order_)
227 {}
228 
229 
231 (
232  const vector& axis1,
233  const vector& axis2,
234  axisOrder order
235 )
236 :
238  axis1_(axis1),
239  axis2_(axis2),
240  order_(order)
241 {}
242 
243 
245 :
246  coordinateRotations::axes(axis, Zero, E3_E1_COMPAT) // Guess second axis
247 {}
248 
249 
251 :
252  coordinateRotations::axes()
253 {
254  read(dict);
255 }
256 
257 
258 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
259 
261 {
262  axis1_ = vector(0,0,1); // e3 = global Z
263  axis2_ = vector(1,0,0); // e1 = global X
264  order_ = E3_E1;
265 }
266 
267 
269 {
270  return axes::rotation(axis1_, axis2_, order_);
271 }
272 
273 
274 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
275 
277 {
278  switch (order_)
279  {
280  case E1_E2:
281  os << "e1: " << axis1_ << " e2: " << axis2_;
282  break;
283  case E2_E3:
284  os << "e2: " << axis1_ << " e3: " << axis2_;
285  break;
286  case E3_E1:
287  os << "e1: " << axis2_ << " e3: " << axis1_;
288  break;
289  case E3_E1_COMPAT:
290  os << "axis: " << axis1_ << " direction: " << axis2_;
291  break;
292  }
293 }
294 
295 
297 (
298  const word& keyword,
299  Ostream& os
300 ) const
301 {
302  // We permit direct embedding of the axes specification without
303  // requiring a sub-dictionary.
304 
305  const bool subDict = !keyword.empty();
306 
307  if (subDict)
308  {
309  os.beginBlock(keyword);
310  os.writeEntry("type", type());
311  }
312 
313  switch (order_)
314  {
315  case E1_E2:
316  {
317  os.writeEntry("e1", axis1_);
318  os.writeEntry("e2", axis2_);
319  break;
320  }
321  case E2_E3:
322  {
323  os.writeEntry("e2", axis1_);
324  os.writeEntry("e3", axis2_);
325  break;
326  }
327  case E3_E1:
328  {
329  os.writeEntry("e1", axis2_);
330  os.writeEntry("e3", axis1_);
331  break;
332  }
333  case E3_E1_COMPAT:
334  {
335  os.writeEntry("axis", axis1_);
336  os.writeEntry("direction", axis2_);
337  break;
338  }
339  }
340 
341  if (subDict)
342  {
343  os.endBlock();
344  }
345 }
346 
347 
348 // ************************************************************************* //
Foam::Tensor
A templated (3 x 3) tensor of objects of <T> derived from MatrixSpace.
Definition: complexI.H:275
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
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:268
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::Ostream::beginBlock
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition: Ostream.C:91
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:276
Foam::coordinateRotations::axes::clear
virtual void clear()
Reset specification.
Definition: axesRotation.C:260
Foam::coordinateRotations::axes::axes
axes()
Construct null - 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:77
Foam::coordinateRotations::defineTypeName
defineTypeName(axes)
Foam::coordinateRotations::axes::writeEntry
virtual void writeEntry(const word &keyword, Ostream &os) const
Write dictionary entry.
Definition: axesRotation.C:297
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::Ostream::endBlock
virtual Ostream & endBlock()
Write end block group.
Definition: Ostream.C:109
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:121
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:381
Foam::nl
constexpr char nl
Definition: Ostream.H:385
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
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:232
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:401
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:303