distributionMap.C
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-2022 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 \*---------------------------------------------------------------------------*/
25 
26 #include "distributionMap.H"
28 #include "transformField.H"
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
34  defineTypeNameAndDebug(distributionMap, 0);
35 }
36 
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 
39 template<>
40 void Foam::distributionMap::transform::operator()
41 (
42  const transformer&,
43  const bool,
45 ) const
46 {}
47 template<>
48 void Foam::distributionMap::transform::operator()
49 (
50  const coupledPolyPatch&,
52 ) const
53 {}
54 template<>
55 void Foam::distributionMap::transform::operator()
56 (
57  const coupledPolyPatch&,
58  Map<label>&
59 ) const
60 {}
61 template<>
62 void Foam::distributionMap::transform::operator()
63 (
64  const coupledPolyPatch&,
66 ) const
67 {}
68 
69 
70 template<>
71 void Foam::distributionMap::transform::operator()
72 (
73  const transformer&,
74  const bool,
76 ) const
77 {}
78 template<>
79 void Foam::distributionMap::transform::operator()
80 (
81  const coupledPolyPatch&,
83 ) const
84 {}
85 template<>
86 void Foam::distributionMap::transform::operator()
87 (
88  const coupledPolyPatch&,
90 ) const
91 {}
92 template<>
93 void Foam::distributionMap::transform::operator()
94 (
95  const coupledPolyPatch&,
97 ) const
98 {}
99 
100 
101 template<>
102 void Foam::distributionMap::transform::operator()
103 (
104  const transformer&,
105  const bool,
106  List<bool>&
107 ) const
108 {}
109 template<>
110 void Foam::distributionMap::transform::operator()
111 (
112  const coupledPolyPatch&,
113  UList<bool>&
114 ) const
115 {}
116 template<>
117 void Foam::distributionMap::transform::operator()
118 (
119  const coupledPolyPatch&,
120  Map<bool>&
121 ) const
122 {}
123 template<>
124 void Foam::distributionMap::transform::operator()
125 (
126  const coupledPolyPatch&,
128 ) const
129 {}
130 
131 
133 {
135 
136  forAll(transformElements_, trafoI)
137  {
138  if (transformElements_[trafoI].size() > 0)
139  {
140  os << "transform " << trafoI << ':' << endl
141  << " start : " << transformStart_[trafoI] << endl
142  << " size : " << transformElements_[trafoI].size() << endl;
143  }
144  }
145 }
146 
147 
148 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
149 
151 :
153 {}
154 
155 
157 (
158  const label constructSize,
161  const bool subHasFlip,
162  const bool constructHasFlip
163 )
164 :
166  (
167  constructSize,
168  move(subMap),
169  move(constructMap),
170  subHasFlip,
171  constructHasFlip
172  )
173 {}
174 
175 
177 (
178  const label constructSize,
183  const bool subHasFlip,
184  const bool constructHasFlip
185 )
186 :
188  (
189  constructSize,
190  move(subMap),
191  move(constructMap),
192  subHasFlip,
193  constructHasFlip
194  ),
195  transformElements_(move(transformElements)),
196  transformStart_(move(transformStart))
197 {}
198 
199 
201 (
202  const labelList& sendProcs,
203  const labelList& recvProcs
204 )
205 :
206  distributionMapBase(sendProcs, recvProcs)
207 {}
208 
209 
211 (
212  const globalIndex& globalNumbering,
213  labelList& elements,
214  List<Map<label>>& compactMap,
215  const int tag
216 )
217 :
219  (
220  globalNumbering,
221  elements,
222  compactMap,
223  tag
224  )
225 {}
226 
227 
229 (
230  const globalIndex& globalNumbering,
231  labelListList& cellCells,
232  List<Map<label>>& compactMap,
233  const int tag
234 )
235 :
237  (
238  globalNumbering,
239  cellCells,
240  compactMap,
241  tag
242  )
243 {}
244 
245 
247 (
248  const globalIndex& globalNumbering,
249  labelList& elements,
250  const globalIndexAndTransform& globalTransforms,
251  const labelPairList& transformedElements,
252  labelList& transformedIndices,
253  List<Map<label>>& compactMap,
254  const int tag
255 )
256 :
258 {
259  // Construct per processor compact addressing of the global elements
260  // needed. The ones from the local processor are not included since
261  // these are always all needed.
263  (
264  globalNumbering,
265  elements,
266  compactMap
267  );
268 
269  // Add all (non-local) transformed elements needed.
270  forAll(transformedElements, i)
271  {
272  labelPair elem = transformedElements[i];
273  label proci = globalTransforms.processor(elem);
274  if (proci != Pstream::myProcNo())
275  {
276  label index = globalTransforms.index(elem);
277  label nCompact = compactMap[proci].size();
278  compactMap[proci].insert(index, nCompact);
279  }
280  }
281 
282 
283  // Exchange what I need with processor that supplies it. Renumber elements
284  // into compact numbering
285  labelList compactStart;
287  (
288  tag,
289  globalNumbering,
290  elements,
291  compactMap,
292  compactStart
293  );
294 
295 
296  // Renumber the transformed elements
297  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
298  // Count per transformIndex
299  label nTrafo = globalTransforms.transformPermutations().size();
300  labelList nPerTransform(nTrafo, 0);
301  forAll(transformedElements, i)
302  {
303  labelPair elem = transformedElements[i];
304  label trafoI = globalTransforms.transformIndex(elem);
305  nPerTransform[trafoI]++;
306  }
307  // Offset per transformIndex
308  transformStart_.setSize(nTrafo);
309  transformElements_.setSize(nTrafo);
310  forAll(transformStart_, trafoI)
311  {
312  transformStart_[trafoI] = constructSize_;
313  constructSize_ += nPerTransform[trafoI];
314  transformElements_[trafoI].setSize(nPerTransform[trafoI]);
315  }
316 
317  // Sort transformed elements into their new slot.
318  nPerTransform = 0;
319 
320  transformedIndices.setSize(transformedElements.size());
321  forAll(transformedElements, i)
322  {
323  labelPair elem = transformedElements[i];
324  label proci = globalTransforms.processor(elem);
325  label index = globalTransforms.index(elem);
326  label trafoI = globalTransforms.transformIndex(elem);
327 
328  // Get compact index for untransformed element
329  label rawElemI =
330  (
331  proci == Pstream::myProcNo()
332  ? index
333  : compactMap[proci][index]
334  );
335 
336  label& n = nPerTransform[trafoI];
337  // index of element to transform
338  transformElements_[trafoI][n] = rawElemI;
339  // destination of transformed element
340  transformedIndices[i] = transformStart_[trafoI]+n;
341  n++;
342  }
343 
344  if (debug)
345  {
346  printLayout(Pout);
347  }
348 }
349 
350 
352 (
353  const globalIndex& globalNumbering,
354  labelListList& cellCells,
355  const globalIndexAndTransform& globalTransforms,
356  const List<labelPairList>& transformedElements,
357  labelListList& transformedIndices,
358  List<Map<label>>& compactMap,
359  const int tag
360 )
361 :
363 {
364  // Construct per processor compact addressing of the global elements
365  // needed. The ones from the local processor are not included since
366  // these are always all needed.
368  (
369  globalNumbering,
370  cellCells,
371  compactMap
372  );
373 
374  // Add all (non-local) transformed elements needed.
375  forAll(transformedElements, celli)
376  {
377  const labelPairList& elems = transformedElements[celli];
378 
379  forAll(elems, i)
380  {
381  label proci = globalTransforms.processor(elems[i]);
382  if (proci != Pstream::myProcNo())
383  {
384  label index = globalTransforms.index(elems[i]);
385  label nCompact = compactMap[proci].size();
386  compactMap[proci].insert(index, nCompact);
387  }
388  }
389  }
390 
391 
392  // Exchange what I need with processor that supplies it. Renumber elements
393  // into compact numbering
394  labelList compactStart;
396  (
397  tag,
398  globalNumbering,
399  cellCells,
400  compactMap,
401  compactStart
402  );
403 
404 
405  // Renumber the transformed elements
406  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
407  // Count per transformIndex
408  label nTrafo = globalTransforms.transformPermutations().size();
409  labelList nPerTransform(nTrafo, 0);
410  forAll(transformedElements, celli)
411  {
412  const labelPairList& elems = transformedElements[celli];
413 
414  forAll(elems, i)
415  {
416  label trafoI = globalTransforms.transformIndex(elems[i]);
417  nPerTransform[trafoI]++;
418  }
419  }
420  // Offset per transformIndex
421  transformStart_.setSize(nTrafo);
422  transformElements_.setSize(nTrafo);
423  forAll(transformStart_, trafoI)
424  {
425  transformStart_[trafoI] = constructSize_;
426  constructSize_ += nPerTransform[trafoI];
427  transformElements_[trafoI].setSize(nPerTransform[trafoI]);
428  }
429 
430  // Sort transformed elements into their new slot.
431  nPerTransform = 0;
432 
433  transformedIndices.setSize(transformedElements.size());
434  forAll(transformedElements, celli)
435  {
436  const labelPairList& elems = transformedElements[celli];
437  transformedIndices[celli].setSize(elems.size());
438 
439  forAll(elems, i)
440  {
441  label proci = globalTransforms.processor(elems[i]);
442  label index = globalTransforms.index(elems[i]);
443  label trafoI = globalTransforms.transformIndex(elems[i]);
444 
445  // Get compact index for untransformed element
446  label rawElemI =
447  (
448  proci == Pstream::myProcNo()
449  ? index
450  : compactMap[proci][index]
451  );
452 
453  label& n = nPerTransform[trafoI];
454  // index of element to transform
455  transformElements_[trafoI][n] = rawElemI;
456  // destination of transformed element
457  transformedIndices[celli][i] = transformStart_[trafoI]+n;
458  n++;
459  }
460  }
461 
462  if (debug)
463  {
464  printLayout(Pout);
465  }
466 }
467 
468 
470 :
471  distributionMapBase(map),
472  transformElements_(map.transformElements_),
473  transformStart_(map.transformStart_)
474 {}
475 
476 
478 :
479  distributionMapBase(move(map)),
480  transformElements_(move(map.transformElements_)),
481  transformStart_(move(map.transformStart_))
482 {}
483 
484 
486 {
487  is >> *this;
488 }
489 
490 
492 {
493  return autoPtr<distributionMap>(new distributionMap(*this));
494 }
495 
496 
497 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
498 
500 const
501 {
502  return findLower(transformStart_, index+1);
503 }
504 
505 
507 {
509  transformElements_.transfer(rhs.transformElements_);
510  transformStart_.transfer(rhs.transformStart_);
511 }
512 
513 
514 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
515 
517 {
518  // Check for assignment to self
519  if (this == &rhs)
520  {
522  << "Attempted assignment to self"
523  << abort(FatalError);
524  }
526  transformElements_ = rhs.transformElements_;
527  transformStart_ = rhs.transformStart_;
528 }
529 
530 
531 // * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * * //
532 
534 {
535  is.fatalCheck("operator>>(Istream&, distributionMap&)");
536 
537  is >> static_cast<distributionMapBase&>(map)
538  >> map.transformElements_ >> map.transformStart_;
539 
540  return is;
541 }
542 
543 
544 // * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * * //
545 
547 {
548  os << static_cast<const distributionMapBase&>(map) << token::NL
549  << map.transformElements_ << token::NL
550  << map.transformStart_;
551 
552  return os;
553 }
554 
555 
556 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
void operator=(const distributionMap &)
const List< transformer > & transformPermutations() const
Return access to the permuted transforms.
label index(const labelPair &globalIAndTransform) const
Index carried by the object.
Vector-tensor class used to perform translations, rotations and scaling operations in 3D space...
Definition: transformer.H:83
const labelListList & transformElements() const
For every globalIndexAndTransform::transformPermutations.
Class containing processor-to-processor mapping information.
error FatalError
void operator=(const distributionMapBase &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
distributionMap()
Construct null.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
const labelListList & constructMap() const
From subsetted data to new reconstructed data.
label processor(const labelPair &globalIAndTransform) const
Which processor does this come from?
distributionMapBase()
Construct null.
const labelListList & subMap() const
From subsetted data back to original data.
void transfer(distributionMap &)
Transfer the contents of the argument and annul the argument.
Spatial transformation functions for primitive fields.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: contiguous.H:49
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
Istream & operator>>(Istream &, directionInfo &)
void calcCompactAddressing(const globalIndex &globalNumbering, const labelList &elements, List< Map< label >> &compactMap) const
Construct per processor compact addressing of the global elements.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
void fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:105
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:54
Map from edge (expressed as its endpoints) to value.
Definition: EdgeMap.H:47
const labelList & transformStart() const
Destination in constructMap for transformed elements.
defineTypeNameAndDebug(combustionModel, 0)
void transfer(distributionMapBase &)
Transfer the contents of the argument and annul the argument.
label transformIndex(const labelPair &globalIAndTransform) const
Transform carried by the object.
autoPtr< distributionMap > clone() const
Clone.
void setSize(const label)
Reset size of List.
Definition: List.C:281
Class containing processor-to-processor mapping information.
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
Ostream & operator<<(Ostream &, const ensightPart &)
void exchangeAddressing(const int tag, const globalIndex &globalNumbering, labelList &elements, List< Map< label >> &compactMap, labelList &compactStart)
label whichTransform(const label index) const
Find transform from transformElements.
label findLower(const ListType &, typename ListType::const_reference, const label stary, const BinaryOp &bop)
Find last element < given value in sorted list and return index,.
label n
label constructSize_
Size of reconstructed data.
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
FvWallInfoData< WallInfo, bool > bool
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
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)