FreeFOAM The Cross-Platform CFD Toolkit
coordinateRotation.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 | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "coordinateRotation.H"
27 #include <OpenFOAM/dictionary.H>
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
34  defineTypeNameAndDebug(coordinateRotation, 0);
35  defineRunTimeSelectionTable(coordinateRotation, dictionary);
36 }
37 
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 
40 void Foam::coordinateRotation::calcTransform
41 (
42  const vector& axis1,
43  const vector& axis2,
44  const axisOrder& order
45 )
46 {
47  vector a = axis1 / mag(axis1);
48  vector b = axis2;
49 
50  // Absorb minor nonorthogonality into axis2
51  b = b - (b & a)*a;
52 
53  if (mag(b) < SMALL)
54  {
55  FatalErrorIn("coordinateRotation::calcTransform()")
56  << "axis1, axis2 appear co-linear: "
57  << axis1 << ", " << axis2 << endl
58  << abort(FatalError);
59  }
60 
61  b = b / mag(b);
62  vector c = a ^ b;
63 
64  // the global -> local transformation
65  tensor Rtr;
66  switch (order)
67  {
68  case e1e2:
69  Rtr = tensor(a, b, c);
70  break;
71 
72  case e2e3:
73  Rtr = tensor(c, a, b);
74  break;
75 
76  case e3e1:
77  Rtr = tensor(b, c, a);
78  break;
79 
80  default:
81  FatalErrorIn("coordinateRotation::calcTransform()")
82  << "programmer error" << endl
83  << abort(FatalError);
84  // To satisfy compiler warnings
85  Rtr = tensor::zero;
86  break;
87  }
88 
89  // the local -> global transformation
90  tensor::operator=( Rtr.T() );
91 }
92 
93 
94 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
95 
97 :
99 {}
100 
101 
103 (
104  const vector& axis,
105  const vector& dir
106 )
107 :
109 {
110  calcTransform(axis, dir, e3e1);
111 }
112 
113 
115 (
116  const dictionary& dict
117 )
118 :
120 {
121  operator=(dict);
122 }
123 
124 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
125 
127 (
128  const dictionary& dict
129 )
130 {
131  if (debug)
132  {
133  Pout<< "coordinateRotation::New(const dictionary&) : "
134  << "constructing coordinateRotation"
135  << endl;
136  }
137 
138  // default type is self (alias: "axes")
139  word rotType(typeName_());
140  dict.readIfPresent("type", rotType);
141 
142  // can (must) construct base class directly
143  if (rotType == typeName_() || rotType == "axes")
144  {
146  }
147 
148 
149  dictionaryConstructorTable::iterator cstrIter =
150  dictionaryConstructorTablePtr_->find(rotType);
151 
152  if (cstrIter == dictionaryConstructorTablePtr_->end())
153  {
155  (
156  "coordinateRotation::New(const dictionary&)",
157  dict
158  ) << "Unknown coordinateRotation type "
159  << rotType << nl << nl
160  << "Valid coordinateRotation types are :" << nl
161  << "[default: axes " << typeName_() << "]"
162  << dictionaryConstructorTablePtr_->sortedToc()
163  << exit(FatalIOError);
164  }
165 
166  return autoPtr<coordinateRotation>(cstrIter()(dict));
167 }
168 
169 
170 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
171 
173 {
174  if (debug)
175  {
176  Pout<< "coordinateRotation::operator=(const dictionary&) : "
177  << "assign from " << rhs << endl;
178  }
179 
180  // allow as embedded sub-dictionary "coordinateRotation"
181  const dictionary& dict =
182  (
183  rhs.found(typeName_())
184  ? rhs.subDict(typeName_())
185  : rhs
186  );
187 
188  vector axis1, axis2;
189  axisOrder order(e3e1);
190 
191  if (dict.readIfPresent("e1", axis1) && dict.readIfPresent("e2", axis2))
192  {
193  order = e1e2;
194  }
195  else if (dict.readIfPresent("e2", axis1) && dict.readIfPresent("e3", axis2))
196  {
197  order = e2e3;
198  }
199  else if (dict.readIfPresent("e3", axis1) && dict.readIfPresent("e1", axis2))
200  {
201  order = e3e1;
202  }
203  else if (dict.found("axis") || dict.found("direction"))
204  {
205  // let it bomb if only one of axis/direction is defined
206  order = e3e1;
207  dict.lookup("axis") >> axis1;
208  dict.lookup("direction") >> axis2;
209  }
210  else
211  {
212  // unspecified axes revert to the global system
214  return;
215  }
216 
217  calcTransform(axis1, axis2, order);
218 }
219 
220 
221 // ************************ vim: set sw=4 sts=4 et: ************************ //