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 | Copyright (C) 2011-2016 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  // Private Member Functions
175 
176  //- Helper function: copy transformElements without transformation
177  template<class T>
178  void applyDummyTransforms(List<T>& field) const;
179 
180  template<class T, class TransformOp>
181  void applyTransforms
182  (
183  const globalIndexAndTransform& globalTransforms,
184  List<T>& field,
185  const TransformOp& top
186  ) const;
187 
188  //- Helper function: copy transformElements without transformation
189  template<class T>
190  void applyDummyInverseTransforms(List<T>& field) const;
191 
192  template<class T, class TransformOp>
193  void applyInverseTransforms
194  (
195  const globalIndexAndTransform& globalTransforms,
196  List<T>& field,
197  const TransformOp& top
198  ) const;
199 
200 public:
201 
202  // Public classes
203 
204  //- Default transformation behaviour
205  class transform
206  {
207  public:
208 
209  template<class Type>
210  void operator()
211  (
212  const vectorTensorTransform& vt,
213  const bool forward,
214  List<Type>& fld
215  ) const
216  {
217  const tensor T(forward ? vt.R() : vt.R().T());
218  transformList(T, fld);
219  }
220 
221  template<class Type>
222  void operator()
223  (
224  const vectorTensorTransform& vt,
225  const bool forward,
226  List<List<Type>>& flds
227  ) const
228  {
229  forAll(flds, i)
230  {
231  operator()(vt, forward, flds[i]);
232  }
233  }
234 
235  //- Transform patch-based field
236  template<class Type>
237  void operator()(const coupledPolyPatch& cpp, UList<Type>& fld) const
238  {
239  if (!cpp.parallel())
240  {
241  transformList(cpp.forwardT(), fld);
242  }
243  }
244 
245  //- Transform sparse field
246  template<class Type, template<class> class Container>
247  void operator()(const coupledPolyPatch& cpp, Container<Type>& map)
248  const
249  {
250  if (!cpp.parallel())
251  {
252  transformList(cpp.forwardT(), map);
253  }
254  }
255  };
256 
257  //- Default transformation behaviour for position
258  class transformPosition
259  {
260  public:
261 
262  void operator()
263  (
264  const vectorTensorTransform& vt,
265  const bool forward,
267  ) const
268  {
269  pointField pfld(fld.xfer());
270  if (forward)
271  {
272  fld = vt.transformPosition(pfld);
273  }
274  else
275  {
276  fld = vt.invTransformPosition(pfld);
277  }
278  }
279  void operator()
280  (
281  const vectorTensorTransform& vt,
282  const bool forward,
283  List<List<point>>& flds
284  ) const
285  {
286  forAll(flds, i)
287  {
288  operator()(vt, forward, flds[i]);
289  }
290  }
291  //- Transform patch-based field
292  void operator()(const coupledPolyPatch& cpp, pointField& fld) const
293  {
294  cpp.transformPosition(fld);
295  }
296  template<template<class> class Container>
297  void operator()(const coupledPolyPatch& cpp, Container<point>& map)
298  const
299  {
300  Field<point> fld(map.size());
301  label i = 0;
302  forAllConstIter(typename Container<point>, map, iter)
303  {
304  fld[i++] = iter();
305  }
306  cpp.transformPosition(fld);
307  i = 0;
308  forAllIter(typename Container<point>, map, iter)
309  {
310  iter() = fld[i++];
311  }
312  }
313  };
314 
315 
316  // Declare name of the class and its debug switch
317  ClassName("mapDistribute");
318 
319 
320  // Constructors
321 
322  //- Construct null
323  mapDistribute();
324 
325  //- Construct from components
327  (
328  const label constructSize,
329  const Xfer<labelListList>& subMap,
330  const Xfer<labelListList>& constructMap,
331  const bool subHasFlip = false,
332  const bool constructHasFlip = false
333  );
334 
335  //- Construct from components
337  (
338  const label constructSize,
339  const Xfer<labelListList>& subMap,
340  const Xfer<labelListList>& constructMap,
341  const Xfer<labelListList>& transformElements,
342  const Xfer<labelList>& transformStart,
343  const bool subHasFlip = false,
344  const bool constructHasFlip = false
345  );
346 
347  //- Construct from reverse addressing: per data item the send
348  // processor and the receive processor. (note: data is not stored
349  // sorted per processor so cannot use printLayout).
351  (
352  const labelList& sendProcs,
353  const labelList& recvProcs
354  );
355 
356  //- Construct from list of (possibly) remote elements in globalIndex
357  // numbering (or -1). Determines compact numbering (see above) and
358  // distribute map to get data into this ordering and renumbers the
359  // elements to be in compact numbering.
361  (
362  const globalIndex&,
363  labelList& elements,
364  List<Map<label>>& compactMap,
365  const int tag = Pstream::msgType()
366  );
367 
368  //- Special variant that works with the info sorted into bins
369  // according to local indices. E.g. think cellCells where
370  // cellCells[localCelli] is a list of global cells
372  (
373  const globalIndex&,
374  labelListList& cellCells,
375  List<Map<label>>& compactMap,
376  const int tag = Pstream::msgType()
377  );
378 
379  //- Construct from list of (possibly remote) untransformed elements
380  // in globalIndex numbering (or -1) and (possibly remote)
381  // transformded elements in globalIndexAndTransform numbering.
382  // Determines compact numbering (see above) and
383  // distribute map to get data into this ordering and renumbers the
384  // elements to be in compact numbering.
386  (
387  const globalIndex&,
388  labelList& untransformedElements,
390  const labelPairList& transformedElements,
391  labelList& transformedIndices,
392  List<Map<label>>& compactMap,
393  const int tag = Pstream::msgType()
394  );
395 
396  //- As above but with ListLists.
398  (
399  const globalIndex&,
400  labelListList& cellCells,
402  const List<labelPairList>& transformedElements,
403  labelListList& transformedIndices,
404  List<Map<label>>& compactMap,
405  const int tag = Pstream::msgType()
406  );
407 
408  //- Construct by transferring parameter content
410 
411  //- Construct copy
413 
414  //- Construct from Istream
416 
417  //- Clone
419 
420 
421  //- Destructor
422  virtual ~mapDistribute()
423  {}
424 
425 
426  // Member Functions
427 
428  // Access
429 
430  //- For every globalIndexAndTransform::transformPermutations
431  // gives the elements that need to be transformed
432  const labelListList& transformElements() const
433  {
434  return transformElements_;
435  }
436 
437  //- Destination in constructMap for transformed elements
438  const labelList& transformStart() const
439  {
440  return transformStart_;
441  }
442 
443  //- Find transform from transformElements
444  label whichTransform(const label index) const;
445 
446 
447  // Other
448 
449  //- Transfer the contents of the argument and annul the argument.
450  void transfer(mapDistribute&);
451 
452  //- Transfer contents to the Xfer container
454 
455 
456  //- Distribute data using default commsType.
457  template<class T>
458  void distribute
459  (
460  List<T>& fld,
461  const bool dummyTransform = true,
462  const int tag = UPstream::msgType()
463  ) const;
464 
465  //- Distribute data using default commsType.
466  template<class T, class negateOp>
467  void distribute
468  (
469  List<T>& fld,
470  const negateOp& negOp,
471  const bool dummyTransform = true,
472  const int tag = UPstream::msgType()
473  ) const;
474 
475  //- Distribute data using default commsType.
476  template<class T>
477  void distribute
478  (
479  DynamicList<T>& fld,
480  const bool dummyTransform = true,
481  const int tag = UPstream::msgType()
482  ) const;
483 
484  //- Reverse distribute data using default commsType.
485  template<class T>
486  void reverseDistribute
487  (
488  const label constructSize,
489  List<T>&,
490  const bool dummyTransform = true,
491  const int tag = UPstream::msgType()
492  ) const;
493 
494  //- Reverse distribute data using default commsType.
495  // Since constructSize might be larger than supplied size supply
496  // a nullValue
497  template<class T>
498  void reverseDistribute
499  (
500  const label constructSize,
501  const T& nullValue,
502  List<T>& fld,
503  const bool dummyTransform = true,
504  const int tag = UPstream::msgType()
505  ) const;
506 
507  //- Distribute with transforms
508  template<class T, class TransformOp>
509  void distribute
510  (
512  List<T>& fld,
513  const TransformOp& top,
514  const int tag = UPstream::msgType()
515  ) const;
516 
517  //- Reverse distribute with transforms
518  template<class T, class TransformOp>
519  void reverseDistribute
520  (
522  const label constructSize,
523  List<T>& fld,
524  const TransformOp& top,
525  const int tag = UPstream::msgType()
526  ) const;
527 
528  //- Reverse distribute with transforms
529  template<class T, class TransformOp>
530  void reverseDistribute
531  (
533  const label constructSize,
534  const T& nullValue,
535  List<T>& fld,
536  const TransformOp& top,
537  const int tag = UPstream::msgType()
538  ) const;
539 
540  //- Debug: print layout. Can only be used on maps with sorted
541  // storage (local data first, then non-local data)
542  void printLayout(Ostream& os) const;
543 
544  //- Correct for topo change.
545  void updateMesh(const mapPolyMesh&)
546  {
548  (
549  "mapDistribute::updateMesh(const mapPolyMesh&)"
550  );
551  }
552 
553  // Member Operators
554 
555  void operator=(const mapDistribute&);
556 
557  // IOstream operators
558 
559  //- Read dictionary from Istream
561 
562  //- Write dictionary to Ostream
563  friend Ostream& operator<<(Ostream&, const mapDistribute&);
564 
565 };
566 
567 
568 // Template specialisation for primitives that do not need transform
569 template<>
570 void mapDistribute::transform::operator()
571 (
572  const vectorTensorTransform&,
573  const bool,
574  List<label>&
575 ) const;
576 template<>
577 void mapDistribute::transform::operator()
578 (
579  const coupledPolyPatch&,
580  UList<label>&
581 ) const;
582 template<>
583 void mapDistribute::transform::operator()
584 (
585  const coupledPolyPatch&,
586  Map<label>&
587 ) const;
588 template<>
589 void mapDistribute::transform::operator()
590 (
591  const coupledPolyPatch&,
593 ) const;
594 
595 template<>
596 void mapDistribute::transform::operator()
597 (
598  const coupledPolyPatch&,
600 ) const;
601 template<>
602 void mapDistribute::transform::operator()
603 (
604  const vectorTensorTransform&,
605  const bool,
606  List<scalar>&
607 ) const;
608 template<>
609 void mapDistribute::transform::operator()
610 (
611  const coupledPolyPatch&,
612  Map<scalar>&
613 ) const;
614 template<>
615 void mapDistribute::transform::operator()
616 (
617  const coupledPolyPatch&,
619 ) const;
620 
621 template<>
622 void mapDistribute::transform::operator()
623 (
624  const coupledPolyPatch& cpp,
626 ) const;
627 template<>
628 void mapDistribute::transform::operator()
629 (
630  const vectorTensorTransform&,
631  const bool,
632  List<bool>&
633 ) const;
634 template<>
635 void mapDistribute::transform::operator()
636 (
637  const coupledPolyPatch&,
638  Map<bool>&
639 ) const;
640 template<>
641 void mapDistribute::transform::operator()
642 (
643  const coupledPolyPatch&,
645 ) const;
646 
647 
648 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
649 
650 } // End namespace Foam
651 
652 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
653 
654 #ifdef NoRepository
655  #include "mapDistributeTemplates.C"
656 #endif
657 
658 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
659 
660 #endif
661 
662 // ************************************************************************* //
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
autoPtr< mapDistribute > clone() const
Clone.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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
const labelList & transformStart() const
Destination in constructMap for transformed elements.
Xfer< List< T > > xfer()
Transfer contents to the Xfer container.
Definition: ListI.H:90
friend Istream & operator>>(Istream &, mapDistribute &)
Read dictionary from Istream.
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:453
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
bool constructHasFlip() const
Does constructMap include a sign.
bool subHasFlip() const
Does subMap include a sign.
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:464
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
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
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
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 printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
void operator()(const vectorTensorTransform &vt, const bool forward, List< Type > &fld) const
void reverseDistribute(const label constructSize, List< T > &, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
void operator=(const mapDistribute &)
Istream & operator>>(Istream &, directionInfo &)
virtual ~mapDistribute()
Destructor.
virtual bool parallel() const
Are the cyclic planes parallel.
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 distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute data using default commsType.
#define notImplemented(functionName)
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:356
Class containing processor-to-processor mapping information.
virtual void transformPosition(pointField &) const =0
Transform a patch-based position from other side to this side.
label whichTransform(const label index) const
Find transform from transformElements.
Ostream & operator<<(Ostream &, const ensightPart &)
const labelListList & transformElements() const
For every globalIndexAndTransform::transformPermutations.
virtual const tensorField & forwardT() const
Return face transformation tensor.
Xfer< mapDistribute > xfer()
Transfer contents to the Xfer container.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:53
ClassName("mapDistribute")
label constructSize() const
Constructed data size.
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.