mapDistribute.C
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-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "mapDistribute.H"
31 #include "transformField.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37  defineTypeNameAndDebug(mapDistribute, 0);
38 }
39 
40 
41 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
42 
43 template<>
44 void Foam::mapDistribute::transform::operator()
45 (
47  const bool,
49 ) const {}
50 
51 template<>
52 void Foam::mapDistribute::transform::operator()
53 (
54  const coupledPolyPatch&,
56 ) const {}
57 
58 template<>
59 void Foam::mapDistribute::transform::operator()
60 (
61  const coupledPolyPatch&,
62  Map<label>&
63 ) const {}
64 
65 template<>
66 void Foam::mapDistribute::transform::operator()
67 (
70 ) const {}
71 
72 
73 template<>
74 void Foam::mapDistribute::transform::operator()
75 (
77  const bool,
79 ) const {}
80 
81 template<>
82 void Foam::mapDistribute::transform::operator()
83 (
84  const coupledPolyPatch&,
86 ) const {}
87 
88 template<>
89 void Foam::mapDistribute::transform::operator()
90 (
91  const coupledPolyPatch&,
93 ) const {}
94 
95 template<>
96 void Foam::mapDistribute::transform::operator()
97 (
100 ) const {}
101 
102 
103 template<>
104 void Foam::mapDistribute::transform::operator()
105 (
107  const bool,
108  List<bool>&
109 ) const {}
110 
111 template<>
112 void Foam::mapDistribute::transform::operator()
113 (
114  const coupledPolyPatch&,
115  UList<bool>&
116 ) const {}
117 
118 template<>
119 void Foam::mapDistribute::transform::operator()
120 (
121  const coupledPolyPatch&,
122  Map<bool>&
123 ) const {}
124 
125 template<>
126 void Foam::mapDistribute::transform::operator()
127 (
128  const coupledPolyPatch&,
130 ) const {}
131 
132 
134 {
136 
137  forAll(transformElements_, i)
138  {
139  if (!transformElements_[i].empty())
140  {
141  os << "transform " << i << ':' << nl
142  << " start : " << transformStart_[i] << nl
143  << " size : " << transformElements_[i].size() << endl;
144  }
145  }
146 }
147 
148 
149 Foam::UPtrList<const Foam::mapDistributeBase> Foam::mapDistribute::extractBase
150 (
151  const UPtrList<const mapDistribute>& maps
152 )
153 {
154  UPtrList<const mapDistributeBase> baseMaps(maps.size());
155  forAll(maps, i)
156  {
157  // Implicit cast to <const mapDistributeBase*>
158  baseMaps.set(i, maps.get(i));
159  }
160  return baseMaps;
161 }
162 
163 
164 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
167 :
168  mapDistributeBase(UPstream::worldComm)
169 {}
170 
173 :
174  mapDistributeBase(comm)
175 {}
176 
179 :
180  mapDistributeBase(std::move(map))
181 {}
182 
183 
185 :
186  mapDistributeBase(map),
187  transformElements_(map.transformElements_),
188  transformStart_(map.transformStart_)
189 {}
190 
191 
193 :
195 {
196  transfer(map);
197 }
198 
199 
201 (
202  const label constructSize,
203  labelListList&& subMap,
204  labelListList&& constructMap,
205  labelListList&& transformElements,
206  labelList&& transformStart,
207  const bool subHasFlip,
208  const bool constructHasFlip,
209  const label comm
210 )
211 :
213  (
214  constructSize,
215  std::move(subMap),
216  std::move(constructMap),
217  subHasFlip,
218  constructHasFlip,
219  comm
220  ),
221  transformElements_(std::move(transformElements)),
222  transformStart_(std::move(transformStart))
223 {}
224 
225 
227 (
228  const globalIndex& globalNumbering,
229  labelList& elements,
230  const globalIndexAndTransform& globalTransforms,
231  const labelPairList& transformedElements,
232  labelList& transformedIndices,
233  List<Map<label>>& compactMap,
234  const int tag,
235  const label comm
236 )
237 :
238  mapDistributeBase(comm)
239 {
240  const label myRank = UPstream::myProcNo(comm);
241 
242  // Construct per processor compact addressing of the global elements
243  // needed. The ones from the local processor are not included since
244  // these are always all needed.
246  (
247  globalNumbering,
248  elements,
249  compactMap
250  );
251 
252  // Add all (non-local) transformed elements needed.
253  for (const labelPair& elem : transformedElements)
254  {
255  label proci = globalTransforms.processor(elem);
256  if (proci != myRank)
257  {
258  label index = globalTransforms.index(elem);
259  compactMap[proci].insert(index, compactMap[proci].size());
260  }
261  }
262 
263 
264  // Exchange what I need with processor that supplies it. Renumber elements
265  // into compact numbering
266  labelList compactStart;
268  (
269  tag,
270  globalNumbering,
271  elements,
272  compactMap,
273  compactStart
274  );
275 
276 
277  // Renumber the transformed elements
278  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
279  // Count per transformIndex
280  const label nTrafo = globalTransforms.transformPermutations().size();
281  labelList nPerTransform(nTrafo, Zero);
282  for (const labelPair& elem : transformedElements)
283  {
284  label trafoI = globalTransforms.transformIndex(elem);
285  nPerTransform[trafoI]++;
286  }
287  // Offset per transformIndex
288  transformStart_.resize_nocopy(nTrafo);
289  transformElements_.resize_nocopy(nTrafo);
290  forAll(transformStart_, trafoI)
291  {
292  const label count = nPerTransform[trafoI];
293 
294  transformStart_[trafoI] = constructSize();
295  transformElements_[trafoI].resize_nocopy(count);
296  constructSize() += count;
297  }
298 
299  // Sort transformed elements into their new slot.
300  nPerTransform = 0;
301 
302  transformedIndices.resize_nocopy(transformedElements.size());
303  forAll(transformedElements, i)
304  {
305  const labelPair& elem = transformedElements[i];
306  label proci = globalTransforms.processor(elem);
307  label index = globalTransforms.index(elem);
308  label trafoI = globalTransforms.transformIndex(elem);
309 
310  // Get compact index for untransformed element
311  label rawElemI =
312  (
313  proci == myRank
314  ? index
315  : compactMap[proci][index]
316  );
317 
318  label& n = nPerTransform[trafoI];
319  // index of element to transform
320  transformElements_[trafoI][n] = rawElemI;
321  // destination of transformed element
322  transformedIndices[i] = transformStart_[trafoI]+n;
323  n++;
324  }
325 
326  if (debug)
327  {
328  printLayout(Pout);
329  }
330 }
331 
332 
334 (
335  const globalIndex& globalNumbering,
336  labelListList& cellCells,
337  const globalIndexAndTransform& globalTransforms,
338  const List<labelPairList>& transformedElements,
339  labelListList& transformedIndices,
340  List<Map<label>>& compactMap,
341  const int tag,
342  const label comm
343 )
344 :
345  mapDistributeBase(comm)
346 {
347  const label myRank = UPstream::myProcNo(comm);
348 
349  // Construct per processor compact addressing of the global elements
350  // needed. The ones from the local processor are not included since
351  // these are always all needed.
353  (
354  globalNumbering,
355  cellCells,
356  compactMap
357  );
358 
359  // Add all (non-local) transformed elements needed.
360  for (const labelPairList& elems : transformedElements)
361  {
362  for (const labelPair& elem : elems)
363  {
364  label proci = globalTransforms.processor(elem);
365  if (proci != myRank)
366  {
367  label index = globalTransforms.index(elem);
368  compactMap[proci].insert(index, compactMap[proci].size());
369  }
370  }
371  }
372 
373 
374  // Exchange what I need with processor that supplies it. Renumber elements
375  // into compact numbering
376  labelList compactStart;
378  (
379  tag,
380  globalNumbering,
381  cellCells,
382  compactMap,
383  compactStart
384  );
385 
386 
387  // Renumber the transformed elements
388  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
389  // Count per transformIndex
390  const label nTrafo = globalTransforms.transformPermutations().size();
391  labelList nPerTransform(nTrafo, Zero);
392  for (const labelPairList& elems : transformedElements)
393  {
394  for (const labelPair& elem : elems)
395  {
396  label trafoI = globalTransforms.transformIndex(elem);
397  nPerTransform[trafoI]++;
398  }
399  }
400  // Offset per transformIndex
401  transformStart_.resize_nocopy(nTrafo);
402  transformElements_.resize_nocopy(nTrafo);
403  forAll(transformStart_, trafoI)
404  {
405  const label count = nPerTransform[trafoI];
406 
407  transformStart_[trafoI] = constructSize();
408  transformElements_[trafoI].resize_nocopy(count);
409  constructSize() += count;
410  }
411 
412  // Sort transformed elements into their new slot.
413  nPerTransform = 0;
414 
415  transformedIndices.resize_nocopy(transformedElements.size());
416  forAll(transformedElements, celli)
417  {
418  const labelPairList& elems = transformedElements[celli];
419  transformedIndices[celli].resize_nocopy(elems.size());
420 
421  forAll(elems, i)
422  {
423  label proci = globalTransforms.processor(elems[i]);
424  label index = globalTransforms.index(elems[i]);
425  label trafoI = globalTransforms.transformIndex(elems[i]);
426 
427  // Get compact index for untransformed element
428  label rawElemI =
429  (
430  proci == myRank
431  ? index
432  : compactMap[proci][index]
433  );
434 
435  label& n = nPerTransform[trafoI];
436  // index of element to transform
437  transformElements_[trafoI][n] = rawElemI;
438  // destination of transformed element
439  transformedIndices[celli][i] = transformStart_[trafoI]+n;
440  n++;
441  }
442  }
443 
444  if (debug)
445  {
446  printLayout(Pout);
447  }
448 }
449 
450 
452 (
453  const UPtrList<const mapDistribute>& maps,
454  const labelList& localRanks,
455  const label newComm,
456  const labelListList& newToOldRanks, // from rank in newComm to
457  // ranks in (old)comm
458  labelList& startOfLocal,
459  List<Map<label>>& compactMaps
460 )
461 :
462  mapDistributeBase
463  (
464  extractBase(maps),
465  localRanks,
466  newComm,
467  newToOldRanks,
468  startOfLocal,
469  compactMaps
470  )
471 {
472  // TBD. -have mapDistributeBase::add or something
473  // -set transforms from individual maps
474 }
475 
476 
478 {
479  return autoPtr<mapDistribute>::New(*this);
480 }
481 
482 
483 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
485 Foam::label Foam::mapDistribute::whichTransform(const label index) const
486 {
487  return findLower(transformStart_, index+1);
488 }
489 
490 
492 {
494  transformElements_.clear();
495  transformStart_.clear();
496 }
497 
498 
500 {
501  if (this == &rhs)
502  {
503  return; // Self-assignment is a no-op
504  }
505 
507  transformElements_.transfer(rhs.transformElements_);
508  transformStart_.transfer(rhs.transformStart_);
509 }
510 
511 
512 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
513 
515 {
516  if (this == &rhs)
517  {
518  return; // Self-assignment is a no-op
519  }
522  transformElements_ = rhs.transformElements_;
523  transformStart_ = rhs.transformStart_;
524 }
525 
526 
528 {
529  if (this != &rhs)
530  {
531  // Avoid self-assignment
532  transfer(rhs);
533  }
534 }
535 
536 
537 // ************************************************************************* //
void calcCompactAddressing(const globalIndex &globalNumbering, const labelUList &elements, List< Map< label >> &compactMap) const
Construct per processor compact addressing of the global elements.
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Binary search to find the index of the last element in a sorted list that is less than value...
void clear()
Reset to zero size, only retaining communicator.
label index(const labelPair &globalIAndTransform) const
Index carried by the object.
Vector-tensor class used to perform translations and rotations in 3D space.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
label whichTransform(const label index) const
Find transform from transformElements.
const List< vectorTensorTransform > & transformPermutations() const
Return access to the permuted transforms.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
label constructSize() const noexcept
Constructed data size.
label comm() const noexcept
The communicator used.
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition: ListI.H:175
label processor(const labelPair &globalIAndTransform) const
Which processor does this come from?
List< labelPair > labelPairList
List of labelPair.
Definition: labelPair.H:33
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
void operator=(const mapDistribute &rhs)
Copy assignment.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
Spatial transformation functions for primitive fields.
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:61
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
autoPtr< mapDistribute > clone() const
Clone.
void transfer(mapDistributeBase &rhs)
Transfer the contents of the argument and annul the argument.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:106
void operator=(const mapDistributeBase &rhs)
Copy assignment.
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:56
const direction noexcept
Definition: Scalar.H:258
int debug
Static debugging option.
Pair< label > labelPair
A pair of labels.
Definition: Pair.H:51
OBJstream os(runTime.globalPath()/outputName)
defineTypeNameAndDebug(combustionModel, 0)
label transformIndex(const labelPair &globalIAndTransform) const
Transform carried by the object.
Class containing processor-to-processor mapping information.
void exchangeAddressing(const int tag, const globalIndex &globalNumbering, labelList &elements, List< Map< label >> &compactMap, labelList &compactStart)
void transfer(mapDistribute &map)
Transfer the contents of the argument and annul the argument.
void clear()
Reset to zero size, only retaining communicator.
label n
List< label > labelList
A List of labels.
Definition: List.H:62
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition: autoPtr.H:178
mapDistribute() noexcept
Default construct - uses worldComm.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Inter-processor communications stream.
Definition: UPstream.H:60
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)
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127