mapDistribute.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
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 Class
25  Foam::mapDistribute
26 
27 Description
28  Class containing processor-to-processor mapping information.
29 
30  We store mapping from the bits-to-send to the complete starting list
31  (subXXXMap) and from the received bits to their location in the new
32  list (constructXXXMap).
33 
34 Note:
35  Schedule is a list of processor pairs (one send, one receive. One of
36  them will be myself) which forms a scheduled (i.e. non-buffered) exchange.
37  See distribute on how to use it.
38  Note2: number of items sent on one processor have to equal the number
39  of items received on the other processor.
40 
41  To aid constructing these maps there are the constructors from global
42  numbering, either with or without transforms.
43 
44  - without transforms:
45  Constructors using compact numbering: layout is
46  - all my own elements first (whether used or not)
47  - followed by used-only remote elements sorted by remote processor.
48  So e.g 4 procs and on proc 1 the compact
49  table will first have all globalIndex.localSize() elements from proc1
50  followed by used-only elements of proc0, proc2, proc3.
51  The constructed mapDistribute sends the local elements from and
52  receives the remote elements into their compact position.
53  compactMap[proci] is the position of elements from proci in the compact
54  map. compactMap[myProcNo()] is empty since trivial addressing.
55 
56  It rewrites the input global indices into indices into the constructed
57  data.
58 
59 
60  - with transforms:
61  This requires the precalculated set of possible transforms
62  (globalIndexAndTransform). These are given as permutations (+, -, or none)
63  of up to 3 independent transforms.
64  The layout of the data is
65  - all my own elements first (whether used or not)
66  - followed by used-only remote elements sorted by remote processor.
67  - followed by - for each transformation index - the set of local or
68  remote elements with that transformation.
69  The inputs for the constructor are
70  - the set of untransformed local or remote indices in globalIndex
71  numbering. These get rewritten to be indices into the layout of the data.
72  - the set of transformed local or remote indices in globalIndexAndTransform
73  encoding. These are labelPairs.
74 
75  Any distribute with transforms is now done as:
76  1. exchange data with other processors and receive these into the
77  slots for that processor
78  2. for all transformations transform a subset of the data according
79  to transformElements_[transformI] and store this starting from
80  transformStart_[transformI]
81 
82  In the same way a reverse distribute will
83  1. apply the inverse transform to the data starting at
84  transformStart_[transformI] and copy the result back into the
85  transformElements_[transformI]. These might be local or remote slots.
86  2. the data in the remote slots will now be sent back to the correct
87  location in the originating processor.
88 
89  E.g. a map to handle
90  - mesh points on a mesh with
91  - 1 cyclic so 3 permutations (+,-,none) will have layout
92  - on e.g. processor 1 out of 2:
93 
94  +------+ <- transformStart[2]
95  | |
96  | | <- transform2 applied to data in local or remote slots
97  | |
98  +------+ <- transformStart[1]
99  | |
100  | | <- transform1 applied to data in local or remote slots
101  | |
102  +------+ <- transformStart[1]
103  | |
104  | | <- transform0 applied to data in local or remote slots
105  | |
106  +------+ <- transformStart[0]
107  | |
108  | | <- data from proc2
109  | |
110  +------+
111  | |
112  | | <- data from proc0
113  | |
114  +------+ <- mesh.nPoints()
115  | |
116  | |
117  | |
118  +------+ 0
119 
120 
121  When constructing from components optionally a 'flip' on
122  the maps can be specified. This will interpret the map
123  values as index+flip, similar to e.g. faceProcAddressing. The flip
124  will only be applied to fieldTypes (scalar, vector, .. triad)
125 
126 
127 SourceFiles
128  mapDistribute.C
129  mapDistributeTemplates.C
130 
131 \*---------------------------------------------------------------------------*/
132 
133 #ifndef mapDistribute_H
134 #define mapDistribute_H
135 
136 #include "mapDistributeBase.H"
137 #include "transformer.H"
138 #include "coupledPolyPatch.H"
139 #include "EdgeMap.H"
140 
141 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
142 
143 namespace Foam
144 {
145 
146 class globalIndexAndTransform;
147 
148 
149 // Forward declaration of friend functions and operators
150 
151 class mapDistribute;
152 
153 Istream& operator>>(Istream&, mapDistribute&);
154 Ostream& operator<<(Ostream&, const mapDistribute&);
155 
156 
157 /*---------------------------------------------------------------------------*\
158  Class mapDistribute Declaration
159 \*---------------------------------------------------------------------------*/
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 transformer& vt,
215  const bool forward,
216  List<Type>& fld
217  ) const
218  {
219  if (forward)
220  {
221  vt.transformList(fld);
222  }
223  else
224  {
225  vt.invTransformList(fld);
226  }
227  }
228 
229  template<class Type>
230  void operator()
231  (
232  const transformer& vt,
233  const bool forward,
234  List<List<Type>>& flds
235  ) const
236  {
237  forAll(flds, i)
238  {
239  operator()(vt, forward, flds[i]);
240  }
241  }
242 
243  //- Transform patch-based field
244  template<class Type>
245  void operator()(const coupledPolyPatch& cpp, UList<Type>& fld) const
246  {
247  if (cpp.transform().transforms())
248  {
249  cpp.transform().transformList(fld);
250  }
251  }
252 
253  //- Transform sparse field
254  template<class Type, template<class> class Container>
255  void operator()(const coupledPolyPatch& cpp, Container<Type>& map)
256  const
257  {
258  if (cpp.transform().transforms())
259  {
260  cpp.transform().transformList(map);
261  }
262  }
263  };
264 
265  //- Default transformation behaviour for position
266  class transformPosition
267  {
268  public:
269 
270  void operator()
271  (
272  const transformer& vt,
273  const bool forward,
275  ) const
276  {
277  pointField pfld(move(fld));
278  if (forward)
279  {
280  fld = vt.transformPosition(pfld);
281  }
282  else
283  {
284  fld = vt.invTransformPosition(pfld);
285  }
286  }
287 
288  void operator()
289  (
290  const transformer& vt,
291  const bool forward,
292  List<List<point>>& flds
293  ) const
294  {
295  forAll(flds, i)
296  {
297  operator()(vt, forward, flds[i]);
298  }
299  }
300 
301  //- Transform patch-based field
302  void operator()(const coupledPolyPatch& cpp, pointField& fld) const
303  {
304  cpp.transform().transformPosition(fld, fld);
305  }
306 
307  template<template<class> class Container>
308  void operator()(const coupledPolyPatch& cpp, Container<point>& map)
309  const
310  {
311  Field<point> fld(map.size());
312 
313  label i = 0;
314  forAllConstIter(typename Container<point>, map, iter)
315  {
316  fld[i++] = iter();
317  }
318 
319  cpp.transform().transformPosition(fld, fld);
320 
321  i = 0;
322  forAllIter(typename Container<point>, map, iter)
323  {
324  iter() = fld[i++];
325  }
326  }
327  };
328 
329 
330  // Declare name of the class and its debug switch
331  ClassName("mapDistribute");
332 
333 
334  // Constructors
335 
336  //- Construct null
337  mapDistribute();
338 
339  //- Construct from components
341  (
342  const label constructSize,
345  const bool subHasFlip = false,
346  const bool constructHasFlip = false
347  );
348 
349  //- Construct from components
351  (
352  const label constructSize,
357  const bool subHasFlip = false,
358  const bool constructHasFlip = false
359  );
360 
361  //- Construct from reverse addressing: per data item the send
362  // processor and the receive processor. (note: data is not stored
363  // sorted per processor so cannot use printLayout).
365  (
366  const labelList& sendProcs,
367  const labelList& recvProcs
368  );
369 
370  //- Construct from list of (possibly) remote elements in globalIndex
371  // numbering (or -1). Determines compact numbering (see above) and
372  // distribute map to get data into this ordering and renumbers the
373  // elements to be in compact numbering.
375  (
376  const globalIndex&,
377  labelList& elements,
378  List<Map<label>>& compactMap,
379  const int tag = Pstream::msgType()
380  );
381 
382  //- Special variant that works with the info sorted into bins
383  // according to local indices. E.g. think cellCells where
384  // cellCells[localCelli] is a list of global cells
386  (
387  const globalIndex&,
388  labelListList& cellCells,
389  List<Map<label>>& compactMap,
390  const int tag = Pstream::msgType()
391  );
392 
393  //- Construct from list of (possibly remote) untransformed elements
394  // in globalIndex numbering (or -1) and (possibly remote)
395  // transformded 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 = Pstream::msgType()
408  );
409 
410  //- As above but with ListLists.
412  (
413  const globalIndex&,
414  labelListList& cellCells,
416  const List<labelPairList>& transformedElements,
417  labelListList& transformedIndices,
418  List<Map<label>>& compactMap,
419  const int tag = Pstream::msgType()
420  );
421 
422  //- Copy constructor
424 
425  //- Move constructor
427 
428  //- Construct from Istream
430 
431  //- Clone
433 
434 
435  //- Destructor
436  virtual ~mapDistribute()
437  {}
438 
439 
440  // Member Functions
441 
442  // Access
443 
444  //- For every globalIndexAndTransform::transformPermutations
445  // gives the elements that need to be transformed
446  const labelListList& transformElements() const
447  {
448  return transformElements_;
449  }
450 
451  //- Destination in constructMap for transformed elements
452  const labelList& transformStart() const
453  {
454  return transformStart_;
455  }
456 
457  //- Find transform from transformElements
458  label whichTransform(const label index) const;
459 
460 
461  // Other
462 
463  //- Transfer the contents of the argument and annul the argument.
464  void transfer(mapDistribute&);
465 
466  //- Distribute data using default commsType.
467  template<class T>
468  void distribute
469  (
470  List<T>& fld,
471  const bool dummyTransform = true,
472  const int tag = UPstream::msgType()
473  ) const;
474 
475  //- Distribute data using default commsType.
476  template<class T, class negateOp>
477  void distribute
478  (
479  List<T>& fld,
480  const negateOp& negOp,
481  const bool dummyTransform = true,
482  const int tag = UPstream::msgType()
483  ) const;
484 
485  //- Distribute data using default commsType.
486  template<class T>
487  void distribute
488  (
489  DynamicList<T>& fld,
490  const bool dummyTransform = true,
491  const int tag = UPstream::msgType()
492  ) const;
493 
494  //- Reverse distribute data using default commsType.
495  template<class T>
496  void reverseDistribute
497  (
498  const label constructSize,
499  List<T>&,
500  const bool dummyTransform = true,
501  const int tag = UPstream::msgType()
502  ) const;
503 
504  //- Reverse distribute data using default commsType.
505  // Since constructSize might be larger than supplied size supply
506  // a nullValue
507  template<class T>
508  void reverseDistribute
509  (
510  const label constructSize,
511  const T& nullValue,
512  List<T>& fld,
513  const bool dummyTransform = true,
514  const int tag = UPstream::msgType()
515  ) const;
516 
517  //- Distribute with transforms
518  template<class T, class TransformOp>
519  void distribute
520  (
522  List<T>& fld,
523  const TransformOp& top,
524  const int tag = UPstream::msgType()
525  ) const;
526 
527  //- Reverse distribute with transforms
528  template<class T, class TransformOp>
529  void reverseDistribute
530  (
532  const label constructSize,
533  List<T>& fld,
534  const TransformOp& top,
535  const int tag = UPstream::msgType()
536  ) const;
537 
538  //- Reverse distribute with transforms
539  template<class T, class TransformOp>
540  void reverseDistribute
541  (
543  const label constructSize,
544  const T& nullValue,
545  List<T>& fld,
546  const TransformOp& top,
547  const int tag = UPstream::msgType()
548  ) const;
549 
550  //- Debug: print layout. Can only be used on maps with sorted
551  // storage (local data first, then non-local data)
552  void printLayout(Ostream& os) const;
553 
554  //- Correct for topo change.
555  void updateMesh(const mapPolyMesh&)
556  {
558  (
559  "mapDistribute::updateMesh(const mapPolyMesh&)"
560  );
561  }
562 
563  // Member Operators
564 
565  void operator=(const mapDistribute&);
566 
567  // IOstream Operators
568 
569  //- Read dictionary from Istream
571 
572  //- Write dictionary to Ostream
573  friend Ostream& operator<<(Ostream&, const mapDistribute&);
574 
575 };
576 
577 
578 // Template specialisation for primitives that do not need transform
579 template<>
580 void mapDistribute::transform::operator()
581 (
582  const transformer&,
583  const bool,
584  List<label>&
585 ) const;
586 template<>
587 void mapDistribute::transform::operator()
588 (
589  const coupledPolyPatch&,
590  UList<label>&
591 ) const;
592 template<>
593 void mapDistribute::transform::operator()
594 (
595  const coupledPolyPatch&,
596  Map<label>&
597 ) const;
598 template<>
599 void mapDistribute::transform::operator()
600 (
601  const coupledPolyPatch&,
603 ) const;
604 
605 template<>
606 void mapDistribute::transform::operator()
607 (
608  const coupledPolyPatch&,
610 ) const;
611 template<>
612 void mapDistribute::transform::operator()
613 (
614  const transformer&,
615  const bool,
616  List<scalar>&
617 ) const;
618 template<>
619 void mapDistribute::transform::operator()
620 (
621  const coupledPolyPatch&,
622  Map<scalar>&
623 ) const;
624 template<>
625 void mapDistribute::transform::operator()
626 (
627  const coupledPolyPatch&,
629 ) const;
630 
631 template<>
632 void mapDistribute::transform::operator()
633 (
634  const coupledPolyPatch& cpp,
636 ) const;
637 template<>
638 void mapDistribute::transform::operator()
639 (
640  const transformer&,
641  const bool,
642  List<bool>&
643 ) const;
644 template<>
645 void mapDistribute::transform::operator()
646 (
647  const coupledPolyPatch&,
648  Map<bool>&
649 ) const;
650 template<>
651 void mapDistribute::transform::operator()
652 (
653  const coupledPolyPatch&,
655 ) const;
656 
657 
658 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
659 
660 } // End namespace Foam
661 
662 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
663 
664 #ifdef NoRepository
665  #include "mapDistributeTemplates.C"
666 #endif
667 
668 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
669 
670 #endif
671 
672 // ************************************************************************* //
bool constructHasFlip() const
Does constructMap include a sign.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Vector-tensor class used to perform translations, rotations and scaling operations in 3D space...
Definition: transformer.H:83
friend Istream & operator>>(Istream &, mapDistribute &)
Read dictionary from Istream.
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute data using default commsType.
bool transforms() const
Return true if the transformer transforms a type.
Definition: transformerI.H:133
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:459
const labelListList & subMap() const
From subsetted data back to original data.
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.
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:476
friend Ostream & operator<<(Ostream &, const mapDistribute &)
Write dictionary to Ostream.
virtual const transformer & transform() const =0
Return transformation between the coupled patches.
void transfer(mapDistribute &)
Transfer the contents of the argument and annul the argument.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:158
void updateMesh(const mapPolyMesh &)
Correct for topo change.
void transformList(Container< Type > &) const
Transform the given container.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
const labelList & transformStart() const
Destination in constructMap for transformed elements.
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< ' ';}gmvFile<< nl;forAll(lagrangianScalarNames, i){ const word &name=lagrangianScalarNames[i];IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Default transformation behaviour.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
void operator=(const mapDistribute &)
Istream & operator>>(Istream &, directionInfo &)
autoPtr< mapDistribute > clone() const
Clone.
virtual ~mapDistribute()
Destructor.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:29
Default transformation behaviour for position.
mapDistribute()
Construct null.
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:54
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
void reverseDistribute(const label constructSize, List< T > &, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
label constructSize() const
Constructed data size.
#define notImplemented(functionName)
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:360
const labelListList & transformElements() const
For every globalIndexAndTransform::transformPermutations.
Class containing processor-to-processor mapping information.
Ostream & operator<<(Ostream &, const ensightPart &)
const labelListList & constructMap() const
From subsetted data to new reconstructed data.
vector transformPosition(const vector &v) const
Transform the given position.
Definition: transformerI.H:153
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:52
ClassName("mapDistribute")
rDeltaTY field()
void operator()(const transformer &vt, const bool forward, List< Type > &fld) const
Namespace for OpenFOAM.
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)
bool subHasFlip() const
Does subMap include a sign.