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 {
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,
159  labelListList&& subMap,
160  labelListList&& constructMap,
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,
179  labelListList&& subMap,
180  labelListList&& constructMap,
181  labelListList&& transformElements,
182  labelList&& transformStart,
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 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
void fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:105
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
Class containing processor-to-processor mapping information.
label constructSize_
Size of reconstructed data.
void operator=(const distributionMapBase &)
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
void transfer(distributionMapBase &)
Transfer the contents of the argument and annul the argument.
void calcCompactAddressing(const globalIndex &globalNumbering, const labelList &elements, List< Map< label >> &compactMap) const
Construct per processor compact addressing of the global elements.
void exchangeAddressing(const int tag, const globalIndex &globalNumbering, labelList &elements, List< Map< label >> &compactMap, labelList &compactStart)
Class containing processor-to-processor mapping information.
label whichTransform(const label index) const
Find transform from transformElements.
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
void transfer(distributionMap &)
Transfer the contents of the argument and annul the argument.
autoPtr< distributionMap > clone() const
Clone.
void operator=(const distributionMap &)
distributionMap()
Construct null.
Determination and storage of the possible independent transforms introduced by coupledPolyPatches,...
label transformIndex(const labelPair &globalIAndTransform) const
Transform carried by the object.
label processor(const labelPair &globalIAndTransform) const
Which processor does this come from?
const List< transformer > & transformPermutations() const
Return access to the permuted transforms.
label index(const labelPair &globalIAndTransform) const
Index carried by the object.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:64
Vector-tensor class used to perform translations, rotations and scaling operations in 3D space.
Definition: transformer.H:84
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
Namespace for OpenFOAM.
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:257
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,.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Istream & operator>>(Istream &, pistonPointEdgeData &)
defineTypeNameAndDebug(combustionModel, 0)
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
Ostream & operator<<(Ostream &os, const fvConstraints &constraints)
error FatalError
Spatial transformation functions for primitive fields.