diff --git a/applications/utilities/parallelProcessing/redistributePar/Make/options b/applications/utilities/parallelProcessing/redistributePar/Make/options index 46f67054e2..56880b114a 100644 --- a/applications/utilities/parallelProcessing/redistributePar/Make/options +++ b/applications/utilities/parallelProcessing/redistributePar/Make/options @@ -4,6 +4,7 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ + -I$(LIB_SRC)/regionModels/regionModel/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/mesh/snappyHexMesh/lnInclude @@ -17,4 +18,5 @@ EXE_LIBS = \ -lmeshTools \ -llagrangian \ -ldynamicMesh \ + -lregionModels \ -lsnappyHexMesh diff --git a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C index 0e88e00b6e..133161fcc7 100644 --- a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C +++ b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C @@ -34,27 +34,38 @@ Description Must be run on maximum number of source and destination processors. Balances mesh and writes new mesh to new time directory. + Can optionally run in decompose/reconstruct mode to decompose/reconstruct + mesh and fields. + Usage + \b redistributePar [OPTION] - - redistributePar [OPTION] + Options: + - \par -decompose + Remove any existing \a processor subdirectories and decomposes the + mesh. Equivalent to running without processor subdirectories. - \param -region regionName \n - Distribute named region. + - \par -reconstruct + Reconstruct mesh and fields (like reconstructParMesh+reconstructPar). - \param -decompose \n - Remove any existing \a processor subdirectories and decomposes the - geometry. Equivalent to running without processor subdirectories. + - \par -newTimes + (in combination with -reconstruct) reconstruct only new times. - \param -reconstruct \n - Reconstruct geometry (like reconstructParMesh). Equivalent to setting - numberOfSubdomains 1 in the decomposeParDict. + - \par -dry-run + (not in combination with -reconstruct) Test without actually + decomposing. - \param -newTimes \n - (in combination with -reconstruct) reconstruct only new times. + - \par -cellDist + not in combination with -reconstruct) Write the cell distribution + as a labelList, for use with 'manual' + decomposition method and as a volScalarField for visualization. - \param -cellDist \n - Write the cell distribution as a labelList, for use with 'manual' - decomposition method or as a volScalarField for post-processing. + - \par -region \ + Distribute named region. + + - \par -allRegions + Distribute all regions in regionProperties. Does not check for + existence of processor*. \*---------------------------------------------------------------------------*/ @@ -77,6 +88,7 @@ Usage #include "processorFvPatchField.H" #include "zeroGradientFvPatchFields.H" #include "topoSet.H" +#include "regionProperties.H" #include "parFvFieldReconstructor.H" #include "parLagrangianRedistributor.H" @@ -502,7 +514,7 @@ void writeProcAddressing UPstream::msgType() ); } - else // if (nDestProcs == 1) + else // reconstruct { cellMap = identity(mesh.nCells()); map.cellMap().reverseDistribute(map.nOldCells(), cellMap); @@ -821,6 +833,7 @@ autoPtr redistributeAndWrite const fileName& meshSubDir, const bool doReadFields, const bool decompose, // decompose, i.e. read from undecomposed case + const bool reconstruct, const bool overwrite, const fileName& proc0CaseName, const label nDestProcs, @@ -1173,7 +1186,7 @@ autoPtr redistributeAndWrite map.transfer(rawMap()); - if (nDestProcs == 1) + if (reconstruct) { if (Pstream::master()) { @@ -1224,7 +1237,7 @@ autoPtr redistributeAndWrite << endl; - if (decompose || nDestProcs == 1) + if (decompose || reconstruct) { // Decompose (1 -> N) or reconstruct (N -> 1) // so {boundary,cell,face,point}ProcAddressing have meaning @@ -1275,7 +1288,7 @@ autoPtr redistributeAndWrite // Now we've read refinement data we can remove it meshRefinement::removeFiles(mesh); - if (nDestProcs == 1) + if (reconstruct) { if (Pstream::master()) { @@ -1318,7 +1331,7 @@ autoPtr redistributeAndWrite // cellSets[i].distribute(map); // } // - // if (nDestProcs == 1) + // if (reconstruct) // { // if (Pstream::master()) // { @@ -2256,9 +2269,20 @@ int main(int argc, char *argv[]) // enable -zeroTime to prevent accidentally trashing the initial fields timeSelector::addOptions(true, true); #include "addRegionOption.H" + argList::addBoolOption + ( + "allRegions", + "operate on all regions in regionProperties" + ); #include "addOverwriteOption.H" argList::addBoolOption("decompose", "Decompose case"); argList::addBoolOption("reconstruct", "Reconstruct case"); + argList::addBoolOption + ( + "dry-run", + "Test without writing the decomposition. " + "Changes -cellDist to only write volScalarField." + ); argList::addOption ( "mergeTol", @@ -2285,6 +2309,7 @@ int main(int argc, char *argv[]) Foam::argList args(argc, argv); const bool reconstruct = args.found("reconstruct"); const bool writeCellDist = args.found("cellDist"); + const bool dryrun = args.found("dry-run"); const bool newTimes = args.found("newTimes"); bool decompose = args.found("decompose"); @@ -2466,20 +2491,31 @@ int main(int argc, char *argv[]) } - // Determine any region - word regionName = polyMesh::defaultRegion; - fileName meshSubDir = polyMesh::meshSubDir; - if (args.readIfPresent("region", regionName)) - { - meshSubDir = regionName/polyMesh::meshSubDir; - } - Info<< "Using mesh subdirectory " << meshSubDir << nl << endl; - - // Allow override of decomposeParDict location fileName decompDictFile; args.readIfPresent("decomposeParDict", decompDictFile); + // Get all region names + wordList regionNames; + if (args.found("allRegions")) + { + Info<< "Decomposing all regions in regionProperties" << nl << endl; + regionProperties rp(runTime); + + wordHashSet names; + forAllConstIters(rp, iter) + { + names.insert(iter.object()); + } + + regionNames = names.sortedToc(); + } + else + { + regionNames = {fvMesh::defaultRegion}; + args.readIfPresent("region", regionNames[0]); + } + // Demand driven lagrangian mapper autoPtr lagrangianReconstructorPtr; @@ -2507,317 +2543,333 @@ int main(int argc, char *argv[]) Info<< nl << "Pass1 : reconstructing mesh and addressing" << nl << endl; - // Loop over all times - forAll(timeDirs, timeI) + + forAll(regionNames, regioni) { - // Set time for global database - runTime.setTime(timeDirs[timeI], timeI); - baseRunTime.setTime(timeDirs[timeI], timeI); - - Info<< "Time = " << runTime.timeName() << endl << endl; - - - // See where the mesh is - fileName facesInstance = runTime.findInstance + const word& regionName = regionNames[regioni]; + const fileName meshSubDir ( - meshSubDir, - "faces", - IOobject::READ_IF_PRESENT + regionName == fvMesh::defaultRegion + ? fileName(polyMesh::meshSubDir) + : regionNames[regioni]/polyMesh::meshSubDir ); - //Pout<< "facesInstance:" << facesInstance << endl; - Pstream::scatter(facesInstance); + Info<< "\n\nReconstructing mesh " << regionName << nl << endl; - // Check who has a mesh - const fileName meshPath = - runTime.path()/facesInstance/meshSubDir/"faces"; - - Info<< "Checking for mesh in " << meshPath << nl << endl; - - boolList haveMesh(Pstream::nProcs(), false); - haveMesh[Pstream::myProcNo()] = isFile(meshPath); - Pstream::gatherList(haveMesh); - Pstream::scatterList(haveMesh); - Info<< "Per processor mesh availability:" << nl - << " " << flatOutput(haveMesh) << nl << endl; - - - // Addressing back to reconstructed mesh as xxxProcAddressing. - // - all processors have consistent faceProcAddressing - // - processors with no mesh don't need faceProcAddressing - - - // Note: filePath searches up on processors that don't have - // processor if instance = constant so explicitly check found - // filename. - bool haveAddressing = false; - if (haveMesh[Pstream::myProcNo()]) + // Loop over all times + forAll(timeDirs, timeI) { - // Read faces (just to know their size) - faceCompactIOList faces - ( - IOobject - ( - "faces", - facesInstance, - meshSubDir, - runTime, - IOobject::MUST_READ - ) - ); + // Set time for global database + runTime.setTime(timeDirs[timeI], timeI); + baseRunTime.setTime(timeDirs[timeI], timeI); - // Check faceProcAddressing - labelIOList faceProcAddressing + Info<< "Time = " << runTime.timeName() << endl << endl; + + + // See where the mesh is + fileName facesInstance = runTime.findInstance ( - IOobject - ( - "faceProcAddressing", - facesInstance, - meshSubDir, - runTime, - IOobject::READ_IF_PRESENT - ), - labelList() + meshSubDir, + "faces", + IOobject::READ_IF_PRESENT ); - if - ( - faceProcAddressing.headerOk() - && faceProcAddressing.size() == faces.size() - ) + //Pout<< "facesInstance:" << facesInstance << endl; + + Pstream::scatter(facesInstance); + + // Check who has a mesh + const fileName meshPath = + runTime.path()/facesInstance/meshSubDir/"faces"; + + Info<< "Checking for mesh in " << meshPath << nl << endl; + + boolList haveMesh(Pstream::nProcs(), false); + haveMesh[Pstream::myProcNo()] = isFile(meshPath); + Pstream::gatherList(haveMesh); + Pstream::scatterList(haveMesh); + Info<< "Per processor mesh availability:" << nl + << " " << flatOutput(haveMesh) << nl << endl; + + + // Addressing back to reconstructed mesh as xxxProcAddressing. + // - all processors have consistent faceProcAddressing + // - processors with no mesh don't need faceProcAddressing + + + // Note: filePath searches up on processors that don't have + // processor if instance = constant so explicitly check + // found filename. + bool haveAddressing = false; + if (haveMesh[Pstream::myProcNo()]) { + // Read faces (just to know their size) + faceCompactIOList faces + ( + IOobject + ( + "faces", + facesInstance, + meshSubDir, + runTime, + IOobject::MUST_READ + ) + ); + + // Check faceProcAddressing + labelIOList faceProcAddressing + ( + IOobject + ( + "faceProcAddressing", + facesInstance, + meshSubDir, + runTime, + IOobject::READ_IF_PRESENT + ), + labelList() + ); + if + ( + faceProcAddressing.headerOk() + && faceProcAddressing.size() == faces.size() + ) + { + haveAddressing = true; + } + } + else + { + // Have no mesh. Don't need addressing haveAddressing = true; } - } - else - { - // Have no mesh. Don't need addressing - haveAddressing = true; - } - if (!returnReduce(haveAddressing, andOp())) - { - Info<< "loading mesh from " << facesInstance << endl; - autoPtr meshPtr = loadOrCreateMesh - ( - IOobject - ( - regionName, - facesInstance, - runTime, - Foam::IOobject::MUST_READ - ) - ); - fvMesh& mesh = meshPtr(); - - // Global matching tolerance - const scalar tolDim = getMergeDistance - ( - args, - runTime, - mesh.bounds() - ); - - - // Determine decomposition - // ~~~~~~~~~~~~~~~~~~~~~~~ - - Info<< "Reconstructing mesh for time " << facesInstance << endl; - - label nDestProcs = 1; - labelList finalDecomp = labelList(mesh.nCells(), 0); - - redistributeAndWrite - ( - baseRunTime, - tolDim, - haveMesh, - meshSubDir, - false, // do not read fields - false, // do not read undecomposed case on processor0 - overwrite, - proc0CaseName, - nDestProcs, - finalDecomp, - facesInstance, - mesh - ); - } - } - - - // Pass2 : read mesh and addressing and reconstruct fields - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Info<< nl - << "Pass2 : reconstructing fields" << nl << endl; - - runTime.setTime(timeDirs[0], 0); - baseRunTime.setTime(timeDirs[0], 0); - Info<< "Time = " << runTime.timeName() << endl << endl; - - - Info<< "Reading undecomposed mesh (on master)" << endl; - autoPtr baseMeshPtr = fvMeshTools::newMesh - ( - IOobject - ( - regionName, - baseRunTime.timeName(), - baseRunTime, - IOobject::MUST_READ - ), - true // read on master only - ); - - Info<< "Reading local, decomposed mesh" << endl; - autoPtr meshPtr = loadOrCreateMesh - ( - IOobject - ( - regionName, - baseMeshPtr().facesInstance(), - runTime, - Foam::IOobject::MUST_READ - ) - ); - fvMesh& mesh = meshPtr(); - - - // Read addressing back to base mesh - autoPtr distMap; - readProcAddressing(mesh, baseMeshPtr, distMap); - - // Construct field mapper - autoPtr fvReconstructorPtr - ( - new parFvFieldReconstructor - ( - baseMeshPtr(), - mesh, - distMap(), - Pstream::master() // do I need to write? - ) - ); - - - - // Since we start from Times[0] and not runTime.timeName() we - // might overlook point motion in the first timestep - // (since mesh.readUpdate() below will not be triggered). Instead - // detect points by hand - if (mesh.pointsInstance() != mesh.facesInstance()) - { - Info<< " Detected initial mesh motion;" - << " reconstructing points" << nl - << endl; - fvReconstructorPtr().reconstructPoints(); - } - - - // Loop over all times - forAll(timeDirs, timeI) - { - if (newTimes && masterTimeDirSet.found(timeDirs[timeI].name())) - { - Info<< "Skipping time " << timeDirs[timeI].name() - << endl << endl; - continue; - } - - // Set time for global database - runTime.setTime(timeDirs[timeI], timeI); - baseRunTime.setTime(timeDirs[timeI], timeI); - - Info<< "Time = " << runTime.timeName() << endl << endl; - - - // Check if any new meshes need to be read. - fvMesh::readUpdateState procStat = mesh.readUpdate(); - - if (procStat == fvMesh::POINTS_MOVED) - { - Info<< " Dected mesh motion; reconstructing points" << nl - << endl; - fvReconstructorPtr().reconstructPoints(); - } - else if - ( - procStat == fvMesh::TOPO_CHANGE - || procStat == fvMesh::TOPO_PATCH_CHANGE - ) - { - Info<< " Detected topology change; reconstructing addressing" - << nl << endl; - - if (baseMeshPtr.valid()) + if (!returnReduce(haveAddressing, andOp())) { - // Cannot do a baseMesh::readUpdate() since not all - // processors will have mesh files. So instead just - // recreate baseMesh - baseMeshPtr.clear(); - baseMeshPtr = fvMeshTools::newMesh + Info<< "loading mesh from " << facesInstance << endl; + autoPtr meshPtr = loadOrCreateMesh ( IOobject ( regionName, - baseRunTime.timeName(), - baseRunTime, - IOobject::MUST_READ - ), - true // read on master only + facesInstance, + runTime, + Foam::IOobject::MUST_READ + ) + ); + fvMesh& mesh = meshPtr(); + + // Global matching tolerance + const scalar tolDim = getMergeDistance + ( + args, + runTime, + mesh.bounds() + ); + + + // Determine decomposition + // ~~~~~~~~~~~~~~~~~~~~~~~ + + Info<< "Reconstructing mesh for time " << facesInstance + << endl; + + label nDestProcs = 1; + labelList finalDecomp = labelList(mesh.nCells(), 0); + + redistributeAndWrite + ( + baseRunTime, + tolDim, + haveMesh, + meshSubDir, + false, // do not read fields + false, // do not read undecomposed case on proc0 + true, // write redistributed files to proc0 + overwrite, + proc0CaseName, + nDestProcs, + finalDecomp, + facesInstance, + mesh ); } - - // Re-read procXXXaddressing - readProcAddressing(mesh, baseMeshPtr, distMap); - - // Reset field mapper - fvReconstructorPtr.reset - ( - new parFvFieldReconstructor - ( - baseMeshPtr(), - mesh, - distMap(), - Pstream::master() - ) - ); - lagrangianReconstructorPtr.clear(); } - // Get list of objects - IOobjectList objects(mesh, runTime.timeName()); + // Pass2 : read mesh and addressing and reconstruct fields + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Info<< nl + << "Pass2 : reconstructing fields" << nl << endl; + + runTime.setTime(timeDirs[0], 0); + baseRunTime.setTime(timeDirs[0], 0); + Info<< "Time = " << runTime.timeName() << endl << endl; - // Mesh fields (vol, surface, volInternal) - reconstructMeshFields + Info<< "Reading undecomposed mesh (on master)" << endl; + autoPtr baseMeshPtr = fvMeshTools::newMesh ( - fvReconstructorPtr(), - objects, - selectedFields + IOobject + ( + regionName, + baseRunTime.timeName(), + baseRunTime, + IOobject::MUST_READ + ), + true // read on master only ); - // Clouds (note: might not be present on all processors) - reconstructLagrangian + Info<< "Reading local, decomposed mesh" << endl; + autoPtr meshPtr = loadOrCreateMesh ( - lagrangianReconstructorPtr, - baseMeshPtr(), - mesh, - distMap(), - selectedLagrangianFields + IOobject + ( + regionName, + baseMeshPtr().facesInstance(), + runTime, + Foam::IOobject::MUST_READ + ) + ); + fvMesh& mesh = meshPtr(); + + + // Read addressing back to base mesh + autoPtr distMap; + readProcAddressing(mesh, baseMeshPtr, distMap); + + // Construct field mapper + autoPtr fvReconstructorPtr + ( + new parFvFieldReconstructor + ( + baseMeshPtr(), + mesh, + distMap(), + Pstream::master() // do I need to write? + ) ); - // If there are any "uniform" directories copy them from - // the master processor - if (Pstream::master()) + + + // Since we start from Times[0] and not runTime.timeName() we + // might overlook point motion in the first timestep + // (since mesh.readUpdate() below will not be triggered). Instead + // detect points by hand + if (mesh.pointsInstance() != mesh.facesInstance()) { - fileName uniformDir0 = runTime.timePath()/"uniform"; - if (isDir(uniformDir0)) + Info<< " Detected initial mesh motion;" + << " reconstructing points" << nl + << endl; + fvReconstructorPtr().reconstructPoints(); + } + + + // Loop over all times + forAll(timeDirs, timeI) + { + if (newTimes && masterTimeDirSet.found(timeDirs[timeI].name())) { - Info<< "Detected additional non-decomposed files in " - << uniformDir0 << endl; - cp(uniformDir0, baseRunTime.timePath()); + Info<< "Skipping time " << timeDirs[timeI].name() + << endl << endl; + continue; + } + + // Set time for global database + runTime.setTime(timeDirs[timeI], timeI); + baseRunTime.setTime(timeDirs[timeI], timeI); + + Info<< "Time = " << runTime.timeName() << endl << endl; + + + // Check if any new meshes need to be read. + fvMesh::readUpdateState procStat = mesh.readUpdate(); + + if (procStat == fvMesh::POINTS_MOVED) + { + Info<< " Dected mesh motion; reconstructing points" << nl + << endl; + fvReconstructorPtr().reconstructPoints(); + } + else if + ( + procStat == fvMesh::TOPO_CHANGE + || procStat == fvMesh::TOPO_PATCH_CHANGE + ) + { + Info<< " Detected topology change;" + << " reconstructing addressing" << nl << endl; + + if (baseMeshPtr.valid()) + { + // Cannot do a baseMesh::readUpdate() since not all + // processors will have mesh files. So instead just + // recreate baseMesh + baseMeshPtr.clear(); + baseMeshPtr = fvMeshTools::newMesh + ( + IOobject + ( + regionName, + baseRunTime.timeName(), + baseRunTime, + IOobject::MUST_READ + ), + true // read on master only + ); + } + + // Re-read procXXXaddressing + readProcAddressing(mesh, baseMeshPtr, distMap); + + // Reset field mapper + fvReconstructorPtr.reset + ( + new parFvFieldReconstructor + ( + baseMeshPtr(), + mesh, + distMap(), + Pstream::master() + ) + ); + lagrangianReconstructorPtr.clear(); + } + + + // Get list of objects + IOobjectList objects(mesh, runTime.timeName()); + + + // Mesh fields (vol, surface, volInternal) + reconstructMeshFields + ( + fvReconstructorPtr(), + objects, + selectedFields + ); + + // Clouds (note: might not be present on all processors) + reconstructLagrangian + ( + lagrangianReconstructorPtr, + baseMeshPtr(), + mesh, + distMap(), + selectedLagrangianFields + ); + + // If there are any "uniform" directories copy them from + // the master processor + if (Pstream::master()) + { + fileName uniformDir0 = runTime.timePath()/"uniform"; + if (isDir(uniformDir0)) + { + Info<< "Detected additional non-decomposed files in " + << uniformDir0 << endl; + cp(uniformDir0, baseRunTime.timePath()); + } } } } @@ -2850,184 +2902,225 @@ int main(int argc, char *argv[]) runTime.setTime(masterTime, 0); - // Get time instance directory - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // At this point we should be able to read at least a mesh on - // processor0. Note the changing of the processor0 casename to - // enforce it to read/write from the undecomposed case - fileName masterInstDir; - if (Pstream::master()) + forAll(regionNames, regioni) { - if (decompose) - { - Info<< "Setting caseName to " << baseRunTime.caseName() - << " to find undecomposed mesh" << endl; - runTime.TimePaths::caseName() = baseRunTime.caseName(); - } - - masterInstDir = runTime.findInstance + const word& regionName = regionNames[regioni]; + const fileName meshSubDir ( - meshSubDir, - "faces", - IOobject::READ_IF_PRESENT + regionName == fvMesh::defaultRegion + ? fileName(polyMesh::meshSubDir) + : regionNames[regioni]/polyMesh::meshSubDir ); if (decompose) + { + Info<< "\n\nDecomposing mesh " << regionName << nl << endl; + } + else + { + Info<< "\n\nRedistributing mesh " << regionName << nl << endl; + } + + + // Get time instance directory + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // At this point we should be able to read at least a mesh on + // processor0. Note the changing of the processor0 casename to + // enforce it to read/write from the undecomposed case + + fileName masterInstDir; + if (Pstream::master()) + { + if (decompose) + { + Info<< "Setting caseName to " << baseRunTime.caseName() + << " to find undecomposed mesh" << endl; + runTime.TimePaths::caseName() = baseRunTime.caseName(); + } + + masterInstDir = runTime.findInstance + ( + meshSubDir, + "faces", + IOobject::READ_IF_PRESENT + ); + + if (decompose) + { + Info<< "Restoring caseName to " << proc0CaseName << endl; + runTime.TimePaths::caseName() = proc0CaseName; + } + } + Pstream::scatter(masterInstDir); + + // Check who has a mesh + const fileName meshPath = + runTime.path()/masterInstDir/meshSubDir/"faces"; + + Info<< "Checking for mesh in " << meshPath << nl << endl; + + + boolList haveMesh(Pstream::nProcs(), false); + haveMesh[Pstream::myProcNo()] = isFile(meshPath); + Pstream::gatherList(haveMesh); + Pstream::scatterList(haveMesh); + Info<< "Per processor mesh availability:" << nl + << " " << flatOutput(haveMesh) << nl << endl; + + // Load mesh (or create dummy one) + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + if (Pstream::master() && decompose) + { + Info<< "Setting caseName to " << baseRunTime.caseName() + << " to read undecomposed mesh" << endl; + runTime.TimePaths::caseName() = baseRunTime.caseName(); + } + + autoPtr meshPtr = loadOrCreateMesh + ( + IOobject + ( + regionName, + masterInstDir, + runTime, + Foam::IOobject::MUST_READ + ) + ); + + if (Pstream::master() && decompose) { Info<< "Restoring caseName to " << proc0CaseName << endl; runTime.TimePaths::caseName() = proc0CaseName; } - } - Pstream::scatter(masterInstDir); - // Check who has a mesh - const fileName meshPath = - runTime.path()/masterInstDir/meshSubDir/"faces"; - - Info<< "Checking for mesh in " << meshPath << nl << endl; + fvMesh& mesh = meshPtr(); - boolList haveMesh(Pstream::nProcs(), false); - haveMesh[Pstream::myProcNo()] = isFile(meshPath); - Pstream::gatherList(haveMesh); - Pstream::scatterList(haveMesh); - Info<< "Per processor mesh availability:" << nl - << " " << flatOutput(haveMesh) << nl << endl; + const label nOldCells = mesh.nCells(); + //Pout<< "Loaded mesh : nCells:" << nOldCells + // << " nPatches:" << mesh.boundaryMesh().size() << endl; - // Load mesh (or create dummy one) - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - if (Pstream::master() && decompose) - { - Info<< "Setting caseName to " << baseRunTime.caseName() - << " to read undecomposed mesh" << endl; - runTime.TimePaths::caseName() = baseRunTime.caseName(); - } - - autoPtr meshPtr = loadOrCreateMesh - ( - IOobject + // Global matching tolerance + const scalar tolDim = getMergeDistance ( - regionName, - masterInstDir, + args, runTime, - Foam::IOobject::MUST_READ - ) - ); - - if (Pstream::master() && decompose) - { - Info<< "Restoring caseName to " << proc0CaseName << endl; - runTime.TimePaths::caseName() = proc0CaseName; - } - - fvMesh& mesh = meshPtr(); - - - const label nOldCells = mesh.nCells(); - //Pout<< "Loaded mesh : nCells:" << nOldCells - // << " nPatches:" << mesh.boundaryMesh().size() << endl; - - - // Global matching tolerance - const scalar tolDim = getMergeDistance - ( - args, - runTime, - mesh.bounds() - ); - - // Determine decomposition - // ~~~~~~~~~~~~~~~~~~~~~~~ - - label nDestProcs; - labelList finalDecomp; - determineDecomposition - ( - baseRunTime, - decompDictFile, - decompose, - proc0CaseName, - mesh, - writeCellDist, - - nDestProcs, - finalDecomp - ); - - - wordList cloudNames; - List fieldNames; - - // Detect lagrangian fields - if (Pstream::master() && decompose) - { - runTime.TimePaths::caseName() = baseRunTime.caseName(); - } - parLagrangianRedistributor::findClouds - ( - mesh, - cloudNames, - fieldNames - ); - - // Read lagrangian fields and store on cloud (objectRegistry) - PtrList clouds(cloudNames.size()); - readLagrangian - ( - mesh, - cloudNames, - selectedLagrangianFields, - clouds - ); - if (Pstream::master() && decompose) - { - runTime.TimePaths::caseName() = proc0CaseName; - } - - - // Load fields, do all distribution (mesh and fields - but not - // lagrangian fields; these are done later) - autoPtr distMap = redistributeAndWrite - ( - baseRunTime, - tolDim, - haveMesh, - meshSubDir, - true, // read fields - decompose, // decompose, i.e. read from undecomposed case - overwrite, - proc0CaseName, - nDestProcs, - finalDecomp, - masterInstDir, - mesh - ); - - - // Redistribute any clouds - redistributeLagrangian - ( - lagrangianReconstructorPtr, - mesh, - nOldCells, - distMap(), - clouds - ); - - - // Copy any uniform data - const fileName uniformDir("uniform"); - if (isDir(baseRunTime.timePath()/uniformDir)) - { - Info<< "Detected additional non-decomposed files in " - << baseRunTime.timePath()/uniformDir << endl; - cp - ( - baseRunTime.timePath()/uniformDir, - runTime.timePath()/uniformDir + mesh.bounds() ); + + // Determine decomposition + // ~~~~~~~~~~~~~~~~~~~~~~~ + + label nDestProcs; + labelList finalDecomp; + determineDecomposition + ( + baseRunTime, + decompDictFile, + decompose, + proc0CaseName, + mesh, + writeCellDist, + + nDestProcs, + finalDecomp + ); + + if (dryrun) + { + if (!Pstream::master() && !haveMesh[Pstream::myProcNo()]) + { + // Remove dummy mesh created by loadOrCreateMesh + const bool oldParRun = Pstream::parRun(); + Pstream::parRun() = false; + mesh.removeFiles(); + rmDir(mesh.objectRegistry::objectPath()); + Pstream::parRun() = oldParRun; + } + continue; + } + + + + wordList cloudNames; + List fieldNames; + + // Detect lagrangian fields + if (Pstream::master() && decompose) + { + runTime.TimePaths::caseName() = baseRunTime.caseName(); + } + parLagrangianRedistributor::findClouds + ( + mesh, + cloudNames, + fieldNames + ); + + // Read lagrangian fields and store on cloud (objectRegistry) + PtrList clouds + ( + cloudNames.size() + ); + readLagrangian + ( + mesh, + cloudNames, + selectedLagrangianFields, + clouds + ); + if (Pstream::master() && decompose) + { + runTime.TimePaths::caseName() = proc0CaseName; + } + + + // Load fields, do all distribution (mesh and fields - but not + // lagrangian fields; these are done later) + autoPtr distMap = redistributeAndWrite + ( + baseRunTime, + tolDim, + haveMesh, + meshSubDir, + true, // read fields + decompose, // decompose, i.e. read from undecomposed case + false, // no reconstruction + overwrite, + proc0CaseName, + nDestProcs, + finalDecomp, + masterInstDir, + mesh + ); + + + // Redistribute any clouds + redistributeLagrangian + ( + lagrangianReconstructorPtr, + mesh, + nOldCells, + distMap(), + clouds + ); + + + // Copy any uniform data + const fileName uniformDir("uniform"); + if (isDir(baseRunTime.timePath()/uniformDir)) + { + Info<< "Detected additional non-decomposed files in " + << baseRunTime.timePath()/uniformDir << endl; + cp + ( + baseRunTime.timePath()/uniformDir, + runTime.timePath()/uniformDir + ); + } } }