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-------------------------------------------------------------------------------
11License
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
27Class
28 Foam::mapDistribute
29
30Description
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
37Note:
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
129SourceFiles
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"
142#include "coupledPolyPatch.H"
143
144// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
145
146namespace Foam
147{
148
149// Forward Declarations
150class globalIndexAndTransform;
151class mapDistribute;
152
153Istream& operator>>(Istream&, mapDistribute&);
154Ostream& operator<<(Ostream&, const mapDistribute&);
155
156
157/*---------------------------------------------------------------------------*\
158 Class mapDistribute Declaration
159\*---------------------------------------------------------------------------*/
161class 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
202public:
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,
217 ) const
218 {
219 const tensor T(forward ? vt.R() : vt.R().T());
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 }
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
261 {
262 public:
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 }
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 }
294
295 //- Transform patch-based field
296 void operator()(const coupledPolyPatch& cpp, pointField& fld) const
297 {
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 }
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
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,
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,
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
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>
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>
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>
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>
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
560template<>
562(
563 const vectorTensorTransform&,
564 const bool,
565 List<label>&
566) const;
567template<>
569(
570 const coupledPolyPatch&,
571 UList<label>&
572) const;
573template<>
575(
576 const coupledPolyPatch&,
577 Map<label>&
578) const;
579template<>
581(
582 const coupledPolyPatch&,
583 EdgeMap<label>&
584) const;
585
586template<>
588(
589 const coupledPolyPatch&,
590 UList<scalar>&
591) const;
592template<>
594(
595 const vectorTensorTransform&,
596 const bool,
597 List<scalar>&
598) const;
599template<>
601(
602 const coupledPolyPatch&,
603 Map<scalar>&
604) const;
605template<>
607(
608 const coupledPolyPatch&,
609 EdgeMap<scalar>&
610) const;
611
612template<>
614(
615 const coupledPolyPatch& cpp,
616 UList<bool>& fld
617) const;
618template<>
620(
621 const vectorTensorTransform&,
622 const bool,
623 List<bool>&
624) const;
625template<>
627(
628 const coupledPolyPatch&,
629 Map<bool>&
630) const;
631template<>
633(
634 const coupledPolyPatch&,
635 EdgeMap<bool>&
636) const;
637
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// ************************************************************************* //
Info<< nl<< "Wrote faMesh in vtk format: "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.mesh().time().globalPath()/"finiteArea-edges"));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
A HashTable to objects of type <T> with a label key.
Definition: Map.H:60
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:556
static label worldComm
Default communicator (all processors)
Definition: UPstream.H:293
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
virtual bool parallel() const
Are the cyclic planes parallel.
virtual void transformPosition(pointField &) const =0
Transform a patch-based position from other side to this side.
virtual const tensorField & forwardT() const
Return face transformation tensor.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
friend Ostream & operator(Ostream &, const faMatrix< Type > &)
Determination and storage of the possible independent transforms introduced by coupledPolyPatches,...
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
Class containing processor-to-processor mapping information.
const labelListList & constructMap() const noexcept
From subsetted data to new reconstructed data.
bool constructHasFlip() const noexcept
Does constructMap include a sign.
const labelListList & subMap() const noexcept
From subsetted data back to original data.
bool subHasFlip() const noexcept
Does subMap include a sign.
label comm() const noexcept
The communicator used.
label constructSize() const noexcept
Constructed data size.
Default transformation behaviour for position.
void operator()(const coupledPolyPatch &cpp, Container< point > &map) const
void operator()(const coupledPolyPatch &cpp, pointField &fld) const
Transform patch-based field.
void operator()(const vectorTensorTransform &vt, const bool forward, List< point > &fld) const
Default transformation behaviour.
void operator()(const coupledPolyPatch &cpp, Container< Type > &map) const
Transform sparse field.
void operator()(const coupledPolyPatch &cpp, UList< Type > &fld) const
Transform patch-based field.
void operator()(const vectorTensorTransform &vt, const bool forward, List< Type > &fld) const
Class containing processor-to-processor mapping information.
friend Istream & operator>>(Istream &, mapDistribute &)
Read plain content (not dictionary) from Istream.
label whichTransform(const label index) const
Find transform from transformElements.
void operator=(const mapDistribute &rhs)
Copy assignment.
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
mapDistribute()
Default construct - uses worldComm.
friend Ostream & operator<<(Ostream &, const mapDistribute &)
Write plain content (not dictionary) to Ostream.
ClassName("mapDistribute")
void readDict(const dictionary &dict)
Read entries from dictionary format.
const labelListList & transformElements() const noexcept
For every globalIndexAndTransform::transformPermutations.
void transfer(mapDistribute &map)
Transfer the contents of the argument and annul the argument.
void writeEntries(Ostream &os) const
Write entries in dictionary format.
virtual ~mapDistribute()=default
Destructor.
void reverseDistribute(const label constructSize, List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute data using default commsType.
const labelList & transformStart() const noexcept
Destination in constructMap for transformed elements.
autoPtr< mapDistribute > clone() const
Clone.
void clear()
Reset to zero size, only retaining communicator.
void updateMesh(const mapPolyMesh &)
No correction for topo change.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:162
Vector-tensor class used to perform translations and rotations in 3D space.
#define ClassName(TypeNameString)
Add typeName information from argument TypeNameString to a class.
Definition: className.H:67
const volScalarField & T
rDeltaTY field()
bool
Definition: EEqn.H:20
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:517
OBJstream os(runTime.globalPath()/outputName)
Namespace for OpenFOAM.
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
Istream & operator>>(Istream &, directionInfo &)
const direction noexcept
Definition: Scalar.H:223
void transformList(const tensor &rotTensor, UList< T > &field)
Inplace transform a list of elements.
Definition: transformList.C:52
dictionary dict
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:260
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.
Definition: stdFoam.H:278
Spatial transformation functions for list of values and primitive fields.