mapDistribute.H
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) 2015-2025 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 Class
28  Foam::mapDistribute
29 
30 Description
31  Class containing processor-to-processor mapping information.
32 
33  We store mapping from the bits-to-send to the complete starting list
34  (subXXXMap) and from the received bits to their location in the new
35  list (constructXXXMap).
36 
37 Note:
38  Schedule is a list of processor pairs (one send, one receive. One of
39  them will be myself) which forms a scheduled (i.e. non-buffered) exchange.
40  See distribute on how to use it.
41  Note2: number of items sent on one processor have to equal the number
42  of items received on the other processor.
43 
44  To aid constructing these maps there are the constructors from global
45  numbering, either with or without transforms.
46 
47  - without transforms:
48  Constructors using compact numbering: layout is
49  - all my own elements first (whether used or not)
50  - followed by used-only remote elements sorted by remote processor.
51  So e.g 4 procs and on proc 1 the compact
52  table will first have all globalIndex.localSize() elements from proc1
53  followed by used-only elements of proc0, proc2, proc3.
54  The constructed mapDistribute sends the local elements from and
55  receives the remote elements into their compact position.
56  compactMap[proci] is the position of elements from proci in the compact
57  map. compactMap[myProcNo()] is empty since trivial addressing.
58 
59  It rewrites the input global indices into indices into the constructed
60  data.
61 
62 
63  - with transforms:
64  This requires the precalculated set of possible transforms
65  (globalIndexAndTransform). These are given as permutations (+, -, or none)
66  of up to 3 independent transforms.
67  The layout of the data is
68  - all my own elements first (whether used or not)
69  - followed by used-only remote elements sorted by remote processor.
70  - followed by - for each transformation index - the set of local or
71  remote elements with that transformation.
72  The inputs for the constructor are
73  - the set of untransformed local or remote indices in globalIndex
74  numbering. These get rewritten to be indices into the layout of the data.
75  - the set of transformed local or remote indices in globalIndexAndTransform
76  encoding. These are labelPairs.
77 
78  Any distribute with transforms is now done as:
79  1. exchange data with other processors and receive these into the
80  slots for that processor
81  2. for all transformations transform a subset of the data according
82  to transformElements_[transformI] and store this starting from
83  transformStart_[transformI]
84 
85  In the same way a reverse distribute will
86  1. apply the inverse transform to the data starting at
87  transformStart_[transformI] and copy the result back into the
88  transformElements_[transformI]. These might be local or remote slots.
89  2. the data in the remote slots will now be sent back to the correct
90  location in the originating processor.
91 
92  E.g. a map to handle
93  - mesh points on a mesh with
94  - 1 cyclic so 3 permutations (+,-,none) will have layout
95  - on e.g. processor 1 out of 2:
96 
97  +------+ <- transformStart[2]
98  | |
99  | | <- transform2 applied to data in local or remote slots
100  | |
101  +------+ <- transformStart[1]
102  | |
103  | | <- transform1 applied to data in local or remote slots
104  | |
105  +------+ <- transformStart[1]
106  | |
107  | | <- transform0 applied to data in local or remote slots
108  | |
109  +------+ <- transformStart[0]
110  | |
111  | | <- data from proc2
112  | |
113  +------+
114  | |
115  | | <- data from proc0
116  | |
117  +------+ <- mesh.nPoints()
118  | |
119  | |
120  | |
121  +------+ 0
122 
123 
124  When constructing from components optionally a 'flip' on
125  the maps can be specified. This will interpret the map
126  values as index+flip, similar to e.g. faceProcAddressing. The flip
127  will only be applied to fieldTypes (scalar, vector, .. triad)
128 
129 SourceFiles
130  mapDistribute.C
131  mapDistributeIO.C
132  mapDistributeTemplates.C
133 
134 \*---------------------------------------------------------------------------*/
135 
136 #ifndef Foam_mapDistribute_H
137 #define Foam_mapDistribute_H
138 
139 #include "mapDistributeBase.H"
140 #include "transformList.H"
141 #include "vectorTensorTransform.H"
142 #include "coupledPolyPatch.H"
143 
144 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
145 
146 namespace Foam
147 {
148 
149 // Forward Declarations
150 class globalIndexAndTransform;
151 class mapDistribute;
152 
153 Istream& operator>>(Istream&, mapDistribute&);
154 Ostream& operator<<(Ostream&, const mapDistribute&);
155 
157 /*---------------------------------------------------------------------------*\
158  Class mapDistribute Declaration
159 \*---------------------------------------------------------------------------*/
160 
161 class mapDistribute
162 :
163  public mapDistributeBase
164 {
165  // Private Data
166 
167  //- For every globalIndexAndTransform::transformPermutations
168  //- gives the elements that need to be transformed
169  labelListList transformElements_;
170 
171  //- Destination in constructMap for transformed elements
172  labelList transformStart_;
173 
174 
175  // Private Member Functions
176 
177  //- Helper function: copy transformElements without transformation
178  template<class T>
179  void applyDummyTransforms(UList<T>& field) const;
180 
181  template<class T, class TransformOp>
182  void applyTransforms
183  (
184  const globalIndexAndTransform& globalTransforms,
185  UList<T>& field,
186  const TransformOp& top
187  ) const;
188 
189  //- Helper function: copy transformElements without transformation
190  template<class T>
191  void applyDummyInverseTransforms(UList<T>& field) const;
192 
193  template<class T, class TransformOp>
194  void applyInverseTransforms
195  (
196  const globalIndexAndTransform& globalTransforms,
197  UList<T>& field,
198  const TransformOp& top
199  ) const;
200 
201  //- Helper: convert mapDistribute to mapDistributeBase
202  static UPtrList<const mapDistributeBase> extractBase
203  (
205  );
206 
207 
208 public:
209 
210  // Public classes
211 
212  //- Default transformation behaviour
213  class transform
214  {
215  public:
216 
217  template<class Type>
218  void operator()
219  (
221  const bool forward,
223  ) const
224  {
225  if constexpr (is_rotational_vectorspace_v<Type>)
226  {
227  const tensor rot(forward ? vt.R() : vt.R().T());
228  transformList(rot, fld);
229  }
230  }
231 
232  template<class Type>
233  void operator()
234  (
235  const vectorTensorTransform& vt,
236  const bool forward,
237  List<List<Type>>& flds
238  ) const
239  {
240  if constexpr (is_rotational_vectorspace_v<Type>)
241  {
242  const tensor rot(forward ? vt.R() : vt.R().T());
243  for (auto& fld : flds)
244  {
245  transformList(rot, fld);
246  }
247  }
248  }
249 
250  //- Transform patch-based field
251  template<class Type>
252  void operator()(const coupledPolyPatch& cpp, UList<Type>& fld) const
253  {
254  if constexpr (is_rotational_vectorspace_v<Type>)
255  {
256  if (!cpp.parallel())
257  {
258  transformList(cpp.forwardT(), fld);
259  }
260  }
261  }
262 
263  //- Transform sparse field
264  template<class Type, template<class> class Container>
265  void operator()(const coupledPolyPatch& cpp, Container<Type>& map)
266  const
267  {
268  if constexpr (is_rotational_vectorspace_v<Type>)
269  {
270  if (!cpp.parallel())
271  {
272  transformList(cpp.forwardT(), map);
273  }
274  }
275  }
276  };
277 
278  //- Default transformation behaviour for position
279  class transformPosition
280  {
281  public:
282 
283  void operator()
284  (
285  const vectorTensorTransform& vt,
286  const bool forward,
288  ) const
289  {
290  if (forward)
291  {
292  vt.transformPositionList(fld);
293  }
294  else
295  {
296  vt.invTransformPositionList(fld);
297  }
298  }
299 
300  void operator()
301  (
302  const vectorTensorTransform& vt,
303  const bool forward,
304  List<List<point>>& flds
305  ) const
306  {
307  if (forward)
308  {
309  for (auto& fld : flds)
310  {
311  vt.transformPositionList(fld);
312  }
313  }
314  else
315  {
316  for (auto& fld : flds)
317  {
318  vt.invTransformPositionList(fld);
319  }
320  }
321  }
322 
323  //- Transform patch-based field
324  void operator()(const coupledPolyPatch& cpp, pointField& fld) const
325  {
326  cpp.transformPosition(fld);
327  }
328 
329  template<template<class> class Container>
330  void operator()(const coupledPolyPatch& cpp, Container<point>& map)
331  const
332  {
333  Field<point> fld(map.size());
334  label i = 0;
335  forAllConstIters(map, iter)
336  {
337  fld[i++] = *iter;
338  }
339  cpp.transformPosition(fld);
340  i = 0;
341  forAllIters(map, iter)
342  {
343  *iter = fld[i++];
344  }
345  }
346  };
347 
348 
349  // Declare name of the class and its debug switch
350  ClassName("mapDistribute");
351 
352 
353  // Constructors
354 
355  //- Inherit constructors
357 
358  //- Default construct - uses worldComm
360 
361  //- Default construct with specified communicator
362  explicit mapDistribute(const label comm) noexcept;
363 
364  //- Move construct from base, no transforms
365  explicit mapDistribute(mapDistributeBase&& map);
366 
367  //- Copy construct
368  explicit mapDistribute(const mapDistribute& map);
369 
370  //- Move construct
371  explicit mapDistribute(mapDistribute&& map);
372 
373  //- Read construct from dictionary
374  explicit mapDistribute
375  (
376  const dictionary& dict,
377  const label comm = UPstream::worldComm
378  );
379 
380  //- Move construct from components
382  (
383  const label constructSize,
388  const bool subHasFlip = false,
389  const bool constructHasFlip = false,
390  const label comm = UPstream::worldComm
391  );
392 
393  //- Construct from list of (possibly remote) untransformed elements
394  //- in globalIndex numbering (or -1) and (possibly remote)
395  //- transformed elements in globalIndexAndTransform numbering.
396  // Determines compact numbering (see above) and
397  // distribute map to get data into this ordering and renumbers the
398  // elements to be in compact numbering.
400  (
401  const globalIndex&,
402  labelList& untransformedElements,
404  const labelPairList& transformedElements,
405  labelList& transformedIndices,
406  List<Map<label>>& compactMap,
407  const int tag = UPstream::msgType(),
408  const label comm = UPstream::worldComm
409  );
410 
411  //- As above but with ListLists.
413  (
414  const globalIndex&,
415  labelListList& cellCells,
417  const List<labelPairList>& transformedElements,
418  labelListList& transformedIndices,
419  List<Map<label>>& compactMap,
420  const int tag = UPstream::msgType(),
421  const label comm = UPstream::worldComm
422  );
423 
424  //- Construct from multiple maps and processor collation
425  // Assumes all local data first. Sorts contributions of maps
426  // in processor order i.e. constructed map has all local data first.
427  // Returns
428  // - startOfLocal : per input map the start of the local data. Extends
429  // one beyond number of maps so overall local size
430  // is startOfLocal.last()
431  // - compactMaps : per input map from slot position in the input map
432  // to new slot position. (note there is no information
433  // returned about which processor it is from)
435  (
436  const UPtrList<const mapDistribute>& maps,
437  const labelList& localRanks,
438  const label newComm,
439  const labelListList& newToOldRanks, // from rank in newComm to
440  // ranks in (old)comm
441  labelList& startOfLocal, // per map start of local data
442  List<Map<label>>& compactMaps // per map old slot to new slot
443  );
444 
445  //- Construct from Istream
446  explicit mapDistribute(Istream& is);
447 
448  //- Clone
449  autoPtr<mapDistribute> clone() const;
450 
451 
452  //- Destructor
453  virtual ~mapDistribute() = default;
454 
455 
456  // Member Functions
457 
458  // Access
459 
460  //- For every globalIndexAndTransform::transformPermutations
461  //- gives the elements that need to be transformed
463  {
464  return transformElements_;
465  }
466 
467  //- Destination in constructMap for transformed elements
468  const labelList& transformStart() const noexcept
469  {
470  return transformStart_;
471  }
472 
473  //- Find transform from transformElements
474  label whichTransform(const label index) const;
475 
476 
477  // Other
478 
479  //- Reset to zero size, only retaining communicator
480  void clear();
481 
482  //- Transfer the contents of the argument and annul the argument.
483  void transfer(mapDistribute& map);
484 
485  //- Distribute List data using default commsType,
486  //- default flip/negate operator
487  template<class T>
488  void distribute
489  (
490  List<T>& fld,
491  const bool dummyTransform = true,
492  const int tag = UPstream::msgType()
493  ) const;
494 
495  //- Distribute DynamicList data using default commsType,
496  //- default flip/negate operator
497  template<class T>
498  void distribute
499  (
500  DynamicList<T>& fld,
501  const bool dummyTransform = true,
502  const int tag = UPstream::msgType()
503  ) const;
504 
505  //- Distribute List data using specified commsType,
506  //- default flip/negate operator
507  template<class T>
508  void distribute
509  (
510  const UPstream::commsTypes commsType,
511  List<T>& fld,
512  const bool dummyTransform = true,
513  const int tag = UPstream::msgType()
514  ) const;
515 
516  //- Distribute DynamicList data using specified commsType,
517  //- default flip/negate operator
518  template<class T>
519  void distribute
520  (
521  const UPstream::commsTypes commsType,
523  const bool dummyTransform = true,
524  const int tag = UPstream::msgType()
525  ) const;
526 
527  //- Distribute List data using default commsType
528  //- and the specified negate operator (for flips).
529  template<class T, class NegateOp>
530  void distribute
531  (
532  List<T>& fld,
533  const NegateOp& negOp,
534  const bool dummyTransform = true,
535  const int tag = UPstream::msgType()
536  ) const;
537 
538  //- Distribute List data using specified commsType
539  //- and the specified negate operator (for flips).
540  template<class T, class NegateOp>
541  void distribute
542  (
543  const UPstream::commsTypes commsType,
544  List<T>& fld,
545  const NegateOp& negOp,
546  const bool dummyTransform = true,
547  const int tag = UPstream::msgType()
548  ) const;
549 
550  //- Reverse distribute data using default commsType.
551  template<class T>
552  void reverseDistribute
553  (
554  const label constructSize,
555  List<T>& fld,
556  const bool dummyTransform = true,
557  const int tag = UPstream::msgType()
558  ) const;
559 
560  //- Reverse distribute data using specified commsType.
561  template<class T>
562  void reverseDistribute
563  (
564  const UPstream::commsTypes commsType,
565  const label constructSize,
566  List<T>& fld,
567  const bool dummyTransform = true,
568  const int tag = UPstream::msgType()
569  ) const;
570 
571  //- Reverse distribute data using default commsType.
572  // Since constructSize might be larger than supplied size supply
573  // a nullValue
574  template<class T>
575  void reverseDistribute
576  (
577  const label constructSize,
578  const T& nullValue,
579  List<T>& fld,
580  const bool dummyTransform = true,
581  const int tag = UPstream::msgType()
582  ) const;
583 
584  //- Reverse distribute data using specified commsType.
585  // Since constructSize might be larger than supplied size supply
586  // a nullValue
587  template<class T>
588  void reverseDistribute
589  (
590  const UPstream::commsTypes commsType,
591  const label constructSize,
592  const T& nullValue,
593  List<T>& fld,
594  const bool dummyTransform = true,
595  const int tag = UPstream::msgType()
596  ) const;
597 
598  //- Distribute with transforms
599  template<class T, class TransformOp>
600  void distribute
601  (
603  List<T>& fld,
604  const TransformOp& top,
605  const int tag = UPstream::msgType()
606  ) const;
607 
608 
609  //- Distribute with transforms
610  template<class T, class TransformOp>
611  void distribute
612  (
613  const UPstream::commsTypes commsType,
615  List<T>& fld,
616  const TransformOp& top,
617  const int tag = UPstream::msgType()
618  ) const;
619 
620  //- Reverse distribute with transforms
621  template<class T, class TransformOp>
622  void reverseDistribute
623  (
625  const label constructSize,
626  List<T>& fld,
627  const TransformOp& top,
628  const int tag = UPstream::msgType()
629  ) const;
630 
631  //- Reverse distribute with transforms
632  template<class T, class TransformOp>
633  void reverseDistribute
634  (
635  const UPstream::commsTypes commsType,
637  const label constructSize,
638  List<T>& fld,
639  const TransformOp& top,
640  const int tag = UPstream::msgType()
641  ) const;
642 
643  //- Reverse distribute with transforms
644  template<class T, class TransformOp>
645  void reverseDistribute
646  (
648  const label constructSize,
649  const T& nullValue,
650  List<T>& fld,
651  const TransformOp& top,
652  const int tag = UPstream::msgType()
653  ) const;
654 
655  //- Reverse distribute with transforms
656  template<class T, class TransformOp>
657  void reverseDistribute
658  (
659  const UPstream::commsTypes commsType,
661  const label constructSize,
662  const T& nullValue,
663  List<T>& fld,
664  const TransformOp& top,
665  const int tag = UPstream::msgType()
666  ) const;
667 
668  //- Debug: print layout. Can only be used on maps with sorted
669  // storage (local data first, then non-local data)
670  void printLayout(Ostream& os) const;
671 
672 
673  // Member Operators
674 
675  //- Copy assignment
676  void operator=(const mapDistribute& rhs);
677 
678  //- Move assignment
679  void operator=(mapDistribute&& rhs);
680 
681 
682  // IOstream Operators
683 
684  //- Read entries from dictionary format
685  void readDict(const dictionary& dict);
686 
687  //- Write entries in dictionary format
688  void writeEntries(Ostream& os) const;
689 
690  //- Read plain content (not dictionary) from Istream
692 
693  //- Write plain content (not dictionary) to Ostream
694  friend Ostream& operator<<(Ostream&, const mapDistribute&);
695 
696 
697  // Housekeeping
698 
699  //- No correction for topo change
700  void updateMesh(const mapPolyMesh&)
701  {
703  }
704 };
705 
706 
707 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
708 
709 } // End namespace Foam
710 
711 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
712 
713 #ifdef NoRepository
714  #include "mapDistributeTemplates.C"
715 #endif
716 
717 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
718 
719 #endif
720 
721 // ************************************************************************* //
dictionary dict
rDeltaTY field()
void clear()
Reset to zero size, only retaining communicator.
commsTypes
Communications types.
Definition: UPstream.H:77
void writeEntries(Ostream &os) const
Write entries in dictionary format.
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
friend Istream & operator>>(Istream &, mapDistribute &)
Read plain content (not dictionary) from Istream.
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute List data using default commsType, default flip/negate operator.
Vector-tensor class used to perform translations and rotations in 3D space.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
label whichTransform(const label index) const
Find transform from transformElements.
label constructSize() const noexcept
Constructed data size.
label comm() const noexcept
The communicator used.
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1787
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
Definition: mapDistribute.C:36
void operator=(const mapDistribute &rhs)
Copy assignment.
friend Ostream & operator<<(Ostream &, const mapDistribute &)
Write plain content (not dictionary) to Ostream.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:158
virtual const tensorField & forwardT() const
Return face transformation tensor.
void updateMesh(const mapPolyMesh &)
No correction for topo change.
bool subHasFlip() const noexcept
Does subMap include a sign.
virtual bool parallel() const
Are the cyclic planes parallel.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:61
Default transformation behaviour.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:51
Istream & operator>>(Istream &, directionInfo &)
const labelListList & transformElements() const noexcept
For every globalIndexAndTransform::transformPermutations gives the elements that need to be transform...
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:201
autoPtr< mapDistribute > clone() const
Clone.
const tensor & R() const noexcept
The (forward) rotation tensor.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:106
Default transformation behaviour for position.
void reverseDistribute(const label constructSize, List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
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
Class containing processor-to-processor mapping information.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
const direction noexcept
Definition: scalarImpl.H:255
bool constructHasFlip() const noexcept
Does constructMap include a sign.
OBJstream os(runTime.globalPath()/outputName)
void operator()(const vectorTensorTransform &vt, const bool forward, UList< point > &fld) const
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Spatial transformation functions for list of values and primitive fields.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const labelListList & constructMap() const noexcept
From subsetted data to new reconstructed data.
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:77
void operator()(const vectorTensorTransform &vt, const bool forward, UList< Type > &fld) const
void readDict(const dictionary &dict)
Read entries from dictionary format.
void transformList(const tensor &rotTensor, UList< T > &field)
Inplace transform a list of elements.
Definition: transformList.C:48
Class containing processor-to-processor mapping information.
void transfer(mapDistribute &map)
Transfer the contents of the argument and annul the argument.
virtual void transformPosition(pointField &) const =0
Transform a patch-based position from other side to this side.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
ClassName("mapDistribute")
List< label > labelList
A List of labels.
Definition: List.H:61
const labelList & transformStart() const noexcept
Destination in constructMap for transformed elements.
mapDistributeBase() noexcept
Default construct (uses worldComm)
const labelListList & subMap() const noexcept
From subsetted data back to original data.
Tensor of scalars, i.e. Tensor<scalar>.
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:688
mapDistribute() noexcept
Default construct - uses worldComm.
Definition: mapDistribute.C:69
Inter-processor communications stream.
Definition: UPstream.H:65
Namespace for OpenFOAM.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Determination and storage of the possible independent transforms introduced by coupledPolyPatches, as well as all of the possible permutations of these transforms generated by the presence of multiple coupledPolyPatches, i.e. more than one cyclic boundary. Note that any given point can be on maximum 3 transforms only (and these transforms have to be perpendicular)
A HashTable to objects of type <T> with a label key.