decomposePar.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) 2016-2026 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  decomposePar
29 
30 Group
31  grpParallelUtilities
32 
33 Description
34  Automatically decomposes a mesh and fields of a case for parallel
35  execution of OpenFOAM.
36 
37 Usage
38  \b decomposePar [OPTIONS]
39 
40  Options:
41  - \par -allRegions
42  Decompose all regions in regionProperties. Does not check for
43  existence of processor*.
44 
45  - \par -case <dir>
46  Specify case directory to use (instead of the cwd).
47 
48  - \par -cellDist
49  Write the cell distribution as a labelList, for use with 'manual'
50  decomposition method and as a VTK or volScalarField for visualization.
51 
52  - \par -constant
53  Include the 'constant/' dir in the times list.
54 
55  - \par -copyUniform
56  Copy any \a uniform directories too.
57 
58  - \par -copyZero
59  Copy \a 0 directory to processor* rather than decompose the fields.
60 
61  - \par -debug-switch <name=val>
62  Specify the value of a registered debug switch. Default is 1
63  if the value is omitted. (Can be used multiple times)
64 
65  - \par -decomposeParDict <file>
66  Use specified file for decomposePar dictionary.
67 
68  - \par -dry-run
69  Test without writing the decomposition. Changes -cellDist to
70  only write VTK output.
71 
72  - \par -fields
73  Use existing geometry decomposition and convert fields only.
74 
75  - \par fileHandler <handler>
76  Override the file handler type.
77 
78  - \par -force
79  Remove any existing \a processor subdirectories before decomposing the
80  geometry.
81 
82  - \par -ifRequired
83  Only decompose the geometry if the number of domains has changed from a
84  previous decomposition. No \a processor subdirectories will be removed
85  unless the \a -force option is also specified. This option can be used
86  to avoid redundant geometry decomposition (eg, in scripts), but should
87  be used with caution when the underlying (serial) geometry or the
88  decomposition method etc. have been changed between decompositions.
89 
90  - \par -info-switch <name=val>
91  Specify the value of a registered info switch. Default is 1
92  if the value is omitted. (Can be used multiple times)
93 
94  - \par -latestTime
95  Select the latest time.
96 
97  - \par -lib <name>
98  Additional library or library list to load (can be used multiple times).
99 
100  - \par -noFunctionObjects
101  Do not execute function objects.
102 
103  - \par -noSets
104  Skip decomposing cellSets, faceSets, pointSets.
105 
106  - \par -noZero
107  Exclude the \a 0 dir from the times list.
108 
109  - \par -opt-switch <name=val>
110  Specify the value of a registered optimisation switch (int/bool).
111  Default is 1 if the value is omitted. (Can be used multiple times)
112 
113  - \par -region <regionName>
114  Decompose named region. Does not check for existence of processor*.
115 
116  - \par -time <ranges>
117  Override controlDict settings and decompose selected times. Does not
118  re-decompose the mesh i.e. does not handle moving mesh or changing
119  mesh cases. Eg, ':10,20 40:70 1000:', 'none', etc.
120 
121  - \par -verbose
122  Additional verbosity.
123 
124  - \par -doc
125  Display documentation in browser.
126 
127  - \par -doc-source
128  Display source code in browser.
129 
130  - \par -help
131  Display short help and exit.
132 
133  - \par -help-man
134  Display full help (manpage format) and exit.
135 
136  - \par -help-notes
137  Display help notes (description) and exit.
138 
139  - \par -help-full
140  Display full help and exit.
141 
142 \*---------------------------------------------------------------------------*/
143 
144 #include "argList.H"
145 #include "timeSelector.H"
146 #include "OSspecific.H"
147 #include "IOobjectList.H"
148 
149 #include "decompositionModel.H"
150 #include "domainDecomposition.H"
152 
153 #include "regionProperties.H"
154 
155 #include "fieldsDistributor.H"
156 
157 #include "fvFieldDecomposer.H"
158 #include "pointFields.H"
159 #include "pointFieldDecomposer.H"
160 
162 
163 #include "emptyFaPatch.H"
164 #include "faFieldDecomposer.H"
165 #include "faMeshDecomposition.H"
166 
167 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
168 
169 namespace Foam
170 {
171 
172 // Return cached finite-volume proc addressing,
173 // or read from facesInstance
175 const labelIOList& procAddressing
176 (
177  const UPtrList<fvMesh>& procMeshList,
178  const label proci,
179  const word& name,
180  PtrList<labelIOList>& procAddressingList
181 )
182 {
183  const auto& procMesh = procMeshList[proci];
184 
185  // Allow lazy initial sizing
186  if (procAddressingList.size() < procMeshList.size())
187  {
188  procAddressingList.resize(procMeshList.size());
189  }
190 
191  return procAddressingList.try_emplace
192  (
193  proci,
194  IOobject
195  (
196  name,
197  procMesh.facesInstance(),
198  polyMesh::meshSubDir, // local
199  procMesh,
203  )
204  );
205 }
206 
207 
208 // Return cached finite-area proc addressing,
209 // or read from facesInstance (which is normally just "constant")
211 const labelIOList& procAddressing
212 (
213  const UPtrList<faMesh>& procMeshList,
214  const label proci,
215  const word& name,
216  PtrList<labelIOList>& procAddressingList
217 )
218 {
219  const auto& procMesh = procMeshList[proci];
220 
221  // Allow lazy initial sizing
222  if (procAddressingList.size() < procMeshList.size())
223  {
224  procAddressingList.resize(procMeshList.size());
225  }
226 
227  return procAddressingList.try_emplace
228  (
229  proci,
230  IOobject
231  (
232  name,
233  procMesh.facesInstance(),
234  faMesh::meshSubDir, // local
235  procMesh,
239  )
240  );
241 }
242 
243 
244 // Return cached processor Time or create
245 Foam::Time& emplaceTime
246 (
247  PtrList<Time>& procTimes,
248  const label proci,
249  const argList& args
250 )
251 {
252  if (!procTimes.test(proci))
253  {
254  procTimes.set
255  (
256  proci,
257  new Time
258  (
260  args.rootPath(),
261  args.caseName()/("processor" + Foam::name(proci)),
263  args.allowLibs()
264  )
265  );
266  }
267  return procTimes[proci];
268 }
269 
270 
271 void decomposeUniform
272 (
273  const bool copyUniform,
274  const domainDecomposition& mesh,
275  const Time& processorDb,
276  const word& regionDir = word::null
277 )
278 {
279  const Time& runTime = mesh.time();
280 
281  // Any uniform data to copy/link?
282  const fileName uniformDir(regionDir/"uniform");
283 
284  if (fileHandler().isDir(runTime.timePath()/uniformDir))
285  {
286  Info<< "Detected additional non-decomposed files in "
287  << runTime.relativePath(uniformDir) << endl;
288 
289  // Bit of trickery to synthesise the correct directory base,
290  // e.g. processors4/0.01
291  const fileName timePath = fileHandler().objectPath
292  (
293  IOobject
294  (
295  "dummy",
296  runTime.timeName(),
297  processorDb
298  ),
299  word::null
300  ).path();
301 
302  // If no fields have been decomposed the destination
303  // directory will not have been created so make sure.
304  Foam::mkDir(timePath);
305 
306  if (copyUniform || mesh.distributed())
307  {
308  if (!fileHandler().exists(timePath/uniformDir))
309  {
310  fileHandler().cp
311  (
312  runTime.timePath()/uniformDir,
313  timePath/uniformDir
314  );
315  }
316  }
317  else
318  {
319  // Link with relative paths
320  string parentPath = string("..")/"..";
321 
322  if (!regionDir.empty())
323  {
324  parentPath = parentPath/"..";
325  }
326 
327  fileName currentDir(cwd());
328  Foam::chDir(timePath);
329 
330  if (!fileHandler().exists(uniformDir))
331  {
332  fileHandler().ln
333  (
334  parentPath/runTime.timeName()/uniformDir,
335  uniformDir
336  );
337  }
338  Foam::chDir(currentDir);
339  }
340  }
341 }
342 
343 } // End namespace Foam
344 
345 
346 using namespace Foam;
347 
348 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
349 
350 int main(int argc, char *argv[])
351 {
353  (
354  "Decompose a mesh and fields of a case for parallel execution"
355  );
356 
359  (
360  "decomposeParDict",
361  "file",
362  "Alternative decomposePar dictionary file"
363  );
364 
365  #include "addAllRegionOptions.H"
366  #include "addAllFaRegionOptions.H"
367 
369  (
370  "Test without writing the decomposition. "
371  "Changes -cellDist to only write VTK output."
372  );
375  (
376  "domains",
377  "N",
378  "Override numberOfSubdomains (-dry-run only)",
379  true // Advanced option
380  );
382  (
383  "method",
384  "name",
385  "Override decomposition method (-dry-run only)",
386  true // Advanced option
387  );
388 
390  (
391  "no-finite-area",
392  "Suppress finiteArea mesh/field decomposition",
393  true // Advanced option
394  );
395 
397  (
398  "no-lagrangian",
399  "Suppress lagrangian (cloud) decomposition",
400  true // Advanced option
401  );
402 
404  (
405  "disable-edge-encoding",
406  "Emit edgeProcAddressing without encoding edge flips, "
407  "as per 2512 and earlier [special use]",
408  true // Advanced option
409  );
410 
412  (
413  "cellDist",
414  "Write cell distribution as a labelList - for use with 'manual' "
415  "decomposition method and as a volScalarField for visualization."
416  );
418  (
419  "copyZero",
420  "Copy 0/ directory to processor*/ rather than decompose the fields"
421  );
423  (
424  "copyUniform",
425  "Copy any uniform/ directories too"
426  );
428  (
429  "fields",
430  "Use existing geometry decomposition and convert fields only"
431  );
433  (
434  "no-fields",
435  "Suppress conversion of fields (volume, finite-area, lagrangian)"
436  );
437 
439  (
440  "no-sets",
441  "Skip decomposing cellSets, faceSets, pointSets"
442  );
443  argList::addOptionCompat("no-sets", {"noSets", 2106});
444 
446  (
447  "force",
448  "Remove existing processor*/ subdirs before decomposing the geometry"
449  );
451  (
452  "ifRequired",
453  "Only decompose geometry if the number of domains has changed"
454  );
455 
456  // Allow explicit -constant, have zero from time range
457  timeSelector::addOptions(true, false); // constant(true), zero(false)
458 
459  // Prevent volume BCs from triggering finite-area
461 
462  #include "setRootCase.H"
463 
464  // ------------------------------------------------------------------------
465  // Configuration
466 
467  const bool writeCellDist = args.found("cellDist");
468 
469  // Most of these are ignored for dry-run (not triggered anywhere)
470  const bool copyZero = args.found("copyZero");
471  const bool copyUniform = args.found("copyUniform");
472  const bool decomposeSets = !args.found("no-sets");
473 
474  const bool decomposeIfRequired = args.found("ifRequired");
475 
476  const bool doDecompFields = !args.found("no-fields");
477  const bool doFiniteArea = !args.found("no-finite-area");
478  const bool doLagrangian = !args.found("no-lagrangian");
479 
480  bool decomposeFieldsOnly = args.found("fields");
481  bool forceOverwrite = args.found("force");
482 
483  // Special use - emit old (2512 and earlier) edgeProcAddressing format
484  // without encoded edge flips.
485  if (args.found("disable-edge-encoding"))
486  {
488  }
489 
490  // Set time from database
491  #include "createTime.H"
492 
493  // Allow override of time (unless dry-run)
494  instantList times;
495  if (args.dryRun())
496  {
497  Info<< "\ndry-run: ignoring -copy*, -fields, -force, time selection"
498  << nl;
499  }
500  else
501  {
502  if (decomposeFieldsOnly && !doDecompFields)
503  {
505  << "Options -fields and -no-fields are mutually exclusive"
506  << " ... giving up" << nl
507  << exit(FatalError);
508  }
509 
510  if (!doDecompFields)
511  {
512  Info<< "Skip decompose of all fields" << nl;
513  }
514  if (!doFiniteArea)
515  {
516  Info<< "Skip decompose of finiteArea mesh/fields" << nl;
517  }
518  if (!doLagrangian)
519  {
520  Info<< "Skip decompose of lagrangian positions/fields" << nl;
521  }
522 
524  }
525 
526 
527  // Allow override of decomposeParDict location
528  fileName decompDictFile;
529  if
530  (
531  args.readIfPresent("decomposeParDict", decompDictFile)
532  && !decompDictFile.empty() && !decompDictFile.isAbsolute()
533  )
534  {
535  decompDictFile = runTime.globalPath()/decompDictFile;
536  }
537 
538  // Handle volume region selections
539  #include "getAllRegionOptions.H"
540 
541  // Handle area region selections
542  #include "getAllFaRegionOptions.H"
543 
544  if (!doFiniteArea)
545  {
546  areaRegionNames.clear(); // For consistency
547  }
548 
549  const bool optRegions =
551 
553  {
554  Info<< "Using region: " << regionNames[0] << nl << endl;
555  }
556 
557  forAll(regionNames, regioni)
558  {
559  const word& regionName = regionNames[regioni];
561 
562  if (args.dryRun())
563  {
564  Info<< "dry-run: decomposing mesh " << regionName << nl << nl
565  << "Create mesh..." << flush;
566 
567  domainDecompositionDryRun decompTest
568  (
569  IOobject
570  (
571  regionName,
572  runTime.timeName(),
573  runTime,
577  ),
578  decompDictFile,
579  args.getOrDefault<label>("domains", 0),
580  args.getOrDefault<word>("method", word::null)
581  );
582 
583  decompTest.execute(writeCellDist, args.verbose());
584  continue;
585  }
586 
587  Info<< "\n\nDecomposing mesh";
588  if (!regionDir.empty())
589  {
590  Info<< ' ' << regionName;
591  }
592  Info<< nl << endl;
593 
594  // Determine the existing processor count directly
595  const label nProcsOld =
596  fileHandler().nProcs(runTime.path(), regionDir);
597 
598  // Get requested numberOfSubdomains directly from the dictionary.
599  // Note: have no mesh yet so cannot use decompositionModel::New
600  const label nDomains = decompositionMethod::nDomains
601  (
603  (
605  (
606  IOobject
607  (
609  runTime.time().system(),
610  regionDir, // region (if non-default)
611  runTime,
615  ),
616  decompDictFile
617  )
618  )
619  );
620 
621  // Give file handler a chance to determine the output directory
622  fileHandler().constCast().nProcs(nDomains);
623 
624  if (decomposeFieldsOnly)
625  {
626  // Sanity check on previously decomposed case
627  if (nProcsOld != nDomains)
628  {
630  << "Specified -fields, but the case was decomposed with "
631  << nProcsOld << " domains"
632  << nl
633  << "instead of " << nDomains
634  << " domains as specified in decomposeParDict" << nl
635  << exit(FatalError);
636  }
637  }
638  else if (nProcsOld)
639  {
640  bool procDirsProblem = true;
641 
642  if (decomposeIfRequired && nProcsOld == nDomains)
643  {
644  // We can reuse the decomposition
645  decomposeFieldsOnly = true;
646  procDirsProblem = false;
647  forceOverwrite = false;
648 
649  Info<< "Using existing processor directories" << nl;
650  }
651 
652  if (optRegions)
653  {
654  procDirsProblem = false;
655  forceOverwrite = false;
656  }
657 
658  if (forceOverwrite)
659  {
660  Info<< "Removing " << nProcsOld
661  << " existing processor directories" << endl;
662 
663  // Remove existing processors directory
664  fileNameList dirs
665  (
667  (
668  runTime.path(),
669  fileName::Type::DIRECTORY
670  )
671  );
672  forAllReverse(dirs, diri)
673  {
674  const fileName& d = dirs[diri];
675 
676  label proci = -1;
677 
678  if
679  (
680  d.starts_with("processor")
681  &&
682  (
683  // Collated is "processors"
684  d[9] == 's'
685 
686  // Uncollated has integer(s) after 'processor'
687  || Foam::read(d.substr(9), proci)
688  )
689  )
690  {
691  if (fileHandler().exists(d))
692  {
693  fileHandler().rmDir(d);
694  }
695  }
696  }
697 
698  procDirsProblem = false;
699  }
700 
701  if (procDirsProblem)
702  {
704  << "Case is already decomposed with " << nProcsOld
705  << " domains, use the -force option or manually" << nl
706  << "remove processor directories before decomposing. e.g.,"
707  << nl
708  << " rm -rf " << runTime.path().c_str() << "/processor*"
709  << nl
710  << exit(FatalError);
711  }
712  }
713 
714  Info<< "Create mesh" << endl;
716  (
717  IOobject
718  (
719  regionName,
720  runTime.timeName(),
721  runTime,
725  ),
726  decompDictFile
727  );
728  // Make sure pointMesh gets read as well
730 
731 
732  // Decompose the mesh
733  if (!decomposeFieldsOnly)
734  {
735  mesh.decomposeMesh();
736  mesh.writeDecomposition(decomposeSets);
737 
738  if (writeCellDist)
739  {
740  const labelUList& procIds = mesh.cellToProc();
741 
742  // Write decomposition for visualization
743  mesh.writeVolField("cellDist");
744  //TBD: mesh.writeVTK("cellDist");
745 
746  // Write decomposition as labelList for use with 'manual'
747  // decomposition method.
748 
749  IOobject io
750  (
751  "cellDecomposition",
753  mesh,
757  );
758 
759  labelIOList::writeContents(io, procIds);
760 
761  Info<< nl << "Wrote decomposition to "
762  << io.objectRelPath()
763  << " for use in manual decomposition." << endl;
764  }
765 
766  fileHandler().flush();
767  }
768 
769  // Finite area handling
770  // - all area regions use the same volume decomposition
772  HashTable<bool> faMeshEdgeEncoding;
773 
774  if (doFiniteArea && !areaRegionNames.empty())
775  {
776  const word boundaryInst =
777  mesh.time().findInstance(mesh.meshDir(), "boundary");
778 
779  for (const word& areaName : areaRegionNames)
780  {
781  autoPtr<faMeshDecomposition> faDecompPtr;
782 
783  IOobject io
784  (
785  "faBoundary",
786  boundaryInst,
787  faMesh::meshDir(mesh, areaName),
788  mesh.time(),
792  );
793 
794  if (io.typeHeaderOk<faBoundaryMesh>(true))
795  {
796  // Always based on the volume decomposition!
798  (
799  areaName,
800  mesh,
801  mesh.nProcs(),
802  mesh.model()
803  );
804  }
805 
806  if (faDecompPtr)
807  {
808  if (!decomposeFieldsOnly)
809  {
810  // Decompose the finite-area mesh
811  auto& aMesh = faDecompPtr();
812  Info<< "\nFinite area mesh decomposition: "
813  << areaName << endl;
814 
815  aMesh.decomposeMesh();
816  aMesh.writeDecomposition();
817 
818  // Remember edge encoding used
819  faMeshEdgeEncoding.set
820  (
821  areaName,
823  );
824  }
825 
826  // Cache for subsequent field decomposition
827  faMeshes.set(areaName, std::move(faDecompPtr));
828  }
829  }
830  }
831 
832 
833  if (copyZero)
834  {
835  // Copy the 0/ directory into each of the processor directories
836  // with fallback of 0.orig/ directory if necessary.
837 
838  fileName inputDir(runTime.path()/"0");
839 
840  bool canCopy = fileHandler().isDir(inputDir);
841  if (!canCopy)
842  {
843  // Try with "0.orig" instead
844  inputDir.ext("orig");
845  canCopy = fileHandler().isDir(inputDir);
846  }
847 
848  if (canCopy)
849  {
850  // Avoid copying into the same directory multiple times
851  // (collated format). Don't need a hash here.
852  fileName prevOutputDir;
853  for (label proci = 0; proci < mesh.nProcs(); ++proci)
854  {
855  Time processorDb
856  (
858  args.rootPath(),
859  args.caseName()/("processor" + Foam::name(proci)),
860  false, // No function objects
861  false // No extra controlDict libs
862  );
863  // processorDb.setTime(runTime);
864 
865  // Get corresponding directory name
866  // (to handle processors/)
867  const fileName outputDir
868  (
869  fileHandler().objectPath
870  (
871  IOobject
872  (
873  word::null, // name
874  "0", // instance (time == 0)
875  processorDb
876  ),
877  word::null
878  )
879  );
880 
881  if (outputDir != prevOutputDir)
882  {
883  Info<< "Processor " << proci
884  << ": copying \""
885  << inputDir.name() << "/\" to "
886  << runTime.relativePath(outputDir)
887  << endl;
888 
889  fileHandler().cp(inputDir, outputDir);
890  prevOutputDir = outputDir;
891  }
892  }
893  }
894  else
895  {
896  Info<< "No 0/ or 0.orig/ directory to copy" << nl;
897  }
898  }
899  else
900  {
901  // Decompose field files, lagrangian, finite-area
902  const auto numProcs = mesh.nProcs();
903 
904  // Cached processor meshes and maps.
905  // These are only preserved if running with multiple times.
906  PtrList<Time> processorDbList(numProcs);
907  PtrList<fvMesh> procMeshList(numProcs);
908  PtrList<labelIOList> faceProcAddressingList(numProcs);
909  PtrList<labelIOList> cellProcAddressingList(numProcs);
910  PtrList<labelIOList> boundaryProcAddressingList(numProcs);
911  PtrList<labelIOList> pointProcAddressingList(numProcs);
912  PtrList<labelIOList> pointBoundaryProcAddressingList(numProcs);
913 
914  PtrList<fvFieldDecomposer> fieldDecomposerList(numProcs);
915  PtrList<pointFieldDecomposer> pointFieldDecomposerList(numProcs);
916 
917 
918  // Cached processor meshes and maps.
919  // These are only preserved if running with multiple times.
920  HashPtrTable<PtrList<faMesh>> procFaMeshes;
921  HashPtrTable<PtrList<labelIOList>> faFaceProcAddressing;
922  HashPtrTable<PtrList<labelIOList>> faEdgeProcAddressing;
923  HashPtrTable<PtrList<labelIOList>> faBoundProcAddressing;
924  HashPtrTable<PtrList<faFieldDecomposer>> faFieldDecomposers;
925 
926  // Slightly wasteful, but with an *existing* finite-area
927  // decomposition must scan edgeProcAddressing (from disk)
928  // to know if it uses flip encoding or not.
929 
930  if
931  (
932  doDecompFields
933  && !faMeshes.empty() && faMeshEdgeEncoding.empty()
934  )
935  {
936  for (label proci = numProcs-1; proci >= 0; --proci)
937  {
938  auto& procTime = emplaceTime(processorDbList, proci, args);
939 
940  forAllConstIters(faMeshes, iter)
941  {
942  const word& areaName = iter.key();
943 
944  if (faMeshEdgeEncoding.contains(areaName))
945  {
946  // Already found the encoding type
947  continue;
948  }
949 
950  IOobject ioAddr
951  (
952  "edgeProcAddressing",
953  procTime.constant(),
954  faMesh::meshDir(regionName, areaName),
955  procTime,
959  );
960 
961  labelList edgeProcAddr
962  (
964  );
965 
966  // Look for 0 or -ve values
967  auto i = ListOps::find_if
968  (
969  edgeProcAddr,
970  labelRange::le0()
971  );
972 
973  if (i >= 0)
974  {
975  // A -ve value : definitely uses edge encoding.
976  // A '0' value : only occurs without encoding.
977  faMeshEdgeEncoding.set
978  (
979  areaName,
980  (edgeProcAddr[i] < 0)
981  );
982  }
983  }
984  }
985  }
986 
987  // Report edge-encoding (if disabled)
988  if (!faMeshEdgeEncoding.empty())
989  {
990  bool header = false;
991  forAllConstIters(faMeshEdgeEncoding, iter)
992  {
993  const auto& areaName = iter.key();
994  const bool encoding = iter.val();
995 
996  if (!encoding)
997  {
998  if (!header)
999  {
1000  header = true;
1001  Info<< "Area region without edge encoding:" << nl;
1002  }
1003  Info<< " " << areaName;
1004  }
1005  }
1006  if (header)
1007  {
1008  Info<< endl;
1009  }
1010  }
1011 
1012 
1013  // Loop over all times
1014  forAll(times, timei)
1015  {
1016  runTime.setTime(times[timei], timei);
1017 
1018  Info<< nl << "Time = " << runTime.timeName() << endl;
1019 
1020  // Field objects at this time
1021  IOobjectList objects;
1022 
1023  if (doDecompFields)
1024  {
1025  // List of volume mesh objects for this instance
1026  objects = IOobjectList(mesh, runTime.timeName());
1027 
1028  // Ignore generated fields: (cellDist)
1029  objects.remove("cellDist");
1030 
1031  }
1032 
1033  // The finite-area fields (single or multiple per volume)
1034  HashTable<IOobjectList> faObjects;
1035 
1036  if (doDecompFields && doFiniteArea && faMeshes.size())
1037  {
1038  // Lists of finite-area fields
1039  faObjects.reserve(faMeshes.size());
1040 
1041  forAllConstIters(faMeshes, iter)
1042  {
1043  const word& areaName = iter.key();
1044 
1045  // The finite-area objects for this area region
1046  IOobjectList objs
1047  (
1049  runTime.timeName(),
1050  polyMesh::regionName(areaName),
1052  );
1053 
1054  if (!objs.empty())
1055  {
1056  faObjects.emplace_set(areaName, std::move(objs));
1057  }
1058  }
1059  }
1060 
1061  // Volume/surface/internal fields
1062  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1063 
1064  fvFieldDecomposer::fieldsCache volumeFieldCache;
1065  if (doDecompFields)
1066  {
1067  volumeFieldCache.readAllFields(mesh, objects);
1068  }
1069 
1070 
1071  // Point fields
1072  // ~~~~~~~~~~~~
1073 
1074  // Read decomposed pointMesh
1075  const pointMesh& pMesh =
1077 
1078  pointFieldDecomposer::fieldsCache pointFieldCache;
1079  if (doDecompFields)
1080  {
1081  pointFieldCache.readAllFields(pMesh, objects);
1082  }
1083 
1084 
1085  // Lagrangian fields
1086  // ~~~~~~~~~~~~~~~~~
1087 
1088  fileNameList cloudDirs;
1089  if (doDecompFields && doLagrangian)
1090  {
1091  cloudDirs = fileHandler().readDir
1092  (
1095  );
1096  }
1097 
1098  // Particles
1099  PtrList<Cloud<indexedParticle>> lagrangianPositions
1100  (
1101  cloudDirs.size()
1102  );
1103  // Particles per cell
1104  PtrList<List<SLList<indexedParticle*>*>> cellParticles
1105  (
1106  cloudDirs.size()
1107  );
1108 
1109  lagrangianFieldDecomposer::fieldsCache lagrangianFieldCache
1110  (
1111  cloudDirs.size()
1112  );
1113 
1114  label cloudI = 0;
1115 
1116  for (const fileName& cloudDir : cloudDirs)
1117  {
1118  IOobjectList cloudObjects
1119  (
1120  mesh,
1121  runTime.timeName(),
1122  cloud::prefix/cloudDir,
1124  );
1125 
1126  // Note: look up "positions" for backwards compatibility
1127  if
1128  (
1129  cloudObjects.found("coordinates")
1130  || cloudObjects.found("positions")
1131  )
1132  {
1133  // Read lagrangian particles
1134  // ~~~~~~~~~~~~~~~~~~~~~~~~~
1135 
1136  Info<< "Identified lagrangian data set: "
1137  << cloudDir << endl;
1138 
1139  lagrangianPositions.set
1140  (
1141  cloudI,
1143  (
1144  mesh,
1145  cloudDir,
1146  false
1147  )
1148  );
1149 
1150 
1151  // Sort particles per cell
1152  // ~~~~~~~~~~~~~~~~~~~~~~~
1153 
1154  cellParticles.set
1155  (
1156  cloudI,
1158  (
1159  mesh.nCells(),
1160  static_cast<SLList<indexedParticle*>*>(nullptr)
1161  )
1162  );
1163 
1164  label i = 0;
1165 
1166  for (indexedParticle& p : lagrangianPositions[cloudI])
1167  {
1168  p.index() = i++;
1169 
1170  label celli = p.cell();
1171 
1172  // Check
1173  if (celli < 0 || celli >= mesh.nCells())
1174  {
1176  << "Illegal cell number " << celli
1177  << " for particle with index "
1178  << p.index()
1179  << " at position "
1180  << p.position() << nl
1181  << "Cell number should be between 0 and "
1182  << mesh.nCells()-1 << nl
1183  << "On this mesh the particle should"
1184  << " be in cell "
1185  << mesh.findCell(p.position())
1186  << exit(FatalError);
1187  }
1188 
1189  if (!cellParticles[cloudI][celli])
1190  {
1191  cellParticles[cloudI][celli] =
1193  }
1194 
1195  cellParticles[cloudI][celli]->append(&p);
1196  }
1197 
1198  // Read fields
1199  // ~~~~~~~~~~~
1200 
1201  IOobjectList lagrangianObjects
1202  (
1203  mesh,
1204  runTime.timeName(),
1205  cloud::prefix/cloudDirs[cloudI],
1207  );
1208 
1209  lagrangianFieldCache.readAllFields
1210  (
1211  cloudI,
1212  lagrangianObjects
1213  );
1214 
1215  ++cloudI;
1216  }
1217  }
1218 
1219  lagrangianPositions.resize(cloudI);
1220  cellParticles.resize(cloudI);
1221  lagrangianFieldCache.resize(cloudI);
1222 
1223 
1224  // Finite-area (area/edge) fields
1225  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1226 
1228 
1229  if (doDecompFields && doFiniteArea)
1230  {
1231  forAllConstIters(faObjects, iter)
1232  {
1233  const word& areaName = iter.key();
1234  const auto& objs = iter.val();
1235 
1236  if
1237  (
1238  const auto meshIter = faMeshes.cfind(areaName);
1239  (meshIter.good() && !objs.empty())
1240  )
1241  {
1242  const faMesh& aMesh = *(meshIter.val());
1243  auto& cache = areaFieldCaches.emplace_set(areaName);
1244 
1245  cache.readAllFields(aMesh, objs);
1246  }
1247  }
1248  }
1249 
1250  Info<< endl;
1251 
1252  // Split the fields over processors
1253  for
1254  (
1255  label proci = 0;
1256  doDecompFields && proci < numProcs;
1257  ++proci
1258  )
1259  {
1260  Info<< "Processor " << proci << ": field transfer" << endl;
1261 
1262  auto& processorDb =
1263  emplaceTime(processorDbList, proci, args);
1264  processorDb.setTime(runTime);
1265 
1266  // Read the mesh
1267  const auto& procMesh = procMeshList.try_emplace
1268  (
1269  proci,
1270  IOobject
1271  (
1272  regionName,
1273  processorDb.timeName(),
1274  processorDb
1275  )
1276  );
1277 
1278  const auto& faceProcAddressing = procAddressing
1279  (
1280  procMeshList,
1281  proci,
1282  "faceProcAddressing",
1283  faceProcAddressingList
1284  );
1285 
1286  const auto& cellProcAddressing = procAddressing
1287  (
1288  procMeshList,
1289  proci,
1290  "cellProcAddressing",
1291  cellProcAddressingList
1292  );
1293 
1294  const auto& boundaryProcAddressing = procAddressing
1295  (
1296  procMeshList,
1297  proci,
1298  "boundaryProcAddressing",
1299  boundaryProcAddressingList
1300  );
1301 
1302 
1303  // FV fields: volume, surface, internal
1304  {
1305  if (!fieldDecomposerList.test(proci))
1306  {
1307  fieldDecomposerList.set
1308  (
1309  proci,
1310  new fvFieldDecomposer
1311  (
1312  mesh,
1313  procMesh,
1314  faceProcAddressing,
1315  cellProcAddressing,
1316  boundaryProcAddressing
1317  )
1318  );
1319  }
1320 
1321  volumeFieldCache.decomposeAllFields
1322  (
1323  fieldDecomposerList[proci]
1324  );
1325 
1326  if (times.size() == 1)
1327  {
1328  // Clear cached decomposer
1329  fieldDecomposerList.set(proci, nullptr);
1330  }
1331  }
1332 
1333 
1334  // Point fields
1335  if (!pointFieldCache.empty())
1336  {
1337  const auto& pointProcAddressing = procAddressing
1338  (
1339  procMeshList,
1340  proci,
1341  "pointProcAddressing",
1342  pointProcAddressingList
1343  );
1344 
1345  const pointMesh& procPMesh =
1347 
1348  if (!pointBoundaryProcAddressingList.test(proci))
1349  {
1350  pointBoundaryProcAddressingList.set
1351  (
1352  proci,
1354  (
1355  IOobject
1356  (
1357  "boundaryProcAddressing",
1358  procMesh.facesInstance(),
1361  procPMesh.thisDb(),
1365  ),
1366  boundaryProcAddressing
1367  )
1368  );
1369  }
1370  const auto& pointBoundaryProcAddressing =
1371  pointBoundaryProcAddressingList[proci];
1372 
1373 
1374  if (!pointFieldDecomposerList.test(proci))
1375  {
1376  pointFieldDecomposerList.set
1377  (
1378  proci,
1380  (
1381  pMesh,
1382  procPMesh,
1383  pointProcAddressing,
1384  pointBoundaryProcAddressing
1385  )
1386  );
1387  }
1388 
1389  pointFieldCache.decomposeAllFields
1390  (
1391  pointFieldDecomposerList[proci]
1392  );
1393 
1394  if (times.size() == 1)
1395  {
1396  // Early deletion
1397  pointBoundaryProcAddressingList.set
1398  (
1399  proci,
1400  nullptr
1401  );
1402  pointProcAddressingList.set(proci, nullptr);
1403  pointFieldDecomposerList.set(proci, nullptr);
1404  }
1405  }
1406 
1407 
1408  // If there is lagrangian data write it out
1409  forAll(lagrangianPositions, cloudi)
1410  {
1411  if (lagrangianPositions[cloudi].size())
1412  {
1413  lagrangianFieldDecomposer fieldDecomposer
1414  (
1415  mesh,
1416  procMesh,
1417  faceProcAddressing,
1418  cellProcAddressing,
1419  cloudDirs[cloudi],
1420  lagrangianPositions[cloudi],
1421  cellParticles[cloudi]
1422  );
1423 
1424  // Lagrangian fields
1425  lagrangianFieldCache.decomposeAllFields
1426  (
1427  cloudi,
1428  cloudDirs[cloudi],
1429  fieldDecomposer
1430  );
1431  }
1432  }
1433 
1434  if (doDecompFields)
1435  {
1436  // Decompose "uniform" directory in the time region
1437  // directory
1438  decomposeUniform
1439  (
1440  copyUniform, mesh, processorDb, regionDir
1441  );
1442 
1443  // For a multi-region case, also decompose "uniform"
1444  // directory in the time directory
1445  if (regionNames.size() > 1 && regioni == 0)
1446  {
1447  decomposeUniform(copyUniform, mesh, processorDb);
1448  }
1449  }
1450 
1451  if (times.size() == 1)
1452  {
1453  // Early deletion
1454  boundaryProcAddressingList.set(proci, nullptr);
1455  cellProcAddressingList.set(proci, nullptr);
1456  faceProcAddressingList.set(proci, nullptr);
1457  }
1458 
1459  // Finite-area fields
1460  for (const auto& iter : areaFieldCaches.csorted())
1461  {
1462  const word& areaName = iter.key();
1463  const auto& areaCache = *(iter.val());
1464 
1465  // Serial mesh:
1466  const faMesh& aMesh = *(faMeshes[areaName]);
1467 
1468  // List of proc meshes:
1469  auto& faProcMeshList =
1470  procFaMeshes.try_emplace(areaName, numProcs);
1471 
1472  auto& procFaMesh =
1473  faProcMeshList
1474  .try_emplace(proci, areaName, procMesh);
1475 
1476  const auto& faFaceProcAddr =
1477  procAddressing
1478  (
1479  faProcMeshList,
1480  proci,
1481  "faceProcAddressing",
1482  faFaceProcAddressing.try_emplace(areaName)
1483  );
1484 
1485  const auto& faBoundProcAddr =
1486  procAddressing
1487  (
1488  faProcMeshList,
1489  proci,
1490  "boundaryProcAddressing",
1491  faBoundProcAddressing.try_emplace(areaName)
1492  );
1493 
1494  const auto& faEdgeProcAddr =
1495  procAddressing
1496  (
1497  faProcMeshList,
1498  proci,
1499  "edgeProcAddressing",
1500  faEdgeProcAddressing.try_emplace(areaName)
1501  );
1502 
1503 
1504  auto& faFieldDecomposerList =
1505  faFieldDecomposers.try_emplace(areaName, numProcs);
1506 
1507  if (!faFieldDecomposerList.test(proci))
1508  {
1509  faFieldDecomposerList.emplace
1510  (
1511  proci,
1512  //
1513  aMesh,
1514  procFaMesh,
1515  faEdgeProcAddr,
1516  faFaceProcAddr,
1517  faBoundProcAddr,
1518  // noEdgeEncoding
1519  (!faMeshEdgeEncoding.lookup(areaName, true))
1520  );
1521  }
1522 
1523  auto& fieldDecomposer = faFieldDecomposerList[proci];
1524 
1525  areaCache.decomposeAllFields
1526  (
1527  fieldDecomposer,
1528  args.verbose() // report
1529  );
1530  }
1531 
1532  // We have cached all the constant mesh data for the current
1533  // processor. This is only important if running with
1534  // multiple times, otherwise it is just extra storage.
1535  if (times.size() == 1)
1536  {
1537  forAllIters(faFieldDecomposers, iter)
1538  {
1539  iter.val()->set(proci, nullptr);
1540  }
1541  forAllIters(faEdgeProcAddressing, iter)
1542  {
1543  iter.val()->set(proci, nullptr);
1544  }
1545  forAllIters(faFaceProcAddressing, iter)
1546  {
1547  iter.val()->set(proci, nullptr);
1548  }
1549  forAllIters(faBoundProcAddressing, iter)
1550  {
1551  iter.val()->set(proci, nullptr);
1552  }
1553  forAllIters(procFaMeshes, iter)
1554  {
1555  iter.val()->set(proci, nullptr);
1556  }
1557 
1558  procMeshList.set(proci, nullptr);
1559  processorDbList.set(proci, nullptr);
1560  }
1561  }
1562  }
1563  }
1564  }
1565 
1566  Info<< "\nEnd\n" << endl;
1567 
1568  return 0;
1569 }
1570 
1571 
1572 // ************************************************************************* //
Finite area mesh (used for 2-D non-Euclidian finite area method) defined using a patch of faces on a ...
Definition: faMesh.H:133
T & try_emplace(const Key &key, Args &&... args)
Like emplace_set() but will not overwrite an occupied (non-null) location.
const T * test(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
Definition: UPtrListI.H:127
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:477
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:119
A class for handling file names.
Definition: fileName.H:72
List of IOobjects with searching and retrieving facilities. Implemented as a HashTable, so the various sorted methods should be used if traversing in parallel.
Definition: IOobjectList.H:55
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:844
void append(const T &elem)
Add copy at back of list.
Definition: LList.H:744
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
bool empty() const noexcept
No fields.
fileName timePath() const
Return current time path = path/timeName.
Definition: Time.H:512
fileName path() const
The path for the case = rootPath/caseName.
Definition: TimePathsI.H:102
const word & regionName() const
The mesh region name or word::null if polyMesh::defaultRegion.
Definition: polyMesh.C:832
bool allowFaModels() noexcept
The enable/disable state for regionFaModel (default: true)
void readAllFields(const faMesh &mesh, const IOobjectList &objects)
Read all fields given mesh and objects.
Template class for non-intrusive linked lists.
Definition: LList.H:46
static FOAM_NO_DANGLING_REFERENCE const pointMesh & New(const polyMesh &mesh, Args &&... args)
Get existing or create MeshObject registered with typeName.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
bool empty() const noexcept
True if List is empty (ie, size() is zero)
Definition: UList.H:702
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:412
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:518
bool chDir(const fileName &dir)
Change current directory to the one specified and return true on success.
Definition: POSIX.C:613
fileName relativePath(const fileName &input, const bool caseTag=false) const
Return the input relative to the globalPath by stripping off a leading value of the globalPath...
Definition: TimePathsI.H:122
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:389
UPtrList< const node_type > csorted() const
Const access to the hash-table contents in sorted order (sorted by keys).
Definition: HashTable.C:181
static void noParallel()
Remove the parallel options.
Definition: argList.C:599
refPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler - forwards to fileOperation::handler()
static const word canonicalName
The canonical name ("decomposeParDict") under which the MeshObject is registered. ...
fileName globalPath() const
The global path for the case = rootPath/globalCaseName.
Definition: TimePathsI.H:108
wordList regionNames
static bool isAbsolute(const std::string &str)
Return true if filename starts with a &#39;/&#39; or &#39;\&#39; or (windows-only) with a filesystem-root.
Definition: fileNameI.H:129
Ignore writing from objectRegistry::writeObject()
A HashTable of pointers to objects of type <T>, with deallocation management of the pointers...
Definition: HashPtrTable.H:51
void decomposeAllFields(const fvFieldDecomposer &decomposer, bool report=false) const
Decompose and write all fields.
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:300
static void writeContents(const IOobject &io, const UList< label > &content)
Write contents. The IOobject is never registered.
Definition: IOList.C:194
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:360
static void addOptionCompat(const word &optName, std::pair< const char *, int > compat)
Specify an alias for the option name.
Definition: argList.C:433
Automatic domain decomposition class for finite-volume meshes.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:68
wordList areaRegionNames
bool allowFunctionObjects() const
The controlDict &#39;functions&#39; entry is allowed to be used.
Definition: argList.C:2279
#define FOAM_NO_DANGLING_REFERENCE
Definition: stdFoam.H:81
void readAllFields(const pointMesh &mesh, const IOobjectList &objects)
Read all fields given mesh and objects.
bool emplace_set(const Key &key, Args &&... args)
Emplace set an entry, overwriting any existing entries.
Definition: HashTableI.H:141
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:127
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:50
Mesh representing a set of points created from polyMesh.
Definition: pointMesh.H:45
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:400
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:866
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:358
bool allowLibs() const
The controlDict &#39;libs&#39; entry is allowed to be used. (eg, has not been disabled by the -no-libs option...
Definition: argList.C:2297
static const objectRegistry & Registry(const polyMesh &pMesh)
Return the singleton parent registry (on the polyMesh) that contains all objects related to finite-ar...
Definition: faMesh.C:157
void readAllFields(const fvMesh &mesh, const IOobjectList &objects)
Read all fields given mesh and objects.
static List< label > readContents(const IOobject &io)
Read and return contents. The IOobject is never registered.
Definition: IOList.C:177
dynamicFvMesh & mesh
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:620
T & emplace_set(const Key &key, Args &&... args)
Emplace set an entry, overwriting any existing entries.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
bool contains(const Key &key) const
True if hashed key is contained (found) in table.
Definition: HashTableI.H:72
word findInstance(const fileName &directory, const word &name=word::null, IOobjectOption::readOption rOpt=IOobjectOption::MUST_READ, const word &stopInstance=word::null, const bool constant_fallback=true) const
Return time instance (location) of directory containing the file name (eg, used in reading mesh data)...
Definition: Time.C:724
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
Definition: HashTableI.H:113
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:133
A class for handling words, derived from Foam::string.
Definition: word.H:63
static void addDryRunOption(const string &usage, bool advanced=false)
Enable a &#39;dry-run&#39; bool option, with usage information.
Definition: argList.C:519
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
Definition: faMesh.C:1022
const Time & time() const noexcept
Return time registry.
const word & executable() const noexcept
Name of executable without the path.
Definition: argListI.H:44
int dryRun() const noexcept
Return the dry-run flag.
Definition: argListI.H:109
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:407
Extract command arguments and options from the supplied argc and argv parameters. ...
Definition: argList.H:118
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
bool set(const Key &key, T *ptr)
Assign a new entry, overwrites existing.
const word & system() const noexcept
Return system name.
Definition: TimePathsI.H:137
const auto & io
const objectRegistry & thisDb() const
Return database. For now is its polyMesh.
Definition: pointMesh.H:201
Reading is optional [identical to LAZY_READ].
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:315
static const word null
An empty word.
Definition: word.H:84
bool exists(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: POSIX.C:841
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:400
static instantList selectIfPresent(Time &runTime, const argList &args)
If any time option provided return the set of times - as per select0() - otherwise return just the cu...
Definition: timeSelector.C:291
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition: Time.C:904
A HashTable similar to std::unordered_map.
Definition: HashTable.H:108
static word controlDictName
The default control dictionary name (normally "controlDict")
Definition: Time.H:267
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:106
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
Definition: PtrList.H:174
const fileName & caseName() const noexcept
Return case name (parallel run) or global case (serial run)
Definition: argListI.H:62
label nDomains() const noexcept
Number of domains.
void resize(label newCapacity)
Rehash the hash table with new number of buckets. Currently identical to setCapacity() ...
Definition: HashTable.C:722
bool empty() const noexcept
True if the hash table is empty.
Definition: HashTable.H:353
static void addVerboseOption(const string &usage="", bool advanced=false)
Enable a &#39;verbose&#39; bool option, with usage information.
Definition: argList.C:535
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
Definition: Time.C:713
Point field decomposer.
const fileName & rootPath() const noexcept
Return root path.
Definition: argListI.H:56
T & try_emplace(const label i, Args &&... args)
Like emplace_set() but will not overwrite an occupied (non-null) location.
Definition: PtrListI.H:211
Finite Volume volume and surface field decomposer.
void resize(const label newLen)
Adjust size of PtrList.
Definition: PtrList.C:120
Required Classes.
void decomposeAllFields(const pointFieldDecomposer &decomposer, bool report=false) const
Decompose and write all fields.
static word meshSubDir
Return the mesh sub-directory name (usually "pointMesh")
Definition: pointMesh.H:107
static word meshSubDir
The mesh sub-directory name (usually "faMesh")
Definition: faMesh.H:750
bool starts_with(char c) const
True if string starts with given character (cf. C++20)
Definition: string.H:436
Ostream & flush(Ostream &os)
Flush stream.
Definition: Ostream.H:508
const T & lookup(const Key &key, const T &deflt) const
Return hashed entry if it exists, or return the given default.
Definition: HashTableI.H:222
Foam::word regionName(args.getOrDefault< word >("region", Foam::polyMesh::defaultRegion))
label nCells() const noexcept
Number of mesh cells.
autoPtr< IOobject > remove(const IOobject &io)
Remove object from the list by its IOobject::name().
Definition: IOobjectList.H:302
const word & regionDir
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: PtrList.H:56
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
Definition: HashTable.C:729
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
Definition: polyMesh.C:826
Nothing to be read.
Required Classes.
fileName cwd()
The physical or logical current working directory path name.
Definition: POSIX.C:596
Finite area boundary mesh, which is a faPatch list with registered IO, a reference to the associated ...
label findCell(const point &p, const cellDecomposition=CELL_TETS) const
Find cell enclosing this location and return index.
Definition: polyMesh.C:1496
messageStream Info
Information stream (stdout output on master, null elsewhere)
label find_if(const ListType &input, const UnaryPredicate &pred, const label start=0)
Find index of the first occurrence that satisfies the predicate.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:416
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
Definition: argListI.H:316
volScalarField & p
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition: autoPtr.H:178
Testing of domain decomposition for finite-volume meshes.
fileNameList readDir(const fileName &directory, const fileName::Type type=fileName::Type::FILE, const bool filtergz=true, const bool followLink=true)
Read a directory and return the entries as a fileName List.
Definition: POSIX.C:969
Foam::argList args(argc, argv)
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:188
A class for handling character strings derived from std::string.
Definition: string.H:73
Adds label index to base particle.
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:644
int verbose() const noexcept
Return the verbose flag.
Definition: argListI.H:121
Do not request registration (bool: false)
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:171
static void addOptions(const bool constant=true, const bool withZero=false)
Add timeSelector options to argList::validOptions.
Definition: timeSelector.C:101
bool set(const Key &key, const T &obj)
Copy assign a new entry, overwriting existing entries.
Definition: HashTableI.H:174
Namespace for OpenFOAM.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
static IOobject selectIO(const IOobject &io, const fileName &altFile, const word &ioName="")
Return the IOobject, but also consider an alternative file name.
Definition: IOobject.C:256
static bool allowEdgeEncoding() noexcept
The enable/disable state for allowing encoding of edgeProcAddressing edge flips (default: true) ...
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
Definition: UPtrList.H:366
Lagrangian field decomposer.
static const word prefix
The prefix to local: lagrangian.
Definition: cloud.H:79