coordinateSystem.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) 2018-2022 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 "coordinateSystem.H"
30 #include "cartesianCS.H"
31 #include "IOstream.H"
32 #include "axesRotation.H"
33 #include "identityRotation.H"
34 #include "transform.H"
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41  defineTypeNameAndDebug(coordinateSystem, 0);
42  defineRunTimeSelectionTable(coordinateSystem, dictionary);
43  defineRunTimeSelectionTable(coordinateSystem, registry);
44 }
45 
47 
48 
49 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
50 
51 namespace
52 {
53 
54 //- Can we ignore the 'type' on output?
55 // For output, can treat the base class as Cartesian too,
56 // since it defaults to cartesian on input.
57 inline bool ignoreOutputCoordType(const std::string& modelType)
58 {
59  return
60  (
61  modelType.empty()
62  || modelType == Foam::coordSystem::cartesian::typeName
63  || modelType == Foam::coordinateSystem::typeName
64  );
65 }
66 
67 } // End anonymous namespace
68 
69 
70 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
71 
73 (
74  const dictionary& dict,
76 )
77 {
78  origin_ = Zero;
79 
80  // The 'origin' is optional if using "coordinateSystem" dictionary itself
81  if
82  (
84  && (dict.dictName() == coordinateSystem::typeName)
85  )
86  {
88  }
89 
90  dict.readEntry("origin", origin_, keyType::LITERAL, readOrigin);
91 
92 
93  note_.clear();
94  dict.readIfPresent("note", note_);
95 
96  const auto finder = dict.csearchCompat
97  (
98  "rotation", {{"coordinateRotation", 1806}},
100  );
101 
102  if (finder.good())
103  {
104  if (finder.isDict())
105  {
106  // Use the sub-dict, which is expected to contain "type"
107  spec_ = coordinateRotation::New(finder.dict());
108  }
109  else
110  {
111  // Type specified by "rotation" primitive entry, with the balance
112  // of the rotation specified within the current dictionary too
113  const word rotationType(finder->get<word>());
114  spec_.reset(coordinateRotation::New(rotationType, dict));
115  }
116  }
117  else
118  {
119  // Fall through to expecting e1/e2/e3 specification in the dictionary
121  }
122 
123  rot_ = spec_->R();
124 }
126 
127 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
128 
130 :
131  spec_(nullptr),
132  origin_(Zero),
133  rot_(sphericalTensor::I),
134  name_(),
135  note_()
136 {}
137 
138 
140 :
141  spec_(new coordinateRotations::identity()),
142  origin_(Zero),
143  rot_(sphericalTensor::I),
144  name_(),
145  note_()
146 {}
147 
148 
150 :
152 {}
153 
154 
156 :
157  coordinateSystem(word::null, point::zero, std::move(crot))
158 {}
159 
160 
162 :
163  spec_(csys.spec_.clone()),
164  origin_(csys.origin_),
165  rot_(csys.rot_),
166  name_(csys.name_),
167  note_(csys.note_)
168 {}
169 
170 
172 :
173  spec_(std::move(csys.spec_)),
174  origin_(std::move(csys.origin_)),
175  rot_(std::move(csys.rot_)),
176  name_(std::move(csys.name_)),
177  note_(std::move(csys.note_))
178 {}
179 
180 
182 :
183  coordinateSystem(nullptr)
184 {
185  if (csys)
186  {
187  // Has valid autoPtr - move.
188  coordinateSystem::operator=(std::move(*csys));
189  csys.clear();
190  }
191  else
192  {
193  // No valid autoPtr - treat like identity
195  }
196 }
197 
198 
200 (
201  const word& name,
202  const coordinateSystem& csys
203 )
204 :
205  spec_(csys.spec_.clone()),
206  origin_(csys.origin_),
207  rot_(csys.rot_),
208  name_(name),
209  note_(csys.note_)
210 {}
211 
212 
214 (
215  const point& origin,
216  const coordinateRotation& crot
217 )
218 :
219  coordinateSystem(word::null, origin, crot)
220 {}
221 
222 
224 (
225  const word& name,
226  const point& origin,
227  const coordinateRotation& crot
228 )
229 :
230  spec_(crot.clone()),
231  origin_(origin),
232  rot_(spec_->R()),
233  name_(name),
234  note_()
235 {}
236 
237 
239 (
240  const point& origin,
241  const vector& axis,
242  const vector& dirn
243 )
244 :
245  coordinateSystem(word::null, origin, axis, dirn)
246 {}
247 
248 
250 (
251  const word& name,
252  const point& origin,
253  const vector& axis,
254  const vector& dirn
255 )
256 :
257  spec_(new coordinateRotations::axes(axis, dirn)),
258  origin_(origin),
259  rot_(spec_->R()),
260  name_(name),
261  note_()
262 {}
263 
264 
266 (
267  const dictionary& dict,
268  IOobjectOption::readOption readOrigin
269 )
270 :
271  coordinateSystem(nullptr)
272 {
273  assign(dict, readOrigin);
274 }
275 
276 
278 (
279  const dictionary& dict,
280  const word& dictName,
281  IOobjectOption::readOption readOrigin
282 )
283 :
284  coordinateSystem(nullptr)
285 {
286  if (dictName.size())
287  {
288  // Allow 'origin' to be optional if reading from a sub-dict
289  if (IOobjectOption::isReadRequired(readOrigin))
290  {
291  readOrigin = IOobjectOption::READ_IF_PRESENT;
292  }
293  assign(dict.subDict(dictName), readOrigin);
294  }
295  else
296  {
297  assign(dict, readOrigin);
298  }
299 }
301 
302 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
303 
305 {
306  spec_->clear();
307  origin_ = Zero;
308  rot_ = sphericalTensor::I;
309  note_.clear();
310 }
311 
312 
313 Foam::tensor Foam::coordinateSystem::R(const point& global) const
314 {
315  return rot_;
316 }
317 
318 
320 (
321  const UList<point>& global
322 ) const
323 {
324  return rotationsImpl(global);
325 }
326 
327 
329 (
330  const pointUIndList& global
331 ) const
332 {
333  return rotationsImpl(global);
334 }
335 
336 
338 (
339  const point& localCart
340 ) const
341 {
342  return Foam::transform(rot_, localCart) + origin_;
343 }
344 
345 
347 (
348  const point& global
349 ) const
350 {
351  return Foam::invTransform(rot_, global - origin_);
352 }
353 
354 
356 (
357  const vector& local,
358  bool translate
359 ) const
360 {
361  if (translate)
362  {
363  return this->transform(local) + origin_;
364  }
365 
366  return this->transform(local);
367 }
368 
369 
371 (
372  const vectorField& local,
373  bool translate
374 ) const
375 {
376  if (translate)
377  {
378  return this->transform(local) + origin_;
379  }
380 
381  return this->transform(local);
382 }
383 
384 
386 (
387  const vector& global,
388  bool translate
389 ) const
390 {
391  if (translate)
392  {
393  return this->invTransform(global - origin_);
394  }
395 
396  return this->invTransform(global);
397 }
398 
399 
401 (
402  const vectorField& global,
403  bool translate
404 ) const
405 {
406  if (translate)
407  {
408  return this->invTransform(global - origin_);
409  }
410 
411  return this->invTransform(global);
412 }
413 
414 
416 {
417  spec_.reset(std::move(crot));
418  if (spec_)
419  {
420  rot_ = spec_->R();
421  }
422  else
423  {
424  rot_ = sphericalTensor::I;
425  }
426 }
427 
428 
429 void Foam::coordinateSystem::write(Ostream& os) const
430 {
431  if (!valid())
432  {
433  return;
434  }
435 
436  // Suppress output of type for 'cartesian', 'coordinateSystem', ...
437  if (!ignoreOutputCoordType(type()))
438  {
439  os << type() << ' ';
440  }
441 
442  os << "origin: " << origin_ << ' ';
443  spec_->write(os);
444 }
445 
446 
448 {
449  writeEntry(coordinateSystem::typeName, os);
450 }
451 
452 
453 void Foam::coordinateSystem::writeEntry(const word& keyword, Ostream& os) const
454 {
455  if (!valid())
456  {
457  return;
458  }
459 
460  const bool subDict = !keyword.empty();
461 
462  if (subDict)
463  {
464  os.beginBlock(keyword);
465 
466  // Suppress output of type for 'cartesian', 'coordinateSystem', ...
467  if (!ignoreOutputCoordType(type()))
468  {
469  os.writeEntry<word>("type", type());
470  }
471 
472  if (note_.size())
473  {
474  // The 'note' is optional
475  os.writeEntry("note", note_);
476  }
477  }
478 
479  os.writeEntry("origin", origin_);
480 
481  spec_->writeEntry("rotation", os);
482 
483  if (subDict)
484  {
485  os.endBlock();
486  }
487 }
489 
490 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
491 
493 {
494  name_ = csys.name_;
495  note_ = csys.note_;
496  origin_ = csys.origin_;
497 
498  // Some extra safety
499  if (csys.spec_)
500  {
501  rotation(csys.spec_.clone());
502  }
503  else
504  {
505  spec_.reset(new coordinateRotations::identity());
506  rot_ = sphericalTensor::I;
507  }
508 }
509 
510 
511 void Foam::coordinateSystem::operator=(coordinateSystem&& csys)
512 {
513  name_ = std::move(csys.name_);
514  note_ = std::move(csys.note_);
515  spec_ = std::move(csys.spec_);
516  origin_ = csys.origin_;
517  rot_ = csys.rot_;
518 }
519 
520 
522 {
524 }
525 
526 
528 {
529  coordinateSystem::operator=(std::move(*csys));
530  csys.clear();
531 }
533 
534 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
535 
537 {
538  return
539  (
540  a.type() != b.type()
541  || a.origin() != b.origin()
542  || a.R() != b.R()
543  );
544 }
545 
546 
547 Foam::Ostream& Foam::operator<<(Ostream& os, const coordinateSystem& csys)
548 {
549  csys.write(os);
551  return os;
552 }
553 
554 
555 // ************************************************************************* //
virtual vector globalToLocal(const vector &global, bool translate) const
From global Cartesian system to the local coordinate system with optional translation for the origin...
Base class for coordinate system specification, the default coordinate system type is cartesian ...
User specification of a coordinate rotation.
dictionary dict
virtual Ostream & write(const char c)
Write character.
Definition: OBJstream.C:71
word name_
The name of the coordinate system (optional)
dimensionSet invTransform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:535
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:120
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:45
virtual vector localToGlobal(const vector &local, bool translate) const
From local coordinate system to the global Cartesian system with optional translation for the origin...
const word dictName("faMeshDefinition")
point origin_
The coordinate system origin.
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:312
Macros for easy insertion into run-time selection tables.
virtual void clear()
Reset origin and rotation to an identity coordinateSystem.
coordinateSystem()
Default construct. This is an identity coordinate system.
An identity coordinateRotation.
virtual const point & origin() const
Return origin.
virtual const tensor & R() const
Return const reference to the rotation tensor.
point transformPoint(const point &localCart) const
Transform point and add origin offset.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:752
string note_
An optional note describing the coordinate system.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:52
static const Identity< scalar > I
Definition: Identity.H:100
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Definition: labelList.C:31
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
A class for handling words, derived from Foam::string.
Definition: word.H:63
3D tensor transformation operations.
virtual Ostream & endBlock()
Write end block group.
Definition: Ostream.C:98
point invTransformPoint(const point &global) const
Remove origin offset and inverse transform point.
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
virtual const coordinateRotation & rotation() const
The rotation specification.
bool local
Definition: EEqn.H:20
String literal.
Definition: keyType.H:82
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:99
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
defineTypeNameAndDebug(combustionModel, 0)
bool isReadRequired() const noexcept
True if (MUST_READ | MUST_READ_IF_MODIFIED) bits are set.
void assign(const dictionary &dict, IOobjectOption::readOption readOrigin=IOobjectOption::MUST_READ)
Assign from dictionary content with specified read handling of the &#39;origin&#39; entry.
tensor rot_
The rotation tensor.
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:76
static const SphericalTensor I
static coordinateSystem dummy_
Dummy coordinate system for suppressed manipulation.
#define R(A, B, C, D, E, F, K, M)
A coordinateRotation specified using global axes.
Definition: axesRotation.H:101
A List with indirect addressing. Like IndirectList but does not store addressing. ...
Definition: faMatrix.H:57
virtual void writeEntry(Ostream &os) const
Write &#39;coordinateSystem&#39; dictionary entry.
virtual void write(Ostream &os) const
Write.
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition: Ostream.C:80
virtual tensor R() const =0
Calculate and return the rotation tensor.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:58
bool operator!=(const eddy &a, const eddy &b)
Definition: eddy.H:299
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
void operator=(const coordinateSystem &csys)
Copy assignment.
A class for managing temporary objects.
Definition: HashPtrTable.H:50
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:529
Tensor of scalars, i.e. Tensor<scalar>.
autoPtr< coordinateRotation > spec_
User specification of the coordinate rotation.
Namespace for OpenFOAM.
static autoPtr< coordinateRotation > New(const word &modelType, const dictionary &dict)
Select construct the specified coordinate rotation type.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:157
readOption
Enumeration defining read preferences.