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  {
87  readOrigin = IOobjectOption::lazierRead(readOrigin);
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  readOrigin = IOobjectOption::lazierRead(readOrigin);
290 
291  assign(dict.subDict(dictName), readOrigin);
292  }
293  else
294  {
295  assign(dict, readOrigin);
296  }
297 }
299 
300 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
301 
303 {
304  spec_->clear();
305  origin_ = Zero;
306  rot_ = sphericalTensor::I;
307  note_.clear();
308 }
309 
310 
311 Foam::tensor Foam::coordinateSystem::R(const point& global) const
312 {
313  return rot_;
314 }
315 
316 
318 (
319  const UList<point>& global
320 ) const
321 {
322  return rotationsImpl(global);
323 }
324 
325 
327 (
328  const pointUIndList& global
329 ) const
330 {
331  return rotationsImpl(global);
332 }
333 
334 
336 (
337  const point& localCart
338 ) const
339 {
340  return Foam::transform(rot_, localCart) + origin_;
341 }
342 
343 
345 (
346  const point& global
347 ) const
348 {
349  return Foam::invTransform(rot_, global - origin_);
350 }
351 
352 
354 (
355  const vector& local,
356  bool translate
357 ) const
358 {
359  if (translate)
360  {
361  return this->transform(local) + origin_;
362  }
363 
364  return this->transform(local);
365 }
366 
367 
369 (
370  const vectorField& local,
371  bool translate
372 ) const
373 {
374  if (translate)
375  {
376  return this->transform(local) + origin_;
377  }
378 
379  return this->transform(local);
380 }
381 
382 
384 (
385  const vector& global,
386  bool translate
387 ) const
388 {
389  if (translate)
390  {
391  return this->invTransform(global - origin_);
392  }
393 
394  return this->invTransform(global);
395 }
396 
397 
399 (
400  const vectorField& global,
401  bool translate
402 ) const
403 {
404  if (translate)
405  {
406  return this->invTransform(global - origin_);
407  }
408 
409  return this->invTransform(global);
410 }
411 
412 
414 {
415  spec_.reset(std::move(crot));
416  if (spec_)
417  {
418  rot_ = spec_->R();
419  }
420  else
421  {
422  rot_ = sphericalTensor::I;
423  }
424 }
425 
426 
427 void Foam::coordinateSystem::write(Ostream& os) const
428 {
429  if (!good())
430  {
431  return;
432  }
433 
434  // Suppress output of type for 'cartesian', 'coordinateSystem', ...
435  if (!ignoreOutputCoordType(type()))
436  {
437  os << type() << ' ';
438  }
439 
440  os << "origin: " << origin_ << ' ';
441  spec_->write(os);
442 }
443 
444 
446 {
447  writeEntry(coordinateSystem::typeName, os);
448 }
449 
450 
451 void Foam::coordinateSystem::writeEntry(const word& keyword, Ostream& os) const
452 {
453  if (!good())
454  {
455  return;
456  }
457 
458  const bool subDict = !keyword.empty();
459 
460  if (subDict)
461  {
462  os.beginBlock(keyword);
463 
464  // Suppress output of type for 'cartesian', 'coordinateSystem', ...
465  if (!ignoreOutputCoordType(type()))
466  {
467  os.writeEntry<word>("type", type());
468  }
469 
470  if (note_.size())
471  {
472  // The 'note' is optional
473  os.writeEntry("note", note_);
474  }
475  }
476 
477  os.writeEntry("origin", origin_);
478 
479  spec_->writeEntry("rotation", os);
480 
481  if (subDict)
482  {
483  os.endBlock();
484  }
485 }
487 
488 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
489 
491 {
492  name_ = csys.name_;
493  note_ = csys.note_;
494  origin_ = csys.origin_;
495 
496  // Some extra safety
497  if (csys.spec_)
498  {
499  rotation(csys.spec_.clone());
500  }
501  else
502  {
503  spec_.reset(new coordinateRotations::identity());
504  rot_ = sphericalTensor::I;
505  }
506 }
507 
508 
509 void Foam::coordinateSystem::operator=(coordinateSystem&& csys)
510 {
511  name_ = std::move(csys.name_);
512  note_ = std::move(csys.note_);
513  spec_ = std::move(csys.spec_);
514  origin_ = csys.origin_;
515  rot_ = csys.rot_;
516 }
517 
518 
520 {
522 }
523 
524 
526 {
527  coordinateSystem::operator=(std::move(*csys));
528  csys.clear();
529 }
531 
532 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
533 
535 {
536  return
537  (
538  a.type() != b.type()
539  || a.origin() != b.origin()
540  || a.R() != b.R()
541  );
542 }
543 
544 
545 Foam::Ostream& Foam::operator<<(Ostream& os, const coordinateSystem& csys)
546 {
547  csys.write(os);
549  return os;
550 }
551 
552 
553 // ************************************************************************* //
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
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:527
virtual Ostream & write(const char c) override
Write character.
Definition: OBJstream.C:69
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
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:321
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:799
string note_
An optional note describing the coordinate system.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
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), works like std::iota() but returning a...
Definition: labelLists.C:44
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:108
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:105
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
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 | READ_MODIFIED) bits are set.
static readOption lazierRead(readOption opt) noexcept
Downgrade readOption optional (LAZY_READ), leaves NO_READ intact.
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:77
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:56
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:90
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:57
bool operator!=(const eddy &a, const eddy &b)
Definition: eddy.H:297
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:521
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:127
readOption
Enumeration defining read preferences.