faMeshToolsProcAddr.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) 2022 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
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 "faMeshTools.H"
29 #include "BitOps.H"
30 #include "fileOperation.H"
31 #include "areaFields.H"
32 #include "edgeFields.H"
34 
35 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 
40 // Create a reconstruct map.
41 
43 (
44  const faMesh& mesh,
45  const autoPtr<faMesh>& baseMeshPtr,
46  const labelUList& faceProcAddr,
47  const labelUList& edgeProcAddr,
48  const labelUList& pointProcAddr,
49  const labelUList& boundaryProcAddr
50 )
51 {
52  const label nOldPoints = mesh.nPoints();
53  const label nOldFaces = mesh.nFaces();
54  const label nOldEdges = mesh.nEdges();
55 
60 
61  const faBoundaryMesh& oldBndMesh = mesh.boundary();
62  labelList oldPatchStarts(oldBndMesh.patchStarts());
63 
64  // Patches: purge -1 entries
65  labelList patchProcAddr
66  (
68  (
69  boundaryProcAddr,
70  labelRange::ge0()
71  )
72  );
73 
74 
75  labelListList faceSubMap(Pstream::nProcs());
76  faceSubMap[Pstream::masterNo()] = identity(nOldFaces);
77 
78  labelListList edgeSubMap(Pstream::nProcs());
79  edgeSubMap[Pstream::masterNo()] = identity(nOldEdges);
80 
81  labelListList pointSubMap(Pstream::nProcs());
82  pointSubMap[Pstream::masterNo()] = identity(nOldPoints);
83 
84  labelListList patchSubMap(Pstream::nProcs());
85  patchSubMap[Pstream::masterNo()] = patchProcAddr;
86 
87 
88  // Gather addressing on the master
89  labelListList faceAddressing(Pstream::nProcs());
90  faceAddressing[Pstream::myProcNo()] = faceProcAddr;
91  Pstream::gatherList(faceAddressing);
92 
93  labelListList edgeAddressing(Pstream::nProcs());
94  edgeAddressing[Pstream::myProcNo()] = edgeProcAddr;
95  Pstream::gatherList(edgeAddressing);
96 
97  labelListList pointAddressing(Pstream::nProcs());
98  pointAddressing[Pstream::myProcNo()] = pointProcAddr;
99  Pstream::gatherList(pointAddressing);
100 
101  labelListList patchAddressing(Pstream::nProcs());
102  patchAddressing[Pstream::myProcNo()] = patchProcAddr;
103  Pstream::gatherList(patchAddressing);
104 
105 
106  // NB: can only have a reconstruct on master!
107  if (Pstream::master() && baseMeshPtr && baseMeshPtr->nFaces())
108  {
109  const faMesh& baseMesh = *baseMeshPtr;
110 
111  const label nNewPoints = baseMesh.nPoints();
112  const label nNewFaces = baseMesh.nFaces();
113  const label nNewEdges = baseMesh.nEdges();
114  const label nNewPatches = baseMesh.boundary().size();
115 
120 
121  mapDistribute faFaceMap
122  (
123  nNewFaces,
124  std::move(faceSubMap),
125  std::move(faceAddressing),
126  false, // subHasFlip
127  false // constructHasFlip
128  );
129 
130  mapDistribute faEdgeMap
131  (
132  nNewEdges,
133  std::move(edgeSubMap),
134  std::move(edgeAddressing),
135  false, // subHasFlip
136  false // constructHasFlip
137  );
138 
139  mapDistribute faPointMap
140  (
141  nNewPoints,
142  std::move(pointSubMap),
143  std::move(pointAddressing)
144  );
145 
146  mapDistribute faPatchMap
147  (
148  nNewPatches,
149  std::move(patchSubMap),
150  std::move(patchAddressing)
151  );
152 
153  return mapDistributePolyMesh
154  (
155  // Mesh before changes
156  nOldPoints,
157  nOldEdges, // area: nOldEdges (volume: nOldFaces)
158  nOldFaces, // area: nOldFaces (volume: nOldCells)
159 
160  std::move(oldPatchStarts),
161  labelList(), // oldPatchNMeshPoints [unused]
162 
163  mapDistribute(std::move(faPointMap)),
164  mapDistribute(std::move(faEdgeMap)), // edgeMap (volume: faceMap)
165  mapDistribute(std::move(faFaceMap)), // faceMap (volume: cellMap)
166  mapDistribute(std::move(faPatchMap))
167  );
168  }
169  else
170  {
171  mapDistribute faFaceMap
172  (
173  0, // nNewFaces
174  std::move(faceSubMap),
175  labelListList(Pstream::nProcs()), // constructMap
176  false, // subHasFlip
177  false // constructHasFlip
178  );
179 
180  mapDistribute faEdgeMap
181  (
182  0, // nNewEdges
183  std::move(edgeSubMap),
184  labelListList(Pstream::nProcs()), // constructMap
185  false, // subHasFlip
186  false // constructHasFlip
187  );
188 
189  mapDistribute faPointMap
190  (
191  0, // nNewPoints
192  std::move(pointSubMap),
193  labelListList(Pstream::nProcs()) // constructMap
194  );
195 
196  mapDistribute faPatchMap
197  (
198  0, // nNewPatches
199  std::move(patchSubMap),
200  labelListList(Pstream::nProcs()) // constructMap
201  );
202 
203  return mapDistributePolyMesh
204  (
205  // Mesh before changes
206  nOldPoints,
207  nOldEdges, // area: nOldEdges (volume: nOldFaces)
208  nOldFaces, // area: nOldFaces (volume: nOldCells)
209 
210  std::move(oldPatchStarts),
211  labelList(), // oldPatchNMeshPoints [unused]
212 
213  mapDistribute(std::move(faPointMap)),
214  mapDistribute(std::move(faEdgeMap)), // edgeMap (volume: faceMap)
215  mapDistribute(std::move(faFaceMap)), // faceMap (volume: cellMap)
216  mapDistribute(std::move(faPatchMap))
217  );
218  }
219 }
220 
221 } // End namespace Foam
222 
223 
224 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
225 
228 (
229  const faMesh& mesh,
230  const autoPtr<faMesh>& baseMeshPtr
231 )
232 {
233  IOobject ioAddr
234  (
235  "procAddressing",
236  mesh.facesInstance(),
238  mesh.thisDb(),
242  );
243 
244  //if (ioAddr.typeHeaderOk<labelIOList>(true))
245  //{
246  // Pout<< "Reading addressing from " << io.name() << " at "
247  // << mesh.facesInstance() << nl << endl;
248  // distMap.reset(new IOmapDistributePolyMesh(io));
249  //}
250  //else
251 
252  {
253  Info<< "Reading (face|edge|face|point|boundary)ProcAddressing from "
254  << mesh.facesInstance().c_str() << '/'
255  << faMesh::meshSubDir << nl << endl;
256 
257  ioAddr.rename("faceProcAddressing");
258  labelIOList faceProcAddressing(ioAddr, Zero);
259 
260  ioAddr.rename("edgeProcAddressing");
261  labelIOList edgeProcAddressing(ioAddr, Zero);
262 
263  ioAddr.rename("pointProcAddressing");
264  labelIOList pointProcAddressing(ioAddr, Zero);
265 
266  ioAddr.rename("boundaryProcAddressing");
267  labelIOList boundaryProcAddressing(ioAddr, Zero);
268 
269  if
270  (
271  mesh.nFaces() != faceProcAddressing.size()
272  || mesh.nEdges() != edgeProcAddressing.size()
273  || mesh.nPoints() != pointProcAddressing.size()
274  || mesh.boundary().size() != boundaryProcAddressing.size()
275  )
276  {
278  << "Read addressing inconsistent with mesh sizes" << nl
279  << "faces:" << mesh.nFaces()
280  << " addressing:" << faceProcAddressing.objectRelPath()
281  << " size:" << faceProcAddressing.size() << nl
282  << "edges:" << mesh.nEdges()
283  << " addressing:" << edgeProcAddressing.objectRelPath()
284  << " size:" << edgeProcAddressing.size() << nl
285  << "points:" << mesh.nPoints()
286  << " addressing:" << pointProcAddressing.objectRelPath()
287  << " size:" << pointProcAddressing.size()
288  << "patches:" << mesh.boundary().size()
289  << " addressing:" << boundaryProcAddressing.objectRelPath()
290  << " size:" << boundaryProcAddressing.size()
291  << exit(FatalError);
292  }
293 
294  return createReconstructMap
295  (
296  mesh,
297  baseMeshPtr,
298  faceProcAddressing,
299  edgeProcAddressing,
300  pointProcAddressing,
301  boundaryProcAddressing
302  );
303  }
304 }
305 
306 
308 (
309  const faMesh& mesh,
310  const mapDistributePolyMesh& map,
311  const bool decompose,
312  refPtr<fileOperation>& writeHandler,
313  const faMesh* procMesh
314 )
315 {
316  Info<< "Writing ("
317  << (decompose ? "decompose" : "reconstruct")
318  << ") procAddressing files to "
319  << mesh.facesInstance().c_str() << '/'
320  << faMesh::meshSubDir << endl;
321 
322  IOobject ioAddr
323  (
324  "procAddressing",
327  (procMesh && !decompose ? procMesh->thisDb() : mesh.thisDb()),
331  );
332 
333 
334  // faceProcAddressing (faMesh)
335  ioAddr.rename("faceProcAddressing");
336  labelIOList faceMap(ioAddr, Zero);
337 
338  // edgeProcAddressing (faMesh)
339  ioAddr.rename("edgeProcAddressing");
340  labelIOList edgeMap(ioAddr, Zero);
341 
342  // pointProcAddressing (faMesh)
343  ioAddr.rename("pointProcAddressing");
344  labelIOList pointMap(ioAddr, Zero);
345 
346  // boundaryProcAddressing (faMesh)
347  ioAddr.rename("boundaryProcAddressing");
348  labelIOList patchMap(ioAddr, Zero);
349 
350  if (decompose)
351  {
352  // Decompose
353  // - forward map: [undecomposed] -> [decomposed]
354 
355  // area:faces (volume:cells)
356  faceMap = identity(map.nOldCells());
357  map.cellMap().distribute(faceMap);
358 
359  // area:edges (volume:faces)
360  edgeMap = identity(map.nOldFaces());
361  map.faceMap().distribute(edgeMap);
362 
363  pointMap = identity(map.nOldPoints());
364  map.distributePointData(pointMap);
365 
366  patchMap = identity(map.patchMap().constructSize());
367  map.patchMap().mapDistributeBase::distribute
368  (
370  label(-1), // nullValue for new patches...
371  patchMap,
372  flipOp() // negate op
373  );
374  }
375  else // reconstruct
376  {
377  // Reconstruct
378  // - reverse map: [undecomposed] <- [decomposed]
379 
380  // area:faces (volume:cells)
382  map.cellMap().reverseDistribute(map.nOldCells(), faceMap);
383 
384  // area:edges (volume:faces)
385  edgeMap = identity(mesh.patch().nEdges());
386  map.faceMap().reverseDistribute(map.nOldFaces(), edgeMap);
387 
388  pointMap = identity(mesh.nPoints());
389  map.pointMap().reverseDistribute(map.nOldPoints(), pointMap);
390 
391  patchMap = identity(mesh.boundary().size());
392  map.patchMap().mapDistributeBase::reverseDistribute
393  (
395  map.oldPatchSizes().size(),
396  label(-1), // nullValue for unmapped patches...
397  patchMap
398  );
399  }
400 
401  auto oldHandler = fileOperation::fileHandler(writeHandler);
402 
403 
404  // If we want procAddressing, need to manually write it ourselves
405  // since it was not registered anywhere
406 
407  IOmapDistributePolyMeshRef procAddrMap
408  (
409  IOobject
410  (
411  "procAddressing",
414  mesh.thisDb(),
418  ),
419  map
420  );
421 
422 
423  if (decompose)
424  {
425  // Write into proc directories
426  procAddrMap.write();
427  }
428  else
429  {
430  // Reconstruct: "procAddressing" only meaningful for rank 0
431  // and written into base (serial) location (if at all).
432 
433  if (UPstream::master())
434  {
435  const bool oldParRun = UPstream::parRun(false);
436  procAddrMap.write();
437  UPstream::parRun(oldParRun);
438  }
439  }
440 
441 
442  const bool faceOk = faceMap.write();
443  const bool edgeOk = edgeMap.write();
444  const bool pointOk = pointMap.write();
445  const bool patchOk = patchMap.write();
446 
447  writeHandler = fileOperation::fileHandler(oldHandler);
448 
449  if (!edgeOk || !faceOk || !pointOk || !patchOk)
450  {
452  << "Failed to write some of "
453  << faceMap.objectRelPath() << ", "
454  << edgeMap.objectRelPath() << ", "
455  << pointMap.objectRelPath() << ", "
456  << patchMap.objectRelPath() << endl;
457  }
458 }
459 
460 
461 // ************************************************************************* //
Finite area mesh (used for 2-D non-Euclidian finite area method) defined using a patch of faces on a ...
Definition: faMesh.H:87
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:859
static void writeProcAddressing(const faMesh &mesh, const mapDistributePolyMesh &faDistMap, const bool decompose, refPtr< fileOperation > &writeHandler, const faMesh *procMesh=nullptr)
Write decompose/reconstruct addressing.
label nPoints() const noexcept
Number of mesh points.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1049
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Ignore writing from objectRegistry::writeObject()
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
label nFaces() const noexcept
Number of mesh faces.
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
label nFaces() const noexcept
Number of patch faces.
Definition: faMeshI.H:61
static mapDistributePolyMesh readProcAddressing(const faMesh &mesh, const autoPtr< faMesh > &baseMeshPtr)
Read decompose/reconstruct addressing.
label nPoints() const noexcept
Number of local mesh points.
Definition: faMeshI.H:37
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
virtual const objectRegistry & thisDb() const
Return the object registry - resolve conflict polyMesh/lduMesh.
Definition: fvMesh.H:376
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:1065
static void gatherList(const List< commsStruct > &comms, List< T > &values, const int tag, const label comm)
Gather data, but keep individual values separate. Uses the specified communication schedule...
IOList< label > labelIOList
IO for a List of label.
Definition: labelIOList.H:32
dynamicFvMesh & mesh
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...
Definition: labelLists.C:44
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
Definition: UPstream.H:1059
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
Reading is optional [identical to LAZY_READ].
label nEdges() const
Number of mesh edges.
static mapDistributePolyMesh createReconstructMap(const faMesh &mesh, const autoPtr< faMesh > &baseMeshPtr, const labelUList &faceProcAddr, const labelUList &edgeProcAddr, const labelUList &pointProcAddr, const labelUList &boundaryProcAddr)
const faBoundaryMesh & boundary() const noexcept
Return constant reference to boundary mesh.
Definition: faMeshI.H:31
label nEdges() const noexcept
Number of local mesh edges.
Definition: faMeshI.H:43
static word meshSubDir
The mesh sub-directory name (usually "faMesh")
Definition: faMesh.H:701
Class containing processor-to-processor mapping information.
#define WarningInFunction
Report a warning using Foam::Warning.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
Nothing to be read.
Finite area boundary mesh.
fileName objectRelPath() const
The object path relative to the root.
Definition: IOobject.C:524
"nonBlocking" : (MPI_Isend, MPI_Irecv)
messageStream Info
Information stream (stdout output on master, null elsewhere)
const fvBoundaryMesh & boundary() const noexcept
Return reference to boundary mesh.
Definition: fvMesh.H:395
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
static const fileOperation & fileHandler()
Return the current file handler. Will create the default file handler if necessary.
List< label > labelList
A List of labels.
Definition: List.H:62
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
labelList patchStarts() const
Return a list of patch start indices.
A List with indirect addressing.
Definition: IndirectList.H:60
Do not request registration (bool: false)
Namespace for OpenFOAM.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127