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-2019 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 (
46  const vectorTensorTransform&,
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 (
68  const coupledPolyPatch&,
70 ) const {}
71 
72 
73 template<>
74 void Foam::mapDistribute::transform::operator()
75 (
76  const vectorTensorTransform&,
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 (
98  const coupledPolyPatch&,
100 ) const {}
101 
102 
103 template<>
104 void Foam::mapDistribute::transform::operator()
105 (
106  const vectorTensorTransform&,
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_, trafoI)
138  {
139  if (transformElements_[trafoI].size() > 0)
140  {
141  os << "transform " << trafoI << ':' << endl
142  << " start : " << transformStart_[trafoI] << endl
143  << " size : " << transformElements_[trafoI].size() << endl;
144  }
145  }
146 }
147 
148 
149 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
150 
152 :
154 {}
155 
156 
158 :
159  mapDistributeBase(map),
160  transformElements_(map.transformElements_),
161  transformStart_(map.transformStart_)
162 {}
163 
164 
166 :
167  mapDistribute()
168 {
169  transfer(map);
170 }
171 
172 
174 (
175  const label constructSize,
176  labelListList&& subMap,
177  labelListList&& constructMap,
178  const bool subHasFlip,
179  const bool constructHasFlip
180 )
181 :
183  (
184  constructSize,
185  std::move(subMap),
186  std::move(constructMap),
187  subHasFlip,
188  constructHasFlip
189  )
190 {}
191 
192 
194 (
195  const label constructSize,
196  labelListList&& subMap,
197  labelListList&& constructMap,
198  labelListList&& transformElements,
199  labelList&& transformStart,
200  const bool subHasFlip,
201  const bool constructHasFlip
202 )
203 :
205  (
206  constructSize,
207  std::move(subMap),
208  std::move(constructMap),
209  subHasFlip,
210  constructHasFlip
211  ),
212  transformElements_(std::move(transformElements)),
213  transformStart_(std::move(transformStart))
214 {}
215 
216 
218 (
219  const labelUList& sendProcs,
220  const labelUList& recvProcs
221 )
222 :
223  mapDistributeBase(sendProcs, recvProcs)
224 {}
225 
226 
228 (
229  const globalIndex& globalNumbering,
230  labelList& elements,
231  List<Map<label>>& compactMap,
232  const int tag
233 )
234 :
236  (
237  globalNumbering,
238  elements,
239  compactMap,
240  tag
241  )
242 {}
243 
244 
246 (
247  const globalIndex& globalNumbering,
248  labelListList& cellCells,
249  List<Map<label>>& compactMap,
250  const int tag
251 )
252 :
254  (
255  globalNumbering,
256  cellCells,
257  compactMap,
258  tag
259  )
260 {}
261 
262 
264 (
265  const globalIndex& globalNumbering,
266  labelList& elements,
267  const globalIndexAndTransform& globalTransforms,
268  const labelPairList& transformedElements,
269  labelList& transformedIndices,
270  List<Map<label>>& compactMap,
271  const int tag
272 )
273 :
275 {
276  // Construct per processor compact addressing of the global elements
277  // needed. The ones from the local processor are not included since
278  // these are always all needed.
279  calcCompactAddressing
280  (
281  globalNumbering,
282  elements,
283  compactMap
284  );
285 
286  // Add all (non-local) transformed elements needed.
287  forAll(transformedElements, i)
288  {
289  labelPair elem = transformedElements[i];
290  label proci = globalTransforms.processor(elem);
291  if (proci != Pstream::myProcNo())
292  {
293  label index = globalTransforms.index(elem);
294  label nCompact = compactMap[proci].size();
295  compactMap[proci].insert(index, nCompact);
296  }
297  }
298 
299 
300  // Exchange what I need with processor that supplies it. Renumber elements
301  // into compact numbering
302  labelList compactStart;
303  exchangeAddressing
304  (
305  tag,
306  globalNumbering,
307  elements,
308  compactMap,
309  compactStart
310  );
311 
312 
313  // Renumber the transformed elements
314  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
315  // Count per transformIndex
316  label nTrafo = globalTransforms.transformPermutations().size();
317  labelList nPerTransform(nTrafo, Zero);
318  forAll(transformedElements, i)
319  {
320  labelPair elem = transformedElements[i];
321  label trafoI = globalTransforms.transformIndex(elem);
322  nPerTransform[trafoI]++;
323  }
324  // Offset per transformIndex
325  transformStart_.setSize(nTrafo);
326  transformElements_.setSize(nTrafo);
327  forAll(transformStart_, trafoI)
328  {
329  transformStart_[trafoI] = constructSize_;
330  constructSize_ += nPerTransform[trafoI];
331  transformElements_[trafoI].setSize(nPerTransform[trafoI]);
332  }
333 
334  // Sort transformed elements into their new slot.
335  nPerTransform = 0;
336 
337  transformedIndices.setSize(transformedElements.size());
338  forAll(transformedElements, i)
339  {
340  labelPair elem = transformedElements[i];
341  label proci = globalTransforms.processor(elem);
342  label index = globalTransforms.index(elem);
343  label trafoI = globalTransforms.transformIndex(elem);
344 
345  // Get compact index for untransformed element
346  label rawElemI =
347  (
348  proci == Pstream::myProcNo()
349  ? index
350  : compactMap[proci][index]
351  );
352 
353  label& n = nPerTransform[trafoI];
354  // index of element to transform
355  transformElements_[trafoI][n] = rawElemI;
356  // destination of transformed element
357  transformedIndices[i] = transformStart_[trafoI]+n;
358  n++;
359  }
360 
361  if (debug)
362  {
363  printLayout(Pout);
364  }
365 }
366 
367 
369 (
370  const globalIndex& globalNumbering,
371  labelListList& cellCells,
372  const globalIndexAndTransform& globalTransforms,
373  const List<labelPairList>& transformedElements,
374  labelListList& transformedIndices,
375  List<Map<label>>& compactMap,
376  const int tag
377 )
378 :
380 {
381  // Construct per processor compact addressing of the global elements
382  // needed. The ones from the local processor are not included since
383  // these are always all needed.
384  calcCompactAddressing
385  (
386  globalNumbering,
387  cellCells,
388  compactMap
389  );
390 
391  // Add all (non-local) transformed elements needed.
392  forAll(transformedElements, celli)
393  {
394  const labelPairList& elems = transformedElements[celli];
395 
396  forAll(elems, i)
397  {
398  label proci = globalTransforms.processor(elems[i]);
399  if (proci != Pstream::myProcNo())
400  {
401  label index = globalTransforms.index(elems[i]);
402  label nCompact = compactMap[proci].size();
403  compactMap[proci].insert(index, nCompact);
404  }
405  }
406  }
407 
408 
409  // Exchange what I need with processor that supplies it. Renumber elements
410  // into compact numbering
411  labelList compactStart;
412  exchangeAddressing
413  (
414  tag,
415  globalNumbering,
416  cellCells,
417  compactMap,
418  compactStart
419  );
420 
421 
422  // Renumber the transformed elements
423  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
424  // Count per transformIndex
425  label nTrafo = globalTransforms.transformPermutations().size();
426  labelList nPerTransform(nTrafo, Zero);
427  forAll(transformedElements, celli)
428  {
429  const labelPairList& elems = transformedElements[celli];
430 
431  forAll(elems, i)
432  {
433  label trafoI = globalTransforms.transformIndex(elems[i]);
434  nPerTransform[trafoI]++;
435  }
436  }
437  // Offset per transformIndex
438  transformStart_.setSize(nTrafo);
439  transformElements_.setSize(nTrafo);
440  forAll(transformStart_, trafoI)
441  {
442  transformStart_[trafoI] = constructSize_;
443  constructSize_ += nPerTransform[trafoI];
444  transformElements_[trafoI].setSize(nPerTransform[trafoI]);
445  }
446 
447  // Sort transformed elements into their new slot.
448  nPerTransform = 0;
449 
450  transformedIndices.setSize(transformedElements.size());
451  forAll(transformedElements, celli)
452  {
453  const labelPairList& elems = transformedElements[celli];
454  transformedIndices[celli].setSize(elems.size());
455 
456  forAll(elems, i)
457  {
458  label proci = globalTransforms.processor(elems[i]);
459  label index = globalTransforms.index(elems[i]);
460  label trafoI = globalTransforms.transformIndex(elems[i]);
461 
462  // Get compact index for untransformed element
463  label rawElemI =
464  (
465  proci == Pstream::myProcNo()
466  ? index
467  : compactMap[proci][index]
468  );
469 
470  label& n = nPerTransform[trafoI];
471  // index of element to transform
472  transformElements_[trafoI][n] = rawElemI;
473  // destination of transformed element
474  transformedIndices[celli][i] = transformStart_[trafoI]+n;
475  n++;
476  }
477  }
478 
479  if (debug)
480  {
481  printLayout(Pout);
482  }
483 }
484 
485 
487 (
488  labelListList&& subMap,
489  const bool subHasFlip,
490  const bool constructHasFlip
491 )
492 :
493  mapDistributeBase(std::move(subMap), subHasFlip, constructHasFlip)
494 {}
495 
496 
498 {
499  is >> *this;
500 }
501 
502 
504 {
505  return autoPtr<mapDistribute>::New(*this);
506 }
507 
508 
509 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
510 
512 {
513  return findLower(transformStart_, index+1);
514 }
515 
516 
518 {
519  if (this == &rhs)
520  {
521  // Self-assignment is a no-op
522  }
523 
525  transformElements_.transfer(rhs.transformElements_);
526  transformStart_.transfer(rhs.transformStart_);
527 }
528 
529 
530 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
531 
533 {
534  if (this == &rhs)
535  {
536  return; // Self-assignment is a no-op
537  }
538 
540  transformElements_ = rhs.transformElements_;
541  transformStart_ = rhs.transformStart_;
542 }
543 
544 
546 {
547  if (this != &rhs)
548  {
549  // Avoid self-assignment
550  transfer(rhs);
551  }
552 }
553 
554 
555 // * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * * //
556 
558 {
560 
561  is >> static_cast<mapDistributeBase&>(map)
562  >> map.transformElements_ >> map.transformStart_;
563 
564  return is;
565 }
566 
567 
568 // * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * * //
569 
571 {
572  os << static_cast<const mapDistributeBase&>(map) << token::NL
573  << map.transformElements_ << token::NL
574  << map.transformStart_;
575 
576  return os;
577 }
578 
579 
580 // ************************************************************************* //
Foam::globalIndexAndTransform::processor
label processor(const labelPair &globalIAndTransform) const
Which processor does this come from?
Definition: globalIndexAndTransformI.H:357
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::autoPtr::New
static autoPtr< T > New(Args &&... args)
Construct autoPtr of T with forwarding arguments.
Foam::mapDistribute::whichTransform
label whichTransform(const label index) const
Find transform from transformElements.
Definition: mapDistribute.C:511
Foam::IOstream::fatalCheck
void fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:64
Foam::mapDistribute::operator=
void operator=(const mapDistribute &rhs)
Copy assignment.
Definition: mapDistribute.C:532
Foam::mapDistributeBase::operator=
void operator=(const mapDistributeBase &rhs)
Copy assignment.
Definition: mapDistributeBase.C:1269
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
Foam::globalIndexAndTransform::index
label index(const labelPair &globalIAndTransform) const
Index carried by the object.
Definition: globalIndexAndTransformI.H:348
Foam::globalIndexAndTransform::transformPermutations
const List< vectorTensorTransform > & transformPermutations() const
Return access to the permuted transforms.
Definition: globalIndexAndTransformI.H:388
Foam::Map< label >
Foam::operator>>
Istream & operator>>(Istream &, directionInfo &)
Definition: directionInfo.C:228
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::coupledPolyPatch
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
Definition: coupledPolyPatch.H:53
Foam::Pout
prefixOSstream Pout
An Ostream wrapper for parallel output to std::cout.
Foam::mapDistributeBase::transfer
void transfer(mapDistributeBase &rhs)
Transfer the contents of the argument and annul the argument.
Definition: mapDistributeBase.C:840
Foam::mapDistribute::transfer
void transfer(mapDistribute &map)
Transfer the contents of the argument and annul the argument.
Definition: mapDistribute.C:517
transformField.H
Spatial transformation functions for primitive fields.
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::label
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:62
Foam::findLower
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Foam::globalIndexAndTransform::transformIndex
label transformIndex(const labelPair &globalIAndTransform) const
Transform carried by the object.
Definition: globalIndexAndTransformI.H:366
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
globalIndexAndTransform.H
Foam::mapDistribute
Class containing processor-to-processor mapping information.
Definition: mapDistribute.H:163
Foam::token::NL
Newline [isspace].
Definition: token.H:114
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:444
Foam::mapDistributeBase::printLayout
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
Definition: mapDistributeBase.C:211
Foam::autoPtr< Foam::mapDistribute >
Foam::EdgeMap< label >
Foam::Pair
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:54
mapDistribute.H
Foam::List< label >
Foam::vectorTensorTransform
Vector-tensor class used to perform translations and rotations in 3D space.
Definition: vectorTensorTransform.H:63
Foam::UList< label >
bool
bool
Definition: EEqn.H:20
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:261
Foam::mapDistributeBase
Class containing processor-to-processor mapping information.
Definition: mapDistributeBase.H:103
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::mapDistribute::clone
autoPtr< mapDistribute > clone() const
Clone.
Definition: mapDistribute.C:503
Foam::mapDistribute::printLayout
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
Definition: mapDistribute.C:133
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::globalIndexAndTransform
Determination and storage of the possible independent transforms introduced by coupledPolyPatches,...
Definition: globalIndexAndTransform.H:64
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &)
Definition: boundaryPatch.C:102
Foam::mapDistribute::mapDistribute
mapDistribute()
Construct null.
Definition: mapDistribute.C:151