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-2022 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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
35namespace Foam
36{
38}
39
40
41// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
42
43template<>
45(
47 const bool,
49) const {}
50
51template<>
53(
54 const coupledPolyPatch&,
56) const {}
57
58template<>
60(
61 const coupledPolyPatch&,
63) const {}
64
65template<>
67(
68 const coupledPolyPatch&,
70) const {}
71
72
73template<>
75(
77 const bool,
79) const {}
80
81template<>
83(
84 const coupledPolyPatch&,
86) const {}
87
88template<>
90(
91 const coupledPolyPatch&,
93) const {}
94
95template<>
97(
98 const coupledPolyPatch&,
100) const {}
101
102
103template<>
105(
107 const bool,
109) const {}
110
111template<>
113(
114 const coupledPolyPatch&,
116) const {}
117
118template<>
120(
121 const coupledPolyPatch&,
122 Map<bool>&
123) const {}
124
125template<>
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// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
150
152:
153 mapDistribute(UPstream::worldComm)
154{}
155
156
158:
160{}
161
162
164:
165 mapDistributeBase(std::move(map))
166{}
167
168
170:
172 transformElements_(map.transformElements_),
173 transformStart_(map.transformStart_)
174{}
175
176
178:
180{
181 transfer(map);
182}
183
184
186(
187 const label constructSize,
188 labelListList&& subMap,
189 labelListList&& constructMap,
190 labelListList&& transformElements,
191 labelList&& transformStart,
192 const bool subHasFlip,
193 const bool constructHasFlip,
194 const label comm
195)
196:
198 (
199 constructSize,
200 std::move(subMap),
201 std::move(constructMap),
202 subHasFlip,
203 constructHasFlip,
204 comm
205 ),
206 transformElements_(std::move(transformElements)),
207 transformStart_(std::move(transformStart))
208{}
209
210
212(
213 const globalIndex& globalNumbering,
214 labelList& elements,
215 const globalIndexAndTransform& globalTransforms,
216 const labelPairList& transformedElements,
217 labelList& transformedIndices,
218 List<Map<label>>& compactMap,
219 const int tag,
220 const label comm
221)
222:
224{
225 const label myRank = Pstream::myProcNo(comm);
226
227 // Construct per processor compact addressing of the global elements
228 // needed. The ones from the local processor are not included since
229 // these are always all needed.
231 (
232 globalNumbering,
233 elements,
234 compactMap
235 );
236
237 // Add all (non-local) transformed elements needed.
238 forAll(transformedElements, i)
239 {
240 labelPair elem = transformedElements[i];
241 label proci = globalTransforms.processor(elem);
242 if (proci != myRank)
243 {
244 label index = globalTransforms.index(elem);
245 label nCompact = compactMap[proci].size();
246 compactMap[proci].insert(index, nCompact);
247 }
248 }
249
250
251 // Exchange what I need with processor that supplies it. Renumber elements
252 // into compact numbering
253 labelList compactStart;
255 (
256 tag,
257 globalNumbering,
258 elements,
259 compactMap,
260 compactStart
261 );
262
263
264 // Renumber the transformed elements
265 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
266 // Count per transformIndex
267 label nTrafo = globalTransforms.transformPermutations().size();
268 labelList nPerTransform(nTrafo, Zero);
269 forAll(transformedElements, i)
270 {
271 labelPair elem = transformedElements[i];
272 label trafoI = globalTransforms.transformIndex(elem);
273 nPerTransform[trafoI]++;
274 }
275 // Offset per transformIndex
276 transformStart_.setSize(nTrafo);
277 transformElements_.setSize(nTrafo);
278 forAll(transformStart_, trafoI)
279 {
280 transformStart_[trafoI] = constructSize();
281 constructSize() += nPerTransform[trafoI];
282 transformElements_[trafoI].setSize(nPerTransform[trafoI]);
283 }
284
285 // Sort transformed elements into their new slot.
286 nPerTransform = 0;
287
288 transformedIndices.setSize(transformedElements.size());
289 forAll(transformedElements, i)
290 {
291 labelPair elem = transformedElements[i];
292 label proci = globalTransforms.processor(elem);
293 label index = globalTransforms.index(elem);
294 label trafoI = globalTransforms.transformIndex(elem);
295
296 // Get compact index for untransformed element
297 label rawElemI =
298 (
299 proci == myRank
300 ? index
301 : compactMap[proci][index]
302 );
303
304 label& n = nPerTransform[trafoI];
305 // index of element to transform
306 transformElements_[trafoI][n] = rawElemI;
307 // destination of transformed element
308 transformedIndices[i] = transformStart_[trafoI]+n;
309 n++;
310 }
311
312 if (debug)
313 {
315 }
316}
317
318
320(
321 const globalIndex& globalNumbering,
322 labelListList& cellCells,
323 const globalIndexAndTransform& globalTransforms,
324 const List<labelPairList>& transformedElements,
325 labelListList& transformedIndices,
326 List<Map<label>>& compactMap,
327 const int tag,
328 const label comm
329)
330:
332{
333 const label myRank = Pstream::myProcNo(comm);
334
335 // Construct per processor compact addressing of the global elements
336 // needed. The ones from the local processor are not included since
337 // these are always all needed.
339 (
340 globalNumbering,
341 cellCells,
342 compactMap
343 );
344
345 // Add all (non-local) transformed elements needed.
346 forAll(transformedElements, celli)
347 {
348 const labelPairList& elems = transformedElements[celli];
349
350 forAll(elems, i)
351 {
352 label proci = globalTransforms.processor(elems[i]);
353 if (proci != myRank)
354 {
355 label index = globalTransforms.index(elems[i]);
356 label nCompact = compactMap[proci].size();
357 compactMap[proci].insert(index, nCompact);
358 }
359 }
360 }
361
362
363 // Exchange what I need with processor that supplies it. Renumber elements
364 // into compact numbering
365 labelList compactStart;
367 (
368 tag,
369 globalNumbering,
370 cellCells,
371 compactMap,
372 compactStart
373 );
374
375
376 // Renumber the transformed elements
377 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
378 // Count per transformIndex
379 label nTrafo = globalTransforms.transformPermutations().size();
380 labelList nPerTransform(nTrafo, Zero);
381 forAll(transformedElements, celli)
382 {
383 const labelPairList& elems = transformedElements[celli];
384
385 forAll(elems, i)
386 {
387 label trafoI = globalTransforms.transformIndex(elems[i]);
388 nPerTransform[trafoI]++;
389 }
390 }
391 // Offset per transformIndex
392 transformStart_.setSize(nTrafo);
393 transformElements_.setSize(nTrafo);
394 forAll(transformStart_, trafoI)
395 {
396 transformStart_[trafoI] = constructSize();
397 constructSize() += nPerTransform[trafoI];
398 transformElements_[trafoI].setSize(nPerTransform[trafoI]);
399 }
400
401 // Sort transformed elements into their new slot.
402 nPerTransform = 0;
403
404 transformedIndices.setSize(transformedElements.size());
405 forAll(transformedElements, celli)
406 {
407 const labelPairList& elems = transformedElements[celli];
408 transformedIndices[celli].setSize(elems.size());
409
410 forAll(elems, i)
411 {
412 label proci = globalTransforms.processor(elems[i]);
413 label index = globalTransforms.index(elems[i]);
414 label trafoI = globalTransforms.transformIndex(elems[i]);
415
416 // Get compact index for untransformed element
417 label rawElemI =
418 (
419 proci == myRank
420 ? index
421 : compactMap[proci][index]
422 );
423
424 label& n = nPerTransform[trafoI];
425 // index of element to transform
426 transformElements_[trafoI][n] = rawElemI;
427 // destination of transformed element
428 transformedIndices[celli][i] = transformStart_[trafoI]+n;
429 n++;
430 }
431 }
432
433 if (debug)
434 {
436 }
437}
438
439
441{
442 return autoPtr<mapDistribute>::New(*this);
443}
444
445
446// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
447
448Foam::label Foam::mapDistribute::whichTransform(const label index) const
449{
450 return findLower(transformStart_, index+1);
451}
452
453
455{
457 transformElements_.clear();
458 transformStart_.clear();
459}
460
461
463{
464 if (this == &rhs)
465 {
466 return; // Self-assignment is a no-op
467 }
468
470 transformElements_.transfer(rhs.transformElements_);
471 transformStart_.transfer(rhs.transformStart_);
472}
473
474
475// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
476
478{
479 if (this == &rhs)
480 {
481 return; // Self-assignment is a no-op
482 }
483
485 transformElements_ = rhs.transformElements_;
486 transformStart_ = rhs.transformStart_;
487}
488
489
491{
492 if (this != &rhs)
493 {
494 // Avoid self-assignment
495 transfer(rhs);
496 }
497}
498
499
500// ************************************************************************* //
label n
Map from edge (expressed as its endpoints) to value. For easier forward declaration it is currently i...
Definition: EdgeMap.H:54
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
void setSize(const label n)
Alias for resize()
Definition: List.H:218
A HashTable to objects of type <T> with a label key.
Definition: Map.H:60
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Inter-processor communications stream.
Definition: UPstream.H:59
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
friend Ostream & operator(Ostream &, const faMatrix< Type > &)
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< vectorTensorTransform > & 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:68
Class containing processor-to-processor mapping information.
void operator=(const mapDistributeBase &rhs)
Copy assignment.
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
void calcCompactAddressing(const globalIndex &globalNumbering, const labelUList &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)
label comm() const noexcept
The communicator used.
void clear()
Reset to zero size, only retaining communicator.
label constructSize() const noexcept
Constructed data size.
Class containing processor-to-processor mapping information.
label whichTransform(const label index) const
Find transform from transformElements.
void operator=(const mapDistribute &rhs)
Copy assignment.
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
mapDistribute()
Default construct - uses worldComm.
void transfer(mapDistribute &map)
Transfer the contents of the argument and annul the argument.
autoPtr< mapDistribute > clone() const
Clone.
void clear()
Reset to zero size, only retaining communicator.
int myProcNo() const noexcept
Return processor number.
Vector-tensor class used to perform translations and rotations in 3D space.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
bool
Definition: EEqn.H:20
OBJstream os(runTime.globalPath()/outputName)
Namespace for OpenFOAM.
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
Spatial transformation functions for primitive fields.