178 const word& instance,
204 const word& instance,
208 return procAddressing(procMesh,
name, instance, local);
221 const fvMesh& procMesh = procMeshList[proci];
223 if (!procAddressingList.
set(proci))
225 procAddressingList.
set
231 return procAddressingList[proci];
237 const bool copyUniform,
239 const Time& processorDb,
250 Info<<
"Detected additional non-decomposed files in "
261 if (copyUniform ||
mesh.distributed())
275 string parentPath =
string(
"..")/
"..";
279 parentPath = parentPath/
"..";
305int main(
int argc,
char *argv[])
309 "Decompose a mesh and fields of a case for parallel execution"
312 argList::noParallel();
317 "Use specified file for decomposePar dictionary"
322 argList::addDryRunOption
324 "Test without writing the decomposition. "
325 "Changes -cellDist to only write VTK output."
327 argList::addVerboseOption(
"Additional verbosity");
332 "Override numberOfSubdomains (-dry-run only)",
339 "Override decomposition method (-dry-run only)",
343 argList::addBoolOption
346 "Suppress finiteArea mesh/field decomposition",
350 argList::addBoolOption
353 "Suppress lagrangian (cloud) decomposition",
357 argList::addBoolOption
360 "Write cell distribution as a labelList - for use with 'manual' "
361 "decomposition method and as a volScalarField for visualization."
363 argList::addBoolOption
366 "Copy 0/ directory to processor*/ rather than decompose the fields"
368 argList::addBoolOption
371 "Copy any uniform/ directories too"
373 argList::addBoolOption
376 "Use existing geometry decomposition and convert fields only"
378 argList::addBoolOption
381 "Suppress conversion of fields (volume, finite-area, lagrangian)"
384 argList::addBoolOption
387 "Skip decomposing cellSets, faceSets, pointSets"
389 argList::addOptionCompat(
"no-sets", {
"noSets", 2106});
391 argList::addBoolOption
394 "Remove existing processor*/ subdirs before decomposing the geometry"
396 argList::addBoolOption
399 "Only decompose geometry if the number of domains has changed"
403 timeSelector::addOptions(
true,
false);
407 const bool writeCellDist =
args.
found(
"cellDist");
410 const bool copyZero =
args.
found(
"copyZero");
411 const bool copyUniform =
args.
found(
"copyUniform");
412 const bool decomposeSets = !
args.
found(
"no-sets");
414 const bool decomposeIfRequired =
args.
found(
"ifRequired");
416 const bool doDecompFields = !
args.
found(
"no-fields");
417 const bool doFiniteArea = !
args.
found(
"no-finite-area");
418 const bool doLagrangian = !
args.
found(
"no-lagrangian");
420 bool decomposeFieldsOnly =
args.
found(
"fields");
421 bool forceOverwrite =
args.
found(
"force");
431 Info<<
"\ndry-run: ignoring -copy*, -fields, -force, time selection"
436 if (decomposeFieldsOnly && !doDecompFields)
439 <<
"Options -fields and -no-fields are mutually exclusive"
440 <<
" ... giving up" <<
nl
446 Info<<
"Skip decompose of all fields" <<
nl;
450 Info<<
"Skip decompose of finiteArea mesh/fields" <<
nl;
454 Info<<
"Skip decompose of lagrangian positions/fields" <<
nl;
457 times = timeSelector::selectIfPresent(
runTime,
args);
463 if (!decompDictFile.empty() && !decompDictFile.isAbsolute())
465 decompDictFile =
runTime.globalPath()/decompDictFile;
471 const bool optRegions =
487 <<
"Create mesh..." <<
flush;
509 Info<<
"\n\nDecomposing mesh";
517 const label nProcsOld =
522 const label nDomains = decompositionMethod::nDomains
530 decompositionModel::canonicalName,
546 if (decomposeFieldsOnly)
549 if (nProcsOld != nDomains)
552 <<
"Specified -fields, but the case was decomposed with "
553 << nProcsOld <<
" domains"
555 <<
"instead of " << nDomains
556 <<
" domains as specified in decomposeParDict" <<
nl
562 bool procDirsProblem =
true;
564 if (decomposeIfRequired && nProcsOld == nDomains)
567 decomposeFieldsOnly =
true;
568 procDirsProblem =
false;
569 forceOverwrite =
false;
571 Info<<
"Using existing processor directories" <<
nl;
576 procDirsProblem =
false;
577 forceOverwrite =
false;
582 Info<<
"Removing " << nProcsOld
583 <<
" existing processor directories" <<
endl;
591 fileName::Type::DIRECTORY
620 procDirsProblem =
false;
626 <<
"Case is already decomposed with " << nProcsOld
627 <<
" domains, use the -force option or manually" <<
nl
628 <<
"remove processor directories before decomposing. e.g.,"
630 <<
" rm -rf " <<
runTime.path().c_str() <<
"/processor*"
652 if (!decomposeFieldsOnly)
654 mesh.decomposeMesh();
655 mesh.writeDecomposition(decomposeSets);
662 mesh.writeVolField(
"cellDist");
672 mesh.facesInstance(),
680 cellDecomposition.write();
682 Info<<
nl <<
"Wrote decomposition to "
683 << cellDecomposition.objectRelPath()
684 <<
" for use in manual decomposition." <<
endl;
702 inputDir.ext(
"orig");
711 for (label proci = 0; proci <
mesh.nProcs(); ++proci)
715 Time::controlDictName,
737 if (outputDir != prevOutputDir)
739 Info<<
"Processor " << proci
741 << inputDir.name() <<
"/\" to "
742 <<
runTime.relativePath(outputDir)
746 prevOutputDir = outputDir;
752 Info<<
"No 0/ or 0.orig/ directory to copy" <<
nl;
778 runTime.setTime(times[timei], timei);
790 objects.
remove(
"cellDist");
800 mesh.time().findInstance
802 mesh.dbDir()/polyMesh::meshSubDir,
807 IOobject::READ_IF_PRESENT,
815 faMeshDecompPtr.
reset
856 if (doDecompFields && doLagrangian)
860 runTime.timePath()/cloud::prefix,
883 for (
const fileName& cloudDir : cloudDirs)
889 cloud::prefix/cloudDir,
898 cloudObjects.found(
"coordinates")
899 || cloudObjects.found(
"positions")
905 Info<<
"Identified lagrangian data set: "
908 lagrangianPositions.set
939 label celli =
p.cell();
942 if (celli < 0 || celli >=
mesh.nCells())
945 <<
"Illegal cell number " << celli
946 <<
" for particle with index "
949 <<
p.position() <<
nl
950 <<
"Cell number should be between 0 and "
952 <<
"On this mesh the particle should"
954 <<
mesh.findCell(
p.position())
958 if (!cellParticles[cloudI][celli])
960 cellParticles[cloudI][celli] =
964 cellParticles[cloudI][celli]->append(&
p);
974 cloud::prefix/cloudDirs[cloudI],
980 lagrangianFieldCache.readAllFields
990 lagrangianPositions.resize(cloudI);
991 cellParticles.resize(cloudI);
992 lagrangianFieldCache.resize(cloudI);
1000 doDecompFields && proci <
mesh.nProcs();
1004 Info<<
"Processor " << proci <<
": field transfer" <<
endl;
1007 if (!processorDbList.set(proci))
1014 Time::controlDictName,
1021 Time& processorDb = processorDbList[proci];
1027 if (!procMeshList.
set(proci))
1043 const fvMesh& procMesh = procMeshList[proci];
1045 const labelIOList& faceProcAddressing = procAddressing
1049 "faceProcAddressing",
1050 faceProcAddressingList
1053 const labelIOList& cellProcAddressing = procAddressing
1057 "cellProcAddressing",
1058 cellProcAddressingList
1061 const labelIOList& boundaryProcAddressing = procAddressing
1065 "boundaryProcAddressing",
1066 boundaryProcAddressingList
1072 if (!fieldDecomposerList.set(proci))
1074 fieldDecomposerList.set
1083 boundaryProcAddressing
1090 fieldDecomposerList[proci]
1093 if (times.
size() == 1)
1096 fieldDecomposerList.set(proci,
nullptr);
1102 if (!pointFieldCache.
empty())
1104 const labelIOList& pointProcAddressing = procAddressing
1108 "pointProcAddressing",
1109 pointProcAddressingList
1112 const pointMesh& procPMesh = pointMesh::New(procMesh);
1114 if (!pointFieldDecomposerList.set(proci))
1116 pointFieldDecomposerList.set
1123 pointProcAddressing,
1124 boundaryProcAddressing
1131 pointFieldDecomposerList[proci]
1134 if (times.
size() == 1)
1136 pointProcAddressingList.set(proci,
nullptr);
1137 pointFieldDecomposerList.set(proci,
nullptr);
1143 forAll(lagrangianPositions, cloudi)
1145 if (lagrangianPositions[cloudi].size())
1154 lagrangianPositions[cloudi],
1155 cellParticles[cloudi]
1159 lagrangianFieldCache.decomposeAllFields
1181 decomposeUniform(copyUniform,
mesh, processorDb);
1189 if (times.
size() == 1)
1191 boundaryProcAddressingList.set(proci,
nullptr);
1192 cellProcAddressingList.set(proci,
nullptr);
1193 faceProcAddressingList.set(proci,
nullptr);
1194 procMeshList.
set(proci,
nullptr);
1195 processorDbList.set(proci,
nullptr);
1201 if (faMeshDecompPtr)
1203 Info<<
"\nFinite area mesh decomposition" <<
endl;
1207 aMesh.decomposeMesh();
1208 aMesh.writeDecomposition();
1221 const label nAreaFields = areaFieldCache.
size();
1224 Info<<
"Finite area field transfer: "
1225 << nAreaFields <<
" fields" <<
endl;
1231 nAreaFields && proci <
mesh.nProcs();
1235 Info<<
" Processor " << proci <<
endl;
1240 Time::controlDictName,
1259 faMesh procMesh(procFvMesh);
1286 "faceProcAddressing",
1289 auto& faceProcAddressing = *tfaceProcAddr;
1295 "boundaryProcAddressing",
1298 auto& boundaryProcAddressing = *tboundaryProcAddr;
1304 "edgeProcAddressing",
1307 const auto& edgeProcAddressing = *tedgeProcAddr;
1315 boundaryProcAddressing
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Base cloud calls templated on particle type.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
List of IOobjects with searching and retrieving facilities.
bool remove(const IOobject &io)
Remove IOobject from the list.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Template class for non-intrusive linked lists.
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
const T * set(const label i) const
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
static word timeName(const scalar t, const int precision=precision_)
fileName timePath() const
Return current time path.
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
void size(const label n)
Older name for setAddressableSize.
T get(const label index) const
Get a value from the argument at index.
int dryRun() const noexcept
Return the dry-run flag.
int verbose() const noexcept
Return the verbose flag.
const fileName & rootPath() const noexcept
Return root path.
bool found(const word &optName) const
Return true if the named option is found.
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
const word & executable() const noexcept
Name of executable without the path.
const fileName & caseName() const noexcept
Return case name (parallel run) or global case (serial run)
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
void reset(autoPtr< T > &&other) noexcept
Delete managed object and set to new given pointer.
Testing of domain decomposition for finite-volume meshes.
Automatic domain decomposition class for finite-volume meshes.
Finite area boundary mesh.
label size() const
Number of fields.
void readAllFields(const faMesh &mesh, const IOobjectList &objects)
Read all fields given mesh and objects.
void decomposeAllFields(const faFieldDecomposer &decomposer, bool report=false) const
Decompose and write all fields.
Finite Area area and edge field decomposer.
Automatic faMesh decomposition class.
Finite area mesh (used for 2-D non-Euclidian finite area method) defined using a patch of faces on a ...
static word meshSubDir
The mesh sub-directory name (usually "faMesh")
A class for handling file names.
An encapsulation of filesystem-related operations.
virtual void flush() const
Forcibly wait until all output done. Flush any cached data.
virtual bool cp(const fileName &src, const fileName &dst, const bool followLink=true) const =0
Copy, recursively if necessary, the source to the destination.
virtual bool rmDir(const fileName &dir, const bool silent=false) const =0
Remove a directory and its contents.
virtual bool ln(const fileName &src, const fileName &dst) const =0
Create a softlink. dst should not exist. Returns true if.
virtual label nProcs(const fileName &dir, const fileName &local="") const
Get number of processor directories/results. Used for e.g.
virtual bool isDir(const fileName &, const bool followLink=true) const =0
Does the name exist as a DIRECTORY in the file system?
virtual fileName filePath(const bool checkGlobal, const IOobject &, const word &typeName, const bool search=true) const =0
Search for an object. checkGlobal : also check undecomposed case.
virtual fileNameList readDir(const fileName &, const fileName::Type=fileName::FILE, const bool filtergz=true, const bool followLink=true) const =0
Read a directory and return the entries as a string list.
void readAllFields(const fvMesh &mesh, const IOobjectList &objects)
Read all fields given mesh and objects.
void decomposeAllFields(const fvFieldDecomposer &decomposer, bool report=false) const
Decompose and write all fields.
Finite Volume volume and surface field decomposer.
Mesh data needed to do the Finite Volume discretisation.
const Time & time() const
Return the top-level database.
Adds label index to base particle.
Lagrangian field decomposer.
void readAllFields(const pointMesh &mesh, const IOobjectList &objects)
Read all fields given mesh and objects.
bool empty() const
No fields.
void decomposeAllFields(const pointFieldDecomposer &decomposer, bool report=false) const
Decompose and write all fields.
Mesh representing a set of points created from polyMesh.
const fileName & facesInstance() const
Return the current instance directory for faces.
A class for handling character strings derived from std::string.
bool starts_with(const std::string &s) const
True if string starts with the given prefix (cf. C++20)
A class for handling words, derived from Foam::string.
static const word null
An empty word.
Foam::word regionName(Foam::polyMesh::defaultRegion)
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
const fileOperation & fileHandler()
Get current file handler.
fileName cwd()
The physical or logical current working directory path name.
bool read(const char *buf, int32_t &val)
Same as readInt32.
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?
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
IOList< label > labelIOList
Label container classes.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
errorManipArg< error, int > exit(error &err, const int errNo=1)
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Ostream & flush(Ostream &os)
Flush stream.
constexpr char nl
The newline '\n' character (0x0a)
bool chDir(const fileName &dir)
Change current directory to the one specified and return true on success.
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.
#define forAllReverse(list, i)
Reverse loop across all elements in list.