164 #include "readFields.H"
183 const PtrList<fvMesh>& procMeshList,
186 PtrList<labelIOList>& procAddressingList
189 const fvMesh& procMesh = procMeshList[proci];
191 if (!procAddressingList.set(proci))
193 procAddressingList.
set
201 procMesh.facesInstance(),
211 return procAddressingList[proci];
215 void decomposeUniform
217 const bool copyUniform,
218 const domainDecomposition&
mesh,
219 const Time& processorDb,
226 const fileName uniformDir(regionDir/
"uniform");
230 Info<<
"Detected additional non-decomposed files in "
234 const fileName timePath =
241 if (copyUniform ||
mesh.distributed())
255 string parentPath = string(
"..")/
"..";
259 parentPath = parentPath/
"..";
262 fileName currentDir(
cwd());
283 int main(
int argc,
char *argv[])
287 "Decompose a mesh and fields of a case for parallel execution"
290 argList::noParallel();
295 "Use specified file for decomposePar dictionary"
298 argList::addBoolOption
301 "Operate on all regions in regionProperties"
303 argList::addBoolOption
306 "Test without writing the decomposition. "
307 "Changes -cellDist to only write volScalarField."
309 argList::addBoolOption
312 "Additional verbosity"
314 argList::addBoolOption
317 "Write cell distribution as a labelList - for use with 'manual' "
318 "decomposition method and as a volScalarField for visualization."
320 argList::addBoolOption
323 "Copy 0/ directory to processor*/ rather than decompose the fields"
325 argList::addBoolOption
328 "Copy any uniform/ directories too"
330 argList::addBoolOption
333 "Use existing geometry decomposition and convert fields only"
335 argList::addBoolOption
338 "Skip decomposing cellSets, faceSets, pointSets"
340 argList::addBoolOption
343 "Remove existing processor*/ subdirs before decomposing the geometry"
345 argList::addBoolOption
348 "Only decompose geometry if the number of domains has changed"
352 timeSelector::addOptions(
true,
false);
356 const bool dryrun =
args.
found(
"dry-run");
357 const bool optRegion =
args.
found(
"region");
358 const bool allRegions =
args.
found(
"allRegions");
359 const bool writeCellDist =
args.
found(
"cellDist");
360 const bool verbose =
args.
found(
"verbose");
363 const bool copyZero =
args.
found(
"copyZero");
364 const bool copyUniform =
args.
found(
"copyUniform");
365 const bool decomposeSets = !
args.
found(
"noSets");
366 const bool decomposeIfRequired =
args.
found(
"ifRequired");
368 bool decomposeFieldsOnly =
args.
found(
"fields");
369 bool forceOverwrite =
args.
found(
"force");
379 Info<<
"\ndry-run: ignoring -copy*, -fields, -force, time selection"
384 times = timeSelector::selectIfPresent(
runTime,
args);
388 fileName decompDictFile(
args.
get<fileName>(
"decomposeParDict",
""));
389 if (!decompDictFile.empty() && !decompDictFile.isAbsolute())
391 decompDictFile =
runTime.globalPath()/decompDictFile;
398 regionNames = regionProperties(
runTime).names();
400 Info<<
"Decomposing all regions in regionProperties" <<
nl
405 regionNames.resize(1);
406 regionNames.first() =
410 forAll(regionNames, regioni)
412 const word&
regionName = regionNames[regioni];
413 const word& regionDir =
419 <<
"Create mesh..." <<
flush;
421 domainDecompositionDryRun decompTest
435 decompTest.execute(writeCellDist, verbose);
446 const label nDomains = decompositionMethod::nDomains
454 decompositionModel::canonicalName,
468 const_cast<fileOperation&
>(
fileHandler()).setNProcs(nDomains);
470 if (decomposeFieldsOnly)
473 if (nProcs != nDomains)
476 <<
"Specified -fields, but the case was decomposed with "
477 << nProcs <<
" domains"
479 <<
"instead of " << nDomains
480 <<
" domains as specified in decomposeParDict" <<
nl
486 bool procDirsProblem =
true;
488 if (decomposeIfRequired && nProcs == nDomains)
491 decomposeFieldsOnly =
true;
492 procDirsProblem =
false;
493 forceOverwrite =
false;
495 Info<<
"Using existing processor directories" <<
nl;
498 if (allRegions || optRegion)
500 procDirsProblem =
false;
501 forceOverwrite =
false;
506 Info<<
"Removing " << nProcs
507 <<
" existing processor directories" <<
endl;
515 fileName::Type::DIRECTORY
520 const fileName& d = dirs[diri];
523 if (d.find(
"processors") == 0)
532 if (d.find(
"processor") == 0)
535 fileName num(d.substr(9));
547 procDirsProblem =
false;
553 <<
"Case is already decomposed with " << nProcs
554 <<
" domains, use the -force option or manually" <<
nl
555 <<
"remove processor directories before decomposing. e.g.,"
557 <<
" rm -rf " <<
runTime.path().c_str() <<
"/processor*"
564 domainDecomposition
mesh
579 if (!decomposeFieldsOnly)
581 mesh.decomposeMesh();
583 mesh.writeDecomposition(decomposeSets);
602 zeroGradientFvPatchScalarField::typeName
607 cellDist[celli] = procIds[celli];
610 cellDist.correctBoundaryConditions();
613 Info<<
nl <<
"Wrote decomposition as volScalarField to "
614 << cellDist.name() <<
" for visualization."
624 mesh.facesInstance(),
632 cellDecomposition.write();
634 Info<<
nl <<
"Wrote decomposition to "
635 << cellDecomposition.objectPath()
636 <<
" for use in manual decomposition." <<
endl;
646 fileName prevTimePath;
647 for (label proci = 0; proci <
mesh.nProcs(); ++proci)
651 Time::controlDictName,
660 const fileName timePath
667 processorDb.timeName(),
674 if (timePath != prevTimePath)
676 Info<<
"Processor " << proci
677 <<
": copying " <<
runTime.timePath() <<
nl
678 <<
" to " << timePath <<
endl;
681 prevTimePath = timePath;
692 PtrList<Time> processorDbList(
mesh.nProcs());
693 PtrList<fvMesh> procMeshList(
mesh.nProcs());
694 PtrList<labelIOList> faceProcAddressingList(
mesh.nProcs());
695 PtrList<labelIOList> cellProcAddressingList(
mesh.nProcs());
696 PtrList<labelIOList> boundaryProcAddressingList(
mesh.nProcs());
697 PtrList<fvFieldDecomposer> fieldDecomposerList(
mesh.nProcs());
698 PtrList<dimFieldDecomposer> dimFieldDecomposerList(
mesh.nProcs());
699 PtrList<labelIOList> pointProcAddressingList(
mesh.nProcs());
700 PtrList<pointFieldDecomposer> pointFieldDecomposerList
709 runTime.setTime(times[timeI], timeI);
719 PtrList<volScalarField> volScalarFields;
721 PtrList<volVectorField> volVectorFields;
723 PtrList<volSphericalTensorField> volSphericalTensorFields;
725 PtrList<volSymmTensorField> volSymmTensorFields;
727 PtrList<volTensorField> volTensorFields;
733 PtrList<DimensionedField<scalar, volMesh>> dimScalarFields;
735 PtrList<DimensionedField<vector, volMesh>> dimVectorFields;
737 PtrList<DimensionedField<sphericalTensor, volMesh>>
738 dimSphericalTensorFields;
740 PtrList<DimensionedField<symmTensor, volMesh>>
743 PtrList<DimensionedField<tensor, volMesh>> dimTensorFields;
749 PtrList<surfaceScalarField> surfaceScalarFields;
751 PtrList<surfaceVectorField> surfaceVectorFields;
753 PtrList<surfaceSphericalTensorField>
754 surfaceSphericalTensorFields;
756 PtrList<surfaceSymmTensorField> surfaceSymmTensorFields;
758 PtrList<surfaceTensorField> surfaceTensorFields;
766 PtrList<pointScalarField> pointScalarFields;
767 readFields(pMesh, objects, pointScalarFields,
false);
768 PtrList<pointVectorField> pointVectorFields;
769 readFields(pMesh, objects, pointVectorFields,
false);
770 PtrList<pointSphericalTensorField> pointSphericalTensorFields;
771 readFields(pMesh, objects, pointSphericalTensorFields,
false);
772 PtrList<pointSymmTensorField> pointSymmTensorFields;
773 readFields(pMesh, objects, pointSymmTensorFields,
false);
774 PtrList<pointTensorField> pointTensorFields;
775 readFields(pMesh, objects, pointTensorFields,
false);
785 runTime.timePath()/cloud::prefix,
791 PtrList<Cloud<indexedParticle>> lagrangianPositions
796 PtrList<List<SLList<indexedParticle*>*>> cellParticles
801 PtrList<PtrList<labelIOField>> lagrangianLabelFields
805 PtrList<PtrList<labelFieldCompactIOField>>
806 lagrangianLabelFieldFields
810 PtrList<PtrList<scalarIOField>> lagrangianScalarFields
814 PtrList<PtrList<scalarFieldCompactIOField>>
815 lagrangianScalarFieldFields
819 PtrList<PtrList<vectorIOField>> lagrangianVectorFields
823 PtrList<PtrList<vectorFieldCompactIOField>>
824 lagrangianVectorFieldFields
828 PtrList<PtrList<sphericalTensorIOField>>
829 lagrangianSphericalTensorFields
833 PtrList<PtrList<sphericalTensorFieldCompactIOField>>
834 lagrangianSphericalTensorFieldFields(cloudDirs.size());
835 PtrList<PtrList<symmTensorIOField>> lagrangianSymmTensorFields
839 PtrList<PtrList<symmTensorFieldCompactIOField>>
840 lagrangianSymmTensorFieldFields
844 PtrList<PtrList<tensorIOField>> lagrangianTensorFields
848 PtrList<PtrList<tensorFieldCompactIOField>>
849 lagrangianTensorFieldFields
856 for (
const fileName& cloudDir : cloudDirs)
858 IOobjectList cloudObjects
862 cloud::prefix/cloudDir,
871 cloudObjects.found(
"coordinates")
872 || cloudObjects.found(
"positions")
878 Info<<
"Identified lagrangian data set: "
881 lagrangianPositions.set
884 new Cloud<indexedParticle>
899 new List<SLList<indexedParticle*>*>
902 static_cast<SLList<indexedParticle*>*
>(
nullptr)
908 for (indexedParticle&
p : lagrangianPositions[cloudI])
912 label celli =
p.cell();
915 if (celli < 0 || celli >=
mesh.nCells())
918 <<
"Illegal cell number " << celli
919 <<
" for particle with index "
922 <<
p.position() <<
nl
923 <<
"Cell number should be between 0 and "
925 <<
"On this mesh the particle should"
927 <<
mesh.findCell(
p.position())
931 if (!cellParticles[cloudI][celli])
933 cellParticles[cloudI][celli] =
934 new SLList<indexedParticle*>();
937 cellParticles[cloudI][celli]->append(&
p);
943 IOobjectList lagrangianObjects
947 cloud::prefix/cloudDirs[cloudI],
957 lagrangianLabelFields
960 lagrangianFieldDecomposer::readFieldFields
964 lagrangianLabelFieldFields
971 lagrangianScalarFields
974 lagrangianFieldDecomposer::readFieldFields
978 lagrangianScalarFieldFields
985 lagrangianVectorFields
988 lagrangianFieldDecomposer::readFieldFields
992 lagrangianVectorFieldFields
999 lagrangianSphericalTensorFields
1002 lagrangianFieldDecomposer::readFieldFields
1006 lagrangianSphericalTensorFieldFields
1013 lagrangianSymmTensorFields
1016 lagrangianFieldDecomposer::readFieldFields
1020 lagrangianSymmTensorFieldFields
1027 lagrangianTensorFields
1030 lagrangianFieldDecomposer::readFieldFields
1034 lagrangianTensorFieldFields
1041 lagrangianPositions.setSize(cloudI);
1042 cellParticles.setSize(cloudI);
1043 lagrangianLabelFields.setSize(cloudI);
1044 lagrangianLabelFieldFields.setSize(cloudI);
1045 lagrangianScalarFields.setSize(cloudI);
1046 lagrangianScalarFieldFields.setSize(cloudI);
1047 lagrangianVectorFields.setSize(cloudI);
1048 lagrangianVectorFieldFields.setSize(cloudI);
1049 lagrangianSphericalTensorFields.setSize(cloudI);
1050 lagrangianSphericalTensorFieldFields.setSize(cloudI);
1051 lagrangianSymmTensorFields.setSize(cloudI);
1052 lagrangianSymmTensorFieldFields.setSize(cloudI);
1053 lagrangianTensorFields.setSize(cloudI);
1054 lagrangianTensorFieldFields.setSize(cloudI);
1059 for (label proci = 0; proci <
mesh.nProcs(); ++proci)
1061 Info<<
"Processor " << proci <<
": field transfer" <<
endl;
1065 if (!processorDbList.set(proci))
1072 Time::controlDictName,
1079 Time& processorDb = processorDbList[proci];
1085 if (!procMeshList.set(proci))
1095 processorDb.timeName(),
1101 const fvMesh& procMesh = procMeshList[proci];
1107 "faceProcAddressing",
1108 faceProcAddressingList
1111 const labelIOList& cellProcAddressing = procAddressing
1115 "cellProcAddressing",
1116 cellProcAddressingList
1119 const labelIOList& boundaryProcAddressing = procAddressing
1123 "boundaryProcAddressing",
1124 boundaryProcAddressingList
1130 if (!fieldDecomposerList.set(proci))
1132 fieldDecomposerList.set
1135 new fvFieldDecomposer
1141 boundaryProcAddressing
1145 const fvFieldDecomposer& fieldDecomposer =
1146 fieldDecomposerList[proci];
1148 fieldDecomposer.decomposeFields(volScalarFields);
1149 fieldDecomposer.decomposeFields(volVectorFields);
1150 fieldDecomposer.decomposeFields
1152 volSphericalTensorFields
1154 fieldDecomposer.decomposeFields(volSymmTensorFields);
1155 fieldDecomposer.decomposeFields(volTensorFields);
1157 fieldDecomposer.decomposeFields(surfaceScalarFields);
1158 fieldDecomposer.decomposeFields(surfaceVectorFields);
1159 fieldDecomposer.decomposeFields
1161 surfaceSphericalTensorFields
1163 fieldDecomposer.decomposeFields
1165 surfaceSymmTensorFields
1167 fieldDecomposer.decomposeFields(surfaceTensorFields);
1169 if (times.size() == 1)
1172 fieldDecomposerList.set(proci,
nullptr);
1178 if (!dimFieldDecomposerList.set(proci))
1180 dimFieldDecomposerList.set
1183 new dimFieldDecomposer
1192 const dimFieldDecomposer& dimDecomposer =
1193 dimFieldDecomposerList[proci];
1195 dimDecomposer.decomposeFields(dimScalarFields);
1196 dimDecomposer.decomposeFields(dimVectorFields);
1197 dimDecomposer.decomposeFields(dimSphericalTensorFields);
1198 dimDecomposer.decomposeFields(dimSymmTensorFields);
1199 dimDecomposer.decomposeFields(dimTensorFields);
1201 if (times.size() == 1)
1203 dimFieldDecomposerList.set(proci,
nullptr);
1211 pointScalarFields.size()
1212 || pointVectorFields.size()
1213 || pointSphericalTensorFields.size()
1214 || pointSymmTensorFields.size()
1215 || pointTensorFields.size()
1218 const labelIOList& pointProcAddressing = procAddressing
1222 "pointProcAddressing",
1223 pointProcAddressingList
1228 if (!pointFieldDecomposerList.set(proci))
1230 pointFieldDecomposerList.set
1233 new pointFieldDecomposer
1237 pointProcAddressing,
1238 boundaryProcAddressing
1242 const pointFieldDecomposer& pointDecomposer =
1243 pointFieldDecomposerList[proci];
1245 pointDecomposer.decomposeFields(pointScalarFields);
1246 pointDecomposer.decomposeFields(pointVectorFields);
1247 pointDecomposer.decomposeFields
1249 pointSphericalTensorFields
1251 pointDecomposer.decomposeFields(pointSymmTensorFields);
1252 pointDecomposer.decomposeFields(pointTensorFields);
1255 if (times.size() == 1)
1257 pointProcAddressingList.set(proci,
nullptr);
1258 pointFieldDecomposerList.set(proci,
nullptr);
1264 forAll(lagrangianPositions, cloudI)
1266 if (lagrangianPositions[cloudI].size())
1268 lagrangianFieldDecomposer fieldDecomposer
1275 lagrangianPositions[cloudI],
1276 cellParticles[cloudI]
1281 fieldDecomposer.decomposeFields
1284 lagrangianLabelFields[cloudI]
1286 fieldDecomposer.decomposeFieldFields
1289 lagrangianLabelFieldFields[cloudI]
1291 fieldDecomposer.decomposeFields
1294 lagrangianScalarFields[cloudI]
1296 fieldDecomposer.decomposeFieldFields
1299 lagrangianScalarFieldFields[cloudI]
1301 fieldDecomposer.decomposeFields
1304 lagrangianVectorFields[cloudI]
1306 fieldDecomposer.decomposeFieldFields
1309 lagrangianVectorFieldFields[cloudI]
1311 fieldDecomposer.decomposeFields
1314 lagrangianSphericalTensorFields[cloudI]
1316 fieldDecomposer.decomposeFieldFields
1319 lagrangianSphericalTensorFieldFields[cloudI]
1321 fieldDecomposer.decomposeFields
1324 lagrangianSymmTensorFields[cloudI]
1326 fieldDecomposer.decomposeFieldFields
1329 lagrangianSymmTensorFieldFields[cloudI]
1331 fieldDecomposer.decomposeFields
1334 lagrangianTensorFields[cloudI]
1336 fieldDecomposer.decomposeFieldFields
1339 lagrangianTensorFieldFields[cloudI]
1347 decomposeUniform(copyUniform,
mesh, processorDb, regionDir);
1351 if (regionNames.size() > 1 && regioni == 0)
1353 decomposeUniform(copyUniform,
mesh, processorDb);
1359 if (times.size() == 1)
1361 boundaryProcAddressingList.set(proci,
nullptr);
1362 cellProcAddressingList.set(proci,
nullptr);
1363 faceProcAddressingList.set(proci,
nullptr);
1364 procMeshList.set(proci,
nullptr);
1365 processorDbList.set(proci,
nullptr);
1371 IOobject faMeshBoundaryIOobj
1374 mesh.time().findInstance
1376 mesh.dbDir()/polyMesh::meshSubDir,
1381 IOobject::READ_IF_PRESENT,
1386 if (faMeshBoundaryIOobj.typeHeaderOk<faBoundaryMesh>(
true))
1388 Info <<
"\nFinite area mesh decomposition" <<
endl;
1392 aMesh.decomposeMesh();
1394 aMesh.writeDecomposition();
1399 PtrList<areaScalarField> areaScalarFields;
1402 PtrList<areaVectorField> areaVectorFields;
1405 PtrList<areaSphericalTensorField> areaSphericalTensorFields;
1408 PtrList<areaSymmTensorField> areaSymmTensorFields;
1411 PtrList<areaTensorField> areaTensorFields;
1417 PtrList<edgeScalarField> edgeScalarFields;
1423 for (label procI = 0; procI <
mesh.nProcs(); procI++)
1425 Info<<
"Processor " << procI
1426 <<
": finite area field transfer" <<
endl;
1431 Time::controlDictName,
1445 processorDb.timeName(),
1450 faMesh procMesh(procFvMesh);
1475 "faceProcAddressing",
1477 procMesh.meshSubDir,
1479 IOobject::MUST_READ,
1488 "boundaryProcAddressing",
1490 procMesh.meshSubDir,
1492 IOobject::MUST_READ,
1500 areaScalarFields.size()
1501 || areaVectorFields.size()
1502 || areaSphericalTensorFields.size()
1503 || areaSymmTensorFields.size()
1504 || areaTensorFields.size()
1505 || edgeScalarFields.size()
1512 "edgeProcAddressing",
1514 procMesh.meshSubDir,
1516 IOobject::MUST_READ,
1521 faFieldDecomposer fieldDecomposer
1527 boundaryProcAddressing
1530 fieldDecomposer.decomposeFields(areaScalarFields);
1531 fieldDecomposer.decomposeFields(areaVectorFields);
1532 fieldDecomposer.decomposeFields
1534 areaSphericalTensorFields
1536 fieldDecomposer.decomposeFields
1538 areaSymmTensorFields
1540 fieldDecomposer.decomposeFields(areaTensorFields);
1542 fieldDecomposer.decomposeFields(edgeScalarFields);