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 {
38 }
39 
40 
41 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
42 
44 {
46 
47  forAll(transformElements_, i)
48  {
49  if (!transformElements_[i].empty())
50  {
51  os << "transform " << i << ':' << nl
52  << " start : " << transformStart_[i] << nl
53  << " size : " << transformElements_[i].size() << endl;
54  }
55  }
56 }
57 
58 
59 Foam::UPtrList<const Foam::mapDistributeBase> Foam::mapDistribute::extractBase
60 (
61  const UPtrList<const mapDistribute>& maps
62 )
63 {
64  UPtrList<const mapDistributeBase> baseMaps(maps.size());
65  forAll(maps, i)
66  {
67  // Implicit cast to <const mapDistributeBase*>
68  baseMaps.set(i, maps.get(i));
69  }
70  return baseMaps;
71 }
72 
73 
74 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
75 
77 :
78  mapDistributeBase(UPstream::worldComm)
79 {}
80 
81 
83 :
84  mapDistributeBase(comm)
85 {}
86 
87 
89 :
90  mapDistributeBase(std::move(map))
91 {}
92 
93 
95 :
96  mapDistributeBase(map),
97  transformElements_(map.transformElements_),
98  transformStart_(map.transformStart_)
99 {}
100 
101 
103 :
105 {
106  transfer(map);
107 }
108 
109 
111 (
112  const label constructSize,
113  labelListList&& subMap,
114  labelListList&& constructMap,
115  labelListList&& transformElements,
116  labelList&& transformStart,
117  const bool subHasFlip,
118  const bool constructHasFlip,
119  const label comm
120 )
121 :
123  (
124  constructSize,
125  std::move(subMap),
126  std::move(constructMap),
127  subHasFlip,
128  constructHasFlip,
129  comm
130  ),
131  transformElements_(std::move(transformElements)),
132  transformStart_(std::move(transformStart))
133 {}
134 
135 
137 (
138  const globalIndex& globalNumbering,
139  labelList& elements,
140  const globalIndexAndTransform& globalTransforms,
141  const labelPairList& transformedElements,
142  labelList& transformedIndices,
143  List<Map<label>>& compactMap,
144  const int tag,
145  const label comm
146 )
147 :
148  mapDistributeBase(comm)
149 {
150  const label myRank = UPstream::myProcNo(comm);
151 
152  // Construct per processor compact addressing of the global elements
153  // needed. The ones from the local processor are not included since
154  // these are always all needed.
156  (
157  globalNumbering,
158  elements,
159  compactMap
160  );
161 
162  // Add all (non-local) transformed elements needed.
163  for (const labelPair& elem : transformedElements)
164  {
165  label proci = globalTransforms.processor(elem);
166  if (proci != myRank)
167  {
168  label index = globalTransforms.index(elem);
169  compactMap[proci].insert(index, compactMap[proci].size());
170  }
171  }
172 
173 
174  // Exchange what I need with processor that supplies it. Renumber elements
175  // into compact numbering
176  labelList compactStart;
178  (
179  tag,
180  globalNumbering,
181  elements,
182  compactMap,
183  compactStart
184  );
185 
186 
187  // Renumber the transformed elements
188  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
189  // Count per transformIndex
190  const label nTrafo = globalTransforms.transformPermutations().size();
191  labelList nPerTransform(nTrafo, Zero);
192  for (const labelPair& elem : transformedElements)
193  {
194  label trafoI = globalTransforms.transformIndex(elem);
195  nPerTransform[trafoI]++;
196  }
197  // Offset per transformIndex
198  transformStart_.resize_nocopy(nTrafo);
199  transformElements_.resize_nocopy(nTrafo);
200  forAll(transformStart_, trafoI)
201  {
202  const label count = nPerTransform[trafoI];
203 
204  transformStart_[trafoI] = constructSize();
205  transformElements_[trafoI].resize_nocopy(count);
206  constructSize() += count;
207  }
208 
209  // Sort transformed elements into their new slot.
210  nPerTransform = 0;
211 
212  transformedIndices.resize_nocopy(transformedElements.size());
213  forAll(transformedElements, i)
214  {
215  const labelPair& elem = transformedElements[i];
216  label proci = globalTransforms.processor(elem);
217  label index = globalTransforms.index(elem);
218  label trafoI = globalTransforms.transformIndex(elem);
219 
220  // Get compact index for untransformed element
221  label rawElemI =
222  (
223  proci == myRank
224  ? index
225  : compactMap[proci][index]
226  );
227 
228  label& n = nPerTransform[trafoI];
229  // index of element to transform
230  transformElements_[trafoI][n] = rawElemI;
231  // destination of transformed element
232  transformedIndices[i] = transformStart_[trafoI]+n;
233  n++;
234  }
235 
236  if (debug)
237  {
238  printLayout(Pout);
239  }
240 }
241 
242 
244 (
245  const globalIndex& globalNumbering,
246  labelListList& cellCells,
247  const globalIndexAndTransform& globalTransforms,
248  const List<labelPairList>& transformedElements,
249  labelListList& transformedIndices,
250  List<Map<label>>& compactMap,
251  const int tag,
252  const label comm
253 )
254 :
255  mapDistributeBase(comm)
256 {
257  const label myRank = UPstream::myProcNo(comm);
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  cellCells,
266  compactMap
267  );
268 
269  // Add all (non-local) transformed elements needed.
270  for (const labelPairList& elems : transformedElements)
271  {
272  for (const labelPair& elem : elems)
273  {
274  label proci = globalTransforms.processor(elem);
275  if (proci != myRank)
276  {
277  label index = globalTransforms.index(elem);
278  compactMap[proci].insert(index, compactMap[proci].size());
279  }
280  }
281  }
282 
283 
284  // Exchange what I need with processor that supplies it. Renumber elements
285  // into compact numbering
286  labelList compactStart;
288  (
289  tag,
290  globalNumbering,
291  cellCells,
292  compactMap,
293  compactStart
294  );
295 
296 
297  // Renumber the transformed elements
298  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
299  // Count per transformIndex
300  const label nTrafo = globalTransforms.transformPermutations().size();
301  labelList nPerTransform(nTrafo, Zero);
302  for (const labelPairList& elems : transformedElements)
303  {
304  for (const labelPair& elem : elems)
305  {
306  label trafoI = globalTransforms.transformIndex(elem);
307  nPerTransform[trafoI]++;
308  }
309  }
310  // Offset per transformIndex
311  transformStart_.resize_nocopy(nTrafo);
312  transformElements_.resize_nocopy(nTrafo);
313  forAll(transformStart_, trafoI)
314  {
315  const label count = nPerTransform[trafoI];
316 
317  transformStart_[trafoI] = constructSize();
318  transformElements_[trafoI].resize_nocopy(count);
319  constructSize() += count;
320  }
321 
322  // Sort transformed elements into their new slot.
323  nPerTransform = 0;
324 
325  transformedIndices.resize_nocopy(transformedElements.size());
326  forAll(transformedElements, celli)
327  {
328  const labelPairList& elems = transformedElements[celli];
329  transformedIndices[celli].resize_nocopy(elems.size());
330 
331  forAll(elems, i)
332  {
333  label proci = globalTransforms.processor(elems[i]);
334  label index = globalTransforms.index(elems[i]);
335  label trafoI = globalTransforms.transformIndex(elems[i]);
336 
337  // Get compact index for untransformed element
338  label rawElemI =
339  (
340  proci == myRank
341  ? index
342  : compactMap[proci][index]
343  );
344 
345  label& n = nPerTransform[trafoI];
346  // index of element to transform
347  transformElements_[trafoI][n] = rawElemI;
348  // destination of transformed element
349  transformedIndices[celli][i] = transformStart_[trafoI]+n;
350  n++;
351  }
352  }
353 
354  if (debug)
355  {
356  printLayout(Pout);
357  }
358 }
359 
360 
362 (
363  const UPtrList<const mapDistribute>& maps,
364  const labelList& localRanks,
365  const label newComm,
366  const labelListList& newToOldRanks, // from rank in newComm to
367  // ranks in (old)comm
368  labelList& startOfLocal,
369  List<Map<label>>& compactMaps
370 )
371 :
372  mapDistributeBase
373  (
374  extractBase(maps),
375  localRanks,
376  newComm,
377  newToOldRanks,
378  startOfLocal,
379  compactMaps
380  )
381 {
382  // TBD. -have mapDistributeBase::add or something
383  // -set transforms from individual maps
384 }
385 
386 
388 {
389  return autoPtr<mapDistribute>::New(*this);
390 }
391 
392 
393 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
395 Foam::label Foam::mapDistribute::whichTransform(const label index) const
396 {
397  return findLower(transformStart_, index+1);
398 }
399 
400 
402 {
404  transformElements_.clear();
405  transformStart_.clear();
406 }
407 
408 
410 {
411  if (this == &rhs)
412  {
413  return; // Self-assignment is a no-op
414  }
415 
417  transformElements_.transfer(rhs.transformElements_);
418  transformStart_.transfer(rhs.transformStart_);
419 }
420 
421 
422 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
423 
425 {
426  if (this == &rhs)
427  {
428  return; // Self-assignment is a no-op
429  }
432  transformElements_ = rhs.transformElements_;
433  transformStart_ = rhs.transformStart_;
434 }
435 
436 
438 {
439  if (this != &rhs)
440  {
441  // Avoid self-assignment
442  transfer(rhs);
443  }
444 }
445 
446 
447 // ************************************************************************* //
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:114
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.
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:529
label constructSize() const noexcept
Constructed data size.
label comm() const noexcept
The communicator used.
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition: ListI.H:168
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.
Definition: mapDistribute.C:36
void operator=(const mapDistribute &rhs)
Copy assignment.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
Definition: UPstream.H:1611
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:286
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: scalarImpl.H:255
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:61
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition: autoPtr.H:178
mapDistribute() noexcept
Default construct - uses worldComm.
Definition: mapDistribute.C:69
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Inter-processor communications stream.
Definition: UPstream.H:65
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