All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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-2019 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 "transformList.H"
138 #include "vectorTensorTransform.H"
139 #include "coupledPolyPatch.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 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  forAll(flds, i)
232  {
233  operator()(vt, forward, flds[i]);
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  }
246 
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  };
258 
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(move(fld));
272  if (forward)
273  {
274  fld = vt.transformPosition(pfld);
275  }
276  else
277  {
278  fld = vt.invTransformPosition(pfld);
279  }
280  }
281  void operator()
282  (
283  const vectorTensorTransform& vt,
284  const bool forward,
285  List<List<point>>& flds
286  ) const
287  {
288  forAll(flds, i)
289  {
290  operator()(vt, forward, flds[i]);
291  }
292  }
293  //- Transform patch-based field
294  void operator()(const coupledPolyPatch& cpp, pointField& fld) const
295  {
296  cpp.transformPosition(fld);
297  }
298  template<template<class> class Container>
299  void operator()(const coupledPolyPatch& cpp, Container<point>& map)
300  const
301  {
302  Field<point> fld(map.size());
303  label i = 0;
304  forAllConstIter(typename Container<point>, map, iter)
305  {
306  fld[i++] = iter();
307  }
308  cpp.transformPosition(fld);
309  i = 0;
310  forAllIter(typename Container<point>, map, iter)
311  {
312  iter() = fld[i++];
313  }
314  }
315  };
316 
317 
318  // Declare name of the class and its debug switch
319  ClassName("mapDistribute");
320 
321 
322  // Constructors
323 
324  //- Construct null
325  mapDistribute();
326 
327  //- Construct from components
329  (
330  const label constructSize,
333  const bool subHasFlip = false,
334  const bool constructHasFlip = false
335  );
336 
337  //- Construct from components
339  (
340  const label constructSize,
345  const bool subHasFlip = false,
346  const bool constructHasFlip = false
347  );
348 
349  //- Construct from reverse addressing: per data item the send
350  // processor and the receive processor. (note: data is not stored
351  // sorted per processor so cannot use printLayout).
353  (
354  const labelList& sendProcs,
355  const labelList& recvProcs
356  );
357 
358  //- Construct from list of (possibly) remote elements in globalIndex
359  // numbering (or -1). Determines compact numbering (see above) and
360  // distribute map to get data into this ordering and renumbers the
361  // elements to be in compact numbering.
363  (
364  const globalIndex&,
365  labelList& elements,
366  List<Map<label>>& compactMap,
367  const int tag = Pstream::msgType()
368  );
369 
370  //- Special variant that works with the info sorted into bins
371  // according to local indices. E.g. think cellCells where
372  // cellCells[localCelli] is a list of global cells
374  (
375  const globalIndex&,
376  labelListList& cellCells,
377  List<Map<label>>& compactMap,
378  const int tag = Pstream::msgType()
379  );
380 
381  //- Construct from list of (possibly remote) untransformed elements
382  // in globalIndex numbering (or -1) and (possibly remote)
383  // transformded elements in globalIndexAndTransform numbering.
384  // Determines compact numbering (see above) and
385  // distribute map to get data into this ordering and renumbers the
386  // elements to be in compact numbering.
388  (
389  const globalIndex&,
390  labelList& untransformedElements,
392  const labelPairList& transformedElements,
393  labelList& transformedIndices,
394  List<Map<label>>& compactMap,
395  const int tag = Pstream::msgType()
396  );
397 
398  //- As above but with ListLists.
400  (
401  const globalIndex&,
402  labelListList& cellCells,
404  const List<labelPairList>& transformedElements,
405  labelListList& transformedIndices,
406  List<Map<label>>& compactMap,
407  const int tag = Pstream::msgType()
408  );
409 
410  //- Copy constructor
412 
413  //- Move constructor
415 
416  //- Construct from Istream
418 
419  //- Clone
421 
422 
423  //- Destructor
424  virtual ~mapDistribute()
425  {}
426 
427 
428  // Member Functions
429 
430  // Access
431 
432  //- For every globalIndexAndTransform::transformPermutations
433  // gives the elements that need to be transformed
434  const labelListList& transformElements() const
435  {
436  return transformElements_;
437  }
438 
439  //- Destination in constructMap for transformed elements
440  const labelList& transformStart() const
441  {
442  return transformStart_;
443  }
444 
445  //- Find transform from transformElements
446  label whichTransform(const label index) const;
447 
448 
449  // Other
450 
451  //- Transfer the contents of the argument and annul the argument.
452  void transfer(mapDistribute&);
453 
454  //- Distribute data using default commsType.
455  template<class T>
456  void distribute
457  (
458  List<T>& fld,
459  const bool dummyTransform = true,
460  const int tag = UPstream::msgType()
461  ) const;
462 
463  //- Distribute data using default commsType.
464  template<class T, class negateOp>
465  void distribute
466  (
467  List<T>& fld,
468  const negateOp& negOp,
469  const bool dummyTransform = true,
470  const int tag = UPstream::msgType()
471  ) const;
472 
473  //- Distribute data using default commsType.
474  template<class T>
475  void distribute
476  (
477  DynamicList<T>& fld,
478  const bool dummyTransform = true,
479  const int tag = UPstream::msgType()
480  ) const;
481 
482  //- Reverse distribute data using default commsType.
483  template<class T>
484  void reverseDistribute
485  (
486  const label constructSize,
487  List<T>&,
488  const bool dummyTransform = true,
489  const int tag = UPstream::msgType()
490  ) const;
491 
492  //- Reverse distribute data using default commsType.
493  // Since constructSize might be larger than supplied size supply
494  // a nullValue
495  template<class T>
496  void reverseDistribute
497  (
498  const label constructSize,
499  const T& nullValue,
500  List<T>& fld,
501  const bool dummyTransform = true,
502  const int tag = UPstream::msgType()
503  ) const;
504 
505  //- Distribute with transforms
506  template<class T, class TransformOp>
507  void distribute
508  (
510  List<T>& fld,
511  const TransformOp& top,
512  const int tag = UPstream::msgType()
513  ) const;
514 
515  //- Reverse distribute with transforms
516  template<class T, class TransformOp>
517  void reverseDistribute
518  (
520  const label constructSize,
521  List<T>& fld,
522  const TransformOp& top,
523  const int tag = UPstream::msgType()
524  ) const;
525 
526  //- Reverse distribute with transforms
527  template<class T, class TransformOp>
528  void reverseDistribute
529  (
531  const label constructSize,
532  const T& nullValue,
533  List<T>& fld,
534  const TransformOp& top,
535  const int tag = UPstream::msgType()
536  ) const;
537 
538  //- Debug: print layout. Can only be used on maps with sorted
539  // storage (local data first, then non-local data)
540  void printLayout(Ostream& os) const;
541 
542  //- Correct for topo change.
543  void updateMesh(const mapPolyMesh&)
544  {
546  (
547  "mapDistribute::updateMesh(const mapPolyMesh&)"
548  );
549  }
550 
551  // Member Operators
552 
553  void operator=(const mapDistribute&);
554 
555  // IOstream Operators
556 
557  //- Read dictionary from Istream
559 
560  //- Write dictionary to Ostream
561  friend Ostream& operator<<(Ostream&, const mapDistribute&);
562 
563 };
564 
565 
566 // Template specialisation for primitives that do not need transform
567 template<>
568 void mapDistribute::transform::operator()
569 (
570  const vectorTensorTransform&,
571  const bool,
572  List<label>&
573 ) const;
574 template<>
575 void mapDistribute::transform::operator()
576 (
577  const coupledPolyPatch&,
578  UList<label>&
579 ) const;
580 template<>
581 void mapDistribute::transform::operator()
582 (
583  const coupledPolyPatch&,
584  Map<label>&
585 ) const;
586 template<>
587 void mapDistribute::transform::operator()
588 (
589  const coupledPolyPatch&,
591 ) const;
592 
593 template<>
594 void mapDistribute::transform::operator()
595 (
596  const coupledPolyPatch&,
598 ) const;
599 template<>
600 void mapDistribute::transform::operator()
601 (
602  const vectorTensorTransform&,
603  const bool,
604  List<scalar>&
605 ) const;
606 template<>
607 void mapDistribute::transform::operator()
608 (
609  const coupledPolyPatch&,
610  Map<scalar>&
611 ) const;
612 template<>
613 void mapDistribute::transform::operator()
614 (
615  const coupledPolyPatch&,
617 ) const;
618 
619 template<>
620 void mapDistribute::transform::operator()
621 (
622  const coupledPolyPatch& cpp,
624 ) const;
625 template<>
626 void mapDistribute::transform::operator()
627 (
628  const vectorTensorTransform&,
629  const bool,
630  List<bool>&
631 ) const;
632 template<>
633 void mapDistribute::transform::operator()
634 (
635  const coupledPolyPatch&,
636  Map<bool>&
637 ) const;
638 template<>
639 void mapDistribute::transform::operator()
640 (
641  const coupledPolyPatch&,
643 ) const;
644 
645 
646 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
647 
648 } // End namespace Foam
649 
650 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
651 
652 #ifdef NoRepository
653  #include "mapDistributeTemplates.C"
654 #endif
655 
656 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
657 
658 #endif
659 
660 // ************************************************************************* //
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
void operator()(const vectorTensorTransform &vt, const bool forward, List< Type > &fld) const
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.
Vector-tensor class used to perform translations and rotations in 3D space.
#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.
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
virtual const tensorField & forwardT() const
Return face transformation tensor.
void updateMesh(const mapPolyMesh &)
Correct for topo change.
void transformList(const tensor &, UList< T > &)
Apply transformation to list. Either single transformation tensor.
Definition: transformList.C:49
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: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:53
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Spatial transformation functions for primitive fields.
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:356
const labelListList & transformElements() const
For every globalIndexAndTransform::transformPermutations.
Class containing processor-to-processor mapping information.
virtual void transformPosition(pointField &) const =0
Transform a patch-based position from other side to this side.
Ostream & operator<<(Ostream &, const ensightPart &)
const labelListList & constructMap() const
From subsetted data to new reconstructed data.
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")
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.