faMeshReconstructor.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) 2021-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 "faMeshReconstructor.H"
29 #include "globalIndex.H"
30 #include "globalMeshData.H"
31 #include "edgeHashes.H"
32 #include "Time.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
37 
38 
39 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
40 
41 void Foam::faMeshReconstructor::calcAddressing
42 (
43  const labelUList& fvFaceProcAddr
44 )
45 {
46  const globalIndex globalFaceNum(procMesh_.nFaces());
47 
48  // ----------------------
49  // boundaryProcAddressing
50  //
51  // Trivial since non-processor boundary ordering is identical
52 
53  const label nPatches = procMesh_.boundary().size();
54 
55  faBoundaryProcAddr_ = identity(nPatches);
56 
57  // Mark processor patches
58  for
59  (
60  label patchi = procMesh_.boundary().nNonProcessor();
61  patchi < nPatches;
62  ++patchi
63  )
64  {
65  faBoundaryProcAddr_[patchi] = -1;
66  }
67 
68 
69  // ------------------
70  // faceProcAddressing
71  //
72  // Transcribe/rewrite based on finiteVolume faceProcAddressing
73 
74  faFaceProcAddr_ = procMesh_.faceLabels();
75 
76  // From local faceLabels to proc values
77  for (label& facei : faFaceProcAddr_)
78  {
79  // Use finiteVolume info, ignoring face flips
80  facei = mag(fvFaceProcAddr[facei])-1;
81  }
82 
83 
84  // Make global consistent.
85  // Starting at '0', without gaps in numbering etc.
86  // - the sorted order is the obvious solution
87  {
88  globalFaceNum.gather(faFaceProcAddr_, singlePatchFaceLabels_);
89 
90  const labelList globalOrder(Foam::sortedOrder(singlePatchFaceLabels_));
91 
92  singlePatchFaceLabels_ =
93  labelList(singlePatchFaceLabels_, globalOrder);
94 
95  // Set first face to be zero relative to the finiteArea patch
96  // ie, local-face numbering with the first being 0 on any given patch
97  {
98  label patchFirstMeshfacei
99  (
100  singlePatchFaceLabels_.empty()
101  ? 0
102  : singlePatchFaceLabels_.first()
103  );
104  Pstream::broadcast(patchFirstMeshfacei);
105 
106  for (label& facei : faFaceProcAddr_)
107  {
108  facei -= patchFirstMeshfacei;
109  }
110  }
111 
112  PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
113 
114  if (Pstream::master())
115  {
116  // Determine the respective local portions of the global ordering
117 
118  labelList procTargets(globalFaceNum.totalSize());
119 
120  for (const label proci : Pstream::allProcs())
121  {
123  (
124  globalFaceNum.range(proci),
125  procTargets
126  ) = proci;
127  }
128 
129  labelList procStarts(globalFaceNum.offsets());
130  labelList procOrders(globalFaceNum.totalSize());
131 
132  for (const label globali : globalOrder)
133  {
134  const label proci = procTargets[globali];
135 
136  procOrders[procStarts[proci]++] =
137  (globali - globalFaceNum.localStart(proci));
138  }
139 
140  // Send the local portions
141  for (const int proci : Pstream::subProcs())
142  {
143  SubList<label> localOrder
144  (
145  procOrders,
146  globalFaceNum.range(proci)
147  );
148 
149  UOPstream toProc(proci, pBufs);
150  toProc << localOrder;
151  }
152 
153  SubList<label> localOrder(procOrders, globalFaceNum.range(0));
154 
155  faFaceProcAddr_ = labelList(faFaceProcAddr_, localOrder);
156  }
157 
158  pBufs.finishedScatters();
159 
160  if (!Pstream::master())
161  {
162  labelList localOrder;
163 
164  UIPstream fromProc(Pstream::masterNo(), pBufs);
165  fromProc >> localOrder;
166 
167  faFaceProcAddr_ = labelList(faFaceProcAddr_, localOrder);
168  }
169  }
170 
171  // Broadcast the same information everywhere
172  Pstream::broadcast(singlePatchFaceLabels_);
173 
174 
175  // ------------------
176  // edgeProcAddressing
177  //
178  // This is more complicated.
179 
180  // Create a single (serial) patch of the finiteArea mesh without a
181  // corresponding volume mesh, otherwise it would be the same as
182  // reconstructPar on the volume mesh (big, slow, etc).
183  //
184  // Do manual point-merge and relabeling to avoid dependency on
185  // finiteVolume pointProcAddressing
186 
187  faPointProcAddr_.clear(); // Final size == procMesh_.nPoints()
188 
189  // 1.
190  // - Topological point merge of the area meshes
191  // - use the local patch faces and points
192 
193  // 2.
194  // - build a single (serial) patch of the finiteArea mesh only
195  // without any point support from the volume mesh
196  // - it may be possible to skip this step, but not obvious how
197 
198  // The collected faces are contiguous per processor, which gives us
199  // the possibility to easily identify their source by using the
200  // global face indexing (if needed).
201  // The ultimate face locations are handled with a separate ordering
202  // list.
203 
204  const uindirectPrimitivePatch& procPatch = procMesh_.patch();
205 
206 
207  {
208  faceList singlePatchProcFaces; // [proc0faces, proc1faces ...]
209  labelList uniqueMeshPointLabels;
210 
211  // Local face points to compact merged point index
212  labelList pointToGlobal;
213 
214  autoPtr<globalIndex> globalPointsPtr =
215  procMesh_.mesh().globalData().mergePoints
216  (
217  procPatch.meshPoints(),
218  procPatch.meshPointMap(), // unused
219  pointToGlobal,
220  uniqueMeshPointLabels
221  );
222 
223  // Gather faces, renumbered for the *merged* points
224  faceList tmpFaces(globalFaceNum.localSize());
225 
226  forAll(tmpFaces, facei)
227  {
228  tmpFaces[facei] =
229  face(pointToGlobal, procPatch.localFaces()[facei]);
230  }
231 
232  globalFaceNum.gather
233  (
234  tmpFaces,
235  singlePatchProcFaces,
238  );
239 
240  globalPointsPtr().gather
241  (
242  UIndirectList<point>
243  (
244  procPatch.points(), // NB: mesh points (non-local)
245  uniqueMeshPointLabels
246  ),
247  singlePatchPoints_
248  );
249 
250  // Transcribe into final assembled order
251  singlePatchFaces_.resize(singlePatchProcFaces.size());
252 
253  // Target face ordering
254  labelList singlePatchProcAddr;
255  globalFaceNum.gather(faFaceProcAddr_, singlePatchProcAddr);
256 
257  forAll(singlePatchProcAddr, facei)
258  {
259  const label targetFacei = singlePatchProcAddr[facei];
260  singlePatchFaces_[targetFacei] = singlePatchProcFaces[facei];
261  }
262 
263  // Use initial equivalent "global" (serial) patch
264  // to establish the correct point and face walking order
265  //
266  // - only meaningful on master
267  const primitivePatch initialPatch
268  (
269  SubList<face>(singlePatchFaces_),
270  singlePatchPoints_
271  );
272 
273  // Grab the faces/points in local point ordering
274  tmpFaces = initialPatch.localFaces();
275  pointField tmpPoints(initialPatch.localPoints());
276 
277  // Equivalent to a flattened meshPointMap
278  labelList mpm(initialPatch.points().size(), -1);
279  {
280  const labelList& mp = initialPatch.meshPoints();
281  forAll(mp, i)
282  {
283  mpm[mp[i]] = i;
284  }
285  }
286  Pstream::broadcast(mpm);
287 
288  // Rewrite pointToGlobal according to the correct point order
289  for (label& pointi : pointToGlobal)
290  {
291  pointi = mpm[pointi];
292  }
293 
294  // Finalize. overwrite
295  faPointProcAddr_ = std::move(pointToGlobal);
296 
297  singlePatchFaces_ = std::move(tmpFaces);
298  singlePatchPoints_ = std::move(tmpPoints);
299  }
300 
301  // Broadcast the same information everywhere
302  Pstream::broadcast(singlePatchFaces_);
303  Pstream::broadcast(singlePatchPoints_);
304 
305  // Now have enough global information to determine global edge mappings
306 
307  // Equivalent "global" (serial) patch
308  const primitivePatch onePatch
309  (
310  SubList<face>(singlePatchFaces_),
311  singlePatchPoints_
312  );
313 
314  faEdgeProcAddr_.clear();
315  faEdgeProcAddr_.resize(procMesh_.nEdges(), -1);
316 
317  {
318  EdgeMap<label> globalEdgeMapping(2*onePatch.nEdges());
319 
320  // Pass 1: edge-hash lookup with edges in "natural" patch order
321 
322  // Can use local edges() directly without remap via meshPoints()
323  // since the previous sorting means that we are already working
324  // with faces that are in the local point order and even
325  // the points themselves are also in the local point order
326  for (const edge& e : onePatch.edges())
327  {
328  globalEdgeMapping.insert(e, globalEdgeMapping.size());
329  }
330 
331  // Lookup proc local edges (in natural order) to global equivalent
332  for (label edgei = 0; edgei < procPatch.nEdges(); ++edgei)
333  {
334  const edge globalEdge(faPointProcAddr_, procPatch.edges()[edgei]);
335 
336  const auto fnd = globalEdgeMapping.cfind(globalEdge);
337 
338  if (fnd.found())
339  {
340  faEdgeProcAddr_[edgei] = fnd.val();
341  }
342  else
343  {
345  << "Failed to find edge " << globalEdge
346  << " this indicates a programming error" << nl
347  << exit(FatalError);
348  }
349  }
350  }
351 
352  // Now have consistent global edge
353  // This of course would all be too easy.
354  // The finiteArea edge lists have been defined as their own sorted
355  // order with sublists etc.
356 
357  // Gather edge ids for nonProcessor boundaries.
358  // These will also be in the serial geometry
359 
360  Map<label> remapGlobal(2*onePatch.nEdges());
361  for (label edgei = 0; edgei < onePatch.nInternalEdges(); ++edgei)
362  {
363  remapGlobal.insert(edgei, remapGlobal.size());
364  }
365 
366  //
367  singlePatchEdgeLabels_.clear();
368  singlePatchEdgeLabels_.resize(procMesh_.boundary().nNonProcessor());
369 
370  forAll(singlePatchEdgeLabels_, patchi)
371  {
372  const faPatch& fap = procMesh_.boundary()[patchi];
373 
374  labelList& patchEdgeLabels = singlePatchEdgeLabels_[patchi];
375  patchEdgeLabels = fap.edgeLabels();
376 
377  // Renumber from local edges to global edges (natural order)
378  for (label& edgeId : patchEdgeLabels)
379  {
380  edgeId = faEdgeProcAddr_[edgeId];
381  }
382 
383  // OR patchEdgeLabels =
384  // UIndirectList<label>(faEdgeProcAddr_, fap.edgeLabels());
385 
386  // Combine from all processors
387  Pstream::combineReduce(patchEdgeLabels, ListOps::appendEqOp<label>());
388 
389  // Sorted order will be the original non-decomposed order
390  Foam::sort(patchEdgeLabels);
391 
392  for (const label sortedEdgei : patchEdgeLabels)
393  {
394  remapGlobal.insert(sortedEdgei, remapGlobal.size());
395  }
396  }
397 
398  {
399  // Use the map to rewrite the local faEdgeProcAddr_
400 
401  labelList newEdgeProcAddr(faEdgeProcAddr_);
402 
403  label edgei = procMesh_.nInternalEdges();
404 
405  for (const faPatch& fap : procMesh_.boundary())
406  {
407  for (const label patchEdgei : fap.edgeLabels())
408  {
409  const label globalEdgei = faEdgeProcAddr_[patchEdgei];
410 
411  const auto fnd = remapGlobal.cfind(globalEdgei);
412  if (fnd.found())
413  {
414  newEdgeProcAddr[edgei] = fnd.val();
415  ++edgei;
416  }
417  else
418  {
420  << "Failed to find edge " << globalEdgei
421  << " this indicates a programming error" << nl
422  << exit(FatalError);
423  }
424  }
425  }
426 
427  faEdgeProcAddr_ = std::move(newEdgeProcAddr);
428  }
429 }
430 
431 
432 void Foam::faMeshReconstructor::initPatch() const
433 {
434  serialPatchPtr_.reset
435  (
436  new primitivePatch
437  (
438  SubList<face>(singlePatchFaces_),
439  singlePatchPoints_
440  )
441  );
442 }
443 
444 
445 void Foam::faMeshReconstructor::createMesh()
446 {
447  const Time& runTime = procMesh_.thisDb().time();
448 
449  // Time for non-parallel case (w/o functionObjects or libs)
450  serialRunTime_ = Time::New(runTime.globalPath().toAbsolute());
451 
452 
453  // Trivial polyMesh only containing points and faces.
454  // This is valid, provided we don't use it for anything complicated.
455 
456  serialVolMesh_.reset
457  (
458  new polyMesh
459  (
460  IOobject
461  (
462  procMesh_.mesh().name(), // Volume region name
463  procMesh_.mesh().facesInstance(),
464 
465  *serialRunTime_,
466 
470  ),
471  pointField(singlePatchPoints_), // copy
472  faceList(singlePatchFaces_), // copy
473  labelList(singlePatchFaces_.size(), Zero), // faceOwner
474  labelList(), // faceNeighbour
475  false // no syncPar!
476  )
477  );
478 
479  // A simple area-mesh with one-to-one mapping of faceLabels
480  serialAreaMesh_.reset
481  (
482  new faMesh
483  (
484  *serialVolMesh_,
485  identity(singlePatchFaces_.size()) // faceLabels
486  )
487  );
488 
489  auto& completeMesh = *serialAreaMesh_;
490 
491  // Add in non-processor boundary patches
492  faPatchList completePatches(singlePatchEdgeLabels_.size());
493  forAll(completePatches, patchi)
494  {
495  const labelList& patchEdgeLabels = singlePatchEdgeLabels_[patchi];
496 
497  const faPatch& fap = procMesh_.boundary()[patchi];
498 
499  const label neiPolyPatchId = fap.ngbPolyPatchIndex();
500 
501  completePatches.set
502  (
503  patchi,
504  fap.clone
505  (
506  completeMesh.boundary(),
507  patchEdgeLabels,
508  patchi, // index
509  neiPolyPatchId
510  )
511  );
512  }
513 
514  // Serial mesh - no parallel communication
515 
516  const bool oldParRun = Pstream::parRun(false);
517 
518  completeMesh.addFaPatches(completePatches);
519 
520  Pstream::parRun(oldParRun); // Restore parallel state
521 }
522 
523 
524 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
525 
526 Foam::faMeshReconstructor::faMeshReconstructor
527 (
528  const faMesh& procMesh,
529  IOobjectOption::readOption readVolAddressing
530 )
531 :
532  procMesh_(procMesh),
533  errors_(0)
534 {
535  if (!Pstream::parRun())
536  {
538  << "Can only be called in parallel!!" << nl
539  << exit(FatalError);
540  }
541 
542  IOobject ioAddr
543  (
544  "faceProcAddressing",
545  procMesh_.mesh().facesInstance(),
546 
547  // Or search?
548  // procMesh_.time().findInstance
549  // (
550  // // Search for polyMesh face instance
551  // // mesh.facesInstance()
552  // procMesh_.mesh().meshDir(),
553  // "faceProcAddressing"
554  // ),
555 
557  procMesh_.mesh(), // The polyMesh db
558 
559  readVolAddressing, // Read option
562  );
563 
564  // Require faceProcAddressing from finiteVolume decomposition
565  labelIOList fvFaceProcAddr(ioAddr);
566 
567  // Check if any/all where read.
568  // Use 'headerClassName' for checking
569  bool fileOk
570  (
571  (fvFaceProcAddr.readOpt() != IOobjectOption::NO_READ)
572  && fvFaceProcAddr.isHeaderClass<labelIOList>()
573  );
574 
575  Pstream::reduceAnd(fileOk);
576 
577  if (fileOk)
578  {
579  calcAddressing(fvFaceProcAddr);
580  }
581  else
582  {
583  errors_ = 1;
584  }
585 }
586 
587 
588 Foam::faMeshReconstructor::faMeshReconstructor
589 (
590  const faMesh& procMesh,
591  const labelUList& fvFaceProcAddressing
592 )
593 :
594  procMesh_(procMesh),
595  errors_(0)
596 {
597  if (!Pstream::parRun())
598  {
600  << "Can only be called in parallel!!" << nl
601  << exit(FatalError);
602  }
604  calcAddressing(fvFaceProcAddressing);
605 }
606 
607 
608 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
611 {}
612 
613 
614 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
615 
617 {
618  serialAreaMesh_.reset(nullptr);
619  serialVolMesh_.reset(nullptr);
620  serialRunTime_.reset(nullptr);
621 }
622 
623 
625 {
626  if (!serialPatchPtr_)
627  {
628  initPatch();
629  }
630 
631  return *serialPatchPtr_;
632 }
633 
634 
636 {
637  if (!serialPatchPtr_)
638  {
639  initPatch();
640  }
641 
642  return *serialPatchPtr_;
643 }
644 
645 
647 {
648  if (!serialAreaMesh_)
649  {
650  const_cast<faMeshReconstructor&>(*this).createMesh();
651  }
652 
653  return *serialAreaMesh_;
654 }
655 
658 {
659  writeAddressing(procMesh_.mesh().facesInstance());
660 }
661 
662 
664 {
665  // Write copies
666 
667  IOobject ioAddr
668  (
669  "procAddressing",
670  timeName,
672  procMesh_.thisDb(),
675  false // not registered
676  );
677 
678  // boundaryProcAddressing
679  ioAddr.rename("boundaryProcAddressing");
680  IOListRef<label>(ioAddr, faBoundaryProcAddr_).write();
681 
682  // faceProcAddressing
683  ioAddr.rename("faceProcAddressing");
684  IOListRef<label>(ioAddr, faFaceProcAddr_).write();
685 
686  // pointProcAddressing
687  ioAddr.rename("pointProcAddressing");
688  IOListRef<label>(ioAddr, faPointProcAddr_).write();
690  // edgeProcAddressing
691  ioAddr.rename("edgeProcAddressing");
692  IOListRef<label>(ioAddr, faEdgeProcAddr_).write();
693 }
694 
697 {
698  writeMesh(procMesh_.mesh().facesInstance());
699 }
700 
701 
703 {
704  const faMesh& fullMesh = this->mesh();
705 
706  const bool oldDistributed = fileHandler().distributed();
707  auto oldHandler = fileHandler(fileOperation::NewUncollated());
708  fileHandler().distributed(true);
709 
710  if (Pstream::master())
711  {
712  const bool oldParRun = Pstream::parRun(false);
713 
714  IOobject io(fullMesh.boundary());
715 
716  io.rename("faceLabels");
717  IOListRef<label>(io, singlePatchFaceLabels_).write();
718 
719  fullMesh.boundary().write();
720 
721  Pstream::parRun(oldParRun);
722  }
723 
724  // Restore old settings
725  if (oldHandler)
726  {
727  fileHandler(std::move(oldHandler));
728  }
729  fileHandler().distributed(oldDistributed);
730 }
731 
732 
733 // ************************************************************************* //
label nPatches
Definition: readKivaGrid.H:396
PtrList< faPatch > faPatchList
Store lists of faPatch as a PtrList.
Definition: faPatch.H:59
Finite area mesh (used for 2-D non-Euclidian finite area method) defined using a patch of faces on a ...
Definition: faMesh.H:88
void writeMesh() const
Write equivalent mesh information at the polyMesh faceInstances time.
const faMesh & mesh() const
Serial equivalent faMesh.
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:853
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:132
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:578
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
Definition: List.H:463
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
Definition: UPstream.H:748
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:420
virtual void rename(const word &newName)
Rename the object.
Definition: IOobject.H:626
List< face > faceList
A List of faces.
Definition: faceListFwd.H:41
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:402
T & first()
Access first element of the list, position [0].
Definition: UList.H:798
engineTime & runTime
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:639
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:697
static int debug
Debug flag.
autoPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler.
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:806
SubList< label > subList
Declare type of subList.
Definition: List.H:122
autoPtr< globalIndex > mergePoints(labelList &pointToGlobal, labelList &uniquePoints) const
Helper for merging (collocated!) mesh point data.
Ignore writing from objectRegistry::writeObject()
A bare-bones reconstructor for finiteArea meshes when processor meshes are available (in parallel) bu...
const primitivePatch & patch() const
Serial equivalent patch.
label nFaces() const noexcept
Number of patch faces.
Definition: faMeshI.H:73
UList< label > labelUList
A UList of labels.
Definition: UList.H:80
static void broadcast(Type &value, const label comm=UPstream::worldComm)
Broadcast content (contiguous or non-contiguous) to all processes in communicator.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
const uindirectPrimitivePatch & patch() const
Return constant reference to primitive patch.
Definition: faMeshI.H:121
word timeName
Definition: getTimeIndex.H:3
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
A list of faces which address into the list of points.
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
dynamicFvMesh & mesh
const labelList & faceLabels() const noexcept
Return the underlying polyMesh face labels.
Definition: faMeshI.H:115
static void reduceAnd(bool &value, const label communicator=worldComm)
Logical (and) reduction (cf. MPI AllReduce)
"scheduled" : (MPI_Send, MPI_Recv)
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Definition: labelList.C:31
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:109
A class for handling words, derived from Foam::string.
Definition: word.H:63
const Time & time() const noexcept
Return time registry.
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:334
static constexpr int masterNo() noexcept
Process index of the master (always 0)
Definition: UPstream.H:664
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:99
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1293
static void combineReduce(const List< commsStruct > &comms, T &value, const CombineOp &cop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) applying cop to inplace combine value from different processors...
fileName & toAbsolute()
Convert from relative to absolute.
Definition: fileName.C:370
const polyMesh & mesh() const
Return access to polyMesh.
Definition: faMeshI.H:24
virtual void rename(const word &newName)
Rename.
Definition: regIOobject.C:413
const faBoundaryMesh & boundary() const noexcept
Return constant reference to boundary mesh.
Definition: faMeshI.H:31
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field...
label nEdges() const noexcept
Number of local mesh edges.
Definition: faMeshI.H:55
void writeAddressing() const
Write proc addressing at the polyMesh faceInstances time.
static word meshSubDir
The mesh sub-directory name (usually "faMesh")
Definition: faMesh.H:698
PrimitivePatch< UIndirectList< face >, const pointField & > uindirectPrimitivePatch
A PrimitivePatch with UIndirectList for the faces, const reference for the point field.
label nInternalEdges() const noexcept
Number of internal faces.
Definition: faMeshI.H:61
label nNonProcessor() const
The number of patches before the first processor patch.
static bool master(const label communicator=worldComm)
Am I the master rank.
Definition: UPstream.H:672
Nothing to be read.
"nonBlocking" : (MPI_Isend, MPI_Irecv)
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition: UPstream.H:757
List< label > labelList
A List of labels.
Definition: List.H:62
virtual bool write(const bool valid=true) const
Write using setting from DB.
A IOList wrapper for writing external data.
Definition: IOList.H:144
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:166
const objectRegistry & thisDb() const noexcept
Return the object registry.
Do not request registration (bool: false)
const dimensionedScalar mp
Proton mass.
IOList< label > labelIOList
Label container classes.
Definition: labelIOList.H:38
fileName globalPath() const
Return global path for the case.
Definition: TimePathsI.H:73
static autoPtr< fileOperation > NewUncollated()
Static construct the commonly used uncollatedFileOperation.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:157
readOption
Enumeration defining read preferences.