redistributePar.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-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2021 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 Application
28  redistributePar
29 
30 Group
31  grpParallelUtilities
32 
33 Description
34  Redistributes existing decomposed mesh and fields according to the current
35  settings in the decomposeParDict file.
36 
37  Must be run on maximum number of source and destination processors.
38  Balances mesh and writes new mesh to new time directory.
39 
40  Can optionally run in decompose/reconstruct mode to decompose/reconstruct
41  mesh and fields.
42 
43 Usage
44  \b redistributePar [OPTION]
45 
46  Options:
47  - \par -decompose
48  Remove any existing \a processor subdirectories and decomposes the
49  mesh. Equivalent to running without processor subdirectories.
50 
51  - \par -reconstruct
52  Reconstruct mesh and fields (like reconstructParMesh+reconstructPar).
53 
54  - \par -newTimes
55  (in combination with -reconstruct) reconstruct only new times.
56 
57  - \par -dry-run
58  (not in combination with -reconstruct) Test without actually
59  decomposing.
60 
61  - \par -cellDist
62  not in combination with -reconstruct) Write the cell distribution
63  as a labelList, for use with 'manual'
64  decomposition method and as a volScalarField for visualization.
65 
66  - \par -region <regionName>
67  Distribute named region.
68 
69  - \par -allRegions
70  Distribute all regions in regionProperties. Does not check for
71  existence of processor*.
72 
73 \*---------------------------------------------------------------------------*/
74 
75 #include "argList.H"
76 #include "sigFpe.H"
77 #include "Time.H"
78 #include "fvMesh.H"
79 #include "fvMeshTools.H"
80 #include "fvMeshDistribute.H"
81 #include "decompositionMethod.H"
82 #include "decompositionModel.H"
83 #include "timeSelector.H"
84 #include "PstreamReduceOps.H"
85 #include "volFields.H"
86 #include "surfaceFields.H"
88 #include "IOobjectList.H"
89 #include "globalIndex.H"
90 #include "loadOrCreateMesh.H"
91 #include "processorFvPatchField.H"
93 #include "topoSet.H"
94 #include "regionProperties.H"
95 #include "basicFvGeometryScheme.H"
96 
100 #include "hexRef8Data.H"
101 #include "meshRefinement.H"
102 #include "pointFields.H"
103 
104 #include "cyclicACMIFvPatch.H"
106 #include "uncollatedFileOperation.H"
107 #include "collatedFileOperation.H"
108 
109 using namespace Foam;
110 
111 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
112 
113 const int debug(::Foam::debug::debugSwitch("redistributePar", 0));
114 
115 void createTimeDirs(const fileName& path)
116 {
117  // Get current set of local processor's time directories. Uses
118  // fileHandler
119  const instantList localTimeDirs(Time::findTimes(path, "constant"));
120 
121  instantList masterTimeDirs;
122  if (Pstream::master())
123  {
124  //const bool oldParRun = Pstream::parRun(false);
125  //timeDirs = Time::findTimes(path, "constant");
126  //Pstream::parRun(oldParRun); // Restore parallel state
127  masterTimeDirs = localTimeDirs;
128  }
129  Pstream::scatter(masterTimeDirs);
130  //DebugVar(masterTimeDirs);
131  //DebugVar(localTimeDirs);
132 
133  // Sync any cached times (e.g. masterUncollatedFileOperation::times_)
134  // since only master would have done the findTimes
135  for (const instant& t : masterTimeDirs)
136  {
137  if (!localTimeDirs.found(t))
138  {
139  const fileName timePath(path/t.name());
140 
141  //Pout<< "Time:" << t << nl
142  // << " raw :" << timePath << nl
143  // << endl;
144  mkDir(timePath);
145  }
146  }
147 
148  // Just to make sure remove all state and re-scan
149  fileHandler().flush();
150  (void)Time::findTimes(path, "constant");
151 }
152 
153 
154 void copyUniform
155 (
156  const fileOperation& fh,
157  const bool decompose,
158  const bool reconstruct,
159  const word& readTimeName,
160  const objectRegistry& readDb,
161  const objectRegistry& writeDb
162 )
163 {
164  // Detect uniform/ at original database + time
165  const IOobject readIO("uniform", readTimeName, readDb);
166  const fileName readPath
167  (
168  fh.dirPath
169  (
170  false, // local directory
171  readIO,
172  false // do not search in time
173  )
174  );
175  //if (Pstream::master() && !readPath.empty())
176  if (!readPath.empty())
177  {
178  Info<< "Detected additional non-decomposed files in "
179  << readPath << endl;
180 
181  // readPath: searching is the same for all file handlers. Typical:
182  // <case>/0.1/uniform (parent dir, decompose mode)
183  // <case>/processor1/0.1/uniform (redistribute/reconstruct mode)
184  // <case>/processors2/0.1/uniform ,,
185  // writePath:
186  // uncollated : <case>/0.1/uniform (reconstruct mode). Should only
187  // be done by master
188  // uncollated : <case>/processorXXX/0.1/uniform. Should be done by all.
189  // collated : <case>/processors2/0.1/uniform. Should be done by
190  // local master only.
191 
192  // See what local directory
193  const IOobject writeIO("uniform", writeDb.time().timeName(), writeDb);
194  const fileName writePath
195  (
196  fh.objectPath
197  (
198  writeIO,
199  word::null
200  )
201  );
202  // Do we already have this directory?
203  const fileName currentPath(fh.dirPath(false, writeIO, false));
204 
205  if (::debug)
206  {
207  Pout<< " readPath :" << readPath << endl;
208  Pout<< " writePath :" << writePath << endl;
209  Pout<< " currentPath:" << currentPath << endl;
210  }
211 
212  if (readPath == writePath)
213  {
214  return;
215  }
216 
217  if (currentPath.empty())
218  {
219  if (decompose)
220  {
221  // All processors copy to destination
222  fh.cp(readPath, writePath);
223  }
224  else if (reconstruct)
225  {
226  // Only master
227  if (Pstream::master())
228  {
229  const bool oldParRun = Pstream::parRun(false);
230  fh.cp(readPath, writePath);
231  Pstream::parRun(oldParRun);
232  }
233  }
234  else
235  {
236  // Redistribute. If same destination path do only on master,
237  // if different path do on all processors. For now check
238  // if collated file handler only. tbd.
239  if (isA<fileOperations::collatedFileOperation>(fh))
240  {
241  // Collated
242  if (Pstream::master())
243  {
244  const bool oldParRun = Pstream::parRun(false);
245  fh.cp(readPath, writePath);
246  Pstream::parRun(oldParRun);
247  }
248  }
249  else
250  {
251  // Assume uncollated
252  fh.cp(readPath, writePath);
253  }
254  }
255  }
256  }
257 }
258 
259 
260 boolList haveFacesFile(const fileName& meshPath)
261 {
262  const fileName facesPath(meshPath/"faces");
263  Info<< "Checking for mesh in " << facesPath << nl << endl;
264  boolList haveMesh(Pstream::nProcs(), false);
265  haveMesh[Pstream::myProcNo()] = fileHandler().isFile
266  (
267  fileHandler().filePath(facesPath)
268  );
269  Pstream::gatherList(haveMesh);
270  Pstream::scatterList(haveMesh);
271  Info<< "Per processor mesh availability:" << nl
272  << " " << flatOutput(haveMesh) << nl << endl;
273  return haveMesh;
274 }
275 
276 
277 void setBasicGeometry(fvMesh& mesh)
278 {
279  // Set the fvGeometryScheme to basic since it does not require
280  // any parallel communication to construct the geometry. During
281  // redistributePar one might temporarily end up with processors
282  // with zero procBoundaries. Normally procBoundaries trigger geometry
283  // calculation (e.g. send over cellCentres) so on the processors without
284  // procBoundaries this will not happen. The call to the geometry calculation
285  // is not synchronised and this might lead to a hang for geometry schemes
286  // that do require synchronisation
287 
288  tmp<fvGeometryScheme> basicGeometry
289  (
291  (
292  mesh,
293  dictionary(),
294  basicFvGeometryScheme::typeName
295  )
296  );
297  mesh.geometry(basicGeometry);
298 }
299 
300 
301 void printMeshData(const polyMesh& mesh)
302 {
303  // Collect all data on master
304 
305  globalIndex globalCells(mesh.nCells());
306  labelListList patchNeiProcNo(Pstream::nProcs());
307  labelListList patchSize(Pstream::nProcs());
308  const labelList& pPatches = mesh.globalData().processorPatches();
309  patchNeiProcNo[Pstream::myProcNo()].setSize(pPatches.size());
310  patchSize[Pstream::myProcNo()].setSize(pPatches.size());
311  forAll(pPatches, i)
312  {
313  const processorPolyPatch& ppp = refCast<const processorPolyPatch>
314  (
315  mesh.boundaryMesh()[pPatches[i]]
316  );
317  patchNeiProcNo[Pstream::myProcNo()][i] = ppp.neighbProcNo();
318  patchSize[Pstream::myProcNo()][i] = ppp.size();
319  }
320  Pstream::gatherList(patchNeiProcNo);
321  Pstream::gatherList(patchSize);
322 
323 
324  // Print stats
325 
326  globalIndex globalBoundaryFaces(mesh.nBoundaryFaces());
327 
328  label maxProcCells = 0;
329  label totProcFaces = 0;
330  label maxProcPatches = 0;
331  label totProcPatches = 0;
332  label maxProcFaces = 0;
333 
334  for (const int procI : Pstream::allProcs())
335  {
336  Info<< nl
337  << "Processor " << procI << nl
338  << " Number of cells = " << globalCells.localSize(procI)
339  << endl;
340 
341  label nProcFaces = 0;
342 
343  const labelList& nei = patchNeiProcNo[procI];
344 
345  forAll(patchNeiProcNo[procI], i)
346  {
347  Info<< " Number of faces shared with processor "
348  << patchNeiProcNo[procI][i] << " = " << patchSize[procI][i]
349  << endl;
350 
351  nProcFaces += patchSize[procI][i];
352  }
353 
354  Info<< " Number of processor patches = " << nei.size() << nl
355  << " Number of processor faces = " << nProcFaces << nl
356  << " Number of boundary faces = "
357  << globalBoundaryFaces.localSize(procI)-nProcFaces << endl;
358 
359  maxProcCells = max(maxProcCells, globalCells.localSize(procI));
360  totProcFaces += nProcFaces;
361  totProcPatches += nei.size();
362  maxProcPatches = max(maxProcPatches, nei.size());
363  maxProcFaces = max(maxProcFaces, nProcFaces);
364  }
365 
366  // Stats
367 
368  scalar avgProcCells = scalar(globalCells.size())/Pstream::nProcs();
369  scalar avgProcPatches = scalar(totProcPatches)/Pstream::nProcs();
370  scalar avgProcFaces = scalar(totProcFaces)/Pstream::nProcs();
371 
372  // In case of all faces on one processor. Just to avoid division by 0.
373  if (totProcPatches == 0)
374  {
375  avgProcPatches = 1;
376  }
377  if (totProcFaces == 0)
378  {
379  avgProcFaces = 1;
380  }
381 
382  Info<< nl
383  << "Number of processor faces = " << totProcFaces/2 << nl
384  << "Max number of cells = " << maxProcCells
385  << " (" << 100.0*(maxProcCells-avgProcCells)/avgProcCells
386  << "% above average " << avgProcCells << ")" << nl
387  << "Max number of processor patches = " << maxProcPatches
388  << " (" << 100.0*(maxProcPatches-avgProcPatches)/avgProcPatches
389  << "% above average " << avgProcPatches << ")" << nl
390  << "Max number of faces between processors = " << maxProcFaces
391  << " (" << 100.0*(maxProcFaces-avgProcFaces)/avgProcFaces
392  << "% above average " << avgProcFaces << ")" << nl
393  << endl;
394 }
395 
396 
397 // Debugging: write volScalarField with decomposition for post processing.
398 void writeDecomposition
399 (
400  const word& name,
401  const fvMesh& mesh,
402  const labelUList& decomp
403 )
404 {
405  // Write the decomposition as labelList for use with 'manual'
406  // decomposition method.
407  labelIOList cellDecomposition
408  (
409  IOobject
410  (
411  "cellDecomposition",
412  mesh.facesInstance(), // mesh read from facesInstance
413  mesh,
416  false
417  ),
418  decomp
419  );
420  cellDecomposition.write();
421 
422  Info<< "Writing wanted cell distribution to volScalarField " << name
423  << " for postprocessing purposes." << nl << endl;
424 
425  volScalarField procCells
426  (
427  IOobject
428  (
429  name,
430  mesh.time().timeName(),
431  mesh,
434  false // do not register
435  ),
436  mesh,
438  zeroGradientFvPatchScalarField::typeName
439  );
440 
441  forAll(procCells, cI)
442  {
443  procCells[cI] = decomp[cI];
444  }
445 
446  procCells.correctBoundaryConditions();
447  procCells.write();
448 }
449 
450 
451 void determineDecomposition
452 (
453  const Time& baseRunTime,
454  const fileName& decompDictFile, // optional location for decomposeParDict
455  const bool decompose, // decompose, i.e. read from undecomposed case
456  const fileName& proc0CaseName,
457  const fvMesh& mesh,
458  const bool writeCellDist,
459 
460  label& nDestProcs,
461  labelList& decomp
462 )
463 {
464  // Read decomposeParDict (on all processors)
466  (
467  mesh,
468  decompDictFile
469  );
470 
471  decompositionMethod& decomposer = method.decomposer();
472 
473  if (!decomposer.parallelAware())
474  {
476  << "You have selected decomposition method "
477  << decomposer.typeName
478  << " which does" << nl
479  << "not synchronise the decomposition across"
480  << " processor patches." << nl
481  << " You might want to select a decomposition method"
482  << " which is aware of this. Continuing."
483  << endl;
484  }
485 
486  Time& tm = const_cast<Time&>(mesh.time());
487 
488  const bool oldProcCase = tm.processorCase();
489  if (Pstream::master() && decompose)
490  {
491  Info<< "Setting caseName to " << baseRunTime.caseName()
492  << " to read decomposeParDict" << endl;
493  tm.caseName() = baseRunTime.caseName();
494  tm.processorCase(false);
495  }
496 
497  scalarField cellWeights;
498  if (method.found("weightField"))
499  {
500  word weightName = method.get<word>("weightField");
501 
502  volScalarField weights
503  (
504  IOobject
505  (
506  weightName,
507  tm.timeName(),
508  mesh,
511  ),
512  mesh
513  );
514  cellWeights = weights.internalField();
515  }
516 
517  nDestProcs = decomposer.nDomains();
518  decomp = decomposer.decompose(mesh, cellWeights);
519 
520  if (Pstream::master() && decompose)
521  {
522  Info<< "Restoring caseName to " << proc0CaseName << endl;
523  tm.caseName() = proc0CaseName;
524  tm.processorCase(oldProcCase);
525  }
526 
527  // Dump decomposition to volScalarField
528  if (writeCellDist)
529  {
530  // Note: on master make sure to write to processor0
531  if (decompose)
532  {
533  if (Pstream::master())
534  {
535  const bool oldParRun = Pstream::parRun(false);
536 
537  Info<< "Setting caseName to " << baseRunTime.caseName()
538  << " to write undecomposed cellDist" << endl;
539 
540  tm.caseName() = baseRunTime.caseName();
541  tm.processorCase(false);
542  writeDecomposition("cellDist", mesh, decomp);
543  Info<< "Restoring caseName to " << proc0CaseName << endl;
544  tm.caseName() = proc0CaseName;
545  tm.processorCase(oldProcCase);
546 
547  Pstream::parRun(oldParRun);
548  }
549  }
550  else
551  {
552  writeDecomposition("cellDist", mesh, decomp);
553  }
554  }
555 }
556 
557 
558 // Write addressing if decomposing (1 to many) or reconstructing (many to 1)
559 void writeProcAddressing
560 (
561  autoPtr<fileOperation>&& writeHandler,
562  const fvMesh& mesh,
563  const mapDistributePolyMesh& map,
564  const bool decompose
565 )
566 {
567  Info<< "Writing procAddressing files to " << mesh.facesInstance()
568  << endl;
569 
570  labelIOList cellMap
571  (
572  IOobject
573  (
574  "cellProcAddressing",
577  mesh,
579  ),
580  0
581  );
582 
584  (
585  IOobject
586  (
587  "faceProcAddressing",
590  mesh,
592  ),
593  0
594  );
595 
596  labelIOList pointMap
597  (
598  IOobject
599  (
600  "pointProcAddressing",
603  mesh,
605  ),
606  0
607  );
608 
609  labelIOList patchMap
610  (
611  IOobject
612  (
613  "boundaryProcAddressing",
616  mesh,
618  ),
619  0
620  );
621 
622  // Decomposing: see how cells moved from undecomposed case
623  if (decompose)
624  {
625  cellMap = identity(map.nOldCells());
626  map.distributeCellData(cellMap);
627 
628  faceMap = identity(map.nOldFaces());
629  {
630  const mapDistribute& faceDistMap = map.faceMap();
631 
632  if (faceDistMap.subHasFlip() || faceDistMap.constructHasFlip())
633  {
634  // Offset by 1
635  faceMap = faceMap + 1;
636  }
637  // Apply face flips
639  (
641  List<labelPair>(),
642  faceDistMap.constructSize(),
643  faceDistMap.subMap(),
644  faceDistMap.subHasFlip(),
645  faceDistMap.constructMap(),
646  faceDistMap.constructHasFlip(),
647  faceMap,
648  flipLabelOp()
649  );
650  }
651 
652  pointMap = identity(map.nOldPoints());
653  map.distributePointData(pointMap);
654 
655  patchMap = identity(map.oldPatchSizes().size());
656  const mapDistribute& patchDistMap = map.patchMap();
657  // Use explicit distribute since we need to provide a null value
658  // (for new patches) and this is the only call that allow us to
659  // provide one ...
661  (
663  List<labelPair>(),
664  patchDistMap.constructSize(),
665  patchDistMap.subMap(),
666  patchDistMap.subHasFlip(),
667  patchDistMap.constructMap(),
668  patchDistMap.constructHasFlip(),
669  patchMap,
670  label(-1),
671  eqOp<label>(),
672  flipOp(),
674  );
675  }
676  else // reconstruct
677  {
678  cellMap = identity(mesh.nCells());
679  map.cellMap().reverseDistribute(map.nOldCells(), cellMap);
680 
682  {
683  const mapDistribute& faceDistMap = map.faceMap();
684 
685  if (faceDistMap.subHasFlip() || faceDistMap.constructHasFlip())
686  {
687  // Offset by 1
688  faceMap = faceMap + 1;
689  }
690 
692  (
694  List<labelPair>(),
695  map.nOldFaces(),
696  faceDistMap.constructMap(),
697  faceDistMap.constructHasFlip(),
698  faceDistMap.subMap(),
699  faceDistMap.subHasFlip(),
700  faceMap,
701  flipLabelOp()
702  );
703  }
704 
705  pointMap = identity(mesh.nPoints());
706  map.pointMap().reverseDistribute(map.nOldPoints(), pointMap);
707 
708  const mapDistribute& patchDistMap = map.patchMap();
709  patchMap = identity(mesh.boundaryMesh().size());
710  patchDistMap.reverseDistribute
711  (
712  map.oldPatchSizes().size(),
713  label(-1),
714  patchMap
715  );
716  }
717 
718  autoPtr<fileOperation> defaultHandler;
719  if (writeHandler.valid())
720  {
721  defaultHandler = fileHandler(std::move(writeHandler));
722  }
723 
724  const bool cellOk = cellMap.write();
725  const bool faceOk = faceMap.write();
726  const bool pointOk = pointMap.write();
727  const bool patchOk = patchMap.write();
728 
729  if (defaultHandler.valid())
730  {
731  writeHandler = fileHandler(std::move(defaultHandler));
732  }
733 
734  if (!cellOk || !faceOk || !pointOk || !patchOk)
735  {
737  << "Failed to write " << cellMap.objectPath()
738  << ", " << faceMap.objectPath()
739  << ", " << pointMap.objectPath()
740  << ", " << patchMap.objectPath()
741  << endl;
742  }
743 }
744 
745 
746 // Remove addressing
747 void removeProcAddressing(const polyMesh& mesh)
748 {
749  for (const auto prefix : {"boundary", "cell", "face", "point"})
750  {
751  IOobject io
752  (
753  prefix + word("ProcAddressing"),
756  mesh
757  );
758 
759  const fileName procFile(io.objectPath());
760  rm(procFile);
761  }
762 }
763 
764 
765 // Generic mesh-based field reading
766 template<class GeoField>
767 void readField
768 (
769  const IOobject& io,
770  const fvMesh& mesh,
771  const label i,
773 )
774 {
775  fields.set(i, new GeoField(io, mesh));
776 }
777 
778 
779 // Definition of readField for GeometricFields only
780 template<class Type, template<class> class PatchField, class GeoMesh>
781 void readField
782 (
783  const IOobject& io,
784  const fvMesh& mesh,
785  const label i,
787 )
788 {
789  fields.set
790  (
791  i,
793  );
794 }
795 
796 
797 // Read vol or surface fields
798 template<class GeoField>
799 void readFields
800 (
801  const boolList& haveMesh,
802  const fvMesh& mesh,
803  const autoPtr<fvMeshSubset>& subsetterPtr,
804  IOobjectList& allObjects,
806 )
807 {
808  // Get my objects of type
809  IOobjectList objects(allObjects.lookupClass(GeoField::typeName));
810 
811  // Check that we all have all objects
812  wordList objectNames = objects.sortedNames();
813 
814  // Get master names
815  wordList masterNames(objectNames);
816  Pstream::scatter(masterNames);
817 
818  if (haveMesh[Pstream::myProcNo()] && objectNames != masterNames)
819  {
821  << "Objects not synchronised across processors." << nl
822  << "Master has " << flatOutput(masterNames) << nl
823  << "Processor " << Pstream::myProcNo()
824  << " has " << flatOutput(objectNames)
825  << exit(FatalError);
826  }
827 
828  fields.setSize(masterNames.size());
829 
830  // Have master send all fields to processors that don't have a mesh
831  if (Pstream::master())
832  {
833  forAll(masterNames, i)
834  {
835  const word& name = masterNames[i];
836  IOobject& io = *objects[name];
838 
839  // Load field (but not oldTime)
840  //const bool oldParRun = Pstream::parRun(false);
841  readField(io, mesh, i, fields);
842  //Pstream::parRun(oldParRun);
843 
844  // Create zero sized field and send
845  if (subsetterPtr)
846  {
847  const bool oldParRun = Pstream::parRun(false);
848  tmp<GeoField> tsubfld = subsetterPtr().interpolate(fields[i]);
849  Pstream::parRun(oldParRun);
850 
851  // Send to all processors that don't have a mesh
852  for (const int procI : Pstream::subProcs())
853  {
854  if (!haveMesh[procI])
855  {
857  toProc<< tsubfld();
858  }
859  }
860  }
861  }
862  }
863  else if (!haveMesh[Pstream::myProcNo()])
864  {
865  // Don't have mesh (nor fields). Receive empty field from master.
866 
867  forAll(masterNames, i)
868  {
869  const word& name = masterNames[i];
870 
871  // Receive field
872  IPstream fromMaster
873  (
876  );
877  dictionary fieldDict(fromMaster);
878 
879  fields.set
880  (
881  i,
882  new GeoField
883  (
884  IOobject
885  (
886  name,
887  mesh.time().timeName(),
888  mesh,
891  ),
892  mesh,
893  fieldDict
894  )
895  );
896 
898  //fields[i].write();
899  }
900  }
901  else
902  {
903  // Have mesh so just try to load
904  forAll(masterNames, i)
905  {
906  const word& name = masterNames[i];
907  IOobject& io = *objects[name];
909 
910  // Load field (but not oldtime)
911  readField(io, mesh, i, fields);
912  }
913  }
914 }
915 
916 
917 // Variant of GeometricField::correctBoundaryConditions that only
918 // evaluates selected patch fields
919 template<class GeoField, class CoupledPatchType>
920 void correctCoupledBoundaryConditions(fvMesh& mesh)
921 {
923  (
924  mesh.objectRegistry::lookupClass<GeoField>()
925  );
926 
927  forAllIters(flds, iter)
928  {
929  GeoField& fld = *iter();
930 
931  typename GeoField::Boundary& bfld = fld.boundaryFieldRef();
932  if
933  (
936  )
937  {
938  const label nReq = Pstream::nRequests();
939 
940  forAll(bfld, patchi)
941  {
942  auto& pfld = bfld[patchi];
943  const auto& fvp = mesh.boundary()[patchi];
944 
945  if (fvp.coupled() && !isA<cyclicACMIFvPatch>(fvp))
946  {
947  pfld.initEvaluate(Pstream::defaultCommsType);
948  }
949  }
950 
951  // Block for any outstanding requests
952  if
953  (
956  )
957  {
958  Pstream::waitRequests(nReq);
959  }
960 
961  for (auto& pfld : bfld)
962  {
963  const auto& fvp = pfld.patch();
964 
965  if (fvp.coupled() && !isA<cyclicACMIFvPatch>(fvp))
966  {
967  pfld.evaluate(Pstream::defaultCommsType);
968  }
969  }
970  }
972  {
973  const lduSchedule& patchSchedule =
974  fld.mesh().globalData().patchSchedule();
975 
976  forAll(patchSchedule, patchEvali)
977  {
978  const label patchi = patchSchedule[patchEvali].patch;
979  const auto& fvp = mesh.boundary()[patchi];
980  auto& pfld = bfld[patchi];
981 
982  if (fvp.coupled() && !isA<cyclicACMIFvPatch>(fvp))
983  {
984  if (patchSchedule[patchEvali].init)
985  {
986  pfld.initEvaluate(Pstream::commsTypes::scheduled);
987  }
988  else
989  {
990  pfld.evaluate(Pstream::commsTypes::scheduled);
991  }
992  }
993  }
994  }
995  else
996  {
998  << "Unsupported communications type "
1000  << exit(FatalError);
1001  }
1002  }
1003 }
1004 
1005 
1006 // Inplace redistribute mesh and any fields
1007 autoPtr<mapDistributePolyMesh> redistributeAndWrite
1008 (
1009  autoPtr<fileOperation>&& writeHandler,
1010  const Time& baseRunTime,
1011  const boolList& haveMesh,
1012  const fileName& meshSubDir,
1013  const bool doReadFields,
1014  const bool decompose, // decompose, i.e. read from undecomposed case
1015  const bool reconstruct,
1016  const bool overwrite,
1017  const fileName& proc0CaseName,
1018  const label nDestProcs,
1019  const labelList& decomp,
1020  const fileName& masterInstDir,
1021  fvMesh& mesh
1022 )
1023 {
1024  Time& runTime = const_cast<Time&>(mesh.time());
1025  const bool oldProcCase = runTime.processorCase();
1026 
1028  //Info<< "Before distribution:" << endl;
1029  //printMeshData(mesh);
1030 
1031 
1032  PtrList<volScalarField> volScalarFields;
1033  PtrList<volVectorField> volVectorFields;
1034  PtrList<volSphericalTensorField> volSphereTensorFields;
1035  PtrList<volSymmTensorField> volSymmTensorFields;
1036  PtrList<volTensorField> volTensorFields;
1037 
1038  PtrList<surfaceScalarField> surfScalarFields;
1039  PtrList<surfaceVectorField> surfVectorFields;
1040  PtrList<surfaceSphericalTensorField> surfSphereTensorFields;
1041  PtrList<surfaceSymmTensorField> surfSymmTensorFields;
1042  PtrList<surfaceTensorField> surfTensorFields;
1043 
1047  PtrList<DimensionedField<symmTensor, volMesh>> dimSymmTensorFields;
1049 
1050  DynamicList<word> pointFieldNames;
1051 
1052 
1053  if (doReadFields)
1054  {
1055  // Create 0 sized mesh to do all the generation of zero sized
1056  // fields on processors that have zero sized meshes. Note that this is
1057  // only necessary on master but since polyMesh construction with
1058  // Pstream::parRun does parallel comms we have to do it on all
1059  // processors
1060  autoPtr<fvMeshSubset> subsetterPtr;
1061 
1062  const bool allHaveMesh = !haveMesh.found(false);
1063  if (!allHaveMesh)
1064  {
1065  // Find last non-processor patch.
1067 
1068  const label nonProcI = (patches.nNonProcessor() - 1);
1069 
1070  if (nonProcI < 0)
1071  {
1073  << "Cannot find non-processor patch on processor "
1074  << Pstream::myProcNo() << nl
1075  << " Current patches:" << patches.names()
1076  << abort(FatalError);
1077  }
1078 
1079  // Subset 0 cells, no parallel comms.
1080  // This is used to create zero-sized fields.
1081  subsetterPtr.reset
1082  (
1083  new fvMeshSubset(mesh, bitSet(), nonProcI, false)
1084  );
1085  }
1086 
1087 
1088  // Get original objects (before incrementing time!)
1089  if (Pstream::master() && decompose)
1090  {
1091  runTime.caseName() = baseRunTime.caseName();
1092  runTime.processorCase(false);
1093  }
1094  IOobjectList objects(mesh, runTime.timeName());
1095  if (Pstream::master() && decompose)
1096  {
1097  runTime.caseName() = proc0CaseName;
1098  runTime.processorCase(oldProcCase);
1099  }
1100 
1101  Info<< "From time " << runTime.timeName()
1102  << " mesh:" << mesh.objectRegistry::objectPath()
1103  << " have objects:" << objects.names() << endl;
1104 
1105  // We don't want to map the decomposition (mapping already tested when
1106  // mapping the cell centre field)
1107  auto iter = objects.find("cellDist");
1108  if (iter.found())
1109  {
1110  objects.erase(iter);
1111  }
1112 
1113 
1114  // volFields
1115 
1116  if (Pstream::master() && decompose)
1117  {
1118  runTime.caseName() = baseRunTime.caseName();
1119  runTime.processorCase(false);
1120  }
1121  readFields
1122  (
1123  haveMesh,
1124  mesh,
1125  subsetterPtr,
1126  objects,
1127  volScalarFields
1128  );
1129 
1130  readFields
1131  (
1132  haveMesh,
1133  mesh,
1134  subsetterPtr,
1135  objects,
1136  volVectorFields
1137  );
1138 
1139  readFields
1140  (
1141  haveMesh,
1142  mesh,
1143  subsetterPtr,
1144  objects,
1145  volSphereTensorFields
1146  );
1147 
1148  readFields
1149  (
1150  haveMesh,
1151  mesh,
1152  subsetterPtr,
1153  objects,
1154  volSymmTensorFields
1155  );
1156 
1157  readFields
1158  (
1159  haveMesh,
1160  mesh,
1161  subsetterPtr,
1162  objects,
1163  volTensorFields
1164  );
1165 
1166 
1167  // surfaceFields
1168 
1169  readFields
1170  (
1171  haveMesh,
1172  mesh,
1173  subsetterPtr,
1174  objects,
1175  surfScalarFields
1176  );
1177 
1178  readFields
1179  (
1180  haveMesh,
1181  mesh,
1182  subsetterPtr,
1183  objects,
1184  surfVectorFields
1185  );
1186 
1187  readFields
1188  (
1189  haveMesh,
1190  mesh,
1191  subsetterPtr,
1192  objects,
1193  surfSphereTensorFields
1194  );
1195 
1196  readFields
1197  (
1198  haveMesh,
1199  mesh,
1200  subsetterPtr,
1201  objects,
1202  surfSymmTensorFields
1203  );
1204 
1205  readFields
1206  (
1207  haveMesh,
1208  mesh,
1209  subsetterPtr,
1210  objects,
1211  surfTensorFields
1212  );
1213 
1214 
1215  // Dimensioned internal fields
1216  readFields
1217  (
1218  haveMesh,
1219  mesh,
1220  subsetterPtr,
1221  objects,
1222  dimScalarFields
1223  );
1224 
1225  readFields
1226  (
1227  haveMesh,
1228  mesh,
1229  subsetterPtr,
1230  objects,
1231  dimVectorFields
1232  );
1233 
1234  readFields
1235  (
1236  haveMesh,
1237  mesh,
1238  subsetterPtr,
1239  objects,
1240  dimSphereTensorFields
1241  );
1242 
1243  readFields
1244  (
1245  haveMesh,
1246  mesh,
1247  subsetterPtr,
1248  objects,
1249  dimSymmTensorFields
1250  );
1251 
1252  readFields
1253  (
1254  haveMesh,
1255  mesh,
1256  subsetterPtr,
1257  objects,
1258  dimTensorFields
1259  );
1260 
1261 
1262  // pointFields currently not supported. Read their names so we
1263  // can delete them.
1264  {
1265  // Get my objects of type
1266  pointFieldNames.append
1267  (
1268  objects.lookupClass(pointScalarField::typeName).sortedNames()
1269  );
1270  pointFieldNames.append
1271  (
1272  objects.lookupClass(pointVectorField::typeName).sortedNames()
1273  );
1274  pointFieldNames.append
1275  (
1276  objects.lookupClass
1277  (
1278  pointSphericalTensorField::typeName
1279  ).sortedNames()
1280  );
1281  pointFieldNames.append
1282  (
1283  objects.lookupClass
1284  (
1285  pointSymmTensorField::typeName
1286  ).sortedNames()
1287  );
1288  pointFieldNames.append
1289  (
1290  objects.lookupClass(pointTensorField::typeName).sortedNames()
1291  );
1292 
1293  // Make sure all processors have the same set
1294  Pstream::scatter(pointFieldNames);
1295  }
1296 
1297  if (Pstream::master() && decompose)
1298  {
1299  runTime.caseName() = proc0CaseName;
1300  runTime.processorCase(oldProcCase);
1301  }
1302  }
1303 
1304 
1305  // Mesh distribution engine
1306  fvMeshDistribute distributor(mesh);
1307 
1308  // Do all the distribution of mesh and fields
1309  autoPtr<mapDistributePolyMesh> rawMap = distributor.distribute(decomp);
1310 
1311  // Print some statistics
1312  Info<< "After distribution:" << endl;
1313  printMeshData(mesh);
1314 
1315  // Get other side of processor boundaries
1316  correctCoupledBoundaryConditions
1317  <
1320  >(mesh);
1321  correctCoupledBoundaryConditions
1322  <
1325  >(mesh);
1326  correctCoupledBoundaryConditions
1327  <
1330  >(mesh);
1331  correctCoupledBoundaryConditions
1332  <
1335  >(mesh);
1336  correctCoupledBoundaryConditions
1337  <
1340  >(mesh);
1341  // No update surface fields
1342 
1343 
1344  // Set the minimum write precision
1346 
1347 
1348  if (!overwrite)
1349  {
1350  ++runTime;
1352  }
1353  else
1354  {
1355  mesh.setInstance(masterInstDir);
1356  }
1357 
1358 
1360  (
1361  IOobject
1362  (
1363  "procAddressing",
1364  mesh.facesInstance(),
1366  mesh,
1369  )
1370  );
1371  map.transfer(rawMap());
1372 
1373 
1374  if (reconstruct)
1375  {
1376  if (Pstream::master())
1377  {
1378  Info<< "Setting caseName to " << baseRunTime.caseName()
1379  << " to write reconstructed mesh and fields." << endl;
1380  runTime.caseName() = baseRunTime.caseName();
1381  const bool oldProcCase(runTime.processorCase(false));
1382  const bool oldParRun = Pstream::parRun(false);
1383 
1384  mesh.write();
1386  for (const word& fieldName : pointFieldNames)
1387  {
1388  IOobject io
1389  (
1390  fieldName,
1391  runTime.timeName(),
1392  mesh
1393  );
1394 
1395  const fileName fieldFile(io.objectPath());
1396  if (topoSet::debug) DebugVar(fieldFile);
1397  rm(fieldFile);
1398  }
1399  Pstream::parRun(oldParRun);
1400 
1401  // Now we've written all. Reset caseName on master
1402  Info<< "Restoring caseName to " << proc0CaseName << endl;
1403  runTime.caseName() = proc0CaseName;
1404  runTime.processorCase(oldProcCase);
1405  }
1406  }
1407  else
1408  {
1409  autoPtr<fileOperation> defaultHandler;
1410  if (writeHandler.valid())
1411  {
1412  defaultHandler = fileHandler(std::move(writeHandler));
1413  }
1414 
1415  mesh.write();
1416 
1417  if (defaultHandler.valid())
1418  {
1419  writeHandler = fileHandler(std::move(defaultHandler));
1420  }
1422  for (const word& fieldName : pointFieldNames)
1423  {
1424  IOobject io
1425  (
1426  fieldName,
1427  runTime.timeName(),
1428  mesh
1429  );
1430 
1431  const fileName fieldFile(io.objectPath());
1432  if (topoSet::debug) DebugVar(fieldFile);
1433  rm(fieldFile);
1434  }
1435  }
1436  Info<< "Written redistributed mesh to " << mesh.facesInstance() << nl
1437  << endl;
1438 
1439 
1440  if (decompose || reconstruct)
1441  {
1442  // Decompose (1 -> N) or reconstruct (N -> 1)
1443  // so {boundary,cell,face,point}ProcAddressing have meaning
1444  writeProcAddressing(std::move(writeHandler), mesh, map, decompose);
1445  }
1446  else
1447  {
1448  // Redistribute (N -> M)
1449  // {boundary,cell,face,point}ProcAddressing would be incorrect
1450  // - can either remove or redistribute previous
1451  removeProcAddressing(mesh);
1452  }
1453 
1454 
1455  // Refinement data
1456  {
1457 
1458  // Read refinement data
1459  if (Pstream::master() && decompose)
1460  {
1461  runTime.caseName() = baseRunTime.caseName();
1462  runTime.processorCase(false);
1463  }
1464  IOobject io
1465  (
1466  "dummy",
1467  mesh.facesInstance(),
1469  mesh,
1472  false
1473  );
1474 
1475  hexRef8Data refData(io);
1476  if (Pstream::master() && decompose)
1477  {
1478  runTime.caseName() = proc0CaseName;
1479  runTime.processorCase(oldProcCase);
1480  }
1481 
1482  // Make sure all processors have valid data (since only some will
1483  // read)
1484  refData.sync(io);
1485 
1486  // Distribute
1487  refData.distribute(map);
1488 
1489 
1490  // Now we've read refinement data we can remove it
1492 
1493  if (reconstruct)
1494  {
1495  if (Pstream::master())
1496  {
1497  const bool oldParRun = Pstream::parRun(false);
1498 
1499  Info<< "Setting caseName to " << baseRunTime.caseName()
1500  << " to write reconstructed refinement data." << endl;
1501  runTime.caseName() = baseRunTime.caseName();
1502  const bool oldProcCase(runTime.processorCase(false));
1503 
1504  refData.write();
1505 
1506  // Now we've written all. Reset caseName on master
1507  Info<< "Restoring caseName to " << proc0CaseName << endl;
1508  runTime.caseName() = proc0CaseName;
1509  runTime.processorCase(oldProcCase);
1510 
1511  Pstream::parRun(oldParRun);
1512  }
1513  }
1514  else
1515  {
1516  refData.write();
1517  }
1518  }
1519 
1521  //{
1522  // // Read sets
1523  // if (Pstream::master() && decompose)
1524  // {
1525  // runTime.caseName() = baseRunTime.caseName();
1526  // runTime.processorCase(false);
1527  // }
1528  // IOobjectList objects(mesh, mesh.facesInstance(), "polyMesh/sets");
1529  //
1530  // PtrList<cellSet> cellSets;
1531  // ReadFields(objects, cellSets);
1532  //
1533  // if (Pstream::master() && decompose)
1534  // {
1535  // runTime.caseName() = proc0CaseName;
1536  // runTime.processorCase(oldProcCase);
1537  // }
1538  //
1539  // forAll(cellSets, i)
1540  // {
1541  // cellSets[i].distribute(map);
1542  // }
1543  //
1544  // if (reconstruct)
1545  // {
1546  // if (Pstream::master())
1547  // {
1548  // Info<< "Setting caseName to " << baseRunTime.caseName()
1549  // << " to write reconstructed refinement data." << endl;
1550  // runTime.caseName() = baseRunTime.caseName();
1551  // const bool oldProcCase(runTime.processorCase(false));
1552  //
1553  // forAll(cellSets, i)
1554  // {
1555  // cellSets[i].distribute(map);
1556  // }
1557  //
1558  // // Now we've written all. Reset caseName on master
1559  // Info<< "Restoring caseName to " << proc0CaseName << endl;
1560  // runTime.caseName() = proc0CaseName;
1561  // runTime.processorCase(oldProcCase);
1562  // }
1563  // }
1564  // else
1565  // {
1566  // forAll(cellSets, i)
1567  // {
1568  // cellSets[i].distribute(map);
1569  // }
1570  // }
1571  //}
1572 
1573 
1574  return autoPtr<mapDistributePolyMesh>::New(std::move(map));
1575 }
1576 
1577 
1578 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1579 //
1580 // Field Mapping
1581 //
1582 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1583 
1584 autoPtr<mapDistributePolyMesh> createReconstructMap
1585 (
1586  const autoPtr<fvMesh>& baseMeshPtr,
1587  const fvMesh& mesh,
1588  const labelList& cellProcAddressing,
1590  const labelList& pointProcAddressing,
1591  const labelList& boundaryProcAddressing
1592 )
1593 {
1594  // Send addressing to master
1595  labelListList cellAddressing(Pstream::nProcs());
1596  cellAddressing[Pstream::myProcNo()] = cellProcAddressing;
1597  Pstream::gatherList(cellAddressing);
1598 
1599  labelListList faceAddressing(Pstream::nProcs());
1600  faceAddressing[Pstream::myProcNo()] = faceProcAddressing;
1601  Pstream::gatherList(faceAddressing);
1602 
1603  labelListList pointAddressing(Pstream::nProcs());
1604  pointAddressing[Pstream::myProcNo()] = pointProcAddressing;
1605  Pstream::gatherList(pointAddressing);
1606 
1607  labelListList boundaryAddressing(Pstream::nProcs());
1608  {
1609  // Remove -1 entries
1610  DynamicList<label> patchProcAddressing(boundaryProcAddressing.size());
1611  forAll(boundaryProcAddressing, i)
1612  {
1613  if (boundaryProcAddressing[i] != -1)
1614  {
1615  patchProcAddressing.append(boundaryProcAddressing[i]);
1616  }
1617  }
1618  boundaryAddressing[Pstream::myProcNo()] = patchProcAddressing;
1619  Pstream::gatherList(boundaryAddressing);
1620  }
1621 
1622 
1624 
1625  if (baseMeshPtr && baseMeshPtr->nCells())
1626  {
1627  const fvMesh& baseMesh = *baseMeshPtr;
1628 
1629  labelListList cellSubMap(Pstream::nProcs());
1630  cellSubMap[Pstream::masterNo()] = identity(mesh.nCells());
1631 
1632  mapDistribute cellMap
1633  (
1634  baseMesh.nCells(),
1635  std::move(cellSubMap),
1636  std::move(cellAddressing)
1637  );
1638 
1639  labelListList faceSubMap(Pstream::nProcs());
1640  faceSubMap[Pstream::masterNo()] = identity(mesh.nFaces());
1641 
1643  (
1644  baseMesh.nFaces(),
1645  std::move(faceSubMap),
1646  std::move(faceAddressing),
1647  false, //subHasFlip
1648  true //constructHasFlip
1649  );
1650 
1651  labelListList pointSubMap(Pstream::nProcs());
1652  pointSubMap[Pstream::masterNo()] = identity(mesh.nPoints());
1653 
1654  mapDistribute pointMap
1655  (
1656  baseMesh.nPoints(),
1657  std::move(pointSubMap),
1658  std::move(pointAddressing)
1659  );
1660 
1661  labelListList patchSubMap(Pstream::nProcs());
1662  // Send (filtered) patches to master
1663  patchSubMap[Pstream::masterNo()] =
1664  boundaryAddressing[Pstream::myProcNo()];
1665 
1666  mapDistribute patchMap
1667  (
1668  baseMesh.boundaryMesh().size(),
1669  std::move(patchSubMap),
1670  std::move(boundaryAddressing)
1671  );
1672 
1673  const label nOldPoints = mesh.nPoints();
1674  const label nOldFaces = mesh.nFaces();
1675  const label nOldCells = mesh.nCells();
1676 
1677  const polyBoundaryMesh& pbm = mesh.boundaryMesh();
1678  labelList oldPatchStarts(pbm.size());
1679  labelList oldPatchNMeshPoints(pbm.size());
1680  forAll(pbm, patchI)
1681  {
1682  oldPatchStarts[patchI] = pbm[patchI].start();
1683  oldPatchNMeshPoints[patchI] = pbm[patchI].nPoints();
1684  }
1685 
1686  mapPtr.reset
1687  (
1689  (
1690  nOldPoints,
1691  nOldFaces,
1692  nOldCells,
1693  std::move(oldPatchStarts),
1694  std::move(oldPatchNMeshPoints),
1695  std::move(pointMap),
1696  std::move(faceMap),
1697  std::move(cellMap),
1698  std::move(patchMap)
1699  )
1700  );
1701  }
1702  else
1703  {
1704  labelListList cellSubMap(Pstream::nProcs());
1705  cellSubMap[Pstream::masterNo()] = identity(mesh.nCells());
1706  labelListList cellConstructMap(Pstream::nProcs());
1707 
1708  mapDistribute cellMap
1709  (
1710  0,
1711  std::move(cellSubMap),
1712  std::move(cellConstructMap)
1713  );
1714 
1715  labelListList faceSubMap(Pstream::nProcs());
1716  faceSubMap[Pstream::masterNo()] = identity(mesh.nFaces());
1717  labelListList faceConstructMap(Pstream::nProcs());
1718 
1720  (
1721  0,
1722  std::move(faceSubMap),
1723  std::move(faceConstructMap),
1724  false, //subHasFlip
1725  true //constructHasFlip
1726  );
1727 
1728  labelListList pointSubMap(Pstream::nProcs());
1729  pointSubMap[Pstream::masterNo()] = identity(mesh.nPoints());
1730  labelListList pointConstructMap(Pstream::nProcs());
1731 
1732  mapDistribute pointMap
1733  (
1734  0,
1735  std::move(pointSubMap),
1736  std::move(pointConstructMap)
1737  );
1738 
1739  labelListList patchSubMap(Pstream::nProcs());
1740  // Send (filtered) patches to master
1741  patchSubMap[Pstream::masterNo()] =
1742  boundaryAddressing[Pstream::myProcNo()];
1743  labelListList patchConstructMap(Pstream::nProcs());
1744 
1745  mapDistribute patchMap
1746  (
1747  0,
1748  std::move(patchSubMap),
1749  std::move(patchConstructMap)
1750  );
1751 
1752  const label nOldPoints = mesh.nPoints();
1753  const label nOldFaces = mesh.nFaces();
1754  const label nOldCells = mesh.nCells();
1755 
1756  const polyBoundaryMesh& pbm = mesh.boundaryMesh();
1757  labelList oldPatchStarts(pbm.size());
1758  labelList oldPatchNMeshPoints(pbm.size());
1759  forAll(pbm, patchI)
1760  {
1761  oldPatchStarts[patchI] = pbm[patchI].start();
1762  oldPatchNMeshPoints[patchI] = pbm[patchI].nPoints();
1763  }
1764 
1765  mapPtr.reset
1766  (
1768  (
1769  nOldPoints,
1770  nOldFaces,
1771  nOldCells,
1772  std::move(oldPatchStarts),
1773  std::move(oldPatchNMeshPoints),
1774  std::move(pointMap),
1775  std::move(faceMap),
1776  std::move(cellMap),
1777  std::move(patchMap)
1778  )
1779  );
1780  }
1781 
1782  return mapPtr;
1783 }
1784 
1785 
1786 void readProcAddressing
1787 (
1788  const fvMesh& mesh,
1789  const autoPtr<fvMesh>& baseMeshPtr,
1791 )
1792 {
1793  //IOobject io
1794  //(
1795  // "procAddressing",
1796  // mesh.facesInstance(),
1797  // polyMesh::meshSubDir,
1798  // mesh,
1799  // IOobject::MUST_READ
1800  //);
1801  //if (io.typeHeaderOk<labelIOList>(true))
1802  //{
1803  // Pout<< "Reading addressing from " << io.name() << " at "
1804  // << mesh.facesInstance() << nl << endl;
1805  // distMap.reset(new IOmapDistributePolyMesh(io));
1806  //}
1807  //else
1808  {
1809  Info<< "Reading addressing from procXXXAddressing at "
1810  << mesh.facesInstance() << nl << endl;
1811  labelIOList cellProcAddressing
1812  (
1813  IOobject
1814  (
1815  "cellProcAddressing",
1816  mesh.facesInstance(),
1818  mesh,
1820  ),
1821  labelList()
1822  );
1824  (
1825  IOobject
1826  (
1827  "faceProcAddressing",
1828  mesh.facesInstance(),
1830  mesh,
1832  ),
1833  labelList()
1834  );
1835  labelIOList pointProcAddressing
1836  (
1837  IOobject
1838  (
1839  "pointProcAddressing",
1840  mesh.facesInstance(),
1842  mesh,
1844  ),
1845  labelList()
1846  );
1847  labelIOList boundaryProcAddressing
1848  (
1849  IOobject
1850  (
1851  "boundaryProcAddressing",
1852  mesh.facesInstance(),
1854  mesh,
1856  ),
1857  labelList()
1858  );
1859 
1860 
1861  if
1862  (
1863  mesh.nCells() != cellProcAddressing.size()
1864  || mesh.nPoints() != pointProcAddressing.size()
1865  || mesh.nFaces() != faceProcAddressing.size()
1866  || mesh.boundaryMesh().size() != boundaryProcAddressing.size()
1867  )
1868  {
1870  << "Read addressing inconsistent with mesh sizes" << nl
1871  << "cells:" << mesh.nCells()
1872  << " addressing:" << cellProcAddressing.objectPath()
1873  << " size:" << cellProcAddressing.size() << nl
1874  << "faces:" << mesh.nFaces()
1875  << " addressing:" << faceProcAddressing.objectPath()
1876  << " size:" << faceProcAddressing.size() << nl
1877  << "points:" << mesh.nPoints()
1878  << " addressing:" << pointProcAddressing.objectPath()
1879  << " size:" << pointProcAddressing.size()
1880  << "patches:" << mesh.boundaryMesh().size()
1881  << " addressing:" << boundaryProcAddressing.objectPath()
1882  << " size:" << boundaryProcAddressing.size()
1883  << exit(FatalError);
1884  }
1885 
1886  distMap.clear();
1887  distMap = createReconstructMap
1888  (
1889  baseMeshPtr,
1890  mesh,
1891  cellProcAddressing,
1893  pointProcAddressing,
1894  boundaryProcAddressing
1895  );
1896  }
1897 }
1898 
1899 
1900 void reconstructMeshFields
1901 (
1902  const parFvFieldReconstructor& fvReconstructor,
1903  const IOobjectList& objects,
1904  const wordRes& selectedFields
1905 )
1906 {
1907  // Dimensioned fields
1908 
1909  fvReconstructor.reconstructFvVolumeInternalFields<scalar>
1910  (
1911  objects,
1912  selectedFields
1913  );
1914  fvReconstructor.reconstructFvVolumeInternalFields<vector>
1915  (
1916  objects,
1917  selectedFields
1918  );
1920  (
1921  objects,
1922  selectedFields
1923  );
1925  (
1926  objects,
1927  selectedFields
1928  );
1929  fvReconstructor.reconstructFvVolumeInternalFields<tensor>
1930  (
1931  objects,
1932  selectedFields
1933  );
1934 
1935 
1936  // volFields
1937 
1938  fvReconstructor.reconstructFvVolumeFields<scalar>
1939  (
1940  objects,
1941  selectedFields
1942  );
1943  fvReconstructor.reconstructFvVolumeFields<vector>
1944  (
1945  objects,
1946  selectedFields
1947  );
1949  (
1950  objects,
1951  selectedFields
1952  );
1953  fvReconstructor.reconstructFvVolumeFields<symmTensor>
1954  (
1955  objects,
1956  selectedFields
1957  );
1958  fvReconstructor.reconstructFvVolumeFields<tensor>
1959  (
1960  objects,
1961  selectedFields
1962  );
1963 
1964 
1965  // surfaceFields
1966 
1967  fvReconstructor.reconstructFvSurfaceFields<scalar>
1968  (
1969  objects,
1970  selectedFields
1971  );
1972  fvReconstructor.reconstructFvSurfaceFields<vector>
1973  (
1974  objects,
1975  selectedFields
1976  );
1978  (
1979  objects,
1980  selectedFields
1981  );
1982  fvReconstructor.reconstructFvSurfaceFields<symmTensor>
1983  (
1984  objects,
1985  selectedFields
1986  );
1987  fvReconstructor.reconstructFvSurfaceFields<tensor>
1988  (
1989  objects,
1990  selectedFields
1991  );
1992 }
1993 
1994 
1995 void reconstructLagrangian
1996 (
1997  autoPtr<parLagrangianRedistributor>& lagrangianReconstructorPtr,
1998  const fvMesh& baseMesh,
1999  const fvMesh& mesh,
2000  const mapDistributePolyMesh& distMap,
2001  const wordRes& selectedLagrangianFields
2002 )
2003 {
2004  // Clouds (note: might not be present on all processors)
2005 
2006  wordList cloudNames;
2008  // Find all cloudNames on all processors
2010 
2011  if (cloudNames.size())
2012  {
2013  if (!lagrangianReconstructorPtr)
2014  {
2015  lagrangianReconstructorPtr.reset
2016  (
2018  (
2019  mesh,
2020  baseMesh,
2021  mesh.nCells(), // range of cell indices in clouds
2022  distMap
2023  )
2024  );
2025  }
2027  *lagrangianReconstructorPtr;
2028 
2029  for (const word& cloudName : cloudNames)
2030  {
2031  Info<< "Reconstructing lagrangian fields for cloud "
2032  << cloudName << nl << endl;
2033 
2034  autoPtr<mapDistributeBase> lagrangianMapPtr =
2035  lagrangianReconstructor.redistributeLagrangianPositions
2036  (
2037  cloudName
2038  );
2039 
2040  const mapDistributeBase& lagrangianMap = *lagrangianMapPtr;
2041 
2042  IOobjectList cloudObjs
2043  (
2044  mesh,
2045  mesh.time().timeName(),
2047  );
2048 
2049  lagrangianReconstructor.redistributeFields<label>
2050  (
2051  lagrangianMap,
2052  cloudName,
2053  cloudObjs,
2054  selectedLagrangianFields
2055  );
2056  lagrangianReconstructor.redistributeFieldFields<label>
2057  (
2058  lagrangianMap,
2059  cloudName,
2060  cloudObjs,
2061  selectedLagrangianFields
2062  );
2063  lagrangianReconstructor.redistributeFields<scalar>
2064  (
2065  lagrangianMap,
2066  cloudName,
2067  cloudObjs,
2068  selectedLagrangianFields
2069  );
2070  lagrangianReconstructor.redistributeFieldFields<scalar>
2071  (
2072  lagrangianMap,
2073  cloudName,
2074  cloudObjs,
2075  selectedLagrangianFields
2076  );
2077  lagrangianReconstructor.redistributeFields<vector>
2078  (
2079  lagrangianMap,
2080  cloudName,
2081  cloudObjs,
2082  selectedLagrangianFields
2083  );
2084  lagrangianReconstructor.redistributeFieldFields<vector>
2085  (
2086  lagrangianMap,
2087  cloudName,
2088  cloudObjs,
2089  selectedLagrangianFields
2090  );
2091  lagrangianReconstructor.redistributeFields
2092  <sphericalTensor>
2093  (
2094  lagrangianMap,
2095  cloudName,
2096  cloudObjs,
2097  selectedLagrangianFields
2098  );
2099  lagrangianReconstructor.redistributeFieldFields
2100  <sphericalTensor>
2101  (
2102  lagrangianMap,
2103  cloudName,
2104  cloudObjs,
2105  selectedLagrangianFields
2106  );
2107  lagrangianReconstructor.redistributeFields<symmTensor>
2108  (
2109  lagrangianMap,
2110  cloudName,
2111  cloudObjs,
2112  selectedLagrangianFields
2113  );
2114  lagrangianReconstructor.redistributeFieldFields
2115  <symmTensor>
2116  (
2117  lagrangianMap,
2118  cloudName,
2119  cloudObjs,
2120  selectedLagrangianFields
2121  );
2122  lagrangianReconstructor.redistributeFields<tensor>
2123  (
2124  lagrangianMap,
2125  cloudName,
2126  cloudObjs,
2127  selectedLagrangianFields
2128  );
2129  lagrangianReconstructor.redistributeFieldFields<tensor>
2130  (
2131  lagrangianMap,
2132  cloudName,
2133  cloudObjs,
2134  selectedLagrangianFields
2135  );
2136  }
2137  }
2138 }
2139 
2140 
2141 // Read clouds (note: might not be present on all processors)
2142 void readLagrangian
2143 (
2144  const fvMesh& mesh,
2145  const wordList& cloudNames,
2146  const wordRes& selectedLagrangianFields,
2148 )
2149 {
2150  (void)mesh.tetBasePtIs();
2151 
2152  forAll(cloudNames, i)
2153  {
2154  //Pout<< "Loading cloud " << cloudNames[i] << endl;
2155  clouds.set
2156  (
2157  i,
2158  new unmappedPassivePositionParticleCloud(mesh, cloudNames[i], false)
2159  );
2160 
2161 
2162  //for (passivePositionParticle& p : clouds[i]))
2163  //{
2164  // Pout<< "Particle position:" << p.position()
2165  // << " cell:" << p.cell()
2166  // << " with cc:" << mesh.cellCentres()[p.cell()]
2167  // << endl;
2168  //}
2169 
2170 
2171  IOobjectList cloudObjs(clouds[i], clouds[i].time().timeName());
2172 
2173  //Pout<< "Found clould objects:" << cloudObjs.names() << endl;
2174 
2176  <IOField<label>>
2177  (
2178  clouds[i],
2179  cloudObjs,
2180  selectedLagrangianFields
2181  );
2184  (
2185  clouds[i],
2186  cloudObjs,
2187  selectedLagrangianFields
2188  );
2190  <CompactIOField<Field<label>, label>>
2191  (
2192  clouds[i],
2193  cloudObjs,
2194  selectedLagrangianFields
2195  );
2196 
2197 
2199  <IOField<scalar>>
2200  (
2201  clouds[i],
2202  cloudObjs,
2203  selectedLagrangianFields
2204  );
2207  (
2208  clouds[i],
2209  cloudObjs,
2210  selectedLagrangianFields
2211  );
2213  <CompactIOField<Field<scalar>, scalar>>
2214  (
2215  clouds[i],
2216  cloudObjs,
2217  selectedLagrangianFields
2218  );
2219 
2220 
2222  <IOField<vector>>
2223  (
2224  clouds[i],
2225  cloudObjs,
2226  selectedLagrangianFields
2227  );
2230  (
2231  clouds[i],
2232  cloudObjs,
2233  selectedLagrangianFields
2234  );
2237  (
2238  clouds[i],
2239  cloudObjs,
2240  selectedLagrangianFields
2241  );
2242 
2243 
2246  (
2247  clouds[i],
2248  cloudObjs,
2249  selectedLagrangianFields
2250  );
2253  (
2254  clouds[i],
2255  cloudObjs,
2256  selectedLagrangianFields
2257  );
2260  (
2261  clouds[i],
2262  cloudObjs,
2263  selectedLagrangianFields
2264  );
2265 
2266 
2269  (
2270  clouds[i],
2271  cloudObjs,
2272  selectedLagrangianFields
2273  );
2276  (
2277  clouds[i],
2278  cloudObjs,
2279  selectedLagrangianFields
2280  );
2283  (
2284  clouds[i],
2285  cloudObjs,
2286  selectedLagrangianFields
2287  );
2288 
2289 
2291  <IOField<tensor>>
2292  (
2293  clouds[i],
2294  cloudObjs,
2295  selectedLagrangianFields
2296  );
2299  (
2300  clouds[i],
2301  cloudObjs,
2302  selectedLagrangianFields
2303  );
2306  (
2307  clouds[i],
2308  cloudObjs,
2309  selectedLagrangianFields
2310  );
2311  }
2312 }
2313 
2314 
2315 void redistributeLagrangian
2316 (
2317  autoPtr<parLagrangianRedistributor>& lagrangianReconstructorPtr,
2318  const fvMesh& mesh,
2319  const label nOldCells,
2320  const mapDistributePolyMesh& distMap,
2322 )
2323 {
2324  if (clouds.size())
2325  {
2326  if (!lagrangianReconstructorPtr)
2327  {
2328  lagrangianReconstructorPtr.reset
2329  (
2331  (
2332  mesh,
2333  mesh,
2334  nOldCells, // range of cell indices in clouds
2335  distMap
2336  )
2337  );
2338  }
2339  const parLagrangianRedistributor& distributor =
2340  lagrangianReconstructorPtr();
2341 
2342  forAll(clouds, i)
2343  {
2344  autoPtr<mapDistributeBase> lagrangianMapPtr =
2345  distributor.redistributeLagrangianPositions(clouds[i]);
2346  const mapDistributeBase& lagrangianMap = *lagrangianMapPtr;
2347 
2348  distributor.redistributeStoredFields
2349  <IOField<label>>
2350  (
2351  lagrangianMap,
2352  clouds[i]
2353  );
2354  distributor.redistributeStoredFields
2356  (
2357  lagrangianMap,
2358  clouds[i]
2359  );
2360  distributor.redistributeStoredFields
2361  <CompactIOField<Field<label>, label>>
2362  (
2363  lagrangianMap,
2364  clouds[i]
2365  );
2366 
2367 
2368  distributor.redistributeStoredFields
2369  <IOField<scalar>>
2370  (
2371  lagrangianMap,
2372  clouds[i]
2373  );
2374  distributor.redistributeStoredFields
2376  (
2377  lagrangianMap,
2378  clouds[i]
2379  );
2380  distributor.redistributeStoredFields
2381  <CompactIOField<Field<scalar>, scalar>>
2382  (
2383  lagrangianMap,
2384  clouds[i]
2385  );
2386 
2387 
2388  distributor.redistributeStoredFields
2389  <IOField<vector>>
2390  (
2391  lagrangianMap,
2392  clouds[i]
2393  );
2394  distributor.redistributeStoredFields
2396  (
2397  lagrangianMap,
2398  clouds[i]
2399  );
2400  distributor.redistributeStoredFields
2402  (
2403  lagrangianMap,
2404  clouds[i]
2405  );
2406 
2407 
2408  distributor.redistributeStoredFields
2410  (
2411  lagrangianMap,
2412  clouds[i]
2413  );
2414  distributor.redistributeStoredFields
2416  (
2417  lagrangianMap,
2418  clouds[i]
2419  );
2420  distributor.redistributeStoredFields
2422  (
2423  lagrangianMap,
2424  clouds[i]
2425  );
2426 
2427 
2428  distributor.redistributeStoredFields
2430  (
2431  lagrangianMap,
2432  clouds[i]
2433  );
2434  distributor.redistributeStoredFields
2436  (
2437  lagrangianMap,
2438  clouds[i]
2439  );
2440  distributor.redistributeStoredFields
2442  (
2443  lagrangianMap,
2444  clouds[i]
2445  );
2446 
2447 
2448  distributor.redistributeStoredFields
2449  <IOField<tensor>>
2450  (
2451  lagrangianMap,
2452  clouds[i]
2453  );
2454  distributor.redistributeStoredFields
2456  (
2457  lagrangianMap,
2458  clouds[i]
2459  );
2460  distributor.redistributeStoredFields
2462  (
2463  lagrangianMap,
2464  clouds[i]
2465  );
2466  }
2467  }
2468 }
2469 
2470 
2471 int main(int argc, char *argv[])
2472 {
2474  (
2475  "Redistribute decomposed mesh and fields according"
2476  " to the decomposeParDict settings.\n"
2477  "Optionally run in decompose/reconstruct mode"
2478  );
2479 
2480  argList::noFunctionObjects(); // Never use function objects
2481 
2482  // enable -constant ... if someone really wants it
2483  // enable -zeroTime to prevent accidentally trashing the initial fields
2484  timeSelector::addOptions(true, true);
2485 
2486  #include "addAllRegionOptions.H"
2487 
2488  #include "addOverwriteOption.H"
2489  argList::addBoolOption("decompose", "Decompose case");
2490  argList::addBoolOption("reconstruct", "Reconstruct case");
2492  (
2493  "Test without writing the decomposition. "
2494  "Changes -cellDist to only write volScalarField."
2495  );
2497  (
2498  "cellDist",
2499  "Write cell distribution as a labelList - for use with 'manual' "
2500  "decomposition method or as a volScalarField for post-processing."
2501  );
2503  (
2504  "newTimes",
2505  "Only reconstruct new times (i.e. that do not exist already)"
2506  );
2507 
2508 
2509  // Handle arguments
2510  // ~~~~~~~~~~~~~~~~
2511  // (replacement for setRootCase that does not abort)
2512 
2513  argList args(argc, argv);
2514 
2515 
2516  // As much as possible avoid synchronised operation. To be looked at more
2517  // closely for the three scenarios:
2518  // - decompose - reads on master (and from parent directory) and sends
2519  // dictionary to slaves
2520  // - distribute - reads on potentially a different number of processors
2521  // than it writes to
2522  // - reconstruct - reads parallel, write on master only and to parent
2523  // directory
2524  autoPtr<fileOperation> writeHandler;
2525  if
2526  (
2527  fileHandler().type()
2528  != fileOperations::uncollatedFileOperation::typeName
2529  )
2530  {
2531  // Install 'uncollated' as fileHandler. Save old one in writeHandler.
2532  writeHandler = fileHandler(fileOperation::NewUncollated());
2533  }
2534 
2535  // Switch off parallel synchronisation of cached time directories
2536  fileHandler().distributed(true);
2537 
2538  // File handler to be used for writing
2539  const fileOperation& fh
2540  (
2541  writeHandler.valid()
2542  ? writeHandler()
2543  : fileHandler()
2544  );
2545 
2546 
2547 
2548  // Make sure to call findTimes on all processors to force caching of
2549  // time directories
2550  (void)fileHandler().findTimes(args.path(), "constant");
2551 
2552 
2553  #include "foamDlOpenLibs.H"
2554 
2555  const bool reconstruct = args.found("reconstruct");
2556  const bool writeCellDist = args.found("cellDist");
2557  const bool dryrun = args.dryRun();
2558  const bool newTimes = args.found("newTimes");
2559 
2560  bool decompose = args.found("decompose");
2561  bool overwrite = args.found("overwrite");
2562 
2563  // Disable NaN setting and floating point error trapping. This is to avoid
2564  // any issues inside the field redistribution inside fvMeshDistribute
2565  // which temporarily moves processor faces into existing patches. These
2566  // will now not have correct values. After all bits have been assembled
2567  // the processor fields will be restored but until then there might
2568  // be uninitialised values which might upset some patch field constructors.
2569  // Workaround by disabling floating point error trapping. TBD: have
2570  // actual field redistribution instead of subsetting inside
2571  // fvMeshDistribute.
2572  Foam::sigFpe::unset(true);
2573 
2574  const wordRes selectedFields;
2575  const wordRes selectedLagrangianFields;
2576 
2577 
2578  if (decompose)
2579  {
2580  Info<< "Decomposing case (like decomposePar)" << nl << endl;
2581  if (reconstruct)
2582  {
2584  << "Cannot specify both -decompose and -reconstruct"
2585  << exit(FatalError);
2586  }
2587  }
2588  else if (reconstruct)
2589  {
2590  Info<< "Reconstructing case (like reconstructParMesh)" << nl << endl;
2591  }
2592 
2593 
2594  if (decompose || reconstruct)
2595  {
2596  if (!overwrite)
2597  {
2599  << "Working in decompose or reconstruction mode automatically"
2600  << " implies -overwrite" << nl << endl;
2601  overwrite = true;
2602  }
2603  }
2604 
2605 
2606  if (!Pstream::parRun())
2607  {
2609  << ": This utility can only be run parallel"
2610  << exit(FatalError);
2611  }
2612 
2613 
2614  if (!isDir(args.rootPath()))
2615  {
2617  << ": cannot open root directory " << args.rootPath()
2618  << exit(FatalError);
2619  }
2620 
2621  // Detect if running data-distributed (multiple roots)
2622  bool nfs = true;
2623  {
2624  List<fileName> roots(1, args.rootPath());
2626  nfs = (roots.size() == 1);
2627  }
2628 
2629  if (!nfs)
2630  {
2631  Info<< "Detected multiple roots i.e. non-nfs running"
2632  << nl << endl;
2633  }
2634 
2635  // Check if we have processor directories. Ideally would like to
2636  // use fileHandler().dirPath here but we don't have runTime yet and
2637  // want to delay constructing runTime until we've synced all time
2638  // directories...
2639  const fileName procDir(fileHandler().filePath(args.path()));
2640  if (isDir(procDir))
2641  {
2642  if (decompose)
2643  {
2644  Info<< "Removing existing processor directory" << procDir << endl;
2645  fileHandler().rmDir(procDir);
2646  }
2647  }
2648  else
2649  {
2650  // Directory does not exist. If this happens on master -> decompose mode
2651  if (Pstream::master())
2652  {
2653  decompose = true;
2654  Info<< "No processor directories; switching on decompose mode"
2655  << nl << endl;
2656  }
2657  }
2658  // If master changed to decompose mode make sure all nodes know about it
2659  Pstream::scatter(decompose);
2660 
2661 
2662  // If running distributed we have problem of new processors not finding
2663  // a system/controlDict. However if we switch on the master-only reading
2664  // the problem becomes that the time directories are differing sizes and
2665  // e.g. latestTime will pick up a different time (which causes createTime.H
2666  // to abort). So for now make sure to have master times on all
2667  // processors
2668  if (!reconstruct)
2669  {
2670  Info<< "Creating time directories on all processors" << nl << endl;
2671  createTimeDirs(args.path());
2672  }
2673 
2674  // Construct time
2675  // ~~~~~~~~~~~~~~
2676 
2677  #include "createTime.H"
2678  runTime.functionObjects().off(); // Extra safety?
2679 
2680 
2681  // Save local processor0 casename
2682  const fileName proc0CaseName = runTime.caseName();
2683  const bool oldProcCase = runTime.processorCase();
2684 
2685 
2686  // Construct undecomposed Time
2687  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
2688  // This will read the same controlDict but might have a different
2689  // set of times so enforce same times
2690 
2691  if (!nfs)
2692  {
2693  Info<< "Creating time directories for undecomposed Time"
2694  << " on all processors" << nl << endl;
2695  createTimeDirs(args.globalPath());
2696  }
2697 
2698 
2699  Info<< "Create undecomposed database"<< nl << endl;
2700  Time baseRunTime
2701  (
2702  runTime.controlDict(),
2703  runTime.rootPath(),
2705  runTime.system(),
2706  runTime.constant(),
2707  false // enableFunctionObjects
2708  );
2709 
2710 
2711  wordHashSet masterTimeDirSet;
2712  if (newTimes)
2713  {
2714  instantList baseTimeDirs(baseRunTime.times());
2715  for (const instant& t : baseTimeDirs)
2716  {
2717  masterTimeDirSet.insert(t.name());
2718  }
2719  }
2720 
2721 
2722  // Allow override of decomposeParDict location
2723  const fileName decompDictFile =
2724  args.getOrDefault<fileName>("decomposeParDict", "");
2725 
2726  // Get region names
2727  #include "getAllRegionOptions.H"
2728 
2729  if (regionNames.size() == 1 && regionNames[0] != polyMesh::defaultRegion)
2730  {
2731  Info<< "Using region: " << regionNames[0] << nl << endl;
2732  }
2733 
2734 
2735  // Demand driven lagrangian mapper
2736  autoPtr<parLagrangianRedistributor> lagrangianReconstructorPtr;
2737 
2738 
2739  if (reconstruct)
2740  {
2741  // use the times list from the master processor
2742  // and select a subset based on the command-line options
2744  Pstream::scatter(timeDirs);
2745 
2746  if (timeDirs.empty())
2747  {
2749  << "No times selected"
2750  << exit(FatalError);
2751  }
2752 
2753 
2754  // Pass1 : reconstruct mesh and addressing
2755  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2756 
2757 
2758  Info<< nl
2759  << "Pass1 : reconstructing mesh and addressing" << nl << endl;
2760 
2761 
2762  forAll(regionNames, regioni)
2763  {
2764  const word& regionName = regionNames[regioni];
2765  const word& regionDir =
2766  (
2768  );
2769  const fileName meshSubDir(regionDir/polyMesh::meshSubDir);
2770 
2771  Info<< "\n\nReconstructing mesh " << regionName << nl << endl;
2772 
2773  // Loop over all times
2774  forAll(timeDirs, timeI)
2775  {
2776  // Set time for global database
2777  runTime.setTime(timeDirs[timeI], timeI);
2778  baseRunTime.setTime(timeDirs[timeI], timeI);
2779 
2780  Info<< "Time = " << runTime.timeName() << endl << endl;
2781 
2782 
2783  // See where the mesh is
2784  fileName facesInstance = runTime.findInstance
2785  (
2786  meshSubDir,
2787  "faces",
2789  );
2790  //Pout<< "facesInstance:" << facesInstance << endl;
2791 
2792  Pstream::scatter(facesInstance);
2793 
2794  // Check who has a mesh (by checking for 'faces' file)
2795  const boolList haveMesh
2796  (
2797  haveFacesFile
2798  (
2799  runTime.path()/facesInstance/meshSubDir
2800  )
2801  );
2802 
2803 
2804  // Addressing back to reconstructed mesh as xxxProcAddressing.
2805  // - all processors have consistent faceProcAddressing
2806  // - processors with no mesh don't need faceProcAddressing
2807 
2808 
2809  // Note: filePath searches up on processors that don't have
2810  // processor if instance = constant so explicitly check
2811  // found filename.
2812  bool haveAddressing = false;
2813  if (haveMesh[Pstream::myProcNo()])
2814  {
2815  // Read faces (just to know their size)
2816  faceCompactIOList faces
2817  (
2818  IOobject
2819  (
2820  "faces",
2821  facesInstance,
2822  meshSubDir,
2823  runTime,
2825  )
2826  );
2827 
2828  // Check faceProcAddressing
2830  (
2831  IOobject
2832  (
2833  "faceProcAddressing",
2834  facesInstance,
2835  meshSubDir,
2836  runTime,
2838  ),
2839  labelList()
2840  );
2841  if
2842  (
2843  faceProcAddressing.headerOk()
2844  && faceProcAddressing.size() == faces.size()
2845  )
2846  {
2847  haveAddressing = true;
2848  }
2849  }
2850  else
2851  {
2852  // Have no mesh. Don't need addressing
2853  haveAddressing = true;
2854  }
2855 
2856 
2857  // Additionally check for master faces being readable. Could
2858  // do even more checks, e.g. global number of cells same
2859  // as cellProcAddressing
2860  bool haveUndecomposedMesh = false;
2861  if (Pstream::master())
2862  {
2863  Info<< "Checking " << baseRunTime.caseName()
2864  << " for undecomposed mesh" << endl;
2865 
2866  const bool oldParRun = Pstream::parRun(false);
2867  faceCompactIOList facesIO
2868  (
2869  IOobject
2870  (
2871  "faces",
2872  facesInstance,
2873  meshSubDir,
2874  baseRunTime,
2876  )
2877  );
2878  haveUndecomposedMesh = facesIO.headerOk();
2879  Pstream::parRun(oldParRun);
2880  }
2881  Pstream::scatter(haveUndecomposedMesh);
2882 
2883 
2884  if
2885  (
2886  !haveUndecomposedMesh
2887  || !returnReduce(haveAddressing, andOp<bool>())
2888  )
2889  {
2890  Info<< "loading mesh from " << facesInstance << endl;
2892  (
2893  decompose,
2894  IOobject
2895  (
2896  regionName,
2897  facesInstance,
2898  runTime,
2900  )
2901  );
2902  fvMesh& mesh = meshPtr();
2903 
2904  // Use basic geometry calculation to avoid synchronisation
2905  // problems. See comment in routine
2906  setBasicGeometry(mesh);
2907 
2908 
2909  // Determine decomposition
2910  // ~~~~~~~~~~~~~~~~~~~~~~~
2911 
2912  Info<< "Reconstructing mesh for time " << facesInstance
2913  << endl;
2914 
2915  label nDestProcs = 1;
2916  labelList finalDecomp = labelList(mesh.nCells(), Zero);
2917 
2918  redistributeAndWrite
2919  (
2920  std::move(writeHandler),
2921  baseRunTime,
2922  haveMesh,
2923  meshSubDir,
2924  false, // do not read fields
2925  false, // do not read undecomposed case on proc0
2926  true, // write redistributed files to proc0
2927  overwrite,
2928  proc0CaseName,
2929  nDestProcs,
2930  finalDecomp,
2931  facesInstance,
2932  mesh
2933  );
2934  }
2935  }
2936 
2937  // Make sure all is finished writing until re-reading in pass2
2938  // below
2939  fileHandler().flush();
2940 
2941 
2942  // Pass2 : read mesh and addressing and reconstruct fields
2943  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2944 
2945  Info<< nl
2946  << "Pass2 : reconstructing fields" << nl << endl;
2947 
2948  runTime.setTime(timeDirs[0], 0);
2949  baseRunTime.setTime(timeDirs[0], 0);
2950  Info<< "Time = " << runTime.timeName() << endl << endl;
2951 
2952 
2953  // Read undecomposed mesh on master and 'empty' mesh
2954  // (zero faces, point, cells but valid patches and zones) on slaves.
2955  // This is a bit of tricky code and hidden inside fvMeshTools for
2956  // now.
2957  Info<< "Reading undecomposed mesh (on master)" << endl;
2959  (
2960  IOobject
2961  (
2962  regionName,
2963  baseRunTime.timeName(),
2964  baseRunTime,
2966  ),
2967  true // read on master only
2968  );
2969 
2970  setBasicGeometry(baseMeshPtr());
2971 
2972 
2973  Info<< "Reading local, decomposed mesh" << endl;
2975  (
2976  decompose,
2977  IOobject
2978  (
2979  regionName,
2980  baseMeshPtr().facesInstance(),
2981  runTime,
2983  )
2984  );
2985  fvMesh& mesh = meshPtr();
2986 
2987  if (writeHandler.valid() && Pstream::master())
2988  {
2989  // Remove any left-over empty processor directories created
2990  // by loadOrCreateMesh to get around e.g. collated start-up
2991  // problems. Should not happen in reconstruct mode ...
2992  const bool oldParRun = Pstream::parRun(false);
2994  Pstream::parRun(oldParRun);
2995  }
2996 
2997 
2998  // Read addressing back to base mesh
3000  readProcAddressing(mesh, baseMeshPtr, distMap);
3001 
3002  // Construct field mapper
3003  autoPtr<parFvFieldReconstructor> fvReconstructorPtr
3004  (
3006  (
3007  baseMeshPtr(),
3008  mesh,
3009  distMap(),
3010  Pstream::master() // do I need to write?
3011  )
3012  );
3013 
3014 
3015 
3016  // Since we start from Times[0] and not runTime.timeName() we
3017  // might overlook point motion in the first timestep
3018  // (since mesh.readUpdate() below will not be triggered). Instead
3019  // detect points by hand
3021  {
3022  Info<< " Detected initial mesh motion;"
3023  << " reconstructing points" << nl
3024  << endl;
3025  fvReconstructorPtr().reconstructPoints();
3026  }
3027 
3028 
3029  // Loop over all times
3030  forAll(timeDirs, timeI)
3031  {
3032  if (newTimes && masterTimeDirSet.found(timeDirs[timeI].name()))
3033  {
3034  Info<< "Skipping time " << timeDirs[timeI].name()
3035  << endl << endl;
3036  continue;
3037  }
3038 
3039  // Set time for global database
3040  runTime.setTime(timeDirs[timeI], timeI);
3041  baseRunTime.setTime(timeDirs[timeI], timeI);
3042 
3043  Info<< "Time = " << runTime.timeName() << endl << endl;
3044 
3045 
3046  // Check if any new meshes need to be read.
3048 
3049  if (procStat == fvMesh::POINTS_MOVED)
3050  {
3051  Info<< " Dected mesh motion; reconstructing points" << nl
3052  << endl;
3053  fvReconstructorPtr().reconstructPoints();
3054  }
3055  else if
3056  (
3057  procStat == fvMesh::TOPO_CHANGE
3058  || procStat == fvMesh::TOPO_PATCH_CHANGE
3059  )
3060  {
3061  Info<< " Detected topology change;"
3062  << " reconstructing addressing" << nl << endl;
3063 
3064  if (baseMeshPtr)
3065  {
3066  // Cannot do a baseMesh::readUpdate() since not all
3067  // processors will have mesh files. So instead just
3068  // recreate baseMesh
3069  baseMeshPtr.clear();
3070  baseMeshPtr = fvMeshTools::newMesh
3071  (
3072  IOobject
3073  (
3074  regionName,
3075  baseRunTime.timeName(),
3076  baseRunTime,
3078  ),
3079  true // read on master only
3080  );
3081  }
3082 
3083  // Re-read procXXXaddressing
3084  readProcAddressing(mesh, baseMeshPtr, distMap);
3085 
3086  // Reset field mapper
3087  fvReconstructorPtr.reset
3088  (
3090  (
3091  baseMeshPtr(),
3092  mesh,
3093  distMap(),
3094  Pstream::master()
3095  )
3096  );
3097  lagrangianReconstructorPtr.clear();
3098  }
3099 
3100 
3101  // Get list of objects
3102  IOobjectList objects(mesh, runTime.timeName());
3103 
3104 
3105  // Mesh fields (vol, surface, volInternal)
3106  reconstructMeshFields
3107  (
3108  fvReconstructorPtr(),
3109  objects,
3110  selectedFields
3111  );
3112 
3113  // Clouds (note: might not be present on all processors)
3114  reconstructLagrangian
3115  (
3116  lagrangianReconstructorPtr,
3117  baseMeshPtr(),
3118  mesh,
3119  distMap(),
3120  selectedLagrangianFields
3121  );
3122 
3123  // If there are any "uniform" directories copy them from
3124  // the master processor
3125  copyUniform
3126  (
3127  fh,
3128  decompose,
3129  reconstruct,
3130  mesh.time().timeName(),
3131  mesh,
3132  baseMeshPtr()
3133  );
3134  // Non-region specific. Note: should do outside region loop
3135  // but would then have to replicate the whole time loop ...
3136  copyUniform
3137  (
3138  fh,
3139  decompose,
3140  reconstruct,
3141  mesh.time().timeName(),
3142  mesh.time(), // runTime
3143  baseMeshPtr().time() // baseRunTime
3144  );
3145  }
3146  }
3147  }
3148  else
3149  {
3150  // decompose or redistribution mode.
3151  // decompose : master : read from parent dir
3152  // slave : dummy mesh
3153  // redistribute : all read mesh or dummy mesh
3154 
3155  // Time coming from processor0 (or undecomposed if no processor0)
3156  scalar masterTime;
3157  if (decompose)
3158  {
3159  // Use base time. This is to handle e.g. startTime = latestTime
3160  // which will not do anything if there are no processor directories
3161  masterTime = timeSelector::selectIfPresent
3162  (
3163  baseRunTime,
3164  args
3165  )[0].value();
3166  }
3167  else
3168  {
3169  masterTime = timeSelector::selectIfPresent
3170  (
3171  runTime,
3172  args
3173  )[0].value();
3174  }
3175  Pstream::scatter(masterTime);
3176  Info<< "Setting time to that of master or undecomposed case : "
3177  << masterTime << endl;
3178  runTime.setTime(masterTime, 0);
3179  baseRunTime.setTime(masterTime, 0);
3180 
3181  // Save old time name (since might be incremented)
3182  const word oldTimeName(runTime.timeName());
3183 
3184  forAll(regionNames, regioni)
3185  {
3186  const word& regionName = regionNames[regioni];
3187  const fileName meshSubDir
3188  (
3192  );
3193 
3194  if (decompose)
3195  {
3196  Info<< "\n\nDecomposing mesh " << regionName << nl << endl;
3197  }
3198  else
3199  {
3200  Info<< "\n\nRedistributing mesh " << regionName << nl << endl;
3201  }
3202 
3203 
3204  // Get time instance directory
3205  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
3206  // At this point we should be able to read at least a mesh on
3207  // processor0. Note the changing of the processor0 casename to
3208  // enforce it to read/write from the undecomposed case
3209 
3210  fileName masterInstDir;
3211  if (Pstream::master())
3212  {
3213  if (decompose)
3214  {
3215  Info<< "Setting caseName to " << baseRunTime.caseName()
3216  << " to find undecomposed mesh" << endl;
3217  runTime.caseName() = baseRunTime.caseName();
3218  runTime.processorCase(false);
3219  }
3220 
3221  const bool oldParRun = Pstream::parRun(false);
3222  masterInstDir = runTime.findInstance
3223  (
3224  meshSubDir,
3225  "faces",
3227  );
3228  Pstream::parRun(oldParRun);
3229 
3230  if (decompose)
3231  {
3232  Info<< "Restoring caseName to " << proc0CaseName << endl;
3233  runTime.caseName() = proc0CaseName;
3234  runTime.processorCase(oldProcCase);
3235  }
3236  }
3237  Pstream::scatter(masterInstDir);
3238 
3239  // Check who has a mesh
3240  const fileName meshPath(runTime.path()/masterInstDir/meshSubDir);
3241  const boolList haveMesh(haveFacesFile(meshPath));
3242 
3243  // Collect objectPath of polyMesh for the current file handler. This
3244  // is where the mesh would be written if it didn't exist already.
3245  fileNameList meshDir(Pstream::nProcs());
3246  {
3247  const fileName fName
3248  (
3249  fileHandler().objectPath
3250  (
3251  IOobject("faces", masterInstDir/meshSubDir, runTime),
3252  word::null
3253  )
3254  );
3255  meshDir[Pstream::myProcNo()] = fName.path();
3256  Pstream::gatherList(meshDir);
3257  Pstream::scatterList(meshDir);
3258  //Info<< "Per processor faces dirs:" << nl
3259  // << " " << meshDir << nl << endl;
3260  }
3261 
3262 
3263  // Load mesh (or create dummy one)
3264  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3265 
3266  if (Pstream::master() && decompose)
3267  {
3268  Info<< "Setting caseName to " << baseRunTime.caseName()
3269  << " to read undecomposed mesh" << endl;
3270  runTime.caseName() = baseRunTime.caseName();
3271  runTime.processorCase(false);
3272  }
3273 
3275  (
3276  decompose,
3277  //haveMesh[Pstream::myProcNo()],
3278  IOobject
3279  (
3280  regionName,
3281  masterInstDir,
3282  runTime,
3284  )
3285  );
3286  fvMesh& mesh = meshPtr();
3287 
3288  if (writeHandler.valid())
3289  {
3290  // Remove any left-over empty processor directories created
3291  // by loadOrCreateMesh to get around the collated start-up
3292  // problems
3293  if (Pstream::master()) //fileHandler().comm()))
3294  {
3295  const auto myProci = UPstream::myProcNo(); //comm()
3296  const auto& procs = UPstream::procID
3297  (
3299  );
3300  const bool oldParRun = Pstream::parRun(false);
3301  for (const auto proci : procs)
3302  {
3303  if
3304  (
3305  !haveMesh[proci]
3306  && meshDir[proci] != meshDir[myProci]
3307  )
3308  {
3309  Info<< "Deleting mesh dir:" << meshDir[proci]
3310  << endl;
3311  rmDir(meshDir[proci]);
3312  }
3313  }
3314 
3315  // Remove empty directory
3317 
3318  Pstream::parRun(oldParRun);
3319  }
3320  }
3321 
3322 
3323  if (Pstream::master() && decompose)
3324  {
3325  Info<< "Restoring caseName to " << proc0CaseName << endl;
3326  runTime.caseName() = proc0CaseName;
3327  runTime.processorCase(oldProcCase);
3328  }
3329 
3330  const label nOldCells = mesh.nCells();
3331  //Pout<< "Loaded mesh : nCells:" << nOldCells
3332  // << " nPatches:" << mesh.boundaryMesh().size() << endl;
3333 
3334 
3335  // Determine decomposition
3336  // ~~~~~~~~~~~~~~~~~~~~~~~
3337 
3338  label nDestProcs;
3339  labelList finalDecomp;
3340  determineDecomposition
3341  (
3342  baseRunTime,
3343  decompDictFile,
3344  decompose,
3345  proc0CaseName,
3346  mesh,
3347  writeCellDist,
3348 
3349  nDestProcs,
3350  finalDecomp
3351  );
3352 
3353  if (dryrun)
3354  {
3355  if (!Pstream::master() && !haveMesh[Pstream::myProcNo()])
3356  {
3357  // Remove dummy mesh created by loadOrCreateMesh
3358  const bool oldParRun = Pstream::parRun(false);
3359  mesh.removeFiles();
3360  rmDir(mesh.objectRegistry::objectPath());
3361  Pstream::parRun(oldParRun); // Restore parallel state
3362  }
3363  continue;
3364  }
3365 
3366 
3367 
3368  wordList cloudNames;
3370 
3371  // Detect lagrangian fields
3372  if (Pstream::master() && decompose)
3373  {
3374  runTime.caseName() = baseRunTime.caseName();
3375  runTime.processorCase(false);
3376  }
3378  (
3379  mesh,
3380  cloudNames,
3381  fieldNames
3382  );
3383 
3384  // Read lagrangian fields and store on cloud (objectRegistry)
3386  (
3387  cloudNames.size()
3388  );
3389  readLagrangian
3390  (
3391  mesh,
3392  cloudNames,
3393  selectedLagrangianFields,
3394  clouds
3395  );
3396  if (Pstream::master() && decompose)
3397  {
3398  runTime.caseName() = proc0CaseName;
3399  runTime.processorCase(oldProcCase);
3400  }
3401 
3402  // Load fields, do all distribution (mesh and fields - but not
3403  // lagrangian fields; these are done later)
3404  autoPtr<mapDistributePolyMesh> distMap = redistributeAndWrite
3405  (
3406  std::move(writeHandler),
3407  baseRunTime,
3408  haveMesh,
3409  meshSubDir,
3410  true, // read fields
3411  decompose, // decompose, i.e. read from undecomposed case
3412  false, // no reconstruction
3413  overwrite,
3414  proc0CaseName,
3415  nDestProcs,
3416  finalDecomp,
3417  masterInstDir,
3418  mesh
3419  );
3420 
3421 
3422  // Redistribute any clouds
3423  redistributeLagrangian
3424  (
3425  lagrangianReconstructorPtr,
3426  mesh,
3427  nOldCells,
3428  distMap(),
3429  clouds
3430  );
3431 
3432 
3433  // Copy region-specific uniform
3434  // (e.g. solid/uniform/cumulativeContErr)
3435  copyUniform
3436  (
3437  fh,
3438  decompose,
3439  reconstruct,
3440  oldTimeName, // provided read time
3441  mesh, // read location is mesh (but oldTimeName)
3442  mesh // write location is mesh
3443  );
3444  }
3445 
3446  // Copy non-region specific uniform (e.g. uniform/time)
3447  copyUniform
3448  (
3449  fh,
3450  decompose,
3451  reconstruct,
3452  oldTimeName, // provided read time
3453  ( // read location
3454  decompose
3455  ? baseRunTime
3456  : runTime
3457  ),
3458  runTime // writing location
3459  );
3460  }
3461 
3462 
3463  Info<< "End\n" << endl;
3464 
3465  return 0;
3466 }
3467 
3468 
3469 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::TimePaths::findTimes
static instantList findTimes(const fileName &directory, const word &constantName="constant")
Search a given directory for valid time directories.
Definition: TimePaths.C:140
Foam::IOobject::NO_WRITE
Definition: IOobject.H:195
Foam::autoPtr::New
static autoPtr< T > New(Args &&... args)
Construct autoPtr of T with forwarding arguments.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
volFields.H
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::mapDistributeBase::subMap
const labelListList & subMap() const
From subsetted data back to original data.
Definition: mapDistributeBase.H:289
Foam::fvc::reconstruct
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> reconstruct(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcReconstruct.C:56
Foam::cloud::prefix
static const word prefix
The prefix to local: lagrangian.
Definition: cloud.H:87
uncollatedFileOperation.H
Foam::parFvFieldReconstructor::reconstructFvVolumeInternalFields
label reconstructFvVolumeInternalFields(const IOobjectList &objects, const wordRes &selectedFields=wordRes()) const
Read, reconstruct and write all/selected volume internal fields.
Foam::TimePaths::globalCaseName
const fileName & globalCaseName() const
Return global case name.
Definition: TimePathsI.H:56
Foam::Tensor< scalar >
Foam::mapDistributeBase::constructHasFlip
bool constructHasFlip() const
Does constructMap include a sign.
Definition: mapDistributeBase.H:325
Foam::volTensorField
GeometricField< tensor, fvPatchField, volMesh > volTensorField
Definition: volFieldsFwd.H:66
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
faceProcAddressing
PtrList< labelIOList > & faceProcAddressing
Definition: checkFaceAddressingComp.H:9
Foam::SymmTensor< scalar >
meshPtr
Foam::autoPtr< Foam::fvMesh > meshPtr(nullptr)
collatedFileOperation.H
Foam::loadOrCreateMesh
autoPtr< fvMesh > loadOrCreateMesh(const bool decompose, const IOobject &io)
Load (if it exists) or create zero cell mesh given an IOobject:
Foam::IOobject::AUTO_WRITE
Definition: IOobject.H:194
Foam::UPstream::masterNo
static constexpr int masterNo() noexcept
Process index of the master (always 0)
Definition: UPstream.H:451
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:94
cloudName
const word cloudName(propsDict.get< word >("cloud"))
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
regionProperties.H
Foam::fileOperation
An encapsulation of filesystem-related operations.
Definition: fileOperation.H:68
Foam::parLagrangianRedistributor::redistributeStoredFields
label redistributeStoredFields(const mapDistributeBase &map, passivePositionParticleCloud &cloud) const
Redistribute and write stored lagrangian fields.
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::IOField
A primitive field of type <T> with automated input and output.
Definition: foamVtkLagrangianWriter.H:61
Foam::fvMesh::write
virtual bool write(const bool valid=true) const
Write mesh using IO settings from time.
Definition: fvMesh.C:1041
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:63
processorFvPatchField.H
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:63
Foam::polyMesh::POINTS_MOVED
Definition: polyMesh.H:93
Foam::polyMesh::defaultRegion
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:318
Foam::argList::getOrDefault
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:307
Foam::processorFvPatchField
This boundary condition enables processor communication across patches.
Definition: processorFvPatchField.H:66
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::fvMeshSubset
Given the original mesh and the list of selected cells, it creates the mesh consisting only of the de...
Definition: fvMeshSubset.H:73
topoSet.H
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::DynamicList< word >
Foam::dictionary::found
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
Definition: dictionaryI.H:87
unmappedPassivePositionParticleCloud.H
Foam::debug::debugSwitch
int debugSwitch(const char *name, const int deflt=0)
Lookup debug switch or add default value.
Definition: debug.C:225
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:53
Foam::surfaceInterpolation::geometry
virtual const fvGeometryScheme & geometry() const
Return reference to geometry calculation scheme.
Definition: surfaceInterpolation.C:80
Foam::Pstream::scatterList
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
Definition: gatherScatterList.C:215
Foam::mapDistributePolyMesh::distributeCellData
void distributeCellData(List< T > &lst) const
Distribute list of cell data.
Definition: mapDistributePolyMesh.H:256
addOverwriteOption.H
globalIndex.H
IOmapDistributePolyMesh.H
Foam::fileName::name
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition: fileNameI.H:199
Foam::TimePaths::processorCase
bool processorCase() const noexcept
Return true if this is a processor case.
Definition: TimePathsI.H:36
Foam::polyMesh::meshSubDir
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:321
Foam::fileOperation::NewUncollated
static autoPtr< fileOperation > NewUncollated()
Static construct the commonly used uncollatedFileOperation.
Definition: fileOperation.C:1474
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
Foam::fileOperation::flush
virtual void flush() const
Forcibly wait until all output done. Flush any cached data.
Definition: fileOperation.C:1240
Foam::argList::addNote
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:412
Foam::Time::functionObjects
const functionObjectList & functionObjects() const
Return the list of function objects.
Definition: Time.H:499
Foam::timeSelector::select
instantList select(const instantList &times) const
Select a list of Time values that are within the ranges.
Definition: timeSelector.C:89
Foam::polyMesh::facesInstance
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:852
Foam::mapDistributePolyMesh::transfer
void transfer(mapDistributePolyMesh &map)
Transfer the contents of the argument and annul the argument.
Definition: mapDistributePolyMesh.C:193
Foam::UPstream::waitRequests
static void waitRequests(const label start=0)
Wait until all requests (from start onwards) have finished.
Definition: UPstream.C:262
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::combineReduce
void combineReduce(const List< UPstream::commsStruct > &comms, T &Value, const CombineOp &cop, const int tag, const label comm)
Definition: PstreamCombineReduceOps.H:54
Foam::processorPolyPatch::neighbProcNo
int neighbProcNo() const
Return neighbour processor number.
Definition: processorPolyPatch.H:274
Foam::Pstream::scatter
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
Definition: gatherScatter.C:150
Foam::argList
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:123
Foam::unmappedPassivePositionParticleCloud
passivePositionParticleCloud but with autoMap and writing disabled. Only used for its objectRegistry ...
Definition: unmappedPassivePositionParticleCloud.H:52
Foam::sigFpe::unset
static void unset(bool verbose=false)
Deactivate SIGFPE signal handler and NaN memory initialisation.
Definition: sigFpe.C:204
Foam::rm
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: MSwindows.C:1004
Foam::fileHandler
const fileOperation & fileHandler()
Get current file handler.
Definition: fileOperation.C:1485
Foam::autoPtr::valid
bool valid() const noexcept
Identical to good(), or bool operator.
Definition: autoPtr.H:272
IOobjectList.H
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:444
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
surfaceFields.H
Foam::surfaceFields.
Foam::decompositionModel::decomposer
decompositionMethod & decomposer() const
Return demand-driven decomposition method.
Definition: decompositionModel.C:101
Foam::PtrList::set
const T * set(const label i) const
Return const pointer to element (can be nullptr),.
Definition: PtrList.H:138
Foam::UPstream::defaultCommsType
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:281
Foam::CompactIOField
A Field of objects of type <T> with automated input and output using a compact storage....
Definition: CompactIOField.H:53
decompositionMethod.H
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:107
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::IOobject::writeOpt
writeOption writeOpt() const noexcept
The write option.
Definition: IOobjectI.H:179
Foam::HashSet< word, Hash< word > >
parLagrangianRedistributor.H
Foam::meshRefinement::removeFiles
static void removeFiles(const polyMesh &)
Helper: remove all relevant files from mesh instance.
Definition: meshRefinement.C:3402
Foam::decompositionModel
MeshObject wrapper of decompositionMethod.
Definition: decompositionModel.H:57
Foam::polyBoundaryMesh::start
label start() const
The start label of the boundary faces in the polyMesh face list.
Definition: polyBoundaryMesh.C:611
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
regionNames
wordList regionNames
Definition: getAllRegionOptions.H:37
Foam::fileOperation::findTimes
virtual instantList findTimes(const fileName &, const word &) const
Get sorted list of times.
Definition: fileOperation.C:949
Foam::polyBoundaryMesh::names
wordList names() const
Return a list of patch names.
Definition: polyBoundaryMesh.C:555
Foam::globalMeshData::processorPatches
const labelList & processorPatches() const noexcept
Return list of processor patch labels.
Definition: globalMeshData.H:381
Foam::primitiveMesh::nPoints
label nPoints() const noexcept
Number of mesh points.
Definition: primitiveMeshI.H:37
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
foamDlOpenLibs.H
Foam::mapDistributePolyMesh::cellMap
const mapDistribute & cellMap() const
Cell distribute map.
Definition: mapDistributePolyMesh.H:223
Foam::decompositionModel::New
static const decompositionModel & New(const polyMesh &mesh, const fileName &decompDictFile="", const dictionary *fallback=nullptr)
Definition: decompositionModel.C:83
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::fvMesh::readUpdate
virtual readUpdateState readUpdate()
Update the mesh based on the mesh files saved in time.
Definition: fvMesh.C:648
Foam::parLagrangianRedistributor::findClouds
static void findClouds(const fvMesh &, wordList &cloudNames, List< wordList > &objectNames)
Find all clouds (on all processors) and for each cloud all.
Foam::polyMesh::TOPO_PATCH_CHANGE
Definition: polyMesh.H:95
Foam::parFvFieldReconstructor::reconstructFvSurfaceFields
label reconstructFvSurfaceFields(const IOobjectList &objects, const wordRes &selectedFields=wordRes()) const
Read, reconstruct and write all/selected surface fields.
Foam::polyMesh::pointsInstance
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:846
regionName
Foam::word regionName
Definition: createNamedDynamicFvMesh.H:1
Foam::decompositionMethod::parallelAware
virtual bool parallelAware() const =0
Is method parallel aware?
Foam::argList::noFunctionObjects
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
Definition: argList.C:473
Foam::primitiveMesh::nCells
label nCells() const noexcept
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::UPstream::subProcs
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition: UPstream.H:515
Foam::argList::dryRun
int dryRun() const noexcept
Return the dry-run flag.
Definition: argListI.H:116
Foam::Field< scalar >
Foam::volSymmTensorField
GeometricField< symmTensor, fvPatchField, volMesh > volSymmTensorField
Definition: volFieldsFwd.H:65
Foam::functionObjectList::off
void off()
Switch the function objects off.
Definition: functionObjectList.C:605
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::mapDistributeBase::distribute
static void distribute(const Pstream::commsTypes commsType, const List< labelPair > &schedule, const label constructSize, const labelListList &subMap, const bool subHasFlip, const labelListList &constructMap, const bool constructHasFlip, List< T > &, const negateOp &negOp, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Distribute data. Note:schedule only used for.
Definition: mapDistributeBaseTemplates.C:122
Foam::parLagrangianRedistributor
Lagrangian field redistributor.
Definition: parLagrangianRedistributor.H:61
Foam::fvMeshTools::newMesh
static autoPtr< fvMesh > newMesh(const IOobject &io, const bool masterOnlyReading)
Read mesh or create dummy mesh (0 cells, >0 patches). Works in two.
Definition: fvMeshTools.C:424
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::polyMesh::removeFiles
void removeFiles(const fileName &instanceDir) const
Remove all files from mesh instance.
Definition: polyMesh.C:1325
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:511
Foam::mapDistributePolyMesh::faceMap
const mapDistribute & faceMap() const
Face distribute map.
Definition: mapDistributePolyMesh.H:217
argList.H
Foam::mapDistribute
Class containing processor-to-processor mapping information.
Definition: mapDistribute.H:163
init
mesh init(true)
Foam::IOobject::READ_IF_PRESENT
Definition: IOobject.H:187
Foam::mapDistributePolyMesh::patchMap
const mapDistribute & patchMap() const
Patch distribute map.
Definition: mapDistributePolyMesh.H:229
Foam::TimePaths::times
instantList times() const
Search the case for valid time directories.
Definition: TimePaths.C:149
Foam::primitiveMesh::nBoundaryFaces
label nBoundaryFaces() const noexcept
Number of boundary faces (== nFaces - nInternalFaces)
Definition: primitiveMeshI.H:84
Foam::parLagrangianRedistributor::redistributeLagrangianPositions
autoPtr< mapDistributeBase > redistributeLagrangianPositions(passivePositionParticleCloud &cloud) const
Redistribute and write lagrangian positions.
Foam::CompactIOList< face, label >
Foam::andOp
Definition: ops.H:233
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:42
Foam::processorPolyPatch
Neighbour processor patch.
Definition: processorPolyPatch.H:58
Foam::UPstream::procID
static List< int > & procID(label communicator)
Process ID of given process index.
Definition: UPstream.H:474
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:59
Foam::polyMesh::TOPO_CHANGE
Definition: polyMesh.H:94
Foam::volScalarField
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:57
Foam::fileOperation::rmDir
virtual bool rmDir(const fileName &dir, const bool silent=false) const =0
Remove a directory and its contents.
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
fld
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputLagrangian.H:23
Foam::hexRef8Data
Various for reading/decomposing/reconstructing/distributing refinement data.
Definition: hexRef8Data.H:60
Foam::UPstream::commsTypeNames
static const Enum< commsTypes > commsTypeNames
Names of the communication types.
Definition: UPstream.H:77
Foam::timeSelector::selectIfPresent
static instantList selectIfPresent(Time &runTime, const argList &args)
Definition: timeSelector.C:266
Foam::mapDistributePolyMesh::oldPatchSizes
const labelList & oldPatchSizes() const
List of the old patch sizes.
Definition: mapDistributePolyMesh.H:193
forAllIters
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:223
timeName
word timeName
Definition: getTimeIndex.H:3
Foam::argList::path
fileName path() const
Return the full path to the (processor local) case.
Definition: argListI.H:81
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::Time::controlDict
const dictionary & controlDict() const
Return read access to the controlDict dictionary.
Definition: Time.H:364
Foam::eqOp
Definition: ops.H:71
fieldNames
const wordRes fieldNames(propsDict.getOrDefault< wordRes >("fields", wordRes()))
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
meshRefinement.H
Foam::decompositionMethod
Abstract base class for domain decomposition.
Definition: decompositionMethod.H:51
Foam::mapDistributeBase::subHasFlip
bool subHasFlip() const
Does subMap include a sign.
Definition: mapDistributeBase.H:313
hexRef8Data.H
Foam::GeoMesh
Generic mesh wrapper used by volMesh, surfaceMesh, pointMesh etc.
Definition: GeoMesh.H:48
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
fvMesh.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::flatOutput
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:216
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
Foam::ListOps::uniqueEqOp
List helper to append y unique elements onto the end of x.
Definition: ListOps.H:577
Foam::fileOperation::objectPath
virtual fileName objectPath(const IOobject &io, const word &typeName) const
Generate disk file name for object. Opposite of filePath.
Definition: fileOperation.C:741
PstreamReduceOps.H
Inter-processor communication reduction functions.
Foam::SphericalTensor< scalar >
Foam::IOobjectList
List of IOobjects with searching and retrieving facilities.
Definition: IOobjectList.H:55
Foam::Time::findInstance
word findInstance(const fileName &dir, const word &name=word::null, const IOobject::readOption rOpt=IOobject::MUST_READ, const word &stopInstance=word::null) const
Definition: Time.C:797
Foam::argList::addDryRunOption
static void addDryRunOption(const string &usage, bool advanced=false)
Enable a 'dry-run' bool option, with usage information.
Definition: argList.C:454
Foam::decompositionMethod::nDomains
static label nDomains(const dictionary &decompDict, const word &regionName="")
Return region-specific or top-level numberOfSubdomains entry.
Definition: decompositionMethod.C:83
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::readFields
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const wordHashSet &selectedFields, LIFOStack< regIOobject * > &storedObjects)
Read the selected GeometricFields of the templated type.
Definition: ReadFieldsTemplates.C:312
Foam::polyMesh::readUpdateState
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:90
Foam::HashTable
A HashTable similar to std::unordered_map.
Definition: HashTable.H:105
getAllRegionOptions.H
Priority.
Foam::polyBoundaryMesh::nNonProcessor
label nNonProcessor() const
The number of patches before the first processor patch.
Definition: polyBoundaryMesh.C:535
Foam::volVectorField
GeometricField< vector, fvPatchField, volMesh > volVectorField
Definition: volFieldsFwd.H:62
Foam::autoPtr::reset
void reset(autoPtr< T > &&other) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:117
Foam::fvMesh::boundary
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:685
Foam::mapDistributeBase::constructSize
label constructSize() const
Constructed data size.
Definition: mapDistributeBase.H:277
Foam::argList::addBoolOption
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:324
Foam::IOstream::defaultPrecision
static unsigned int defaultPrecision() noexcept
Return the default precision.
Definition: IOstream.H:342
Time.H
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
masterUncollatedFileOperation.H
Foam::TimePaths::system
const word & system() const
Return system name.
Definition: TimePathsI.H:102
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::Pstream::gatherList
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
Definition: gatherScatterList.C:52
Foam::decompositionMethod::decompose
virtual labelList decompose(const pointField &points, const scalarField &pointWeights) const
Return the wanted processor number for every coordinate.
Definition: decompositionMethod.C:1325
Foam::UPstream::allProcs
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
Definition: UPstream.H:508
Foam::Time::caseName
const fileName & caseName() const
Return case name.
Definition: TimePathsI.H:62
Foam::parFvFieldReconstructor::reconstructFvVolumeFields
label reconstructFvVolumeFields(const IOobjectList &objects, const wordRes &selectedFields=wordRes()) const
Read, reconstruct and write all/selected volume fields.
Foam::UPstream::commsTypes::nonBlocking
Foam::UPstream::msgType
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:540
Foam::UPstream::nRequests
static label nRequests()
Get number of outstanding requests.
Definition: UPstream.C:252
fvMeshDistribute.H
Foam::removeEmptyDirs
void removeEmptyDirs(const fileName &path)
Remove empty directories from bottom up.
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:463
addAllRegionOptions.H
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::parLagrangianRedistributor::readFields
static label readFields(const passivePositionParticleCloud &cloud, const IOobjectList &objects, const wordRes &selectedFields=wordRes())
Read and store all fields of a cloud.
Foam::Time::path
fileName path() const
Return path.
Definition: Time.H:358
fvMeshTools.H
Foam::objectRegistry::names
wordList names() const
The names of all objects.
Definition: objectRegistry.C:147
Foam::UPstream::commsTypes::scheduled
Foam::rmDir
bool rmDir(const fileName &directory, const bool silent=false)
Remove a directory and its contents (optionally silencing warnings)
Definition: MSwindows.C:1028
Foam::lagrangianReconstructor
Reconstructor for lagrangian positions and fields.
Definition: lagrangianReconstructor.H:56
Foam::timeSelector::addOptions
static void addOptions(const bool constant=true, const bool withZero=false)
Add timeSelector options to argList::validOptions.
Definition: timeSelector.C:102
Foam::Vector< scalar >
Foam::Time::rootPath
const fileName & rootPath() const
Return root path.
Definition: TimePathsI.H:50
Foam::UPstream::worldComm
static label worldComm
Default communicator (all processors)
Definition: UPstream.H:293
Foam::UPstream::parRun
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
Foam::List< instant >
Foam::fileOperation::isFile
virtual bool isFile(const fileName &, const bool checkGzip=true, const bool followLink=true) const =0
Does the name exist as a FILE in the file system?
Foam::IOmapDistributePolyMesh
IOmapDistributePolyMesh is derived from mapDistributePolyMesh and IOobject to give the mapDistributeP...
Definition: IOmapDistributePolyMesh.H:53
Foam::Time::setTime
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition: Time.C:1003
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::UList< label >
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::IOList< label >
Foam::wordRes
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:51
Foam::argList::globalPath
fileName globalPath() const
Return the full path to the global case.
Definition: argListI.H:87
path
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
Foam::word::null
static const word null
An empty word.
Definition: word.H:80
timeSelector.H
createTime.H
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::autoPtr::clear
void clear() noexcept
Same as reset(nullptr)
Definition: autoPtr.H:176
Foam::mapDistributeBase
Class containing processor-to-processor mapping information.
Definition: mapDistributeBase.H:103
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::mapDistribute::reverseDistribute
void reverseDistribute(const label constructSize, List< T > &, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
Definition: mapDistributeTemplates.C:182
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:280
Foam::fileOperation::cp
virtual bool cp(const fileName &src, const fileName &dst, const bool followLink=true) const =0
Copy, recursively if necessary, the source to the destination.
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:53
Foam::primitiveMesh::nFaces
label nFaces() const noexcept
Number of mesh faces.
Definition: primitiveMeshI.H:90
Foam::mapDistributePolyMesh::pointMap
const mapDistribute & pointMap() const
Point distribute map.
Definition: mapDistributePolyMesh.H:211
decompositionModel.H
cyclicACMIFvPatch.H
Foam::mapDistributePolyMesh::nOldFaces
label nOldFaces() const
Number of faces in mesh before distribution.
Definition: mapDistributePolyMesh.H:181
Foam::instant
An instant of time. Contains the time value and name.
Definition: instant.H:52
Foam::volSphericalTensorField
GeometricField< sphericalTensor, fvPatchField, volMesh > volSphericalTensorField
Definition: volFieldsFwd.H:64
Foam::mapDistributePolyMesh
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Definition: mapDistributePolyMesh.H:66
Foam::polyMesh::globalData
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1295
regionDir
const word & regionDir
Definition: findMeshDefinitionDict.H:34
Foam::mapDistributePolyMesh::nOldPoints
label nOldPoints() const
Number of points in mesh before distribution.
Definition: mapDistributePolyMesh.H:175
Foam::fvGeometryScheme::New
static tmp< fvGeometryScheme > New(const fvMesh &mesh, const dictionary &dict, const word &defaultScheme)
Return new tmp interpolation scheme.
Definition: fvGeometryScheme.C:44
Foam::IOobject::objectPath
fileName objectPath() const
The complete path + object name.
Definition: IOobjectI.H:214
Foam::mapDistributePolyMesh::nOldCells
label nOldCells() const
Number of cells in mesh before distribution.
Definition: mapDistributePolyMesh.H:187
Foam::fileOperation::dirPath
virtual fileName dirPath(const bool checkGlobal, const IOobject &io, const bool search=true) const =0
Search for a directory. checkGlobal : also check undecomposed.
Foam::TimePaths::constant
const word & constant() const
Return constant name.
Definition: TimePathsI.H:96
Foam::GeometricField< scalar, fvPatchField, volMesh >
Foam::mapDistributeBase::constructMap
const labelListList & constructMap() const
From subsetted data to new reconstructed data.
Definition: mapDistributeBase.H:301
Foam::IOobjectList::lookupClass
IOobjectList lookupClass(const char *clsName) const
The list of IOobjects with the given headerClassName.
Definition: IOobjectList.C:290
Foam::IOobject::NO_READ
Definition: IOobject.H:188
args
Foam::argList args(argc, argv)
Foam::mkDir
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: MSwindows.C:507
parFvFieldReconstructor.H
Foam::mapDistributePolyMesh::distributePointData
void distributePointData(List< T > &lst) const
Distribute list of point data.
Definition: mapDistributePolyMesh.H:242
basicFvGeometryScheme.H
Foam::topoSet::removeFiles
static void removeFiles(const polyMesh &)
Helper: remove all sets files from mesh instance.
Definition: topoSet.C:635
DebugVar
#define DebugVar(var)
Report a variable name and value.
Definition: messageStream.H:404
zeroGradientFvPatchFields.H
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
Foam::fvMeshDistribute
Sends/receives parts of mesh+fvfields to neighbouring processors. Used in load balancing.
Definition: fvMeshDistribute.H:70
Foam::fileOperation::distributed
bool distributed() const noexcept
Distributed roots (parallel run)
Definition: fileOperation.H:239
pointFields.H
Foam::objectRegistry::time
const Time & time() const noexcept
Return time registry.
Definition: objectRegistry.H:178
Foam::polyMesh::setInstance
void setInstance(const fileName &instance, const IOobject::writeOption wOpt=IOobject::AUTO_WRITE)
Set the instance for mesh files.
Definition: polyMeshIO.C:36
fields
multivariateSurfaceInterpolationScheme< scalar >::fieldTable fields
Definition: createFields.H:97
Foam::argList::rootPath
const fileName & rootPath() const noexcept
Return root path.
Definition: argListI.H:63
Foam::UPstream::nProcs
static label nProcs(const label communicator=worldComm)
Number of processes in parallel run, and 1 for serial run.
Definition: UPstream.H:445
Foam::parFvFieldReconstructor
Finite volume reconstructor for volume and surface fields.
Definition: parFvFieldReconstructor.H:61
Foam::dimless
const dimensionSet dimless
Dimensionless.
Definition: dimensionSets.C:189
Foam::isDir
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: MSwindows.C:643
Foam::argList::found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:178
loadOrCreateMesh.H
Load or create (0 size) a mesh. Used in distributing meshes to a larger number of processors.
Foam::UPstream::commsTypes::blocking
Foam::flipOp
Functor to negate primitives. Dummy for most other types.
Definition: flipOp.H:53
Foam::IOobject::MUST_READ
Definition: IOobject.H:185
Foam::flipLabelOp
Negate integer values.
Definition: flipOp.H:85
Foam::polyMesh::tetBasePtIs
const labelIOList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:892