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-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 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(List<T>& field) const;
180 
181  template<class T, class TransformOp>
182  void applyTransforms
183  (
184  const globalIndexAndTransform& globalTransforms,
185  List<T>& field,
186  const TransformOp& top
187  ) const;
188 
189  //- Helper function: copy transformElements without transformation
190  template<class T>
191  void applyDummyInverseTransforms(List<T>& field) const;
192 
193  template<class T, class TransformOp>
194  void applyInverseTransforms
195  (
196  const globalIndexAndTransform& globalTransforms,
197  List<T>& field,
198  const TransformOp& top
199  ) const;
200 
201 
202 public:
203 
204  // Public classes
205 
206  //- Default transformation behaviour
207  class transform
208  {
209  public:
210 
211  template<class Type>
212  void operator()
213  (
214  const vectorTensorTransform& vt,
215  const bool forward,
216  List<Type>& fld
217  ) const
218  {
219  const tensor T(forward ? vt.R() : vt.R().T());
220  transformList(T, fld);
221  }
222 
223  template<class Type>
224  void operator()
225  (
226  const vectorTensorTransform& vt,
227  const bool forward,
228  List<List<Type>>& flds
229  ) const
230  {
231  for (List<Type>& fld : flds)
232  {
233  operator()(vt, forward, fld);
234  }
235  }
236 
237  //- Transform patch-based field
238  template<class Type>
239  void operator()(const coupledPolyPatch& cpp, UList<Type>& fld) const
240  {
241  if (!cpp.parallel())
242  {
243  transformList(cpp.forwardT(), fld);
244  }
245  }
247  //- Transform sparse field
248  template<class Type, template<class> class Container>
249  void operator()(const coupledPolyPatch& cpp, Container<Type>& map)
250  const
251  {
252  if (!cpp.parallel())
253  {
254  transformList(cpp.forwardT(), map);
255  }
256  }
257  };
259  //- Default transformation behaviour for position
260  class transformPosition
261  {
262  public:
263 
264  void operator()
265  (
266  const vectorTensorTransform& vt,
267  const bool forward,
269  ) const
270  {
271  pointField pfld(std::move(fld));
272  if (forward)
273  {
274  fld = vt.transformPosition(pfld);
275  }
276  else
277  {
278  fld = vt.invTransformPosition(pfld);
279  }
280  }
281 
282  void operator()
283  (
284  const vectorTensorTransform& vt,
285  const bool forward,
286  List<List<point>>& flds
287  ) const
288  {
289  for (List<point>& fld : flds)
290  {
291  operator()(vt, forward, fld);
292  }
293  }
295  //- Transform patch-based field
296  void operator()(const coupledPolyPatch& cpp, pointField& fld) const
297  {
298  cpp.transformPosition(fld);
299  }
300 
301  template<template<class> class Container>
302  void operator()(const coupledPolyPatch& cpp, Container<point>& map)
303  const
304  {
305  Field<point> fld(map.size());
306  label i = 0;
307  forAllConstIters(map, iter)
308  {
309  fld[i++] = *iter;
310  }
311  cpp.transformPosition(fld);
312  i = 0;
313  forAllIters(map, iter)
314  {
315  *iter = fld[i++];
316  }
317  }
318  };
319 
320 
321  // Declare name of the class and its debug switch
322  ClassName("mapDistribute");
323 
324 
325  // Constructors
326 
327  //- Inherit constructors
329 
330  //- Default construct - uses worldComm
331  mapDistribute();
332 
333  //- Default construct with specified communicator
334  explicit mapDistribute(const label comm);
335 
336  //- Move construct from base, no transforms
337  explicit mapDistribute(mapDistributeBase&& map);
338 
339  //- Copy construct
340  explicit mapDistribute(const mapDistribute& map);
341 
342  //- Move construct
343  explicit mapDistribute(mapDistribute&& map);
344 
345  //- Read construct from dictionary
346  explicit mapDistribute
347  (
348  const dictionary& dict,
349  const label comm = UPstream::worldComm
350  );
351 
352  //- Move construct from components
354  (
355  const label constructSize,
360  const bool subHasFlip = false,
361  const bool constructHasFlip = false,
362  const label comm = UPstream::worldComm
363  );
364 
365  //- Construct from list of (possibly remote) untransformed elements
366  //- in globalIndex numbering (or -1) and (possibly remote)
367  //- transformed elements in globalIndexAndTransform numbering.
368  // Determines compact numbering (see above) and
369  // distribute map to get data into this ordering and renumbers the
370  // elements to be in compact numbering.
372  (
373  const globalIndex&,
374  labelList& untransformedElements,
375  const globalIndexAndTransform&,
376  const labelPairList& transformedElements,
377  labelList& transformedIndices,
378  List<Map<label>>& compactMap,
379  const int tag = UPstream::msgType(),
380  const label comm = UPstream::worldComm
381  );
382 
383  //- As above but with ListLists.
385  (
386  const globalIndex&,
387  labelListList& cellCells,
388  const globalIndexAndTransform&,
389  const List<labelPairList>& transformedElements,
390  labelListList& transformedIndices,
391  List<Map<label>>& compactMap,
392  const int tag = UPstream::msgType(),
393  const label comm = UPstream::worldComm
394  );
395 
396  //- Construct from Istream
397  explicit mapDistribute(Istream& is);
398 
399  //- Clone
400  autoPtr<mapDistribute> clone() const;
401 
402 
403  //- Destructor
404  virtual ~mapDistribute() = default;
405 
406 
407  // Member Functions
408 
409  // Access
410 
411  //- For every globalIndexAndTransform::transformPermutations
412  // gives the elements that need to be transformed
414  {
415  return transformElements_;
416  }
417 
418  //- Destination in constructMap for transformed elements
419  const labelList& transformStart() const noexcept
420  {
421  return transformStart_;
422  }
423 
424  //- Find transform from transformElements
425  label whichTransform(const label index) const;
426 
427 
428  // Other
429 
430  //- Reset to zero size, only retaining communicator
431  void clear();
432 
433  //- Transfer the contents of the argument and annul the argument.
434  void transfer(mapDistribute& map);
435 
436  //- Distribute data using default commsType.
437  template<class T>
438  void distribute
439  (
440  List<T>& fld,
441  const bool dummyTransform = true,
442  const int tag = UPstream::msgType()
443  ) const;
444 
445  //- Distribute data using default commsType.
446  template<class T, class NegateOp>
447  void distribute
448  (
449  List<T>& fld,
450  const NegateOp& negOp,
451  const bool dummyTransform = true,
452  const int tag = UPstream::msgType()
453  ) const;
454 
455  //- Distribute data using default commsType.
456  template<class T>
457  void distribute
458  (
460  const bool dummyTransform = true,
461  const int tag = UPstream::msgType()
462  ) const;
463 
464  //- Reverse distribute data using default commsType.
465  template<class T>
466  void reverseDistribute
467  (
468  const label constructSize,
469  List<T>& fld,
470  const bool dummyTransform = true,
471  const int tag = UPstream::msgType()
472  ) const;
473 
474  //- Reverse distribute data using default commsType.
475  // Since constructSize might be larger than supplied size supply
476  // a nullValue
477  template<class T>
478  void reverseDistribute
479  (
480  const label constructSize,
481  const T& nullValue,
482  List<T>& fld,
483  const bool dummyTransform = true,
484  const int tag = UPstream::msgType()
485  ) const;
486 
487  //- Distribute with transforms
488  template<class T, class TransformOp>
489  void distribute
490  (
492  List<T>& fld,
493  const TransformOp& top,
494  const int tag = UPstream::msgType()
495  ) const;
496 
497  //- Reverse distribute with transforms
498  template<class T, class TransformOp>
499  void reverseDistribute
500  (
502  const label constructSize,
503  List<T>& fld,
504  const TransformOp& top,
505  const int tag = UPstream::msgType()
506  ) const;
507 
508  //- Reverse distribute with transforms
509  template<class T, class TransformOp>
510  void reverseDistribute
511  (
513  const label constructSize,
514  const T& nullValue,
515  List<T>& fld,
516  const TransformOp& top,
517  const int tag = UPstream::msgType()
518  ) const;
519 
520  //- Debug: print layout. Can only be used on maps with sorted
521  // storage (local data first, then non-local data)
522  void printLayout(Ostream& os) const;
523 
524 
525  // Member Operators
526 
527  //- Copy assignment
528  void operator=(const mapDistribute& rhs);
529 
530  //- Move assignment
531  void operator=(mapDistribute&& rhs);
532 
533 
534  // IOstream Operators
535 
536  //- Read entries from dictionary format
537  void readDict(const dictionary& dict);
538 
539  //- Write entries in dictionary format
540  void writeEntries(Ostream& os) const;
541 
542  //- Read plain content (not dictionary) from Istream
544 
545  //- Write plain content (not dictionary) to Ostream
546  friend Ostream& operator<<(Ostream&, const mapDistribute&);
547 
548 
549  // Housekeeping
550 
551  //- No correction for topo change
552  void updateMesh(const mapPolyMesh&)
553  {
555  }
556 };
557 
558 
559 // Template specialisation for primitives that do not need transform
560 template<>
561 void mapDistribute::transform::operator()
562 (
563  const vectorTensorTransform&,
564  const bool,
565  List<label>&
566 ) const;
567 template<>
568 void mapDistribute::transform::operator()
569 (
570  const coupledPolyPatch&,
571  UList<label>&
572 ) const;
573 template<>
574 void mapDistribute::transform::operator()
575 (
576  const coupledPolyPatch&,
577  Map<label>&
578 ) const;
579 template<>
580 void mapDistribute::transform::operator()
581 (
582  const coupledPolyPatch&,
583  EdgeMap<label>&
584 ) const;
585 
586 template<>
587 void mapDistribute::transform::operator()
588 (
589  const coupledPolyPatch&,
590  UList<scalar>&
591 ) const;
592 template<>
593 void mapDistribute::transform::operator()
594 (
595  const vectorTensorTransform&,
596  const bool,
597  List<scalar>&
598 ) const;
599 template<>
600 void mapDistribute::transform::operator()
601 (
602  const coupledPolyPatch&,
603  Map<scalar>&
604 ) const;
605 template<>
606 void mapDistribute::transform::operator()
607 (
608  const coupledPolyPatch&,
609  EdgeMap<scalar>&
610 ) const;
611 
612 template<>
613 void mapDistribute::transform::operator()
614 (
615  const coupledPolyPatch& cpp,
616  UList<bool>& fld
617 ) const;
618 template<>
619 void mapDistribute::transform::operator()
620 (
621  const vectorTensorTransform&,
622  const bool,
623  List<bool>&
624 ) const;
625 template<>
626 void mapDistribute::transform::operator()
627 (
628  const coupledPolyPatch&,
629  Map<bool>&
630 ) const;
631 template<>
632 void mapDistribute::transform::operator()
633 (
634  const coupledPolyPatch&,
635  EdgeMap<bool>&
636 ) const;
638 
639 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
640 
641 } // End namespace Foam
642 
643 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
644 
645 #ifdef NoRepository
646  #include "mapDistributeTemplates.C"
647 #endif
648 
649 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
650 
651 #endif
652 
653 // ************************************************************************* //
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:51
dictionary dict
rDeltaTY field()
void clear()
Reset to zero size, only retaining communicator.
void operator()(const vectorTensorTransform &vt, const bool forward, List< Type > &fld) const
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:120
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 data using default commsType.
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:806
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
void operator=(const mapDistribute &rhs)
Copy assignment.
friend Ostream & operator<<(Ostream &, const mapDistribute &)
Write plain content (not dictionary) to Ostream.
static label worldComm
Default world communicator (all processors). May differ from globalComm if local worlds are in use...
Definition: UPstream.H:361
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:157
mapDistributeBase()
Default construct (uses worldComm)
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.
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 &)
virtual ~mapDistribute()=default
Destructor.
const labelListList & transformElements() const noexcept
For every globalIndexAndTransform::transformPermutations.
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:328
autoPtr< mapDistribute > clone() const
Clone.
List< labelPair > labelPairList
List of labelPairs.
Definition: labelPair.H:61
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.
mapDistribute()
Default construct - uses worldComm.
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:55
const direction noexcept
Definition: Scalar.H:258
bool constructHasFlip() const noexcept
Does constructMap include a sign.
OBJstream os(runTime.globalPath()/outputName)
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:76
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:45
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.
ClassName("mapDistribute")
void operator()(const vectorTensorTransform &vt, const bool forward, List< point > &fld) const
List< label > labelList
A List of labels.
Definition: List.H:62
const labelList & transformStart() const noexcept
Destination in constructMap for transformed elements.
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:666
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)