Loading...
Searching...
No Matches
fvMeshToolsProcAddr.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) 2015-2025 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "fvMeshTools.H"
29#include "fileOperation.H"
30#include "IndirectList.H"
31#include "labelRange.H"
33#include "OSspecific.H"
34
35// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
36
37namespace Foam
39
40// Create a reconstruct map.
41// The baseMeshPtr is non-null (and probably has cells) on the master
42// is ignored elsewhere.
43//
44// The incomming faceProcAddressing is assumed to have flip addressing.
46(
47 const fvMesh& mesh,
48 const fvMesh* baseMeshPtr,
49 const labelList& cellProcAddressing,
50 const labelList& faceProcAddressing,
51 const labelList& pointProcAddressing,
52 const labelList& boundaryProcAddressing
53)
54{
55 const label nOldPoints = mesh.nPoints();
56 const label nOldFaces = mesh.nFaces();
57 const label nOldCells = mesh.nCells();
58
59 const polyBoundaryMesh& pbm = mesh.boundaryMesh();
60
61 labelList oldPatchStarts(pbm.size());
62 labelList oldPatchNumPoints(pbm.size());
63 forAll(pbm, patchi)
64 {
65 oldPatchStarts[patchi] = pbm[patchi].start();
66 oldPatchNumPoints[patchi] = pbm[patchi].nPoints();
67 }
68
69 // Patches: purge -1 entries
70 labelList patchProcAddressing
71 (
73 (
74 boundaryProcAddressing,
75 labelRange::ge0()
76 )
77 );
78
79
80 labelListList cellSubMap(Pstream::nProcs());
81 cellSubMap[Pstream::masterNo()] = identity(nOldCells);
82
83 labelListList faceSubMap(Pstream::nProcs());
84 faceSubMap[Pstream::masterNo()] = identity(nOldFaces);
85
86 labelListList pointSubMap(Pstream::nProcs());
87 pointSubMap[Pstream::masterNo()] = identity(nOldPoints);
88
89 labelListList patchSubMap(Pstream::nProcs());
90 patchSubMap[Pstream::masterNo()] = patchProcAddressing;
91
92
93 // Gather addressing on master
94 labelListList cellAddressing(Pstream::nProcs());
95 cellAddressing[Pstream::myProcNo()] = cellProcAddressing;
96 Pstream::gatherList(cellAddressing);
97
98 labelListList faceAddressing(Pstream::nProcs());
99 faceAddressing[Pstream::myProcNo()] = faceProcAddressing;
100 Pstream::gatherList(faceAddressing);
101
102 labelListList pointAddressing(Pstream::nProcs());
103 pointAddressing[Pstream::myProcNo()] = pointProcAddressing;
104 Pstream::gatherList(pointAddressing);
105
106 labelListList patchAddressing(Pstream::nProcs());
107 patchAddressing[Pstream::myProcNo()] = patchProcAddressing;
108 Pstream::gatherList(patchAddressing);
109
110
111 // NB: can only have a reconstruct on master!
112 if (UPstream::master() && baseMeshPtr && baseMeshPtr->nCells())
113 {
114 const fvMesh& baseMesh = *baseMeshPtr;
115
116 const label nNewPoints = baseMesh.nPoints();
117 const label nNewFaces = baseMesh.nFaces();
118 const label nNewCells = baseMesh.nCells();
119 const label nNewPatches = baseMesh.boundaryMesh().size();
120
121 mapDistribute cellMap
122 (
123 nNewCells,
124 std::move(cellSubMap),
125 std::move(cellAddressing)
126 );
127
129 (
130 nNewFaces,
131 std::move(faceSubMap),
132 std::move(faceAddressing),
133 false, // subHasFlip
134 true // constructHasFlip
135 );
136
137 mapDistribute pointMap
138 (
139 nNewPoints,
140 std::move(pointSubMap),
141 std::move(pointAddressing)
142 );
143
144 mapDistribute patchMap
145 (
146 nNewPatches,
147 std::move(patchSubMap),
148 std::move(patchAddressing)
149 );
150
152 (
153 nOldPoints,
154 nOldFaces,
155 nOldCells,
156 std::move(oldPatchStarts),
157 std::move(oldPatchNumPoints),
158 std::move(pointMap),
159 std::move(faceMap),
160 std::move(cellMap),
161 std::move(patchMap)
162 );
163 }
164 else
165 {
166 // Zero-sized mesh (eg, processor mesh)
167
168 mapDistribute cellMap
169 (
170 0, // nNewCells
171 std::move(cellSubMap),
172 labelListList(Pstream::nProcs()) // constructMap
173 );
174
176 (
177 0, // nNewFaces
178 std::move(faceSubMap),
179 labelListList(Pstream::nProcs()), // constructMap
180 false, // subHasFlip
181 true // constructHasFlip
182 );
183
184 mapDistribute pointMap
185 (
186 0, // nNewPoints
187 std::move(pointSubMap),
188 labelListList(Pstream::nProcs()) // constructMap
189 );
190
191 mapDistribute patchMap
192 (
193 0, // nNewPatches
194 std::move(patchSubMap),
195 labelListList(Pstream::nProcs()) // constructMap
196 );
197
199 (
200 nOldPoints,
201 nOldFaces,
202 nOldCells,
203 std::move(oldPatchStarts),
204 std::move(oldPatchNumPoints),
205 std::move(pointMap),
206 std::move(faceMap),
207 std::move(cellMap),
208 std::move(patchMap)
209 );
210 }
211}
213} // End namespace Foam
214
215
216// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
217
220(
221 const fvMesh& mesh,
222 const fvMesh* baseMeshPtr
223)
224{
225 // Processor-local reading
226 IOobject ioAddr
227 (
228 "procAddressing",
229 mesh.facesInstance(),
231 mesh.thisDb(),
235 );
236
237 //if (ioAddr.typeHeaderOk<labelIOList>(true))
238 //{
239 // Pout<< "Reading addressing from " << io.name() << " at "
240 // << mesh.facesInstance() << nl << endl;
241 // mapDistributePolyMesh distMap = IOmapDistributePolyMesh(ioAddr);
242 // return autoPtr<mapDistributePolyMesh>::New(std::move(distMap));
243 //}
244 //else
245
246 {
247 Info<< "Reading (cell|face|point|boundary)ProcAddressing from "
248 << mesh.facesInstance().c_str() << '/'
250
251 ioAddr.rename("cellProcAddressing");
252 labelIOList cellProcAddressing(ioAddr, Zero);
253
254 ioAddr.rename("faceProcAddressing");
255 labelIOList faceProcAddressing(ioAddr, Zero);
256
257 ioAddr.rename("pointProcAddressing");
258 labelIOList pointProcAddressing(ioAddr, Zero);
259
260 ioAddr.rename("boundaryProcAddressing");
261 labelIOList boundaryProcAddressing(ioAddr, Zero);
262
263 if
264 (
265 mesh.nCells() != cellProcAddressing.size()
266 || mesh.nPoints() != pointProcAddressing.size()
267 || mesh.nFaces() != faceProcAddressing.size()
268 || mesh.boundaryMesh().size() != boundaryProcAddressing.size()
269 )
270 {
272 << "Read addressing inconsistent with mesh sizes" << nl
273 << "cells:" << mesh.nCells()
274 << " addressing:" << cellProcAddressing.objectRelPath()
275 << " size:" << cellProcAddressing.size() << nl
276 << "faces:" << mesh.nFaces()
277 << " addressing:" << faceProcAddressing.objectRelPath()
278 << " size:" << faceProcAddressing.size() << nl
279 << "points:" << mesh.nPoints()
280 << " addressing:" << pointProcAddressing.objectRelPath()
281 << " size:" << pointProcAddressing.size()
282 << "patches:" << mesh.boundaryMesh().size()
283 << " addressing:" << boundaryProcAddressing.objectRelPath()
284 << " size:" << boundaryProcAddressing.size()
285 << exit(FatalError);
286 }
287
289 (
290 mesh,
291 baseMeshPtr,
292 cellProcAddressing,
293 faceProcAddressing,
294 pointProcAddressing,
295 boundaryProcAddressing
296 );
297 }
298}
299
300
302(
303 const fvMesh& mesh,
304 const mapDistributePolyMesh& map,
305 const bool decompose,
306 const fileName& writeInstance,
307 refPtr<fileOperation>& writeHandler
308)
309{
310 Info<< "Writing ("
311 << (decompose ? "decompose" : "reconstruct")
312 << ") procAddressing files to "
313 << mesh.facesInstance().c_str() << '/'
315
316 // Processor-local outputs for components
317 // NB: the full "procAddressing" output is presumed to already have
318 // been done independently (as a registered object)
319 IOobject ioAddr
320 (
321 "proc-addressing",
322 mesh.facesInstance(),
324 mesh.thisDb(),
328 );
329
330 // cellProcAddressing (polyMesh)
331 ioAddr.rename("cellProcAddressing");
332 labelIOList cellMap(ioAddr, Zero);
333
334 // faceProcAddressing (polyMesh)
335 ioAddr.rename("faceProcAddressing");
336 labelIOList faceMap(ioAddr, Zero);
337
338 // pointProcAddressing (polyMesh)
339 ioAddr.rename("pointProcAddressing");
340 labelIOList pointMap(ioAddr, Zero);
341
342 // boundaryProcAddressing (polyMesh)
343 ioAddr.rename("boundaryProcAddressing");
344 labelIOList patchMap(ioAddr, Zero);
345
346
347 if (decompose)
348 {
349 // Decompose
350 // - forward map: [undecomposed] -> [decomposed]
351
352 cellMap = identity(map.nOldCells());
353 map.distributeCellData(cellMap);
354
355 faceMap = identity(map.nOldFaces());
356 {
357 const mapDistribute& faceDistMap = map.faceMap();
358
359 if (faceDistMap.subHasFlip() || faceDistMap.constructHasFlip())
360 {
361 // Offset by 1
362 faceMap = faceMap + 1;
363 }
364
365 faceDistMap.mapDistributeBase::distribute
366 (
368 faceMap,
369 flipLabelOp() // Apply face flips
370 );
371 }
372
373 pointMap = identity(map.nOldPoints());
374 map.distributePointData(pointMap);
375
376 patchMap = identity(map.oldPatchSizes().size());
377 map.patchMap().mapDistributeBase::distribute
378 (
380 label(-1), // nullValue for new patches...
381 patchMap,
382 flipOp() // negate op
383 );
384 }
385 else
386 {
387 // Reconstruct
388 // - reverse map: [undecomposed] <- [decomposed]
389
390 cellMap = identity(mesh.nCells());
391 map.cellMap().reverseDistribute(map.nOldCells(), cellMap);
392
394 {
395 const mapDistribute& faceDistMap = map.faceMap();
396
397 if (faceDistMap.subHasFlip() || faceDistMap.constructHasFlip())
398 {
399 // Offset by 1
400 faceMap = faceMap + 1;
401 }
402
403 faceDistMap.mapDistributeBase::reverseDistribute
404 (
406 map.nOldFaces(),
407 faceMap,
408 flipLabelOp() // Apply face flips
409 );
410 }
411
412 pointMap = identity(mesh.nPoints());
413 map.pointMap().reverseDistribute(map.nOldPoints(), pointMap);
414
415 patchMap = identity(mesh.boundaryMesh().size());
416 map.patchMap().mapDistributeBase::reverseDistribute
417 (
419 map.oldPatchSizes().size(),
420 label(-1), // nullValue for unmapped patches...
421 patchMap
422 );
423 }
424
425
426 // Switch to using the correct
427 // - fileHandler
428 // - instance
429 // to write to the original mesh/time in the original format. Clunky!
430 // Bypass regIOobject writing to avoid taking over the current time
431 // as instance so instead of e.g. 'celllMap.write()' directly call
432 // the chosen file-handler.
433
434 if (!writeInstance.empty())
435 {
436 cellMap.instance() = writeInstance;
437 faceMap.instance() = writeInstance;
438 pointMap.instance() = writeInstance;
439 patchMap.instance() = writeInstance;
440 }
441
442 const auto& tm = cellMap.time();
443 const IOstreamOption opt(tm.writeStreamOption());
444 {
445 auto oldHandler = fileOperation::fileHandler(writeHandler);
446
447 const bool cellOk = fileHandler().writeObject(cellMap, opt, true);
448 const bool faceOk = fileHandler().writeObject(faceMap, opt, true);
449 const bool pointOk = fileHandler().writeObject(pointMap, opt, true);
450 const bool patchOk = fileHandler().writeObject(patchMap, opt, true);
451
452 writeHandler = fileOperation::fileHandler(oldHandler);
453
454 if (!cellOk || !faceOk || !pointOk || !patchOk)
455 {
457 << "Failed to write some of "
458 << cellMap.objectRelPath() << ", "
459 << faceMap.objectRelPath() << ", "
460 << pointMap.objectRelPath() << ", "
461 << patchMap.objectRelPath() << endl;
462 }
464}
465
466
467// * * * * * * * * * * * * * * * Housekeeping * * * * * * * * * * * * * * * //
468
471(
472 const fvMesh& procMesh,
473 const autoPtr<fvMesh>& baseMeshPtr
474)
475{
476 return readProcAddressing(procMesh, baseMeshPtr.get());
477}
478
479
480// ************************************************************************* //
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
const polyBoundaryMesh & pbm
@ NO_REGISTER
Do not request registration (bool: false).
@ NO_READ
Nothing to be read.
@ READ_IF_PRESENT
Reading is optional [identical to LAZY_READ].
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
const Time & time() const noexcept
Return Time associated with the objectRegistry.
Definition IOobject.C:456
fileName objectRelPath() const
The object path relative to the case.
Definition IOobject.C:581
const fileName & instance() const noexcept
Read access to instance path component.
Definition IOobjectI.H:289
virtual void rename(const word &newName)
Rename the object.
Definition IOobject.H:697
A simple container for options an IOstream can normally have.
static IndirectList< T > subset_if(const UList< T > &values, const UnaryPredicate &pred, const bool invert=false)
Return an IndirectList comprising entries with values that satisfy the predicate.
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
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:1706
@ nonBlocking
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
Definition UPstream.H:84
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
Definition UPstream.H:1691
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
Definition UPstream.H:1697
@ gatherList
gatherList [manual algorithm]
Definition UPstream.H:194
label size() const noexcept
The number of entries in the list.
Definition UPtrListI.H:106
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
T * get() noexcept
Return pointer to managed object without nullptr checking.
Definition autoPtr.H:216
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition autoPtr.H:178
A class for handling file names.
Definition fileName.H:75
static const fileOperation & fileHandler()
Return the current file handler. Will create the default file handler if necessary.
static autoPtr< mapDistributePolyMesh > readProcAddressing(const fvMesh &procMesh, const fvMesh *baseMeshPtr)
Read procAddressing components (reconstructing).
static void writeProcAddressing(const fvMesh &procMesh, const mapDistributePolyMesh &map, const bool decompose, const fileName &writeInstance, refPtr< fileOperation > &writeHandler)
Write addressing if decomposing (1 to many) or reconstructing (many to 1).
Mesh data needed to do the Finite Volume discretisation.
Definition fvMesh.H:85
bool constructHasFlip() const noexcept
Does constructMap include a sign.
bool subHasFlip() const noexcept
Does subMap include a sign.
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
const mapDistribute & patchMap() const noexcept
Patch distribute map.
void distributeCellData(List< T > &values) const
Distribute list of cell data.
label nOldCells() const noexcept
Number of cells in mesh before distribution.
label nOldFaces() const noexcept
Number of faces in mesh before distribution.
const labelList & oldPatchSizes() const noexcept
List of the old patch sizes.
void distributePointData(List< T > &values) const
Distribute list of point data.
const mapDistribute & cellMap() const noexcept
Cell distribute map.
const mapDistribute & pointMap() const noexcept
Point distribute map.
const mapDistribute & faceMap() const noexcept
Face distribute map.
label nOldPoints() const noexcept
Number of points in mesh before distribution.
Class containing processor-to-processor mapping information.
void reverseDistribute(const label constructSize, List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Definition polyMesh.H:609
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh").
Definition polyMesh.H:411
label nPoints() const noexcept
Number of mesh points.
label nCells() const noexcept
Number of mesh cells.
label nFaces() const noexcept
Number of mesh faces.
A class for managing references or pointers (no reference counting).
Definition refPtr.H:54
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
static autoPtr< mapDistributePolyMesh > createReconstructMap(const fvMesh &mesh, const fvMesh *baseMeshPtr, const labelList &cellProcAddressing, const labelList &faceProcAddressing, const labelList &pointProcAddressing, const labelList &boundaryProcAddressing)
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
List< label > labelList
A List of labels.
Definition List.H:62
IOList< label > labelIOList
IO for a List of label.
Definition labelIOList.H:32
refPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler - forwards to fileOperation::handler().
messageStream Info
Information stream (stdout output on master, null elsewhere).
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Negate integer values.
Definition flipOp.H:92
Functor to negate primitives. Dummy for most other types.
Definition flipOp.H:67