ENH: code modernization for decompose/reconstruct

- simplify procAddressing read/write

- avoid accessing points in faMeshReconstructor.
  Can rely on the patch meshPoints (labelList), which does not need
  access to a pointField

- report number of points on decomposed mesh.
  Can be useful additional information.
  Additional statistics for finite area decomposition

- provide bundled reconstructAllFields for various reconstructors

- remove reconstructPar checks for very old face addressing
  (from foam2.0 - ie, older than OpenFOAM itself)

- bundle all reading into fieldsDistributor tools,
  where it can be reused by various utilities as required.

- combine decomposition fields as respective fieldsCache
  which eliminates most of the clutter from decomposePar
  and similfies reuse in the future.

STYLE: remove old wordHashSet selection (deprecated in 2018)

BUG: incorrect face flip handling for faMeshReconstructor

- a latent bug which is not yet triggered since the faMesh faces are
  currently only definable on boundary faces (which never flip)
This commit is contained in:
Mark Olesen
2022-04-24 15:06:40 +02:00
committed by Andrew Heather
parent eccc998ed2
commit 3b6761afed
51 changed files with 3270 additions and 2443 deletions

View File

@ -25,11 +25,7 @@ if (doDecompose && Pstream::parRun())
// Handle area fields // Handle area fields
// ------------------ // ------------------
PtrList<areaScalarField> areaScalarFields; faFieldDecomposer::fieldsCache areaFieldsCache;
PtrList<areaVectorField> areaVectorFields;
PtrList<areaSphericalTensorField> areaSphTensorFields;
PtrList<areaSymmTensorField> areaSymmTensorFields;
PtrList<areaTensorField> areaTensorFields;
const faMesh& fullMesh = reconstructor.mesh(); const faMesh& fullMesh = reconstructor.mesh();
@ -51,26 +47,7 @@ if (doDecompose && Pstream::parRun())
IOobjectList objects(fullMesh.time(), runTime.timeName()); IOobjectList objects(fullMesh.time(), runTime.timeName());
faFieldDecomposer::readFields areaFieldsCache.readAllFields(fullMesh, objects);
(
fullMesh, objects, areaScalarFields
);
faFieldDecomposer::readFields
(
fullMesh, objects, areaVectorFields
);
faFieldDecomposer::readFields
(
fullMesh, objects, areaSphTensorFields
);
faFieldDecomposer::readFields
(
fullMesh, objects, areaSymmTensorFields
);
faFieldDecomposer::readFields
(
fullMesh, objects, areaTensorFields
);
// Restore old settings // Restore old settings
if (oldHandler) if (oldHandler)
@ -81,14 +58,7 @@ if (doDecompose && Pstream::parRun())
} }
} }
const label nAreaFields = const label nAreaFields = areaFieldsCache.size();
(
areaScalarFields.size()
+ areaVectorFields.size()
+ areaSphTensorFields.size()
+ areaSymmTensorFields.size()
+ areaTensorFields.size()
);
if (nAreaFields) if (nAreaFields)
{ {
@ -103,41 +73,8 @@ if (doDecompose && Pstream::parRun())
reconstructor.boundaryProcAddressing() reconstructor.boundaryProcAddressing()
); );
if (areaScalarFields.size()) // Report
{ areaFieldsCache.decomposeAllFields(fieldDecomposer, true);
Info<< " scalars: "
<< flatOutput(PtrListOps::names(areaScalarFields)) << nl;
fieldDecomposer.decomposeFields(areaScalarFields);
}
if (areaVectorFields.size())
{
Info<< " vectors: "
<< flatOutput(PtrListOps::names(areaVectorFields)) << nl;
fieldDecomposer.decomposeFields(areaVectorFields);
}
if (areaSphTensorFields.size())
{
Info<< " sphTensors: "
<< flatOutput(PtrListOps::names(areaSphTensorFields)) << nl;
fieldDecomposer.decomposeFields(areaSphTensorFields);
}
if (areaSymmTensorFields.size())
{
Info<< " symmTensors: "
<< flatOutput(PtrListOps::names(areaSymmTensorFields)) << nl;
fieldDecomposer.decomposeFields(areaSymmTensorFields);
}
if (areaTensorFields.size())
{
Info<< " tensors: "
<< flatOutput(PtrListOps::names(areaTensorFields)) << nl;
fieldDecomposer.decomposeFields(areaTensorFields);
}
Info<< endl; Info<< endl;
} }
} }

View File

@ -46,6 +46,7 @@ Original Authors
#include "IOobjectList.H" #include "IOobjectList.H"
#include "areaFields.H" #include "areaFields.H"
#include "edgeFields.H"
#include "faFieldDecomposer.H" #include "faFieldDecomposer.H"
#include "faMeshReconstructor.H" #include "faMeshReconstructor.H"
#include "PtrListOps.H" #include "PtrListOps.H"

View File

@ -8,6 +8,4 @@ domainDecompositionWrite.C
domainDecompositionDryRun.C domainDecompositionDryRun.C
domainDecompositionDryRunWrite.C domainDecompositionDryRunWrite.C
lagrangianFieldDecomposer.C
EXE = $(FOAM_APPBIN)/decomposePar EXE = $(FOAM_APPBIN)/decomposePar

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2021 OpenCFD Ltd. Copyright (C) 2016-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -150,29 +150,19 @@ Usage
#include "domainDecomposition.H" #include "domainDecomposition.H"
#include "domainDecompositionDryRun.H" #include "domainDecompositionDryRun.H"
#include "labelIOField.H"
#include "labelFieldIOField.H"
#include "scalarIOField.H"
#include "scalarFieldIOField.H"
#include "vectorIOField.H"
#include "vectorFieldIOField.H"
#include "sphericalTensorIOField.H"
#include "sphericalTensorFieldIOField.H"
#include "symmTensorIOField.H"
#include "symmTensorFieldIOField.H"
#include "tensorIOField.H"
#include "tensorFieldIOField.H"
#include "pointFields.H"
#include "regionProperties.H" #include "regionProperties.H"
#include "readFields.H" #include "fieldsDistributor.H"
#include "fvFieldDecomposer.H" #include "fvFieldDecomposer.H"
#include "pointFields.H"
#include "pointFieldDecomposer.H" #include "pointFieldDecomposer.H"
#include "lagrangianFieldDecomposer.H" #include "lagrangianFieldDecomposer.H"
#include "emptyFaPatch.H" #include "emptyFaPatch.H"
#include "faMeshDecomposition.H"
#include "faFieldDecomposer.H" #include "faFieldDecomposer.H"
#include "faMeshDecomposition.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
@ -838,58 +828,14 @@ int main(int argc, char *argv[])
} }
// Vol fields // Volume/surface/internal fields
// ~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PtrList<volScalarField> volScalarFields;
PtrList<volVectorField> volVectorFields; fvFieldDecomposer::fieldsCache volumeFieldCache;
PtrList<volSphericalTensorField> volSphTensorFields;
PtrList<volSymmTensorField> volSymmTensorFields;
PtrList<volTensorField> volTensorFields;
if (doDecompFields) if (doDecompFields)
{ {
readFields(mesh, objects, volScalarFields, false); volumeFieldCache.readAllFields(mesh, objects);
readFields(mesh, objects, volVectorFields, false);
readFields(mesh, objects, volSphTensorFields, false);
readFields(mesh, objects, volSymmTensorFields, false);
readFields(mesh, objects, volTensorFields, false);
}
// Internal fields
// ~~~~~~~~~~~~~~~
PtrList<DimensionedField<scalar, volMesh>> dimScalarFields;
PtrList<DimensionedField<vector, volMesh>> dimVectorFields;
PtrList<DimensionedField<sphericalTensor, volMesh>>
dimSphTensorFields;
PtrList<DimensionedField<symmTensor, volMesh>>
dimSymmTensorFields;
PtrList<DimensionedField<tensor, volMesh>> dimTensorFields;
if (doDecompFields)
{
readFields(mesh, objects, dimScalarFields);
readFields(mesh, objects, dimVectorFields);
readFields(mesh, objects, dimSphTensorFields);
readFields(mesh, objects, dimSymmTensorFields);
readFields(mesh, objects, dimTensorFields);
}
// Surface fields
// ~~~~~~~~~~~~~~
PtrList<surfaceScalarField> surfaceScalarFields;
PtrList<surfaceVectorField> surfaceVectorFields;
PtrList<surfaceSphericalTensorField>
surfaceSphTensorFields;
PtrList<surfaceSymmTensorField> surfaceSymmTensorFields;
PtrList<surfaceTensorField> surfaceTensorFields;
if (doDecompFields)
{
readFields(mesh, objects, surfaceScalarFields, false);
readFields(mesh, objects, surfaceVectorFields, false);
readFields(mesh, objects, surfaceSphTensorFields, false);
readFields(mesh, objects, surfaceSymmTensorFields, false);
readFields(mesh, objects, surfaceTensorFields, false);
} }
@ -897,19 +843,11 @@ int main(int argc, char *argv[])
// ~~~~~~~~~~~~ // ~~~~~~~~~~~~
const pointMesh& pMesh = pointMesh::New(mesh); const pointMesh& pMesh = pointMesh::New(mesh);
PtrList<pointScalarField> pointScalarFields; pointFieldDecomposer::fieldsCache pointFieldCache;
PtrList<pointVectorField> pointVectorFields;
PtrList<pointSphericalTensorField> pointSphTensorFields;
PtrList<pointSymmTensorField> pointSymmTensorFields;
PtrList<pointTensorField> pointTensorFields;
if (doDecompFields) if (doDecompFields)
{ {
readFields(pMesh, objects, pointScalarFields, false); pointFieldCache.readAllFields(pMesh, objects);
readFields(pMesh, objects, pointVectorFields, false);
readFields(pMesh, objects, pointSphTensorFields, false);
readFields(pMesh, objects, pointSymmTensorFields, false);
readFields(pMesh, objects, pointTensorFields, false);
} }
@ -938,63 +876,10 @@ int main(int argc, char *argv[])
cloudDirs.size() cloudDirs.size()
); );
PtrList<PtrList<labelIOField>> lagrangianLabelFields lagrangianFieldDecomposer::fieldsCache lagrangianFieldCache
( (
cloudDirs.size() cloudDirs.size()
); );
PtrList<PtrList<labelFieldCompactIOField>>
lagrangianLabelFieldFields
(
cloudDirs.size()
);
PtrList<PtrList<scalarIOField>> lagrangianScalarFields
(
cloudDirs.size()
);
PtrList<PtrList<scalarFieldCompactIOField>>
lagrangianScalarFieldFields
(
cloudDirs.size()
);
PtrList<PtrList<vectorIOField>> lagrangianVectorFields
(
cloudDirs.size()
);
PtrList<PtrList<vectorFieldCompactIOField>>
lagrangianVectorFieldFields
(
cloudDirs.size()
);
PtrList<PtrList<sphericalTensorIOField>>
lagrangianSphTensorFields
(
cloudDirs.size()
);
PtrList<PtrList<sphericalTensorFieldCompactIOField>>
lagrangianSphTensorFieldFields
(
cloudDirs.size()
);
PtrList<PtrList<symmTensorIOField>>
lagrangianSymmTensorFields
(
cloudDirs.size()
);
PtrList<PtrList<symmTensorFieldCompactIOField>>
lagrangianSymmTensorFieldFields
(
cloudDirs.size()
);
PtrList<PtrList<tensorIOField>> lagrangianTensorFields
(
cloudDirs.size()
);
PtrList<PtrList<tensorFieldCompactIOField>>
lagrangianTensorFieldFields
(
cloudDirs.size()
);
label cloudI = 0; label cloudI = 0;
@ -1095,88 +980,10 @@ int main(int argc, char *argv[])
false false
); );
lagrangianFieldDecomposer::readFields lagrangianFieldCache.readAllFields
( (
cloudI, cloudI,
lagrangianObjects, lagrangianObjects
lagrangianLabelFields
);
lagrangianFieldDecomposer::readFieldFields
(
cloudI,
lagrangianObjects,
lagrangianLabelFieldFields
);
lagrangianFieldDecomposer::readFields
(
cloudI,
lagrangianObjects,
lagrangianScalarFields
);
lagrangianFieldDecomposer::readFieldFields
(
cloudI,
lagrangianObjects,
lagrangianScalarFieldFields
);
lagrangianFieldDecomposer::readFields
(
cloudI,
lagrangianObjects,
lagrangianVectorFields
);
lagrangianFieldDecomposer::readFieldFields
(
cloudI,
lagrangianObjects,
lagrangianVectorFieldFields
);
lagrangianFieldDecomposer::readFields
(
cloudI,
lagrangianObjects,
lagrangianSphTensorFields
);
lagrangianFieldDecomposer::readFieldFields
(
cloudI,
lagrangianObjects,
lagrangianSphTensorFieldFields
);
lagrangianFieldDecomposer::readFields
(
cloudI,
lagrangianObjects,
lagrangianSymmTensorFields
);
lagrangianFieldDecomposer::readFieldFields
(
cloudI,
lagrangianObjects,
lagrangianSymmTensorFieldFields
);
lagrangianFieldDecomposer::readFields
(
cloudI,
lagrangianObjects,
lagrangianTensorFields
);
lagrangianFieldDecomposer::readFieldFields
(
cloudI,
lagrangianObjects,
lagrangianTensorFieldFields
); );
++cloudI; ++cloudI;
@ -1185,18 +992,7 @@ int main(int argc, char *argv[])
lagrangianPositions.resize(cloudI); lagrangianPositions.resize(cloudI);
cellParticles.resize(cloudI); cellParticles.resize(cloudI);
lagrangianLabelFields.resize(cloudI); lagrangianFieldCache.resize(cloudI);
lagrangianLabelFieldFields.resize(cloudI);
lagrangianScalarFields.resize(cloudI);
lagrangianScalarFieldFields.resize(cloudI);
lagrangianVectorFields.resize(cloudI);
lagrangianVectorFieldFields.resize(cloudI);
lagrangianSphTensorFields.resize(cloudI);
lagrangianSphTensorFieldFields.resize(cloudI);
lagrangianSymmTensorFields.resize(cloudI);
lagrangianSymmTensorFieldFields.resize(cloudI);
lagrangianTensorFields.resize(cloudI);
lagrangianTensorFieldFields.resize(cloudI);
Info<< endl; Info<< endl;
@ -1291,35 +1087,11 @@ int main(int argc, char *argv[])
) )
); );
} }
const fvFieldDecomposer& fieldDecomposer =
fieldDecomposerList[proci];
// Vol fields volumeFieldCache.decomposeAllFields
fieldDecomposer.decomposeFields(volScalarFields);
fieldDecomposer.decomposeFields(volVectorFields);
fieldDecomposer.decomposeFields(volSphTensorFields);
fieldDecomposer.decomposeFields(volSymmTensorFields);
fieldDecomposer.decomposeFields(volTensorFields);
// Surface fields
fieldDecomposer.decomposeFields(surfaceScalarFields);
fieldDecomposer.decomposeFields(surfaceVectorFields);
fieldDecomposer.decomposeFields
( (
surfaceSphTensorFields fieldDecomposerList[proci]
); );
fieldDecomposer.decomposeFields
(
surfaceSymmTensorFields
);
fieldDecomposer.decomposeFields(surfaceTensorFields);
// internal fields
fieldDecomposer.decomposeFields(dimScalarFields);
fieldDecomposer.decomposeFields(dimVectorFields);
fieldDecomposer.decomposeFields(dimSphTensorFields);
fieldDecomposer.decomposeFields(dimSymmTensorFields);
fieldDecomposer.decomposeFields(dimTensorFields);
if (times.size() == 1) if (times.size() == 1)
{ {
@ -1330,14 +1102,7 @@ int main(int argc, char *argv[])
// Point fields // Point fields
if if (!pointFieldCache.empty())
(
pointScalarFields.size()
|| pointVectorFields.size()
|| pointSphTensorFields.size()
|| pointSymmTensorFields.size()
|| pointTensorFields.size()
)
{ {
const labelIOList& pointProcAddressing = procAddressing const labelIOList& pointProcAddressing = procAddressing
( (
@ -1363,15 +1128,11 @@ int main(int argc, char *argv[])
) )
); );
} }
const pointFieldDecomposer& pointDecomposer =
pointFieldDecomposerList[proci];
pointDecomposer.decomposeFields(pointScalarFields);
pointDecomposer.decomposeFields(pointVectorFields);
pointDecomposer.decomposeFields(pointSphTensorFields);
pointDecomposer.decomposeFields(pointSymmTensorFields);
pointDecomposer.decomposeFields(pointTensorFields);
pointFieldCache.decomposeAllFields
(
pointFieldDecomposerList[proci]
);
if (times.size() == 1) if (times.size() == 1)
{ {
@ -1382,9 +1143,9 @@ int main(int argc, char *argv[])
// If there is lagrangian data write it out // If there is lagrangian data write it out
forAll(lagrangianPositions, cloudI) forAll(lagrangianPositions, cloudi)
{ {
if (lagrangianPositions[cloudI].size()) if (lagrangianPositions[cloudi].size())
{ {
lagrangianFieldDecomposer fieldDecomposer lagrangianFieldDecomposer fieldDecomposer
( (
@ -1392,74 +1153,18 @@ int main(int argc, char *argv[])
procMesh, procMesh,
faceProcAddressing, faceProcAddressing,
cellProcAddressing, cellProcAddressing,
cloudDirs[cloudI], cloudDirs[cloudi],
lagrangianPositions[cloudI], lagrangianPositions[cloudi],
cellParticles[cloudI] cellParticles[cloudi]
); );
// Lagrangian fields // Lagrangian fields
{ lagrangianFieldCache.decomposeAllFields
fieldDecomposer.decomposeFields (
( cloudi,
cloudDirs[cloudI], cloudDirs[cloudi],
lagrangianLabelFields[cloudI] fieldDecomposer
); );
fieldDecomposer.decomposeFieldFields
(
cloudDirs[cloudI],
lagrangianLabelFieldFields[cloudI]
);
fieldDecomposer.decomposeFields
(
cloudDirs[cloudI],
lagrangianScalarFields[cloudI]
);
fieldDecomposer.decomposeFieldFields
(
cloudDirs[cloudI],
lagrangianScalarFieldFields[cloudI]
);
fieldDecomposer.decomposeFields
(
cloudDirs[cloudI],
lagrangianVectorFields[cloudI]
);
fieldDecomposer.decomposeFieldFields
(
cloudDirs[cloudI],
lagrangianVectorFieldFields[cloudI]
);
fieldDecomposer.decomposeFields
(
cloudDirs[cloudI],
lagrangianSphTensorFields[cloudI]
);
fieldDecomposer.decomposeFieldFields
(
cloudDirs[cloudI],
lagrangianSphTensorFieldFields[cloudI]
);
fieldDecomposer.decomposeFields
(
cloudDirs[cloudI],
lagrangianSymmTensorFields[cloudI]
);
fieldDecomposer.decomposeFieldFields
(
cloudDirs[cloudI],
lagrangianSymmTensorFieldFields[cloudI]
);
fieldDecomposer.decomposeFields
(
cloudDirs[cloudI],
lagrangianTensorFields[cloudI]
);
fieldDecomposer.decomposeFieldFields
(
cloudDirs[cloudI],
lagrangianTensorFieldFields[cloudI]
);
}
} }
} }
@ -1506,38 +1211,17 @@ int main(int argc, char *argv[])
aMesh.writeDecomposition(); aMesh.writeDecomposition();
// Area fields // Area/edge fields
// ~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~
PtrList<areaScalarField> areaScalarFields;
PtrList<areaVectorField> areaVectorFields;
PtrList<areaSphericalTensorField> areaSphTensorFields;
PtrList<areaSymmTensorField> areaSymmTensorFields;
PtrList<areaTensorField> areaTensorFields;
// Edge fields (limited number of types) faFieldDecomposer::fieldsCache areaFieldCache;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PtrList<edgeScalarField> edgeScalarFields;
if (doDecompFields) if (doDecompFields)
{ {
readFields(aMesh, objects, areaScalarFields); areaFieldCache.readAllFields(aMesh, objects);
readFields(aMesh, objects, areaVectorFields);
readFields(aMesh, objects, areaSphTensorFields);
readFields(aMesh, objects, areaSymmTensorFields);
readFields(aMesh, objects, areaTensorFields);
readFields(aMesh, objects, edgeScalarFields);
} }
const label nAreaFields = const label nAreaFields = areaFieldCache.size();
(
areaScalarFields.size()
+ areaVectorFields.size()
+ areaSphTensorFields.size()
+ areaSymmTensorFields.size()
+ areaTensorFields.size()
+ edgeScalarFields.size()
);
Info<< endl; Info<< endl;
Info<< "Finite area field transfer: " Info<< "Finite area field transfer: "
@ -1634,13 +1318,7 @@ int main(int argc, char *argv[])
boundaryProcAddressing boundaryProcAddressing
); );
fieldDecomposer.decomposeFields(areaScalarFields); areaFieldCache.decomposeAllFields(fieldDecomposer);
fieldDecomposer.decomposeFields(areaVectorFields);
fieldDecomposer.decomposeFields(areaSphTensorFields);
fieldDecomposer.decomposeFields(areaSymmTensorFields);
fieldDecomposer.decomposeFields(areaTensorFields);
fieldDecomposer.decomposeFields(edgeScalarFields);
} }
} }
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -37,6 +37,7 @@ License
#include "DynamicList.H" #include "DynamicList.H"
#include "fvFieldDecomposer.H" #include "fvFieldDecomposer.H"
#include "IOobjectList.H" #include "IOobjectList.H"
#include "PtrDynList.H"
#include "cellSet.H" #include "cellSet.H"
#include "faceSet.H" #include "faceSet.H"
#include "pointSet.H" #include "pointSet.H"
@ -178,32 +179,32 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
} }
PtrList<const cellSet> cellSets; PtrDynList<const cellSet> cellSets;
PtrList<const faceSet> faceSets; PtrDynList<const faceSet> faceSets;
PtrList<const pointSet> pointSets; PtrDynList<const pointSet> pointSets;
if (decomposeSets) if (decomposeSets)
{ {
// Read sets // Read sets
IOobjectList objects(*this, facesInstance(), "polyMesh/sets"); IOobjectList objects(*this, facesInstance(), "polyMesh/sets");
{ {
IOobjectList cSets(objects.lookupClass(cellSet::typeName)); IOobjectList sets(objects.lookupClass<cellSet>());
forAllConstIters(cSets, iter) forAllConstIters(sets, iter)
{ {
cellSets.append(new cellSet(*iter())); cellSets.append(new cellSet(*(iter.val())));
} }
} }
{ {
IOobjectList fSets(objects.lookupClass(faceSet::typeName)); IOobjectList sets(objects.lookupClass<faceSet>());
forAllConstIters(fSets, iter) forAllConstIters(sets, iter)
{ {
faceSets.append(new faceSet(*iter())); faceSets.append(new faceSet(*(iter.val())));
} }
} }
{ {
IOobjectList pSets(objects.lookupClass(pointSet::typeName)); IOobjectList sets(objects.lookupClass<pointSet>());
forAllConstIters(pSets, iter) forAllConstIters(sets, iter)
{ {
pointSets.append(new pointSet(*iter())); pointSets.append(new pointSet(*(iter.val())));
} }
} }
} }
@ -225,13 +226,11 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
); );
label maxProcCells = 0; label maxProcCells = 0;
label maxProcFaces = 0;
label totProcFaces = 0; label totProcFaces = 0;
label maxProcPatches = 0; label maxProcPatches = 0;
label totProcPatches = 0; label totProcPatches = 0;
label maxProcFaces = 0;
// Write out the meshes // Write out the meshes
for (label proci = 0; proci < nProcs_; proci++) for (label proci = 0; proci < nProcs_; proci++)
@ -265,7 +264,6 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
{ {
// Mark the original face as used // Mark the original face as used
// Remember to decrement the index by one (turning index) // Remember to decrement the index by one (turning index)
//
label curF = mag(curFaceLabels[facei]) - 1; label curF = mag(curFaceLabels[facei]) - 1;
faceLookup[curF] = facei; faceLookup[curF] = facei;
@ -855,31 +853,35 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
Info<< "Number of cells = " << procMesh.nCells() << nl; Info<< "Number of cells = " << procMesh.nCells() << nl;
if (procMesh.nCells())
{
Info<< " Number of points = " << procMesh.nPoints() << nl;
}
maxProcCells = max(maxProcCells, procMesh.nCells()); maxProcCells = max(maxProcCells, procMesh.nCells());
label nBoundaryFaces = 0; label nBoundaryFaces = 0;
label nProcPatches = 0; label nProcPatches = 0;
label nProcFaces = 0; label nProcFaces = 0;
forAll(procMesh.boundaryMesh(), patchi) for (const polyPatch& pp : procMesh.boundaryMesh())
{ {
if (isA<processorPolyPatch>(procMesh.boundaryMesh()[patchi])) const auto* cpp = isA<processorPolyPatch>(pp);
if (cpp)
{ {
const processorPolyPatch& ppp = const auto& procPatch = *cpp;
refCast<const processorPolyPatch>
(
procMesh.boundaryMesh()[patchi]
);
Info<< " Number of faces shared with processor " Info<< " Number of faces shared with processor "
<< ppp.neighbProcNo() << " = " << ppp.size() << endl; << procPatch.neighbProcNo() << " = "
<< procPatch.size() << nl;
nProcPatches++; nProcFaces += procPatch.size();
nProcFaces += ppp.size(); ++nProcPatches;
} }
else else
{ {
nBoundaryFaces += procMesh.boundaryMesh()[patchi].size(); nBoundaryFaces += pp.size();
} }
} }
@ -892,103 +894,79 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
totProcFaces += nProcFaces; totProcFaces += nProcFaces;
totProcPatches += nProcPatches; totProcPatches += nProcPatches;
maxProcPatches = max(maxProcPatches, nProcPatches);
maxProcFaces = max(maxProcFaces, nProcFaces); maxProcFaces = max(maxProcFaces, nProcFaces);
maxProcPatches = max(maxProcPatches, nProcPatches);
// create and write the addressing information // Write the addressing information
labelIOList pointProcAddressing
(
IOobject
(
"pointProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procPointAddressing_[proci]
);
pointProcAddressing.write();
labelIOList faceProcAddressing IOobject ioAddr
( (
IOobject "procAddressing",
( procMesh.facesInstance(),
"faceProcAddressing", polyMesh::meshSubDir,
procMesh.facesInstance(), procMesh.thisDb(),
procMesh.meshSubDir, IOobject::NO_READ,
procMesh, IOobject::NO_WRITE,
IOobject::NO_READ, false // not registered
IOobject::NO_WRITE
),
procFaceAddressing_[proci]
); );
faceProcAddressing.write();
labelIOList cellProcAddressing // pointProcAddressing
( ioAddr.rename("pointProcAddressing");
IOobject IOListRef<label>(ioAddr, procPointAddressing_[proci]).write();
(
"cellProcAddressing", // faceProcAddressing
procMesh.facesInstance(), ioAddr.rename("faceProcAddressing");
procMesh.meshSubDir, IOListRef<label>(ioAddr, procFaceAddressing_[proci]).write();
procMesh,
IOobject::NO_READ, // cellProcAddressing
IOobject::NO_WRITE ioAddr.rename("cellProcAddressing");
), IOListRef<label>(ioAddr, procCellAddressing_[proci]).write();
procCellAddressing_[proci]
);
cellProcAddressing.write();
// Write patch map for backwards compatibility. // Write patch map for backwards compatibility.
// (= identity map for original patches, -1 for processor patches) // (= identity map for original patches, -1 for processor patches)
label nMeshPatches = curPatchSizes.size(); label nMeshPatches = curPatchSizes.size();
labelList procBoundaryAddressing(identity(nMeshPatches)); labelList procBoundaryAddr(identity(nMeshPatches));
procBoundaryAddressing.setSize(nMeshPatches+nProcPatches, -1); procBoundaryAddr.resize(nMeshPatches+nProcPatches, -1);
labelIOList boundaryProcAddressing // boundaryProcAddressing
( ioAddr.rename("boundaryProcAddressing");
IOobject IOListRef<label>(ioAddr, procBoundaryAddr).write();
(
"boundaryProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procBoundaryAddressing
);
boundaryProcAddressing.write();
} }
scalar avgProcCells = scalar(nCells())/nProcs_;
scalar avgProcPatches = scalar(totProcPatches)/nProcs_;
scalar avgProcFaces = scalar(totProcFaces)/nProcs_;
// In case of all faces on one processor. Just to avoid division by 0.
if (totProcPatches == 0)
{
avgProcPatches = 1;
}
if (totProcFaces == 0)
{
avgProcFaces = 1;
}
// Summary stats
Info<< nl Info<< nl
<< "Number of processor faces = " << totProcFaces/2 << nl << "Number of processor faces = " << (totProcFaces/2) << nl
<< "Max number of cells = " << maxProcCells << "Max number of cells = " << maxProcCells;
<< " (" << 100.0*(maxProcCells-avgProcCells)/avgProcCells
<< "% above average " << avgProcCells << ")" << nl if (maxProcCells != nCells())
<< "Max number of processor patches = " << maxProcPatches {
<< " (" << 100.0*(maxProcPatches-avgProcPatches)/avgProcPatches scalar avgValue = scalar(nCells())/nProcs_;
<< "% above average " << avgProcPatches << ")" << nl
<< "Max number of faces between processors = " << maxProcFaces Info<< " (" << 100.0*(maxProcCells-avgValue)/avgValue
<< " (" << 100.0*(maxProcFaces-avgProcFaces)/avgProcFaces << "% above average " << avgValue << ')';
<< "% above average " << avgProcFaces << ")" << nl }
<< endl; Info<< nl;
Info<< "Max number of processor patches = " << maxProcPatches;
if (totProcPatches)
{
scalar avgValue = scalar(totProcPatches)/nProcs_;
Info<< " (" << 100.0*(maxProcPatches-avgValue)/avgValue
<< "% above average " << avgValue << ')';
}
Info<< nl;
Info<< "Max number of faces between processors = " << maxProcFaces;
if (totProcFaces)
{
scalar avgValue = scalar(totProcFaces)/nProcs_;
Info<< " (" << 100.0*(maxProcFaces-avgValue)/avgValue
<< "% above average " << avgValue << ')';
}
Info<< nl << endl;
return true; return true;
} }

View File

@ -1,90 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "GeometricField.H"
#include "readFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::readFields
(
const typename GeoMesh::Mesh& mesh,
const IOobjectList& objects,
PtrList<GeometricField<Type, PatchField, GeoMesh>>& fields,
const bool readOldTime
)
{
typedef GeometricField<Type, PatchField, GeoMesh> GeoField;
// Search list of objects for fields of type GeoField
IOobjectList fieldObjects(objects.lookupClass<GeoField>());
// Use sorted set of names
// (different processors might read objects in different order)
const wordList masterNames(fieldObjects.sortedNames());
// Construct the fields
fields.resize(masterNames.size());
forAll(masterNames, i)
{
const IOobject& io = *fieldObjects[masterNames[i]];
fields.set(i, new GeoField(io, mesh, readOldTime));
}
}
template<class Mesh, class GeoField>
void Foam::readFields
(
const Mesh& mesh,
const IOobjectList& objects,
PtrList<GeoField>& fields
)
{
// Search list of objects for fields of type GeomField
IOobjectList fieldObjects(objects.lookupClass<GeoField>());
// Use sorted set of names
// (different processors might read objects in different order)
const wordList masterNames(fieldObjects.sortedNames());
// Construct the fields
fields.resize(masterNames.size());
forAll(masterNames, i)
{
const IOobject& io = *fieldObjects[masterNames[i]];
fields.set(i, new GeoField(io, mesh));
}
}
// ************************************************************************* //

View File

@ -1,48 +0,0 @@
{
// Foam version 2.1 changes the addressing of faces in faceProcAddressing
// The following code checks and modifies the addressing for cases where
// the decomposition has been done with the foam2.0 and earlier tools, but
// the reconstruction is attempted with version 2.1 or later
label minFaceIndex = labelMax;
PtrList<labelIOList>& faceProcAddressing = procMeshes.faceProcAddressing();
forAll(faceProcAddressing, proci)
{
const labelList& curFaceAddr = faceProcAddressing[proci];
forAll(curFaceAddr, facei)
{
if (mag(curFaceAddr[facei]) < minFaceIndex)
{
minFaceIndex = mag(curFaceAddr[facei]);
}
}
}
if (minFaceIndex < 1)
{
WarningInFunction
<< "parallel decomposition addressing." << endl
<< "It looks like you are trying to reconstruct the case "
<< "decomposed with an earlier version of FOAM, which could\n"
<< "potentially cause compatibility problems. The code will "
<< "attempt to update the addressing automatically; in case of\n"
<< "failure, please repeat the decomposition of the case using "
<< "the current version fo decomposePar"
<< endl;
forAll(faceProcAddressing, proci)
{
labelList& curFaceAddr = faceProcAddressing[proci];
forAll(curFaceAddr, facei)
{
curFaceAddr[facei] += sign(curFaceAddr[facei]);
}
faceProcAddressing[proci].write();
}
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2021 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -334,11 +334,6 @@ int main(int argc, char *argv[])
// Read all meshes and addressing to reconstructed mesh // Read all meshes and addressing to reconstructed mesh
processorMeshes procMeshes(databases, regionName); processorMeshes procMeshes(databases, regionName);
// Check face addressing for meshes that have been decomposed
// with a very old foam version
#include "checkFaceAddressingComp.H"
// Loop over all times // Loop over all times
forAll(timeDirs, timei) forAll(timeDirs, timei)
{ {
@ -362,11 +357,11 @@ int main(int argc, char *argv[])
} }
// Check if any new meshes need to be read. // Check if any new meshes need to be read.
fvMesh::readUpdateState meshStat = mesh.readUpdate(); polyMesh::readUpdateState meshStat = mesh.readUpdate();
fvMesh::readUpdateState procStat = procMeshes.readUpdate(); polyMesh::readUpdateState procStat = procMeshes.readUpdate();
if (procStat == fvMesh::POINTS_MOVED) if (procStat == polyMesh::POINTS_MOVED)
{ {
// Reconstruct the points for moving mesh cases and write // Reconstruct the points for moving mesh cases and write
// them out // them out
@ -407,83 +402,7 @@ int main(int argc, char *argv[])
procMeshes.boundaryProcAddressing() procMeshes.boundaryProcAddressing()
); );
reconstructor.reconstructFvVolumeInternalFields<scalar> reconstructor.reconstructAllFields(objects, selectedFields);
(
objects,
selectedFields
);
reconstructor.reconstructFvVolumeInternalFields<vector>
(
objects,
selectedFields
);
reconstructor.reconstructFvVolumeInternalFields<sphericalTensor>
(
objects,
selectedFields
);
reconstructor.reconstructFvVolumeInternalFields<symmTensor>
(
objects,
selectedFields
);
reconstructor.reconstructFvVolumeInternalFields<tensor>
(
objects,
selectedFields
);
reconstructor.reconstructFvVolumeFields<scalar>
(
objects,
selectedFields
);
reconstructor.reconstructFvVolumeFields<vector>
(
objects,
selectedFields
);
reconstructor.reconstructFvVolumeFields<sphericalTensor>
(
objects,
selectedFields
);
reconstructor.reconstructFvVolumeFields<symmTensor>
(
objects,
selectedFields
);
reconstructor.reconstructFvVolumeFields<tensor>
(
objects,
selectedFields
);
reconstructor.reconstructFvSurfaceFields<scalar>
(
objects,
selectedFields
);
reconstructor.reconstructFvSurfaceFields<vector>
(
objects,
selectedFields
);
reconstructor.reconstructFvSurfaceFields<sphericalTensor>
(
objects,
selectedFields
);
reconstructor.reconstructFvSurfaceFields<symmTensor>
(
objects,
selectedFields
);
reconstructor.reconstructFvSurfaceFields<tensor>
(
objects,
selectedFields
);
if (reconstructor.nReconstructed() == 0) if (reconstructor.nReconstructed() == 0)
{ {
@ -515,31 +434,7 @@ int main(int argc, char *argv[])
procMeshes.boundaryProcAddressing() procMeshes.boundaryProcAddressing()
); );
reconstructor.reconstructFields<scalar> reconstructor.reconstructAllFields(objects, selectedFields);
(
objects,
selectedFields
);
reconstructor.reconstructFields<vector>
(
objects,
selectedFields
);
reconstructor.reconstructFields<sphericalTensor>
(
objects,
selectedFields
);
reconstructor.reconstructFields<symmTensor>
(
objects,
selectedFields
);
reconstructor.reconstructFields<tensor>
(
objects,
selectedFields
);
if (reconstructor.nReconstructed() == 0) if (reconstructor.nReconstructed() == 0)
{ {
@ -631,78 +526,7 @@ int main(int argc, char *argv[])
reconstructor.reconstructPositions(cloudName); reconstructor.reconstructPositions(cloudName);
reconstructor.reconstructFields<label> reconstructor.reconstructAllFields
(
cloudName,
cloudObjs,
selectedLagrangianFields
);
reconstructor.reconstructFieldFields<label>
(
cloudName,
cloudObjs,
selectedLagrangianFields
);
reconstructor.reconstructFields<scalar>
(
cloudName,
cloudObjs,
selectedLagrangianFields
);
reconstructor.reconstructFieldFields<scalar>
(
cloudName,
cloudObjs,
selectedLagrangianFields
);
reconstructor.reconstructFields<vector>
(
cloudName,
cloudObjs,
selectedLagrangianFields
);
reconstructor.reconstructFieldFields<vector>
(
cloudName,
cloudObjs,
selectedLagrangianFields
);
reconstructor.reconstructFields<sphericalTensor>
(
cloudName,
cloudObjs,
selectedLagrangianFields
);
reconstructor.reconstructFieldFields<sphericalTensor>
(
cloudName,
cloudObjs,
selectedLagrangianFields
);
reconstructor.reconstructFields<symmTensor>
(
cloudName,
cloudObjs,
selectedLagrangianFields
);
reconstructor.reconstructFieldFields<symmTensor>
(
cloudName,
cloudObjs,
selectedLagrangianFields
);
reconstructor.reconstructFields<tensor>
(
cloudName,
cloudObjs,
selectedLagrangianFields
);
reconstructor.reconstructFieldFields<tensor>
( (
cloudName, cloudName,
cloudObjs, cloudObjs,
@ -724,12 +548,12 @@ int main(int argc, char *argv[])
} }
else if else if
( (
objects.lookupClass(areaScalarField::typeName).size() objects.count<areaScalarField>()
|| objects.lookupClass(areaVectorField::typeName).size() || objects.count<areaVectorField>()
|| objects.lookupClass(areaSphericalTensorField::typeName).size() || objects.count<areaSphericalTensorField>()
|| objects.lookupClass(areaSymmTensorField::typeName).size() || objects.count<areaSymmTensorField>()
|| objects.lookupClass(areaTensorField::typeName).size() || objects.count<areaTensorField>()
|| objects.lookupClass(edgeScalarField::typeName).size() || objects.count<edgeScalarField>()
) )
{ {
Info << "Reconstructing FA fields" << nl << endl; Info << "Reconstructing FA fields" << nl << endl;
@ -747,13 +571,7 @@ int main(int argc, char *argv[])
procFaMeshes.boundaryProcAddressing() procFaMeshes.boundaryProcAddressing()
); );
reconstructor.reconstructFaAreaFields<scalar>(objects); reconstructor.reconstructAllFields(objects);
reconstructor.reconstructFaAreaFields<vector>(objects);
reconstructor.reconstructFaAreaFields<sphericalTensor>(objects);
reconstructor.reconstructFaAreaFields<symmTensor>(objects);
reconstructor.reconstructFaAreaFields<tensor>(objects);
reconstructor.reconstructFaEdgeFields<scalar>(objects);
} }
else else
{ {
@ -782,21 +600,19 @@ int main(int argc, char *argv[])
polyMesh::meshSubDir/"sets" polyMesh::meshSubDir/"sets"
); );
IOobjectList cSets(objects.lookupClass(cellSet::typeName)); for (const word& setName : objects.sortedNames<cellSet>())
forAllConstIters(cSets, iter)
{ {
cSetNames.insert(iter.key(), cSetNames.size()); cSetNames.insert(setName, cSetNames.size());
} }
IOobjectList fSets(objects.lookupClass(faceSet::typeName)); for (const word& setName : objects.sortedNames<faceSet>())
forAllConstIters(fSets, iter)
{ {
fSetNames.insert(iter.key(), fSetNames.size()); fSetNames.insert(setName, fSetNames.size());
} }
IOobjectList pSets(objects.lookupClass(pointSet::typeName));
forAllConstIters(pSets, iter) for (const word& setName : objects.sortedNames<pointSet>())
{ {
pSetNames.insert(iter.key(), pSetNames.size()); pSetNames.insert(setName, pSetNames.size());
} }
} }
@ -840,30 +656,25 @@ int main(int argc, char *argv[])
const labelList& cellMap = const labelList& cellMap =
procMeshes.cellProcAddressing()[proci]; procMeshes.cellProcAddressing()[proci];
IOobjectList cSets for (const IOobject& io : objects.sorted<cellSet>())
(
objects.lookupClass(cellSet::typeName)
);
forAllConstIters(cSets, iter)
{ {
// Load cellSet // Load cellSet
const cellSet procSet(*iter()); const cellSet procSet(io);
label setI = cSetNames[iter.key()]; const label seti = cSetNames[io.name()];
if (!cellSets.set(setI)) if (!cellSets.set(seti))
{ {
cellSets.set cellSets.set
( (
setI, seti,
new cellSet new cellSet
( (
mesh, mesh,
iter.key(), io.name(),
procSet.size() procSet.size()
) )
); );
} }
cellSet& cSet = cellSets[setI]; cellSet& cSet = cellSets[seti];
cSet.instance() = runTime.timeName(); cSet.instance() = runTime.timeName();
for (const label celli : procSet) for (const label celli : procSet)
@ -876,30 +687,25 @@ int main(int argc, char *argv[])
const labelList& faceMap = const labelList& faceMap =
procMeshes.faceProcAddressing()[proci]; procMeshes.faceProcAddressing()[proci];
IOobjectList fSets for (const IOobject& io : objects.sorted<faceSet>())
(
objects.lookupClass(faceSet::typeName)
);
forAllConstIters(fSets, iter)
{ {
// Load faceSet // Load faceSet
const faceSet procSet(*iter()); const faceSet procSet(io);
label setI = fSetNames[iter.key()]; const label seti = fSetNames[io.name()];
if (!faceSets.set(setI)) if (!faceSets.set(seti))
{ {
faceSets.set faceSets.set
( (
setI, seti,
new faceSet new faceSet
( (
mesh, mesh,
iter.key(), io.name(),
procSet.size() procSet.size()
) )
); );
} }
faceSet& fSet = faceSets[setI]; faceSet& fSet = faceSets[seti];
fSet.instance() = runTime.timeName(); fSet.instance() = runTime.timeName();
for (const label facei : procSet) for (const label facei : procSet)
@ -911,32 +717,28 @@ int main(int argc, char *argv[])
const labelList& pointMap = const labelList& pointMap =
procMeshes.pointProcAddressing()[proci]; procMeshes.pointProcAddressing()[proci];
IOobjectList pSets for (const IOobject& io : objects.sorted<pointSet>())
(
objects.lookupClass(pointSet::typeName)
);
forAllConstIters(pSets, iter)
{ {
// Load pointSet // Load pointSet
const pointSet propSet(*iter()); const pointSet procSet(io);
label setI = pSetNames[iter.key()]; const label seti = pSetNames[io.name()];
if (!pointSets.set(setI)) if (!pointSets.set(seti))
{ {
pointSets.set pointSets.set
( (
setI, seti,
new pointSet new pointSet
( (
mesh, mesh,
iter.key(), io.name(),
propSet.size() procSet.size()
) )
); );
} }
pointSet& pSet = pointSets[setI]; pointSet& pSet = pointSets[seti];
pSet.instance() = runTime.timeName(); pSet.instance() = runTime.timeName();
for (const label pointi : propSet) for (const label pointi : procSet)
{ {
pSet.insert(pointMap[pointi]); pSet.insert(pointMap[pointi]);
} }

View File

@ -522,14 +522,11 @@ void writeMaps
Info<< " pointProcAddressing" << endl; Info<< " pointProcAddressing" << endl;
ioAddr.rename("pointProcAddressing"); ioAddr.rename("pointProcAddressing");
labelIOList(ioAddr, pointProcAddressing).write(); IOListRef<label>(ioAddr, pointProcAddressing).write();
// From processor face to reconstructed mesh face // From processor face to reconstructed mesh face
Info<< " faceProcAddressing" << endl; Info<< " faceProcAddressing" << endl;
ioAddr.rename("faceProcAddressing"); ioAddr.rename("faceProcAddressing");
labelIOList faceProcAddr(ioAddr, faceProcAddressing); labelIOList faceProcAddr(ioAddr, faceProcAddressing);
// Now add turning index to faceProcAddressing. // Now add turning index to faceProcAddressing.
@ -572,17 +569,15 @@ void writeMaps
// From processor cell to reconstructed mesh cell // From processor cell to reconstructed mesh cell
Info<< " cellProcAddressing" << endl; Info<< " cellProcAddressing" << endl;
ioAddr.rename("cellProcAddressing"); ioAddr.rename("cellProcAddressing");
labelIOList(ioAddr, cellProcAddressing).write(); IOListRef<label>(ioAddr, cellProcAddressing).write();
// From processor patch to reconstructed mesh patch // From processor patch to reconstructed mesh patch
Info<< " boundaryProcAddressing" << endl; Info<< " boundaryProcAddressing" << endl;
ioAddr.rename("boundaryProcAddressing"); ioAddr.rename("boundaryProcAddressing");
labelIOList(ioAddr, boundProcAddressing).write(); IOListRef<label>(ioAddr, boundProcAddressing).write();
Info<< endl; Info<< endl;
} }

View File

@ -78,6 +78,7 @@ Usage
#include "fvMesh.H" #include "fvMesh.H"
#include "fvMeshTools.H" #include "fvMeshTools.H"
#include "fvMeshDistribute.H" #include "fvMeshDistribute.H"
#include "fieldsDistributor.H"
#include "decompositionMethod.H" #include "decompositionMethod.H"
#include "decompositionModel.H" #include "decompositionModel.H"
#include "timeSelector.H" #include "timeSelector.H"
@ -260,7 +261,6 @@ void printMeshData(const polyMesh& mesh)
{ {
// Collect all data on master // Collect all data on master
globalIndex globalCells(mesh.nCells());
labelListList patchNeiProcNo(Pstream::nProcs()); labelListList patchNeiProcNo(Pstream::nProcs());
labelListList patchSize(Pstream::nProcs()); labelListList patchSize(Pstream::nProcs());
const labelList& pPatches = mesh.globalData().processorPatches(); const labelList& pPatches = mesh.globalData().processorPatches();
@ -281,74 +281,94 @@ void printMeshData(const polyMesh& mesh)
// Print stats // Print stats
globalIndex globalBoundaryFaces(mesh.nBoundaryFaces()); const globalIndex globalCells(mesh.nCells());
const globalIndex globalBoundaryFaces(mesh.nBoundaryFaces());
label maxProcCells = 0; label maxProcCells = 0;
label maxProcFaces = 0;
label totProcFaces = 0; label totProcFaces = 0;
label maxProcPatches = 0; label maxProcPatches = 0;
label totProcPatches = 0; label totProcPatches = 0;
label maxProcFaces = 0;
for (const int procI : Pstream::allProcs()) for (const int proci : Pstream::allProcs())
{ {
const label nLocalCells = globalCells.localSize(proci);
const label nBndFaces = globalBoundaryFaces.localSize(proci);
Info<< nl Info<< nl
<< "Processor " << procI << nl << "Processor " << proci;
<< " Number of cells = " << globalCells.localSize(procI)
<< endl;
label nProcFaces = 0; if (!nLocalCells)
const labelList& nei = patchNeiProcNo[procI];
forAll(patchNeiProcNo[procI], i)
{ {
Info<< " Number of faces shared with processor " Info<< " (empty)" << endl;
<< patchNeiProcNo[procI][i] << " = " << patchSize[procI][i] continue;
<< endl; }
else
nProcFaces += patchSize[procI][i]; {
Info<< nl
<< " Number of cells = " << nLocalCells << endl;
} }
Info<< " Number of processor patches = " << nei.size() << nl label nProcFaces = 0;
<< " Number of processor faces = " << nProcFaces << nl const labelList& nei = patchNeiProcNo[proci];
<< " Number of boundary faces = "
<< globalBoundaryFaces.localSize(procI)-nProcFaces << endl;
maxProcCells = max(maxProcCells, globalCells.localSize(procI)); forAll(patchNeiProcNo[proci], i)
{
Info<< " Number of faces shared with processor "
<< patchNeiProcNo[proci][i] << " = "
<< patchSize[proci][i] << nl;
nProcFaces += patchSize[proci][i];
}
{
Info<< " Number of processor patches = " << nei.size() << nl
<< " Number of processor faces = " << nProcFaces << nl
<< " Number of boundary faces = "
<< nBndFaces-nProcFaces << endl;
}
maxProcCells = max(maxProcCells, nLocalCells);
totProcFaces += nProcFaces; totProcFaces += nProcFaces;
totProcPatches += nei.size(); totProcPatches += nei.size();
maxProcPatches = max(maxProcPatches, nei.size());
maxProcFaces = max(maxProcFaces, nProcFaces); maxProcFaces = max(maxProcFaces, nProcFaces);
maxProcPatches = max(maxProcPatches, nei.size());
} }
// Stats // Summary stats
scalar avgProcCells = scalar(globalCells.size())/Pstream::nProcs();
scalar avgProcPatches = scalar(totProcPatches)/Pstream::nProcs();
scalar avgProcFaces = scalar(totProcFaces)/Pstream::nProcs();
// In case of all faces on one processor. Just to avoid division by 0.
if (totProcPatches == 0)
{
avgProcPatches = 1;
}
if (totProcFaces == 0)
{
avgProcFaces = 1;
}
Info<< nl Info<< nl
<< "Number of processor faces = " << totProcFaces/2 << nl << "Number of processor faces = " << (totProcFaces/2) << nl
<< "Max number of cells = " << maxProcCells << "Max number of cells = " << maxProcCells;
<< " (" << 100.0*(maxProcCells-avgProcCells)/avgProcCells
<< "% above average " << avgProcCells << ")" << nl if (maxProcCells != globalCells.totalSize())
<< "Max number of processor patches = " << maxProcPatches {
<< " (" << 100.0*(maxProcPatches-avgProcPatches)/avgProcPatches scalar avgValue = scalar(globalCells.totalSize())/Pstream::nProcs();
<< "% above average " << avgProcPatches << ")" << nl
<< "Max number of faces between processors = " << maxProcFaces Info<< " (" << 100.0*(maxProcCells-avgValue)/avgValue
<< " (" << 100.0*(maxProcFaces-avgProcFaces)/avgProcFaces << "% above average " << avgValue << ')';
<< "% above average " << avgProcFaces << ")" << nl }
<< endl; Info<< nl;
Info<< "Max number of processor patches = " << maxProcPatches;
if (totProcPatches)
{
scalar avgValue = scalar(totProcPatches)/Pstream::nProcs();
Info<< " (" << 100.0*(maxProcPatches-avgValue)/avgValue
<< "% above average " << avgValue << ')';
}
Info<< nl;
Info<< "Max number of faces between processors = " << maxProcFaces;
if (totProcFaces)
{
scalar avgValue = scalar(totProcFaces)/Pstream::nProcs();
Info<< " (" << 100.0*(maxProcFaces-avgValue)/avgValue
<< "% above average " << avgValue << ')';
}
Info<< nl << endl;
} }
@ -513,180 +533,6 @@ void determineDecomposition
} }
// Generic mesh-based field reading
template<class GeoField>
void readField
(
const IOobject& io,
const fvMesh& mesh,
const label i,
PtrList<GeoField>& fields
)
{
fields.set(i, new GeoField(io, mesh));
}
// Definition of readField for GeometricFields only
template<class Type, template<class> class PatchField, class GeoMesh>
void readField
(
const IOobject& io,
const fvMesh& mesh,
const label i,
PtrList<GeometricField<Type, PatchField, GeoMesh>>& fields
)
{
fields.set
(
i,
new GeometricField<Type, PatchField, GeoMesh>(io, mesh, false)
);
}
// Read vol or surface fields
template<class GeoField>
void readFields
(
const boolList& haveMesh,
const fvMesh& mesh,
const autoPtr<fvMeshSubset>& subsetterPtr,
IOobjectList& allObjects,
PtrList<GeoField>& fields
)
{
// Get my objects of type
IOobjectList objects(allObjects.lookupClass(GeoField::typeName));
// Check that we all have all objects
wordList objectNames = objects.sortedNames();
// Get master names
wordList masterNames(objectNames);
Pstream::scatter(masterNames);
if (haveMesh[Pstream::myProcNo()] && objectNames != masterNames)
{
FatalErrorInFunction
<< "Objects not synchronised across processors." << nl
<< "Master has " << flatOutput(masterNames) << nl
<< "Processor " << Pstream::myProcNo()
<< " has " << flatOutput(objectNames)
<< exit(FatalError);
}
fields.setSize(masterNames.size());
// Have master send all fields to processors that don't have a mesh. The
// issue is if a patchField does any parallel operations inside its
// construct-from-dictionary. This will not work when going to more
// processors (e.g. decompose = 1 -> many) ! We could make a special
// exception for decomposePar but nicer would be to have read-communicator
// ... For now detect if decomposing & disable parRun
if (Pstream::master())
{
// Work out if we're decomposing - none of the subprocs has a mesh
bool decompose = true;
for (const int procI : Pstream::subProcs())
{
if (haveMesh[procI])
{
decompose = false;
}
}
forAll(masterNames, i)
{
const word& name = masterNames[i];
IOobject& io = *objects[name];
io.writeOpt(IOobject::AUTO_WRITE);
// Load field (but not oldTime)
const bool oldParRun = Pstream::parRun();
if (decompose)
{
Pstream::parRun(false);
}
readField(io, mesh, i, fields);
if (decompose)
{
Pstream::parRun(oldParRun);
}
// Create zero sized field and send
if (subsetterPtr)
{
const bool oldParRun = Pstream::parRun(false);
tmp<GeoField> tsubfld = subsetterPtr().interpolate(fields[i]);
Pstream::parRun(oldParRun);
// Send to all processors that don't have a mesh
for (const int procI : Pstream::subProcs())
{
if (!haveMesh[procI])
{
OPstream toProc(Pstream::commsTypes::blocking, procI);
toProc<< tsubfld();
}
}
}
}
}
else if (!haveMesh[Pstream::myProcNo()])
{
// Don't have mesh (nor fields). Receive empty field from master.
forAll(masterNames, i)
{
const word& name = masterNames[i];
// Receive field
IPstream fromMaster
(
Pstream::commsTypes::blocking,
Pstream::masterNo()
);
dictionary fieldDict(fromMaster);
fields.set
(
i,
new GeoField
(
IOobject
(
name,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
fieldDict
)
);
//// Write it for next time round (since mesh gets written as well)
//fields[i].write();
}
}
else
{
// Have mesh so just try to load
forAll(masterNames, i)
{
const word& name = masterNames[i];
IOobject& io = *objects[name];
io.writeOpt(IOobject::AUTO_WRITE);
// Load field (but not oldtime)
readField(io, mesh, i, fields);
}
}
}
// Variant of GeometricField::correctBoundaryConditions that only // Variant of GeometricField::correctBoundaryConditions that only
// evaluates selected patch fields // evaluates selected patch fields
template<class GeoField, class CoupledPatchType> template<class GeoField, class CoupledPatchType>
@ -817,7 +663,8 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
runTime.caseName() = baseRunTime.caseName(); runTime.caseName() = baseRunTime.caseName();
runTime.processorCase(false); runTime.processorCase(false);
} }
readFields
fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -826,7 +673,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
volScalarFields volScalarFields
); );
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -835,7 +682,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
volVectorFields volVectorFields
); );
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -844,7 +691,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
volSphereTensorFields volSphereTensorFields
); );
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -853,7 +700,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
volSymmTensorFields volSymmTensorFields
); );
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -865,7 +712,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
// surfaceFields // surfaceFields
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -874,7 +721,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
surfScalarFields surfScalarFields
); );
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -883,7 +730,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
surfVectorFields surfVectorFields
); );
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -892,7 +739,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
surfSphereTensorFields surfSphereTensorFields
); );
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -901,7 +748,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
surfSymmTensorFields surfSymmTensorFields
); );
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -912,7 +759,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
// Dimensioned internal fields // Dimensioned internal fields
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -921,7 +768,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
dimScalarFields dimScalarFields
); );
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -930,7 +777,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
dimVectorFields dimVectorFields
); );
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -939,7 +786,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
dimSphereTensorFields dimSphereTensorFields
); );
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,
@ -948,7 +795,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
dimSymmTensorFields dimSymmTensorFields
); );
readFields fieldsDistributor::readFields
( (
haveMesh, haveMesh,
mesh, mesh,

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -23,29 +23,69 @@ License
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Global Class
readFields fieldsDistributor
Description Description
Common methods/utilities for field decomposers/distributors etc.
SourceFiles SourceFiles
readFields.C fieldsDistributorTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef readFields_H #ifndef Foam_fieldsDistributor_H
#define readFields_H #define Foam_fieldsDistributor_H
#include "IOobjectList.H" #include "IOobjectList.H"
#include "boolList.H"
#include "PtrList.H" #include "PtrList.H"
#include "GeometricField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
// Read the fields and hold on the pointer list
/*---------------------------------------------------------------------------*\
Class fieldsDistributor Declaration
\*---------------------------------------------------------------------------*/
class fieldsDistributor
{
public:
// Reading helpers
//- Generic mesh-based field reading
template<class GeoField>
static void readField
(
const IOobject& io,
const typename GeoField::Mesh& mesh,
const label i,
PtrList<GeoField>& fields
);
//- Definition of readField for GeometricFields only
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void readFields static void readField
(
const IOobject& io,
const typename GeoMesh::Mesh& mesh,
const label i,
PtrList<GeometricField<Type, PatchField, GeoMesh>>& fields
);
//- Read fields and store on the pointer list
template
<
class Type,
template<class> class PatchField,
class GeoMesh
>
static void readFields
( (
const typename GeoMesh::Mesh& mesh, const typename GeoMesh::Mesh& mesh,
const IOobjectList& objects, const IOobjectList& objects,
@ -53,21 +93,39 @@ namespace Foam
const bool readOldTime const bool readOldTime
); );
// Read the fields and hold on the pointer list //- Read fields and hold on the pointer list
template<class Mesh, class GeoField> template<class Mesh, class GeoField>
void readFields static void readFields
( (
const Mesh& mesh, const Mesh& mesh,
const IOobjectList& objects, const IOobjectList& objects,
PtrList<GeoField>& fields PtrList<GeoField>& fields
); );
}
//- Read volume/surface/point/area fields that may or may not exist
//- on all processors
template<class GeoField, class MeshSubsetter>
static void readFields
(
const boolList& haveMeshOnProc,
const typename GeoField::Mesh& mesh,
const autoPtr<MeshSubsetter>& subsetterPtr,
IOobjectList& allObjects,
PtrList<GeoField>& fields,
const bool deregister = false
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "readFields.C" #include "fieldsDistributorTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,330 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class GeoField>
void Foam::fieldsDistributor::readField
(
const IOobject& io,
const typename GeoField::Mesh& mesh,
const label i,
PtrList<GeoField>& fields
)
{
fields.set(i, new GeoField(io, mesh));
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::fieldsDistributor::readField
(
const IOobject& io,
const typename GeoMesh::Mesh& mesh,
const label i,
PtrList<GeometricField<Type, PatchField, GeoMesh>>& fields
)
{
fields.set
(
i,
new GeometricField<Type, PatchField, GeoMesh>(io, mesh, false)
);
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::fieldsDistributor::readFields
(
const typename GeoMesh::Mesh& mesh,
const IOobjectList& objects,
PtrList<GeometricField<Type, PatchField, GeoMesh>>& fields,
const bool readOldTime
)
{
typedef GeometricField<Type, PatchField, GeoMesh> GeoField;
// GeoField fields - sorted for consistent order on all processors
UPtrList<const IOobject> fieldObjects(objects.sorted<GeoField>());
// Construct the fields
fields.resize(fieldObjects.size());
forAll(fieldObjects, i)
{
fields.set(i, new GeoField(fieldObjects[i], mesh, readOldTime));
}
}
template<class Mesh, class GeoField>
void Foam::fieldsDistributor::readFields
(
const Mesh& mesh,
const IOobjectList& objects,
PtrList<GeoField>& fields
)
{
// GeoField fields - sorted for consistent order on all processors
UPtrList<const IOobject> fieldObjects(objects.sorted<GeoField>());
// Construct the fields
fields.resize(fieldObjects.size());
forAll(fieldObjects, i)
{
fields.set(i, new GeoField(fieldObjects[i], mesh));
}
}
template<class GeoField, class MeshSubsetter>
void Foam::fieldsDistributor::readFields
(
const boolList& haveMeshOnProc,
const typename GeoField::Mesh& mesh,
const autoPtr<MeshSubsetter>& subsetterPtr,
IOobjectList& allObjects,
PtrList<GeoField>& fields,
const bool deregister
)
{
// Get my objects of type
IOobjectList objects(allObjects.lookupClass<GeoField>());
// Check that we all have all objects
wordList objectNames = objects.sortedNames();
// Get master names
wordList masterNames(objectNames);
Pstream::broadcast(masterNames);
if (haveMeshOnProc[Pstream::myProcNo()] && objectNames != masterNames)
{
FatalErrorInFunction
<< "Objects not synchronised across processors." << nl
<< "Master has " << flatOutput(masterNames) << nl
<< "Processor " << Pstream::myProcNo()
<< " has " << flatOutput(objectNames)
<< exit(FatalError);
}
fields.clear();
fields.resize(masterNames.size());
if (fields.empty())
{
if (deregister)
{
// Extra safety - remove all such types
HashTable<const GeoField*> other
(
mesh.thisDb().objectRegistry::template lookupClass<GeoField>()
);
forAllConstIters(other, iter)
{
GeoField& fld = const_cast<GeoField&>(*iter.val());
if (!fld.ownedByRegistry())
{
fld.checkOut();
}
}
}
// Early exit
return;
}
// Have master send all fields to processors that don't have a mesh. The
// issue is if a patchField does any parallel operations inside its
// construct-from-dictionary. This will not work when going to more
// processors (e.g. decompose = 1 -> many) ! We could make a special
// exception for decomposePar but nicer would be to have read-communicator
// ... For now detect if decomposing & disable parRun
if (Pstream::master())
{
// Work out if we're decomposing - none of the subprocs has a mesh
bool decompose = true;
for (const int proci : Pstream::subProcs())
{
if (haveMeshOnProc[proci])
{
decompose = false;
}
}
const bool oldParRun = Pstream::parRun();
if (decompose)
{
Pstream::parRun(false);
}
forAll(masterNames, i)
{
const word& name = masterNames[i];
IOobject& io = *objects[name];
io.writeOpt(IOobject::AUTO_WRITE);
// Load field (but not oldTime)
readField(io, mesh, i, fields);
}
Pstream::parRun(oldParRun); // Restore any changes
}
else if (haveMeshOnProc[Pstream::myProcNo()])
{
// Have mesh so just try to load
forAll(masterNames, i)
{
const word& name = masterNames[i];
IOobject& io = *objects[name];
io.writeOpt(IOobject::AUTO_WRITE);
/// Pout<< "Attempt read: " << name << endl;
// Load field (but not oldTime)
readField(io, mesh, i, fields);
}
}
// Missing fields on any processors?
// - construct from dictionary
PtrList<dictionary> fieldDicts;
if (Pstream::master())
{
// Broadcast zero sized fields everywhere (if needed)
// Send like a list of dictionaries
OPBstream toProcs(UPstream::masterNo()); // worldComm
const label nDicts = (subsetterPtr ? fields.size() : label(0));
toProcs << nDicts << token::BEGIN_LIST; // Begin list
if (nDicts)
{
// Disable communication for interpolate() method
const bool oldParRun = Pstream::parRun(false);
const auto& subsetter = subsetterPtr();
forAll(fields, i)
{
tmp<GeoField> tsubfld = subsetter.interpolate(fields[i]);
// Surround each with {} as dictionary entry
toProcs.beginBlock();
toProcs << tsubfld();
toProcs.endBlock();
}
Pstream::parRun(oldParRun); // Restore state
}
toProcs << token::END_LIST << token::NL; // End list
}
else
{
// Receive the broadcast...
IPBstream fromMaster(UPstream::masterNo()); // worldComm
// But only consume where needed...
if (!haveMeshOnProc[Pstream::myProcNo()])
{
fromMaster >> fieldDicts;
}
}
// Use the received dictionaries to create fields
// (will be empty if we didn't require them)
// Disable communication when constructing from dictionary
const bool oldParRun = Pstream::parRun(false);
forAll(fieldDicts, i)
{
fields.set
(
i,
new GeoField
(
IOobject
(
masterNames[i],
mesh.time().timeName(),
mesh.thisDb(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
fieldDicts[i]
)
);
}
Pstream::parRun(oldParRun); // Restore any changes
// Finally. Can checkOut of registry as required
if (deregister)
{
/// Info<< "De-registering fields:";
for (auto& fld : fields)
{
/// Info<< " " << fld.name();
// Ensure it is not destroyed by polyMesh deletion
fld.checkOut();
}
/// Info<< nl;
// Extra safety - remove all such types
HashTable<const GeoField*> other
(
mesh.thisDb().objectRegistry::template lookupClass<GeoField>()
);
forAllConstIters(other, iter)
{
GeoField& fld = const_cast<GeoField&>(*iter.val());
if (!fld.ownedByRegistry())
{
fld.checkOut();
}
}
}
}
// ************************************************************************* //

View File

@ -2,7 +2,14 @@ decompositionInformation.C
decompositionModel.C decompositionModel.C
dimFieldDecomposer.C dimFieldDecomposer.C
fvFieldDecomposer.C fvFieldDecomposer.C
fvFieldDecomposerCache.C
pointFieldDecomposer.C pointFieldDecomposer.C
pointFieldDecomposerCache.C
lagrangianFieldDecomposer.C
lagrangianFieldDecomposerCache.C
LIB = $(FOAM_LIBBIN)/libdecompose LIB = $(FOAM_LIBBIN)/libdecompose

View File

@ -32,12 +32,12 @@ Description
SourceFiles SourceFiles
dimFieldDecomposer.C dimFieldDecomposer.C
dimFieldDecomposerFields.C dimFieldDecomposerTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef dimFieldDecomposer_H #ifndef Foam_dimFieldDecomposer_H
#define dimFieldDecomposer_H #define Foam_dimFieldDecomposer_H
#include "fvMesh.H" #include "fvMesh.H"
#include "surfaceFields.H" #include "surfaceFields.H"
@ -121,7 +121,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "dimFieldDecomposerFields.C" #include "dimFieldDecomposerTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -47,8 +47,8 @@ Foam::dimFieldDecomposer::decomposeField
IOobject IOobject
( (
field.name(), field.name(),
procMesh_.time().timeName(), procMesh_.thisDb().time().timeName(),
procMesh_, procMesh_.thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
false false

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd. Copyright (C) 2021-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,6 +28,11 @@ License
#include "fvFieldDecomposer.H" #include "fvFieldDecomposer.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::fvFieldDecomposer::verbose_ = 1;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fvFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer Foam::fvFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer
@ -95,7 +100,7 @@ processorVolPatchFieldDecomposer
Foam::fvFieldDecomposer::processorVolPatchFieldDecomposer:: Foam::fvFieldDecomposer::processorVolPatchFieldDecomposer::
processorVolPatchFieldDecomposer processorVolPatchFieldDecomposer
( (
const fvMesh& mesh, const polyMesh& mesh,
const labelUList& addressingSlice const labelUList& addressingSlice
) )
: :

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd. Copyright (C) 2021-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,12 +32,13 @@ Description
SourceFiles SourceFiles
fvFieldDecomposer.C fvFieldDecomposer.C
fvFieldDecomposerFields.C fvFieldDecomposerCache.C
fvFieldDecomposerTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef fvFieldDecomposer_H #ifndef Foam_fvFieldDecomposer_H
#define fvFieldDecomposer_H #define Foam_fvFieldDecomposer_H
#include "fvMesh.H" #include "fvMesh.H"
#include "fvPatchFieldMapper.H" #include "fvPatchFieldMapper.H"
@ -48,6 +49,9 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward Declarations
class IOobjectList;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class fvFieldDecomposer Declaration Class fvFieldDecomposer Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -56,6 +60,8 @@ class fvFieldDecomposer
{ {
public: public:
// Public Classes
//- Patch field decomposer class //- Patch field decomposer class
class patchFieldDecomposer class patchFieldDecomposer
: :
@ -126,7 +132,7 @@ public:
//- Construct given addressing from complete mesh //- Construct given addressing from complete mesh
processorVolPatchFieldDecomposer processorVolPatchFieldDecomposer
( (
const fvMesh& mesh, const polyMesh& mesh,
const labelUList& addressingSlice const labelUList& addressingSlice
); );
@ -232,13 +238,24 @@ private:
PtrList<scalarField> faceSign_; PtrList<scalarField> faceSign_;
// Private Member Functions
//- No copy construct
fvFieldDecomposer(const fvFieldDecomposer&) = delete;
//- No copy assignment
void operator=(const fvFieldDecomposer&) = delete;
public: public:
//- No copy construct // Public Classes
fvFieldDecomposer(const fvFieldDecomposer&) = delete; class fieldsCache;
//- No copy assignment
void operator=(const fvFieldDecomposer&) = delete; // Static Data
//- Output verbosity when writing
static int verbose_;
// Constructors // Constructors
@ -336,6 +353,69 @@ public:
}; };
/*---------------------------------------------------------------------------*\
Class fvFieldDecomposer::fieldsCache Declaration
\*---------------------------------------------------------------------------*/
class fvFieldDecomposer::fieldsCache
{
// Private Data
class privateCache;
//- All field and field-field types for lagrangian
std::unique_ptr<privateCache> cache_;
// Private Member Functions
//- No copy construct
fieldsCache(const fieldsCache&) = delete;
//- No copy assignment
void operator=(const fieldsCache&) = delete;
public:
// Constructors
//- Default construct
fieldsCache();
//- Destructor
~fieldsCache();
// Member Functions
//- No fields
bool empty() const;
//- Total number of fields
label size() const;
//- Clear out
void clear();
//- Read all fields given mesh and objects
void readAllFields
(
const fvMesh& mesh,
const IOobjectList& objects
);
//- Decompose and write all fields
void decomposeAllFields
(
const fvFieldDecomposer& decomposer,
bool report = false
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam
@ -343,7 +423,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "fvFieldDecomposerFields.C" #include "fvFieldDecomposerTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,228 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "fvFieldDecomposer.H"
#include "fieldsDistributor.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "IOobjectList.H"
#include "PtrListOps.H"
// * * * * * * * * * * * * * * * * Declarations * * * * * * * * * * * * * * //
namespace Foam
{
// All volume internal types
class fvFieldDecomposer::fieldsCache::privateCache
{
public:
#undef declareField
#define declareField(Type) \
PtrList<DimensionedField<Type, volMesh>> Type##DimFields_; \
PtrList<GeometricField<Type, fvPatchField, volMesh>> Type##VolFields_; \
PtrList<GeometricField<Type, fvsPatchField, surfaceMesh>> Type##SurfFields_;
declareField(scalar);
declareField(vector);
declareField(sphericalTensor);
declareField(symmTensor);
declareField(tensor);
#undef declareField
label size() const noexcept
{
label count = 0;
#undef doLocalCode
#define doLocalCode(Type) \
{ \
count += Type##DimFields_.size(); \
count += Type##VolFields_.size(); \
count += Type##SurfFields_.size(); \
}
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
return count;
}
bool empty() const noexcept { return !size(); }
void readAll(const fvMesh& mesh, const IOobjectList& objects)
{
#undef doLocalCode
#define doLocalCode(Type) \
{ \
fieldsDistributor::readFields \
( \
mesh, \
objects, \
Type##DimFields_ \
); \
fieldsDistributor::readFields \
( \
mesh, \
objects, \
Type##VolFields_, \
false /* readOldTime = false */ \
); \
fieldsDistributor::readFields \
( \
mesh, \
objects, \
Type##SurfFields_, \
false /* readOldTime = false */ \
); \
}
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
}
template<class GeoField>
static void decompose
(
const fvFieldDecomposer& decomposer,
const PtrList<GeoField>& fields,
bool report
)
{
if (!fields.empty())
{
if (report)
{
Info<< " "
<< pTraits<typename GeoField::value_type>::typeName
<< "s: "
<< flatOutput(PtrListOps::names(fields)) << nl;
}
decomposer.decomposeFields(fields);
}
}
void decomposeAll
(
const fvFieldDecomposer& decomposer,
bool report
) const
{
#undef doLocalCode
#define doLocalCode(Flavour) \
{ \
decompose(decomposer, scalar##Flavour##Fields_, report); \
decompose(decomposer, vector##Flavour##Fields_, report); \
decompose(decomposer, sphericalTensor##Flavour##Fields_, report); \
decompose(decomposer, symmTensor##Flavour##Fields_, report); \
decompose(decomposer, tensor##Flavour##Fields_, report); \
}
doLocalCode(Vol);
doLocalCode(Surf);
doLocalCode(Dim);
#undef doLocalCode
}
};
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fvFieldDecomposer::fieldsCache::fieldsCache()
:
cache_(new privateCache)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
// Destructor not in header (used incomplete type)
Foam::fvFieldDecomposer::fieldsCache::~fieldsCache()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::fvFieldDecomposer::fieldsCache::empty() const
{
return (!cache_ || cache_->empty());
}
Foam::label Foam::fvFieldDecomposer::fieldsCache::size() const
{
return (cache_ ? cache_->size() : label(0));
}
void Foam::fvFieldDecomposer::fieldsCache::clear()
{
cache_.reset(new privateCache);
}
void Foam::fvFieldDecomposer::fieldsCache::readAllFields
(
const fvMesh& mesh,
const IOobjectList& objects
)
{
if (cache_)
{
cache_->readAll(mesh, objects);
}
}
void Foam::fvFieldDecomposer::fieldsCache::decomposeAllFields
(
const fvFieldDecomposer& decomposer,
bool report
) const
{
if (cache_)
{
cache_->decomposeAll(decomposer, report);
}
}
// ************************************************************************* //

View File

@ -32,6 +32,8 @@ License
#include "processorCyclicFvPatchField.H" #include "processorCyclicFvPatchField.H"
#include "processorCyclicFvsPatchField.H" #include "processorCyclicFvsPatchField.H"
#include "emptyFvPatchFields.H" #include "emptyFvPatchFields.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -52,8 +54,8 @@ Foam::fvFieldDecomposer::decomposeField
IOobject IOobject
( (
field.name(), field.name(),
procMesh_.time().timeName(), procMesh_.thisDb().time().timeName(),
procMesh_, procMesh_.thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
false false
@ -100,8 +102,8 @@ Foam::fvFieldDecomposer::decomposeField
IOobject IOobject
( (
field.name(), field.name(),
procMesh_.time().timeName(), procMesh_.thisDb().time().timeName(),
procMesh_, procMesh_.thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
@ -118,7 +120,7 @@ Foam::fvFieldDecomposer::decomposeField
// 2. Change the fvPatchFields to the correct type using a mapper // 2. Change the fvPatchFields to the correct type using a mapper
// constructor (with reference to the now correct internal field) // constructor (with reference to the now correct internal field)
typename VolFieldType::Boundary& bf = resF.boundaryFieldRef(); auto& bf = resF.boundaryFieldRef();
forAll(bf, patchi) forAll(bf, patchi)
{ {
@ -272,8 +274,8 @@ Foam::fvFieldDecomposer::decomposeField
IOobject IOobject
( (
field.name(), field.name(),
procMesh_.time().timeName(), procMesh_.thisDb().time().timeName(),
procMesh_, procMesh_.thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
@ -289,7 +291,7 @@ Foam::fvFieldDecomposer::decomposeField
// 2. Change the fvsPatchFields to the correct type using a mapper // 2. Change the fvsPatchFields to the correct type using a mapper
// constructor (with reference to the now correct internal field) // constructor (with reference to the now correct internal field)
typename SurfaceFieldType::Boundary& bf = resF.boundaryFieldRef(); auto& bf = resF.boundaryFieldRef();
forAll(boundaryAddressing_, patchi) forAll(boundaryAddressing_, patchi)
{ {

View File

@ -94,7 +94,7 @@ Foam::lagrangianFieldDecomposer::lagrangianFieldDecomposer
} }
} }
particleIndices_.setSize(pi); particleIndices_.resize(pi);
IOPosition<Cloud<passiveParticle>>(positions_).write(); IOPosition<Cloud<passiveParticle>>(positions_).write();
} }

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,12 +32,14 @@ Description
SourceFiles SourceFiles
lagrangianFieldDecomposer.C lagrangianFieldDecomposer.C
lagrangianFieldDecomposerFields.C lagrangianFieldDecomposerCache.C
lagrangianFieldDecomposerReadFields.C
lagrangianFieldDecomposerTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef lagrangianFieldDecomposer_H #ifndef Foam_lagrangianFieldDecomposer_H
#define lagrangianFieldDecomposer_H #define Foam_lagrangianFieldDecomposer_H
#include "Cloud.H" #include "Cloud.H"
#include "CompactIOField.H" #include "CompactIOField.H"
@ -48,6 +51,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward Declarations
class IOobjectList; class IOobjectList;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
@ -56,7 +60,7 @@ class IOobjectList;
class lagrangianFieldDecomposer class lagrangianFieldDecomposer
{ {
// Private data // Private Data
//- Reference to processor mesh //- Reference to processor mesh
const polyMesh& procMesh_; const polyMesh& procMesh_;
@ -79,6 +83,10 @@ class lagrangianFieldDecomposer
public: public:
// Public Classes
class fieldsCache;
// Constructors // Constructors
//- Construct from components //- Construct from components
@ -94,29 +102,29 @@ public:
); );
// Member Functions // Field Reading
// Read the fields and hold on the pointer list //- Read the fields and store on the pointer list
template<class Type> template<class Type>
static void readFields static void readFields
( (
const label cloudI, const label cloudi,
const IOobjectList& lagrangianObjects, const IOobjectList& lagrangianObjects,
PtrList<PtrList<IOField<Type>>>& lagrangianFields PtrList<PtrList<IOField<Type>>>& cloudFields
); );
//- Read the field-fields and store on the pointer list
template<class Type> template<class Type>
static void readFieldFields static void readFieldFields
( (
const label cloudI, const label cloudi,
const IOobjectList& lagrangianObjects, const IOobjectList& lagrangianObjects,
PtrList PtrList<PtrList<CompactIOField<Field<Type>, Type>>>& cloudFields
<
PtrList<CompactIOField<Field<Type>, Type>>
>& lagrangianFields
); );
// Member Functions
//- Decompose volume field //- Decompose volume field
template<class Type> template<class Type>
tmp<IOField<Type>> decomposeField tmp<IOField<Type>> decomposeField
@ -149,6 +157,77 @@ public:
}; };
/*---------------------------------------------------------------------------*\
Class lagrangianFieldDecomposer::fieldsCache Declaration
\*---------------------------------------------------------------------------*/
class lagrangianFieldDecomposer::fieldsCache
{
// Private Data
class privateCache;
//- All field and field-field types for lagrangian
std::unique_ptr<privateCache> cache_;
// Private Member Functions
//- No copy construct
fieldsCache(const fieldsCache&) = delete;
//- No copy assignment
void operator=(const fieldsCache&) = delete;
public:
// Constructors
//- Default construct (no clouds)
fieldsCache();
//- Construct for given number of clouds
explicit fieldsCache(const label nClouds);
//- Destructor
~fieldsCache();
// Member Functions
//- No clouds
bool empty() const;
//- Number of clouds
label size() const;
//- Clear out
void clear();
//- Resize for the number of clouds
void resize(const label nClouds);
//- Read all fields and field-fields for given cloud and objects
void readAllFields
(
const label cloudi,
const IOobjectList& lagrangianObjects
);
//- Decompose and write all fields and field-fields for given cloud
void decomposeAllFields
(
const label cloudi,
const fileName& cloudDir,
const lagrangianFieldDecomposer& decomposer,
bool report = false
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam
@ -156,7 +235,8 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "lagrangianFieldDecomposerFields.C" #include "lagrangianFieldDecomposerReadFields.C"
#include "lagrangianFieldDecomposerTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,241 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "lagrangianFieldDecomposer.H"
#include "labelIOField.H"
#include "labelFieldIOField.H"
#include "scalarIOField.H"
#include "scalarFieldIOField.H"
#include "vectorIOField.H"
#include "vectorFieldIOField.H"
#include "sphericalTensorIOField.H"
#include "sphericalTensorFieldIOField.H"
#include "symmTensorIOField.H"
#include "symmTensorFieldIOField.H"
#include "tensorIOField.H"
#include "tensorFieldIOField.H"
// * * * * * * * * * * * * * * * * Declarations * * * * * * * * * * * * * * //
namespace Foam
{
// All lagrangian field/field-field types
class lagrangianFieldDecomposer::fieldsCache::privateCache
{
public:
#undef declareField
#define declareField(Type) \
PtrList<PtrList<IOField<Type>>> Type##Fields_; \
PtrList<PtrList<CompactIOField<Field<Type>, Type>>> Type##FieldFields_;
declareField(label);
declareField(scalar);
declareField(vector);
declareField(sphericalTensor);
declareField(symmTensor);
declareField(tensor);
#undef declareField
bool empty() const noexcept { return labelFields_.empty(); }
label size() const noexcept { return labelFields_.size(); }
void resize(const label len)
{
#undef doLocalCode
#define doLocalCode(Type) \
{ \
Type##Fields_.resize(len); \
Type##FieldFields_.resize(len); \
}
doLocalCode(label);
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
}
void readAll(const label cloudi, const IOobjectList& lagrangianObjects)
{
#undef doLocalCode
#define doLocalCode(Type) \
{ \
lagrangianFieldDecomposer::readFields \
( \
cloudi, \
lagrangianObjects, \
Type##Fields_ \
); \
lagrangianFieldDecomposer::readFieldFields \
( \
cloudi, \
lagrangianObjects, \
Type##FieldFields_ \
); \
}
doLocalCode(label);
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
}
void decomposeAll
(
const label cloudi,
const fileName& cloudDir,
const lagrangianFieldDecomposer& decomposer,
bool report /* unused */
) const
{
#undef doLocalCode
#define doLocalCode(Type) \
{ \
decomposer.decomposeFields \
( \
cloudDir, \
Type##Fields_[cloudi] \
); \
decomposer.decomposeFieldFields \
( \
cloudDir, \
Type##FieldFields_[cloudi] \
); \
}
doLocalCode(label);
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
}
};
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::lagrangianFieldDecomposer::fieldsCache::fieldsCache()
:
cache_(new privateCache)
{}
Foam::lagrangianFieldDecomposer::fieldsCache::fieldsCache
(
const label nClouds
)
:
cache_(new privateCache)
{
cache_->resize(nClouds);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
// Destructor not in header (used incomplete type)
Foam::lagrangianFieldDecomposer::fieldsCache::~fieldsCache()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::lagrangianFieldDecomposer::fieldsCache::empty() const
{
return (!cache_ || cache_->empty());
}
Foam::label Foam::lagrangianFieldDecomposer::fieldsCache::size() const
{
return (cache_ ? cache_->size() : label(0));
}
void Foam::lagrangianFieldDecomposer::fieldsCache::clear()
{
cache_.reset(new privateCache);
}
void Foam::lagrangianFieldDecomposer::fieldsCache::resize
(
const label nClouds
)
{
if (cache_)
{
cache_->resize(nClouds);
}
}
void Foam::lagrangianFieldDecomposer::fieldsCache::readAllFields
(
const label cloudi,
const IOobjectList& lagrangianObjects
)
{
if (cache_)
{
cache_->readAll(cloudi, lagrangianObjects);
}
}
void Foam::lagrangianFieldDecomposer::fieldsCache::decomposeAllFields
(
const label cloudi,
const fileName& cloudDir,
const lagrangianFieldDecomposer& decomposer,
bool report
) const
{
if (cache_)
{
cache_->decomposeAll(cloudi, cloudDir, decomposer, report);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,108 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "lagrangianFieldDecomposer.H"
#include "IOobjectList.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::lagrangianFieldDecomposer::readFields
(
const label cloudi,
const IOobjectList& lagrangianObjects,
PtrList<PtrList<IOField<Type>>>& lagrangianFields
)
{
// List of lagrangian field objects
UPtrList<const IOobject> fieldObjects
(
lagrangianObjects.sorted<IOField<Type>>()
);
lagrangianFields.set
(
cloudi,
new PtrList<IOField<Type>>(fieldObjects.size())
);
label fieldi = 0;
for (const IOobject& io : fieldObjects)
{
lagrangianFields[cloudi].set(fieldi++, new IOField<Type>(io));
}
}
template<class Type>
void Foam::lagrangianFieldDecomposer::readFieldFields
(
const label cloudi,
const IOobjectList& lagrangianObjects,
PtrList<PtrList<CompactIOField<Field<Type>, Type>>>& lagrangianFields
)
{
// List of lagrangian field objects
UPtrList<const IOobject> fieldObjects;
fieldObjects.append
(
lagrangianObjects.sorted<IOField<Field<Type>>>()
);
fieldObjects.append
(
lagrangianObjects.sorted<CompactIOField<Field<Type>, Type>>()
);
Foam::sort(fieldObjects, nameOp<IOobject>());
lagrangianFields.set
(
cloudi,
new PtrList<CompactIOField<Field<Type>, Type>>(fieldObjects.size())
);
label fieldi = 0;
for (const IOobject& io : fieldObjects)
{
lagrangianFields[cloudi].set
(
fieldi++,
new CompactIOField<Field<Type>, Type>(io)
);
}
}
// ************************************************************************* //

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -30,95 +31,6 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::lagrangianFieldDecomposer::readFields
(
const label cloudI,
const IOobjectList& lagrangianObjects,
PtrList<PtrList<IOField<Type>>>& lagrangianFields
)
{
// Search list of objects for lagrangian fields
IOobjectList lagrangianTypeObjects
(
lagrangianObjects.lookupClass(IOField<Type>::typeName)
);
lagrangianFields.set
(
cloudI,
new PtrList<IOField<Type>>
(
lagrangianTypeObjects.size()
)
);
label lagrangianFieldi = 0;
forAllConstIters(lagrangianTypeObjects, iter)
{
lagrangianFields[cloudI].set
(
lagrangianFieldi++,
new IOField<Type>(*iter())
);
}
}
template<class Type>
void Foam::lagrangianFieldDecomposer::readFieldFields
(
const label cloudI,
const IOobjectList& lagrangianObjects,
PtrList<PtrList<CompactIOField<Field<Type>, Type>>>& lagrangianFields
)
{
// Search list of objects for lagrangian fields
IOobjectList lagrangianTypeObjectsA
(
lagrangianObjects.lookupClass(IOField<Field<Type>>::typeName)
);
IOobjectList lagrangianTypeObjectsB
(
lagrangianObjects.lookupClass
(
CompactIOField<Field<Type>,
Type>::typeName
)
);
lagrangianFields.set
(
cloudI,
new PtrList<CompactIOField<Field<Type>, Type>>
(
lagrangianTypeObjectsA.size() + lagrangianTypeObjectsB.size()
)
);
label lagrangianFieldi = 0;
forAllConstIters(lagrangianTypeObjectsA, iter)
{
lagrangianFields[cloudI].set
(
lagrangianFieldi++,
new CompactIOField<Field<Type>, Type>(*iter())
);
}
forAllConstIters(lagrangianTypeObjectsB, iter)
{
lagrangianFields[cloudI].set
(
lagrangianFieldi++,
new CompactIOField<Field<Type>, Type>(*iter())
);
}
}
template<class Type> template<class Type>
Foam::tmp<Foam::IOField<Type>> Foam::tmp<Foam::IOField<Type>>
Foam::lagrangianFieldDecomposer::decomposeField Foam::lagrangianFieldDecomposer::decomposeField
@ -127,9 +39,6 @@ Foam::lagrangianFieldDecomposer::decomposeField
const IOField<Type>& field const IOField<Type>& field
) const ) const
{ {
// Create and map the internal field values
Field<Type> procField(field, particleIndices_);
// Create the field for the processor // Create the field for the processor
return tmp<IOField<Type>>::New return tmp<IOField<Type>>::New
( (
@ -143,7 +52,8 @@ Foam::lagrangianFieldDecomposer::decomposeField
IOobject::NO_WRITE, IOobject::NO_WRITE,
false false
), ),
procField // Mapping internal field values
Field<Type>(field, particleIndices_)
); );
} }
@ -156,9 +66,6 @@ Foam::lagrangianFieldDecomposer::decomposeFieldField
const CompactIOField<Field<Type>, Type>& field const CompactIOField<Field<Type>, Type>& field
) const ) const
{ {
// Create and map the internal field values
Field<Field<Type>> procField(field, particleIndices_);
// Create the field for the processor // Create the field for the processor
return tmp<CompactIOField<Field<Type>, Type>>::New return tmp<CompactIOField<Field<Type>, Type>>::New
( (
@ -172,7 +79,8 @@ Foam::lagrangianFieldDecomposer::decomposeFieldField
IOobject::NO_WRITE, IOobject::NO_WRITE,
false false
), ),
procField // Mapping internal field values
Field<Field<Type>>(field, particleIndices_)
); );
} }
@ -184,13 +92,11 @@ void Foam::lagrangianFieldDecomposer::decomposeFields
const PtrList<GeoField>& fields const PtrList<GeoField>& fields
) const ) const
{ {
//if (particleIndices_.size()) const bool existsOnProc = (particleIndices_.size() > 0);
for (const GeoField& fld : fields)
{ {
bool valid = particleIndices_.size() > 0; decomposeField(cloudName, fld)().write(existsOnProc);
forAll(fields, fieldi)
{
decomposeField(cloudName, fields[fieldi])().write(valid);
}
} }
} }
@ -202,13 +108,11 @@ void Foam::lagrangianFieldDecomposer::decomposeFieldFields
const PtrList<GeoField>& fields const PtrList<GeoField>& fields
) const ) const
{ {
//if (particleIndices_.size()) const bool existsOnProc = (particleIndices_.size() > 0);
for (const GeoField& fld : fields)
{ {
bool valid = particleIndices_.size() > 0; decomposeFieldField(cloudName, fld)().write(existsOnProc);
forAll(fields, fieldi)
{
decomposeFieldField(cloudName, fields[fieldi])().write(valid);
}
} }
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd. Copyright (C) 2021-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,12 +32,13 @@ Description
SourceFiles SourceFiles
pointFieldDecomposer.C pointFieldDecomposer.C
pointFieldDecomposerFields.C pointFieldDecomposerCache.C
pointFieldDecomposerTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef pointFieldDecomposer_H #ifndef Foam_pointFieldDecomposer_H
#define pointFieldDecomposer_H #define Foam_pointFieldDecomposer_H
#include "pointMesh.H" #include "pointMesh.H"
#include "pointPatchFieldMapperPatchRef.H" #include "pointPatchFieldMapperPatchRef.H"
@ -48,6 +49,9 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward Declarations
class IOobjectList;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class pointFieldDecomposer Declaration Class pointFieldDecomposer Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -56,6 +60,8 @@ class pointFieldDecomposer
{ {
public: public:
// Public Classes
//- Point patch field decomposer class //- Point patch field decomposer class
class patchFieldDecomposer class patchFieldDecomposer
: :
@ -122,13 +128,18 @@ private:
PtrList<patchFieldDecomposer> patchFieldDecomposerPtrs_; PtrList<patchFieldDecomposer> patchFieldDecomposerPtrs_;
// Private Member Functions
//- No copy construct
pointFieldDecomposer(const pointFieldDecomposer&) = delete;
//- No copy assignment
void operator=(const pointFieldDecomposer&) = delete;
public: public:
//- No copy construct // Public Classes
pointFieldDecomposer(const pointFieldDecomposer&) = delete; class fieldsCache;
//- No copy assignment
void operator=(const pointFieldDecomposer&) = delete;
// Constructors // Constructors
@ -184,6 +195,69 @@ public:
}; };
/*---------------------------------------------------------------------------*\
Class pointFieldDecomposer::fieldsCache Declaration
\*---------------------------------------------------------------------------*/
class pointFieldDecomposer::fieldsCache
{
// Private Data
class privateCache;
//- All field and field-field types for lagrangian
std::unique_ptr<privateCache> cache_;
// Private Member Functions
//- No copy construct
fieldsCache(const fieldsCache&) = delete;
//- No copy assignment
void operator=(const fieldsCache&) = delete;
public:
// Constructors
//- Default construct
fieldsCache();
//- Destructor
~fieldsCache();
// Member Functions
//- No fields
bool empty() const;
//- Total number of fields
label size() const;
//- Clear out
void clear();
//- Read all fields given mesh and objects
void readAllFields
(
const pointMesh& mesh,
const IOobjectList& objects
);
//- Decompose and write all fields
void decomposeAllFields
(
const pointFieldDecomposer& decomposer,
bool report = false
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam
@ -191,7 +265,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "pointFieldDecomposerFields.C" #include "pointFieldDecomposerTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,208 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "pointFieldDecomposer.H"
#include "fieldsDistributor.H"
#include "pointFields.H"
#include "IOobjectList.H"
#include "PtrListOps.H"
// * * * * * * * * * * * * * * * * Declarations * * * * * * * * * * * * * * //
namespace Foam
{
// All point field types
class pointFieldDecomposer::fieldsCache::privateCache
{
public:
#undef declareField
#define declareField(Type) \
PtrList<GeometricField<Type, pointPatchField, pointMesh>> Type##Fields_;
declareField(scalar);
declareField(vector);
declareField(sphericalTensor);
declareField(symmTensor);
declareField(tensor);
#undef declareField
label size() const noexcept
{
label count = 0;
#undef doLocalCode
#define doLocalCode(Type) \
{ \
count += Type##Fields_.size(); \
}
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
return count;
}
bool empty() const noexcept { return !size(); }
void readAll(const pointMesh& mesh, const IOobjectList& objects)
{
#undef doLocalCode
#define doLocalCode(Type) \
{ \
fieldsDistributor::readFields \
( \
mesh, \
objects, \
Type##Fields_, \
false /* readOldTime = false */ \
); \
}
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
}
template<class GeoField>
static void decompose
(
const pointFieldDecomposer& decomposer,
const PtrList<GeoField>& fields,
bool report
)
{
if (!fields.empty())
{
if (report)
{
Info<< " "
<< pTraits<typename GeoField::value_type>::typeName
<< "s: "
<< flatOutput(PtrListOps::names(fields)) << nl;
}
decomposer.decomposeFields(fields);
}
}
void decomposeAll
(
const pointFieldDecomposer& decomposer,
bool report
) const
{
#undef doLocalCode
#define doLocalCode(Type) \
{ \
decompose(decomposer, Type##Fields_, report); \
}
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
}
};
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::pointFieldDecomposer::fieldsCache::fieldsCache()
:
cache_(new privateCache)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
// Destructor not in header (used incomplete type)
Foam::pointFieldDecomposer::fieldsCache::~fieldsCache()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::pointFieldDecomposer::fieldsCache::empty() const
{
return (!cache_ || cache_->empty());
}
Foam::label Foam::pointFieldDecomposer::fieldsCache::size() const
{
return (cache_ ? cache_->size() : label(0));
}
void Foam::pointFieldDecomposer::fieldsCache::clear()
{
cache_.reset(new privateCache);
}
void Foam::pointFieldDecomposer::fieldsCache::readAllFields
(
const pointMesh& mesh,
const IOobjectList& objects
)
{
if (cache_)
{
cache_->readAll(mesh, objects);
}
}
void Foam::pointFieldDecomposer::fieldsCache::decomposeAllFields
(
const pointFieldDecomposer& decomposer,
bool report
) const
{
if (cache_)
{
cache_->decomposeAll(decomposer, report);
}
}
// ************************************************************************* //

View File

@ -82,8 +82,8 @@ Foam::pointFieldDecomposer::decomposeField
IOobject IOobject
( (
field.name(), field.name(),
procMesh_().time().timeName(), procMesh_.thisDb().time().timeName(),
procMesh_(), procMesh_.thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
false false

View File

@ -1,4 +1,6 @@
faFieldDecomposer.C faFieldDecomposer.C
faFieldDecomposerCache.C
faMeshDecomposition.C faMeshDecomposition.C
LIB = $(FOAM_LIBBIN)/libfaDecompose LIB = $(FOAM_LIBBIN)/libfaDecompose

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2021 OpenCFD Ltd. Copyright (C) 2021-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,12 +36,13 @@ Author
SourceFiles SourceFiles
faFieldDecomposer.C faFieldDecomposer.C
faFieldDecomposerFields.C fvFieldDecomposerCache.C
faFieldDecomposerTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef faFieldDecomposer_H #ifndef Foam_faFieldDecomposer_H
#define faFieldDecomposer_H #define Foam_faFieldDecomposer_H
#include "faMesh.H" #include "faMesh.H"
#include "faPatchFieldMapper.H" #include "faPatchFieldMapper.H"
@ -63,6 +64,8 @@ class faFieldDecomposer
{ {
public: public:
// Public Classes
//- Patch field decomposer class //- Patch field decomposer class
class patchFieldDecomposer class patchFieldDecomposer
: :
@ -270,13 +273,17 @@ private:
public: public:
// Public Classes
class fieldsCache;
// Constructors // Constructors
//- Construct without mappers, added later with reset() //- Construct without mappers, added later with reset()
faFieldDecomposer faFieldDecomposer
( (
const Foam::zero, const Foam::zero,
const faMesh& procMesh, const faMesh& procMesh, // Target mesh
const labelList& edgeAddressing, const labelList& edgeAddressing,
const labelList& faceAddressing, const labelList& faceAddressing,
const labelList& boundaryAddressing const labelList& boundaryAddressing
@ -285,8 +292,8 @@ public:
//- Construct from components using information from the complete mesh //- Construct from components using information from the complete mesh
faFieldDecomposer faFieldDecomposer
( (
const faMesh& completeMesh, const faMesh& completeMesh, // Source mesh
const faMesh& procMesh, const faMesh& procMesh, // Target mesh
const labelList& edgeAddressing, const labelList& edgeAddressing,
const labelList& faceAddressing, const labelList& faceAddressing,
const labelList& boundaryAddressing const labelList& boundaryAddressing
@ -302,7 +309,7 @@ public:
const labelUList& edgeNeigbour, const labelUList& edgeNeigbour,
// Addressing for processor mesh // Addressing for processor mesh
const faMesh& procMesh, const faMesh& procMesh, // Target mesh
const labelList& edgeAddressing, const labelList& edgeAddressing,
const labelList& faceAddressing, const labelList& faceAddressing,
const labelList& boundaryAddressing const labelList& boundaryAddressing
@ -358,7 +365,7 @@ public:
// Reading helpers // Reading helpers
//- Read the fields and hold on the pointer list //- Read the fields and store on the pointer list
template template
< <
class Type, class Type,
@ -373,7 +380,7 @@ public:
const bool readOldTime const bool readOldTime
); );
//- Read fields and hold on the pointer list //- Read fields and store on the pointer list
template<class Mesh, class GeoField> template<class Mesh, class GeoField>
static void readFields static void readFields
( (
@ -384,6 +391,70 @@ public:
}; };
/*---------------------------------------------------------------------------*\
Class faFieldDecomposer::fieldsCache Declaration
\*---------------------------------------------------------------------------*/
class faFieldDecomposer::fieldsCache
{
// Private Data
class privateCache;
//- All field and field-field types for lagrangian
std::unique_ptr<privateCache> cache_;
// Private Member Functions
//- No copy construct
fieldsCache(const fieldsCache&) = delete;
//- No copy assignment
void operator=(const fieldsCache&) = delete;
public:
// Constructors
//- Default construct
fieldsCache();
//- Destructor
~fieldsCache();
// Member Functions
//- No fields
bool empty() const;
//- Number of fields
label size() const;
//- Clear out
void clear();
//- Read all fields given mesh and objects
void readAllFields
(
const faMesh& mesh,
const IOobjectList& objects
);
//- Decompose and write all fields
void decomposeAllFields
(
const faFieldDecomposer& decomposer,
bool report = false
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam
@ -391,8 +462,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "faFieldDecomposerFields.C" #include "faFieldDecomposerTemplates.C"
#include "faFieldDecomposerReadFields.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,221 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "faFieldDecomposer.H"
#include "fieldsDistributor.H"
#include "areaFields.H"
#include "edgeFields.H"
#include "IOobjectList.H"
#include "PtrListOps.H"
// * * * * * * * * * * * * * * * * Declarations * * * * * * * * * * * * * * //
namespace Foam
{
// All area/edge field types
class faFieldDecomposer::fieldsCache::privateCache
{
public:
#undef declareField
#define declareField(Type) \
PtrList<GeometricField<Type, faPatchField, areaMesh>> Type##AreaFields_; \
PtrList<GeometricField<Type, faePatchField, edgeMesh>> Type##EdgeFields_;
declareField(scalar);
declareField(vector);
declareField(sphericalTensor);
declareField(symmTensor);
declareField(tensor);
#undef declareField
label size() const noexcept
{
label count = 0;
#undef doLocalCode
#define doLocalCode(Type) \
{ \
count += Type##AreaFields_.size(); \
count += Type##EdgeFields_.size(); \
}
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
return count;
}
bool empty() const noexcept { return !size(); }
void readAll(const faMesh& mesh, const IOobjectList& objects)
{
#undef doLocalCode
#define doLocalCode(Type) \
{ \
fieldsDistributor::readFields \
( \
mesh, \
objects, \
Type##AreaFields_ \
); \
fieldsDistributor::readFields \
( \
mesh, \
objects, \
Type##AreaFields_, \
false /* readOldTime = false */ \
); \
fieldsDistributor::readFields \
( \
mesh, \
objects, \
Type##EdgeFields_, \
false /* readOldTime = false */ \
); \
}
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
}
template<class GeoField>
static void decompose
(
const faFieldDecomposer& decomposer,
const PtrList<GeoField>& fields,
bool report
)
{
if (!fields.empty())
{
if (report)
{
Info<< " "
<< pTraits<typename GeoField::value_type>::typeName
<< "s: "
<< flatOutput(PtrListOps::names(fields)) << nl;
}
decomposer.decomposeFields(fields);
}
}
void decomposeAll(const faFieldDecomposer& decomposer, bool report) const
{
#undef doLocalCode
#define doLocalCode(Flavour) \
{ \
decompose(decomposer, scalar##Flavour##Fields_, report); \
decompose(decomposer, vector##Flavour##Fields_, report); \
decompose(decomposer, sphericalTensor##Flavour##Fields_, report); \
decompose(decomposer, symmTensor##Flavour##Fields_, report); \
decompose(decomposer, tensor##Flavour##Fields_, report); \
}
doLocalCode(Area);
doLocalCode(Edge);
#undef doLocalCode
}
};
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faFieldDecomposer::fieldsCache::fieldsCache()
:
cache_(new privateCache)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
// Destructor not in header (used incomplete type)
Foam::faFieldDecomposer::fieldsCache::~fieldsCache()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::faFieldDecomposer::fieldsCache::empty() const
{
return (!cache_ || cache_->empty());
}
Foam::label Foam::faFieldDecomposer::fieldsCache::size() const
{
return (cache_ ? cache_->size() : label(0));
}
void Foam::faFieldDecomposer::fieldsCache::clear()
{
cache_.reset(new privateCache);
}
void Foam::faFieldDecomposer::fieldsCache::readAllFields
(
const faMesh& mesh,
const IOobjectList& objects
)
{
if (cache_)
{
cache_->readAll(mesh, objects);
}
}
void Foam::faFieldDecomposer::fieldsCache::decomposeAllFields
(
const faFieldDecomposer& decomposer,
bool report
) const
{
if (cache_)
{
cache_->decomposeAll(decomposer, report);
}
}
// ************************************************************************* //

View File

@ -1,92 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "faFieldDecomposer.H"
#include "GeometricField.H"
#include "IOobjectList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::faFieldDecomposer::readFields
(
const typename GeoMesh::Mesh& mesh,
const IOobjectList& objects,
PtrList<GeometricField<Type, PatchField, GeoMesh>>& fields,
const bool readOldTime
)
{
typedef GeometricField<Type, PatchField, GeoMesh> GeoField;
// Search list of objects for fields of type GeoField
IOobjectList fieldObjects(objects.lookupClass<GeoField>());
// Use sorted set of names
// (different processors might read objects in different order)
const wordList masterNames(fieldObjects.sortedNames());
// Construct the fields
fields.resize(masterNames.size());
forAll(masterNames, i)
{
const IOobject& io = *fieldObjects[masterNames[i]];
fields.set(i, new GeoField(io, mesh, readOldTime));
}
}
template<class Mesh, class GeoField>
void Foam::faFieldDecomposer::readFields
(
const Mesh& mesh,
const IOobjectList& objects,
PtrList<GeoField>& fields
)
{
// Search list of objects for fields of type GeomField
IOobjectList fieldObjects(objects.lookupClass<GeoField>());
// Use sorted set of names
// (different processors might read objects in different order)
const wordList masterNames(fieldObjects.sortedNames());
// Construct the fields
fields.resize(masterNames.size());
forAll(masterNames, i)
{
const IOobject& io = *fieldObjects[masterNames[i]];
fields.set(i, new GeoField(io, mesh));
}
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2021 OpenCFD Ltd. Copyright (C) 2021-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,6 +27,8 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "faFieldDecomposer.H" #include "faFieldDecomposer.H"
#include "GeometricField.H"
#include "IOobjectList.H"
#include "processorFaPatchField.H" #include "processorFaPatchField.H"
#include "processorFaePatchField.H" #include "processorFaePatchField.H"
@ -89,8 +91,8 @@ Foam::faFieldDecomposer::decomposeField
IOobject IOobject
( (
field.name(), field.name(),
procMesh_.time().timeName(), procMesh_.thisDb().time().timeName(),
procMesh_(), procMesh_.thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
@ -200,8 +202,8 @@ Foam::faFieldDecomposer::decomposeField
IOobject IOobject
( (
field.name(), field.name(),
procMesh_.time().timeName(), procMesh_.thisDb().time().timeName(),
procMesh_(), procMesh_.thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),

View File

@ -47,16 +47,16 @@ void Foam::faMeshDecomposition::distributeFaces()
cpuTime decompositionTime; cpuTime decompositionTime;
for (label procI = 0; procI < nProcs(); procI++) for (label proci = 0; proci < nProcs(); ++proci)
{ {
Time processorDb Time processorDb
( (
Time::controlDictName, Time::controlDictName,
time().rootPath(), time().rootPath(),
time().caseName()/("processor" + Foam::name(procI)) time().caseName()/("processor" + Foam::name(proci))
); );
polyMesh procMesh polyMesh procFvMesh
( (
IOobject IOobject
( (
@ -66,6 +66,24 @@ void Foam::faMeshDecomposition::distributeFaces()
) )
); );
IOobject ioAddr
(
"procAddressing",
"constant",
polyMesh::meshSubDir,
procFvMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false // not registered
);
// faceProcAddressing (polyMesh)
ioAddr.rename("faceProcAddressing");
labelIOList fvFaceProcAddressing(ioAddr);
labelHashSet faceProcAddressingHash(2*fvFaceProcAddressing.size());
// If faMesh's fvPatch is a part of the global face zones, faces of that // If faMesh's fvPatch is a part of the global face zones, faces of that
// patch will be present on all processors. Because of that, looping // patch will be present on all processors. Because of that, looping
// through faceProcAddressing will decompose global faMesh faces to the // through faceProcAddressing will decompose global faMesh faces to the
@ -76,77 +94,31 @@ void Foam::faMeshDecomposition::distributeFaces()
// Vanja Skuric, 2016-04-21 // Vanja Skuric, 2016-04-21
if (hasGlobalFaceZones_) if (hasGlobalFaceZones_)
{ {
labelList faceProcAddressing // owner (polyMesh)
( ioAddr.rename("owner");
labelIOList const label ownerSize = labelIOList(ioAddr).size();
(
IOobject
(
"faceProcAddressing",
"constant",
procMesh.meshSubDir,
procMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
const label ownerSize =
(
labelIOList
(
IOobject
(
"owner",
"constant",
procMesh.meshSubDir,
procMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
).size();
labelHashSet faceProcAddressingHash(ownerSize);
for (int i = 0; i < ownerSize; ++i) for (int i = 0; i < ownerSize; ++i)
{ {
faceProcAddressingHash.insert(faceProcAddressing[i]); faceProcAddressingHash.insert(fvFaceProcAddressing[i]);
}
forAll(faceLabels(), faceI)
{
if (faceProcAddressingHash.found(faceLabels()[faceI] + 1))
{
faceToProc_[faceI] = procI;
}
} }
} }
else else
{ {
labelHashSet faceProcAddressingHash faceProcAddressingHash.insert
( (
labelIOList static_cast<labelList&>(fvFaceProcAddressing)
(
IOobject
(
"faceProcAddressing",
"constant",
procMesh.meshSubDir,
procMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
); );
}
forAll(faceLabels(), faceI) forAll(faceLabels(), facei)
{
// With +1 for lookup in faceMap with flip encoding
const label index = (faceLabels()[facei] + 1);
if (faceProcAddressingHash.found(index))
{ {
if (faceProcAddressingHash.found(faceLabels()[faceI] + 1)) faceToProc_[facei] = proci;
{
faceToProc_[faceI] = procI;
}
} }
} }
} }
@ -276,40 +248,37 @@ void Foam::faMeshDecomposition::decomposeMesh()
) )
); );
labelIOList fvPointProcAddressing IOobject ioAddr
( (
IOobject "procAddressing",
( "constant",
"pointProcAddressing", polyMesh::meshSubDir,
"constant", procFvMesh,
procFvMesh.meshSubDir, IOobject::MUST_READ,
procFvMesh, IOobject::NO_WRITE,
IOobject::MUST_READ, false // not registered
IOobject::NO_WRITE
)
); );
// pointProcAddressing (polyMesh)
ioAddr.rename("pointProcAddressing");
labelIOList fvPointProcAddressing(ioAddr);
Map<label> fvFaceProcAddressingHash; Map<label> fvFaceProcAddressingHash;
{ {
labelIOList fvFaceProcAddressing // faceProcAddressing (polyMesh)
( ioAddr.rename("faceProcAddressing");
IOobject labelIOList fvFaceProcAddressing(ioAddr);
(
"faceProcAddressing",
"constant",
procFvMesh.meshSubDir,
procFvMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
forAll(fvFaceProcAddressing, faceI) fvFaceProcAddressingHash.resize(2*fvFaceProcAddressing.size());
forAll(fvFaceProcAddressing, facei)
{ {
fvFaceProcAddressingHash.insert fvFaceProcAddressingHash.insert
( (
fvFaceProcAddressing[faceI], faceI fvFaceProcAddressing[facei],
facei
); );
} }
}; };
@ -365,17 +334,16 @@ void Foam::faMeshDecomposition::decomposeMesh()
const uindirectPrimitivePatch& procPatch = procMesh.patch(); const uindirectPrimitivePatch& procPatch = procMesh.patch();
const vectorField& procPoints = procPatch.localPoints();
const labelList& procMeshPoints = procPatch.meshPoints(); const labelList& procMeshPoints = procPatch.meshPoints();
const edgeList& procEdges = procPatch.edges(); const edgeList& procEdges = procPatch.edges();
labelList& curPatchPointAddressing = procPatchPointAddressing_[procI]; labelList& curPatchPointAddressing = procPatchPointAddressing_[procI];
curPatchPointAddressing.setSize(procPoints.size(), -1); curPatchPointAddressing.resize(procMeshPoints.size(), -1);
forAll(procPoints, pointI) forAll(procMeshPoints, pointi)
{ {
curPatchPointAddressing[pointI] = curPatchPointAddressing[pointi] =
map[fvPointProcAddressing[procMeshPoints[pointI]]]; map[fvPointProcAddressing[procMeshPoints[pointi]]];
} }
labelList& curPatchEdgeAddressing = procPatchEdgeAddressing_[procI]; labelList& curPatchEdgeAddressing = procPatchEdgeAddressing_[procI];
@ -1154,9 +1122,12 @@ bool Foam::faMeshDecomposition::writeDecomposition()
sharedPointLookup.insert(globallySharedPoints_[pointi], pointi); sharedPointLookup.insert(globallySharedPoints_[pointi], pointi);
} }
label maxProcFaces = 0;
label totProcFaces = 0;
label maxProcEdges = 0;
label totProcEdges = 0; label totProcEdges = 0;
label maxProcPatches = 0; label maxProcPatches = 0;
label maxProcEdges = 0; label totProcPatches = 0;
// Write out the meshes // Write out the meshes
for (label procI = 0; procI < nProcs(); procI++) for (label procI = 0; procI < nProcs(); procI++)
@ -1193,7 +1164,7 @@ bool Foam::faMeshDecomposition::writeDecomposition()
( (
"boundaryProcAddressing", "boundaryProcAddressing",
"constant", "constant",
procFvMesh.meshSubDir, polyMesh::meshSubDir,
procFvMesh, procFvMesh,
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
@ -1286,19 +1257,35 @@ bool Foam::faMeshDecomposition::writeDecomposition()
procMesh.write(); procMesh.write();
Info<< endl // Statistics
<< "Processor " << procI << nl Info<< nl << "Processor " << procI;
<< " Number of faces = " << procMesh.nFaces()
<< endl; if (procMesh.nFaces())
{
Info<< nl << " ";
}
else
{
Info<< ": ";
}
Info<< "Number of faces = " << procMesh.nFaces() << nl;
if (procMesh.nFaces())
{
Info<< " Number of points = " << procMesh.nPoints() << nl;
}
totProcFaces += procMesh.nFaces();
maxProcFaces = max(maxProcFaces, procMesh.nFaces());
label nBoundaryEdges = 0; label nBoundaryEdges = 0;
label nProcPatches = 0; label nProcPatches = 0;
label nProcEdges = 0; label nProcEdges = 0;
forAll(procMesh.boundary(), patchi) for (const faPatch& fap : procMesh.boundary())
{ {
const auto* ppp = const auto* ppp = isA<processorFaPatch>(fap);
isA<processorFaPatch>(procMesh.boundary()[patchi]);
if (ppp) if (ppp)
{ {
@ -1306,92 +1293,93 @@ bool Foam::faMeshDecomposition::writeDecomposition()
Info<< " Number of edges shared with processor " Info<< " Number of edges shared with processor "
<< procPatch.neighbProcNo() << " = " << procPatch.neighbProcNo() << " = "
<< procPatch.size() << endl; << procPatch.size() << nl;
nProcEdges += procPatch.size(); nProcEdges += procPatch.size();
++nProcPatches; ++nProcPatches;
} }
else else
{ {
nBoundaryEdges += procMesh.boundary()[patchi].size(); nBoundaryEdges += fap.size();
} }
} }
Info<< " Number of processor patches = " << nProcPatches << nl if (procMesh.nFaces() && (nBoundaryEdges || nProcEdges))
<< " Number of processor edges = " << nProcEdges << nl {
<< " Number of boundary edges = " << nBoundaryEdges << endl; Info<< " Number of processor patches = " << nProcPatches << nl
<< " Number of processor edges = " << nProcEdges << nl
<< " Number of boundary edges = " << nBoundaryEdges << nl;
}
totProcEdges += nProcEdges; totProcEdges += nProcEdges;
maxProcPatches = max(maxProcPatches, nProcPatches); totProcPatches += nProcPatches;
maxProcEdges = max(maxProcEdges, nProcEdges); maxProcEdges = max(maxProcEdges, nProcEdges);
maxProcPatches = max(maxProcPatches, nProcPatches);
// create and write the addressing information // Write the addressing information
labelIOList pointProcAddressing
(
IOobject
(
"pointProcAddressing",
"constant",
procMesh.meshSubDir,
procFvMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procPatchPointAddressing_[procI]
);
pointProcAddressing.write();
labelIOList edgeProcAddressing IOobject ioAddr
( (
IOobject "procAddressing",
( "constant",
"edgeProcAddressing", faMesh::meshSubDir,
"constant", procMesh.thisDb(),
procMesh.meshSubDir, IOobject::NO_READ,
procFvMesh, IOobject::NO_WRITE,
IOobject::NO_READ, false // not registered
IOobject::NO_WRITE
),
procEdgeAddressing_[procI]
); );
edgeProcAddressing.write();
labelIOList faceProcAddressing // pointProcAddressing
( ioAddr.rename("pointProcAddressing");
IOobject IOListRef<label>(ioAddr, procPatchPointAddressing_[procI]).write();
(
"faceProcAddressing",
"constant",
procMesh.meshSubDir,
procFvMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFaceAddressing_[procI]
);
faceProcAddressing.write();
labelIOList boundaryProcAddressing // edgeProcAddressing
( ioAddr.rename("edgeProcAddressing");
IOobject IOListRef<label>(ioAddr, procEdgeAddressing_[procI]).write();
(
"boundaryProcAddressing", // faceProcAddressing
"constant", ioAddr.rename("faceProcAddressing");
procMesh.meshSubDir, IOListRef<label>(ioAddr, procFaceAddressing_[procI]).write();
procFvMesh,
IOobject::NO_READ, // boundaryProcAddressing
IOobject::NO_WRITE ioAddr.rename("boundaryProcAddressing");
), IOListRef<label>(ioAddr, procBoundaryAddressing_[procI]).write();
procBoundaryAddressing_[procI]
);
boundaryProcAddressing.write();
} }
// Summary stats
Info<< nl Info<< nl
<< "Number of processor edges = " << totProcEdges/2 << nl << "Number of processor edges = " << (totProcEdges/2) << nl
<< "Max number of processor patches = " << maxProcPatches << nl << "Max number of faces = " << maxProcFaces;
<< "Max number of faces between processors = " << maxProcEdges
<< endl; if (maxProcFaces != totProcFaces)
{
scalar avgValue = scalar(totProcFaces)/nProcs_;
Info<< " (" << 100.0*(maxProcFaces-avgValue)/avgValue
<< "% above average " << avgValue << ')';
}
Info<< nl;
Info<< "Max number of processor patches = " << maxProcPatches;
if (totProcPatches)
{
scalar avgValue = scalar(totProcPatches)/nProcs_;
Info<< " (" << 100.0*(maxProcPatches-avgValue)/avgValue
<< "% above average " << avgValue << ')';
}
Info<< nl;
Info<< "Max number of edges between processors = " << maxProcEdges;
if (totProcEdges)
{
scalar avgValue = scalar(totProcEdges)/nProcs_;
Info<< " (" << 100.0*(maxProcEdges-avgValue)/avgValue
<< "% above average " << avgValue << ')';
}
Info<< nl << endl;
return true; return true;
} }

View File

@ -39,8 +39,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef faMeshDecomposition_H #ifndef Foam_faMeshDecomposition_H
#define faMeshDecomposition_H #define Foam_faMeshDecomposition_H
#include "polyMesh.H" #include "polyMesh.H"
#include "faMesh.H" #include "faMesh.H"

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -26,6 +27,13 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "faFieldReconstructor.H" #include "faFieldReconstructor.H"
#include "areaFields.H"
#include "edgeFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::faFieldReconstructor::verbose_ = 1;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -42,8 +50,42 @@ Foam::faFieldReconstructor::faFieldReconstructor
procMeshes_(procMeshes), procMeshes_(procMeshes),
edgeProcAddressing_(edgeProcAddressing), edgeProcAddressing_(edgeProcAddressing),
faceProcAddressing_(faceProcAddressing), faceProcAddressing_(faceProcAddressing),
boundaryProcAddressing_(boundaryProcAddressing) boundaryProcAddressing_(boundaryProcAddressing),
nReconstructed_(0)
{} {}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::faFieldReconstructor::reconstructAllFields
(
const IOobjectList& objects,
const wordRes& selected
)
{
label nTotal = 0;
do
{
#undef doLocalCode
#define doLocalCode(Method) \
{ \
nTotal += this->Method <scalar> (objects, selected); \
nTotal += this->Method <vector> (objects, selected); \
nTotal += this->Method <sphericalTensor> (objects, selected); \
nTotal += this->Method <symmTensor> (objects, selected); \
nTotal += this->Method <tensor> (objects, selected); \
}
doLocalCode(reconstructAreaFields);
doLocalCode(reconstructEdgeFields);
#undef doLocalCode
}
while (false);
return nTotal;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -35,12 +36,12 @@ Author
SourceFiles SourceFiles
faFieldReconstructor.C faFieldReconstructor.C
faFieldReconstructorFields.C faFieldReconstructorTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef faFieldReconstructor_H #ifndef Foam_faFieldReconstructor_H
#define faFieldReconstructor_H #define Foam_faFieldReconstructor_H
#include "PtrList.H" #include "PtrList.H"
#include "faMesh.H" #include "faMesh.H"
@ -59,7 +60,7 @@ namespace Foam
class faFieldReconstructor class faFieldReconstructor
{ {
// Private data // Private Data
//- Reconstructed mesh reference //- Reconstructed mesh reference
faMesh& mesh_; faMesh& mesh_;
@ -76,6 +77,9 @@ class faFieldReconstructor
//- List of processor boundary addressing lists //- List of processor boundary addressing lists
const PtrList<labelIOList>& boundaryProcAddressing_; const PtrList<labelIOList>& boundaryProcAddressing_;
//- Number of fields reconstructed
label nReconstructed_;
// Private Member Functions // Private Member Functions
@ -88,6 +92,8 @@ class faFieldReconstructor
public: public:
// Public Classes
class faPatchFieldReconstructor class faPatchFieldReconstructor
: :
public faPatchFieldMapper public faPatchFieldMapper
@ -111,7 +117,7 @@ public:
{} {}
// Member functions // Member Functions
virtual label size() const virtual label size() const
{ {
@ -140,13 +146,19 @@ public:
}; };
// Static Data
//- Output verbosity when writing
static int verbose_;
// Constructors // Constructors
//- Construct from components //- Construct from components
faFieldReconstructor faFieldReconstructor
( (
faMesh& mesh, faMesh& mesh, // Target mesh
const PtrList<faMesh>& procMeshes, const PtrList<faMesh>& procMeshes, // Source meshes
const PtrList<labelIOList>& edgeProcAddressing, const PtrList<labelIOList>& edgeProcAddressing,
const PtrList<labelIOList>& faceProcAddressing, const PtrList<labelIOList>& faceProcAddressing,
const PtrList<labelIOList>& boundaryProcAddressing const PtrList<labelIOList>& boundaryProcAddressing
@ -155,34 +167,80 @@ public:
// Member Functions // Member Functions
//- Return number of fields reconstructed
label nReconstructed() const noexcept
{
return nReconstructed_;
}
//- Reconstruct area field //- Reconstruct area field
template<class Type> template<class Type>
tmp<GeometricField<Type, faPatchField, areaMesh>> tmp<GeometricField<Type, faPatchField, areaMesh>>
reconstructFaAreaField reconstructField
( (
const IOobject& fieldIoObject const IOobject& fieldObject,
); const PtrList<GeometricField<Type, faPatchField, areaMesh>>&
) const;
//- Read and reconstruct area field
template<class Type>
tmp<GeometricField<Type, faPatchField, areaMesh>>
reconstructAreaField(const IOobject& fieldObject);
//- Reconstruct edge field //- Reconstruct edge field
template<class Type> template<class Type>
tmp<GeometricField<Type, faePatchField, edgeMesh>> tmp<GeometricField<Type, faePatchField, edgeMesh>>
reconstructFaEdgeField reconstructField
( (
const IOobject& fieldIoObject const IOobject& fieldObject,
const PtrList<GeometricField<Type, faePatchField, edgeMesh>>&
) const;
//- Read and reconstruct edge field
template<class Type>
tmp<GeometricField<Type, faePatchField, edgeMesh>>
reconstructEdgeField(const IOobject& fieldObject);
//- Read, reconstruct and write specified area fields
template<class Type>
label reconstructAreaFields
(
const UPtrList<const IOobject>& fieldObjects
); );
//- Reconstruct and write all area fields //- Read, reconstruct and write specified edge fields
template<class Type> template<class Type>
void reconstructFaAreaFields label reconstructEdgeFields
( (
const IOobjectList& objects const UPtrList<const IOobject>& fieldObjects
); );
//- Reconstruct and write all area fields
//- Read, reconstruct and write all/selected area fields
// An empty wordRes corresponds to select ALL.
template<class Type> template<class Type>
void reconstructFaEdgeFields label reconstructAreaFields
( (
const IOobjectList& objects const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
);
//- Read, reconstruct and write all/selected edge fields
// An empty wordRes corresponds to select ALL.
template<class Type>
label reconstructEdgeFields
(
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
);
//- Reconstruct all supported area/edge field types
label reconstructAllFields
(
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
); );
}; };
@ -194,7 +252,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
# include "faFieldReconstructorFields.C" # include "faFieldReconstructorTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -38,37 +38,12 @@ License
template<class Type> template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh>> Foam::tmp<Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh>>
Foam::faFieldReconstructor::reconstructFaAreaField Foam::faFieldReconstructor::reconstructField
( (
const IOobject& fieldIoObject const IOobject& fieldObject,
) const PtrList<GeometricField<Type, faPatchField, areaMesh>>& procFields
) const
{ {
// Read the field for all the processors
PtrList<GeometricField<Type, faPatchField, areaMesh>> procFields
(
procMeshes_.size()
);
forAll(procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, faPatchField, areaMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField // Create the internalField
Field<Type> internalField(mesh_.nFaces()); Field<Type> internalField(mesh_.nFaces());
@ -278,9 +253,9 @@ Foam::faFieldReconstructor::reconstructFaAreaField
( (
IOobject IOobject
( (
fieldIoObject.name(), fieldObject.name(),
mesh_.time().timeName(), mesh_.thisDb().time().timeName(),
mesh_(), mesh_.thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
@ -294,38 +269,12 @@ Foam::faFieldReconstructor::reconstructFaAreaField
template<class Type> template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh>> Foam::tmp<Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh>>
Foam::faFieldReconstructor::reconstructFaEdgeField Foam::faFieldReconstructor::reconstructField
( (
const IOobject& fieldIoObject const IOobject& fieldObject,
) const PtrList<GeometricField<Type, faePatchField, edgeMesh>>& procFields
) const
{ {
// Read the field for all the processors
PtrList<GeometricField<Type, faePatchField, edgeMesh>> procFields
(
procMeshes_.size()
);
forAll(procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, faePatchField, edgeMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField // Create the internalField
Field<Type> internalField(mesh_.nInternalEdges()); Field<Type> internalField(mesh_.nInternalEdges());
@ -555,9 +504,9 @@ Foam::faFieldReconstructor::reconstructFaEdgeField
( (
IOobject IOobject
( (
fieldIoObject.name(), fieldObject.name(),
mesh_.time().timeName(), mesh_.thisDb().time().timeName(),
mesh_(), mesh_.thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
@ -569,58 +518,209 @@ Foam::faFieldReconstructor::reconstructFaEdgeField
} }
// Reconstruct and write all area fields
template<class Type> template<class Type>
void Foam::faFieldReconstructor::reconstructFaAreaFields Foam::tmp<Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh>>
Foam::faFieldReconstructor::reconstructAreaField
( (
const IOobjectList& objects const IOobject& fieldObject
) )
{ {
const word& clsName = // Read the field for all the processors
GeometricField<Type, faPatchField, areaMesh>::typeName; PtrList<GeometricField<Type, faPatchField, areaMesh>> procFields
(
procMeshes_.size()
);
const wordList fieldNames = objects.sortedNames(clsName); forAll(procMeshes_, proci)
if (fieldNames.size())
{ {
Info<< " Reconstructing " << clsName << "s\n" << endl; procFields.set
(
proci,
new GeometricField<Type, faPatchField, areaMesh>
(
IOobject
(
fieldObject.name(),
procMeshes_[proci].thisDb().time().timeName(),
procMeshes_[proci].thisDb(),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[proci]
)
);
} }
for (const word& fieldName : fieldNames) return reconstructField
{ (
Info << " " << fieldName << endl; IOobject
reconstructFaAreaField<Type>(*(objects[fieldName]))().write(); (
} fieldObject.name(),
mesh_.thisDb().time().timeName(),
if (fieldNames.size()) Info<< endl; mesh_.thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFields
);
} }
// Reconstruct and write all edge fields
template<class Type> template<class Type>
void Foam::faFieldReconstructor::reconstructFaEdgeFields Foam::tmp<Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh>>
Foam::faFieldReconstructor::reconstructEdgeField
( (
const IOobjectList& objects const IOobject& fieldObject
) )
{ {
const word& clsName = // Read the field for all the processors
GeometricField<Type, faePatchField, edgeMesh>::typeName; PtrList<GeometricField<Type, faePatchField, edgeMesh>> procFields
(
procMeshes_.size()
);
const wordList fieldNames = objects.sortedNames(clsName); forAll(procMeshes_, proci)
if (fieldNames.size())
{ {
Info<< " Reconstructing " << clsName << "s\n" << endl; procFields.set
(
proci,
new GeometricField<Type, faePatchField, edgeMesh>
(
IOobject
(
fieldObject.name(),
procMeshes_[proci].thisDb().time().timeName(),
procMeshes_[proci].thisDb(),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[proci]
)
);
} }
for (const word& fieldName : fieldNames) return reconstructField
{ (
Info << " " << fieldName << endl; IOobject
(
fieldObject.name(),
mesh_.thisDb().time().timeName(),
mesh_.thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFields
);
}
reconstructFaEdgeField<Type>(*(objects[fieldName]))().write();
template<class Type>
Foam::label Foam::faFieldReconstructor::reconstructAreaFields
(
const UPtrList<const IOobject>& fieldObjects
)
{
typedef GeometricField<Type, faPatchField, areaMesh> fieldType;
label nFields = 0;
for (const IOobject& io : fieldObjects)
{
if (io.isHeaderClass<fieldType>())
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << endl;
}
++nFields;
reconstructAreaField<Type>(io)().write();
++nReconstructed_;
}
} }
if (fieldNames.size()) Info<< endl; if (verbose_ && nFields) Info<< endl;
return nFields;
}
template<class Type>
Foam::label Foam::faFieldReconstructor::reconstructEdgeFields
(
const UPtrList<const IOobject>& fieldObjects
)
{
typedef GeometricField<Type, faePatchField, edgeMesh> fieldType;
label nFields = 0;
for (const IOobject& io : fieldObjects)
{
if (io.isHeaderClass<fieldType>())
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << endl;
}
++nFields;
reconstructEdgeField<Type>(io)().write();
++nReconstructed_;
}
}
if (verbose_ && nFields) Info<< endl;
return nFields;
}
template<class Type>
Foam::label Foam::faFieldReconstructor::reconstructAreaFields
(
const IOobjectList& objects,
const wordRes& selectedFields
)
{
typedef GeometricField<Type, faPatchField, areaMesh> fieldType;
return reconstructAreaFields<Type>
(
(
selectedFields.empty()
? objects.sorted<fieldType>()
: objects.sorted<fieldType>(selectedFields)
)
);
}
template<class Type>
Foam::label Foam::faFieldReconstructor::reconstructEdgeFields
(
const IOobjectList& objects,
const wordRes& selectedFields
)
{
typedef GeometricField<Type, faePatchField, edgeMesh> fieldType;
return reconstructEdgeFields<Type>
(
(
selectedFields.empty()
? objects.sorted<fieldType>()
: objects.sorted<fieldType>(selectedFields)
)
);
} }

View File

@ -77,7 +77,7 @@ void Foam::faMeshReconstructor::calcAddressing
for (label& facei : faFaceProcAddr_) for (label& facei : faFaceProcAddr_)
{ {
// Use finiteVolume info, ignoring face flips // Use finiteVolume info, ignoring face flips
facei = mag(fvFaceProcAddr[facei] - 1); facei = mag(fvFaceProcAddr[facei])-1;
} }
@ -449,7 +449,7 @@ void Foam::faMeshReconstructor::initPatch() const
void Foam::faMeshReconstructor::createMesh() void Foam::faMeshReconstructor::createMesh()
{ {
const Time& runTime = procMesh_.mesh().time(); const Time& runTime = procMesh_.thisDb().time();
// Time for non-parallel case (w/o functionObjects or libs) // Time for non-parallel case (w/o functionObjects or libs)
serialRunTime_ = Time::New(runTime.globalPath().toAbsolute()); serialRunTime_ = Time::New(runTime.globalPath().toAbsolute());
@ -654,7 +654,7 @@ void Foam::faMeshReconstructor::writeAddressing(const word& timeName) const
"procAddressing", "procAddressing",
timeName, timeName,
faMesh::meshSubDir, faMesh::meshSubDir,
procMesh_.mesh(), // The polyMesh procMesh_.thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
false // not registered false // not registered
@ -662,19 +662,19 @@ void Foam::faMeshReconstructor::writeAddressing(const word& timeName) const
// boundaryProcAddressing // boundaryProcAddressing
ioAddr.rename("boundaryProcAddressing"); ioAddr.rename("boundaryProcAddressing");
labelIOList(ioAddr, faBoundaryProcAddr_).write(); IOListRef<label>(ioAddr, faBoundaryProcAddr_).write();
// faceProcAddressing // faceProcAddressing
ioAddr.rename("faceProcAddressing"); ioAddr.rename("faceProcAddressing");
labelIOList(ioAddr, faFaceProcAddr_).write(); IOListRef<label>(ioAddr, faFaceProcAddr_).write();
// pointProcAddressing // pointProcAddressing
ioAddr.rename("pointProcAddressing"); ioAddr.rename("pointProcAddressing");
labelIOList(ioAddr, faPointProcAddr_).write(); IOListRef<label>(ioAddr, faPointProcAddr_).write();
// edgeProcAddressing // edgeProcAddressing
ioAddr.rename("edgeProcAddressing"); ioAddr.rename("edgeProcAddressing");
labelIOList(ioAddr, faEdgeProcAddr_).write(); IOListRef<label>(ioAddr, faEdgeProcAddr_).write();
} }
@ -699,7 +699,7 @@ void Foam::faMeshReconstructor::writeMesh(const word& timeName) const
IOobject io(fullMesh.boundary()); IOobject io(fullMesh.boundary());
io.rename("faceLabels"); io.rename("faceLabels");
labelIOList(io, singlePatchFaceLabels_).write(); IOListRef<label>(io, singlePatchFaceLabels_).write();
fullMesh.boundary().write(); fullMesh.boundary().write();

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,102 +28,50 @@ License
#include "processorFaMeshes.H" #include "processorFaMeshes.H"
#include "Time.H" #include "Time.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::processorFaMeshes::read() void Foam::processorFaMeshes::read()
{ {
forAll(fvMeshes_, procI) forAll(fvMeshes_, proci)
{ {
meshes_.set meshes_.set(proci, new faMesh(fvMeshes_[proci]));
// Read the addressing information
IOobject ioAddr
( (
procI, "procAddressing",
new faMesh(fvMeshes_[procI]) "constant", // Placeholder
faMesh::meshSubDir,
meshes_[proci].thisDb(),
IOobject::MUST_READ,
IOobject::NO_WRITE
); );
pointProcAddressing_.set const auto& runTime = meshes_[proci].thisDb().time();
( const auto& meshDir = meshes_[proci].meshDir();
procI,
new labelIOList
(
IOobject
(
"pointProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"pointProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
edgeProcAddressing_.set // pointProcAddressing (faMesh)
( ioAddr.rename("pointProcAddressing");
procI, ioAddr.instance() = runTime.findInstance(meshDir, ioAddr.name());
new labelIOList pointProcAddressing_.set(proci, new labelIOList(ioAddr));
(
IOobject
(
"edgeProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"edgeProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
faceProcAddressing_.set // edgeProcAddressing (faMesh)
( ioAddr.rename("edgeProcAddressing");
procI, ioAddr.instance() = runTime.findInstance(meshDir, ioAddr.name());
new labelIOList edgeProcAddressing_.set(proci, new labelIOList(ioAddr));
(
IOobject
(
"faceProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"faceProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
boundaryProcAddressing_.set // faceProcAddressing (faMesh)
( ioAddr.rename("faceProcAddressing");
procI, ioAddr.instance() = runTime.findInstance(meshDir, ioAddr.name());
new labelIOList faceProcAddressing_.set(proci, new labelIOList(ioAddr));
(
IOobject // boundaryProcAddressing (faMesh)
( ioAddr.rename("boundaryProcAddressing");
"boundaryProcAddressing", ioAddr.instance() = runTime.findInstance(meshDir, ioAddr.name());
meshes_[procI].time().findInstance boundaryProcAddressing_.set(proci, new labelIOList(ioAddr));
(
meshes_[procI].meshDir(),
"faceProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
} }
} }
@ -131,11 +80,11 @@ void Foam::processorFaMeshes::read()
Foam::processorFaMeshes::processorFaMeshes Foam::processorFaMeshes::processorFaMeshes
( (
const UPtrList<fvMesh>& processorFvMeshes const UPtrList<fvMesh>& procFvMeshes
) )
: :
fvMeshes_(processorFvMeshes), fvMeshes_(procFvMeshes),
meshes_(processorFvMeshes.size()), meshes_(procFvMeshes.size()),
pointProcAddressing_(meshes_.size()), pointProcAddressing_(meshes_.size()),
edgeProcAddressing_(meshes_.size()), edgeProcAddressing_(meshes_.size()),
faceProcAddressing_(meshes_.size()), faceProcAddressing_(meshes_.size()),
@ -145,4 +94,40 @@ Foam::processorFaMeshes::processorFaMeshes
} }
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
void Foam::processorFaMeshes::removeFiles(const faMesh& mesh)
{
IOobject ioAddr
(
"procAddressing",
mesh.facesInstance(),
faMesh::meshSubDir,
mesh.thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false // not registered
);
// procAddressing
rm(ioAddr.objectPath());
// pointProcAddressing
ioAddr.rename("pointProcAddressing");
rm(ioAddr.objectPath());
// edgeProcAddressing
ioAddr.rename("edgeProcAddressing");
rm(ioAddr.objectPath());
// faceProcAddressing
ioAddr.rename("faceProcAddressing");
rm(ioAddr.objectPath());
// boundaryProcAddressing
ioAddr.rename("boundaryProcAddressing");
rm(ioAddr.objectPath());
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -37,8 +37,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef processorFaMeshes_H #ifndef Foam_processorFaMeshes_H
#define processorFaMeshes_H #define Foam_processorFaMeshes_H
#include "PtrList.H" #include "PtrList.H"
#include "faMesh.H" #include "faMesh.H"
@ -57,7 +57,7 @@ namespace Foam
class processorFaMeshes class processorFaMeshes
{ {
// Private data // Private Data
//- List of processor finite volume meshes //- List of processor finite volume meshes
const UPtrList<fvMesh>& fvMeshes_; const UPtrList<fvMesh>& fvMeshes_;
@ -95,40 +95,44 @@ public:
// Constructors // Constructors
//- Construct from components //- Construct from components
explicit processorFaMeshes(const UPtrList<fvMesh>& processorFvMeshes); explicit processorFaMeshes(const UPtrList<fvMesh>& procFvMeshes);
// Member Functions // Member Functions
const PtrList<faMesh>& meshes() const const PtrList<faMesh>& meshes() const noexcept
{ {
return meshes_; return meshes_;
} }
PtrList<faMesh>& meshes() PtrList<faMesh>& meshes() noexcept
{ {
return meshes_; return meshes_;
} }
const PtrList<labelIOList>& pointProcAddressing() const const PtrList<labelIOList>& pointProcAddressing() const noexcept
{ {
return pointProcAddressing_; return pointProcAddressing_;
} }
PtrList<labelIOList>& edgeProcAddressing() PtrList<labelIOList>& edgeProcAddressing() noexcept
{ {
return edgeProcAddressing_; return edgeProcAddressing_;
} }
const PtrList<labelIOList>& faceProcAddressing() const const PtrList<labelIOList>& faceProcAddressing() const noexcept
{ {
return faceProcAddressing_; return faceProcAddressing_;
} }
const PtrList<labelIOList>& boundaryProcAddressing() const const PtrList<labelIOList>& boundaryProcAddressing() const noexcept
{ {
return boundaryProcAddressing_; return boundaryProcAddressing_;
} }
//- Helper: remove all procAddressing files from mesh instance
static void removeFiles(const faMesh& mesh);
}; };

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -26,6 +27,13 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "fvFieldReconstructor.H" #include "fvFieldReconstructor.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::fvFieldReconstructor::verbose_ = 1;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -71,4 +79,38 @@ Foam::fvFieldReconstructor::fvFieldReconstructor
} }
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::fvFieldReconstructor::reconstructAllFields
(
const IOobjectList& objects,
const wordRes& selected
)
{
label nTotal = 0;
do
{
#undef doLocalCode
#define doLocalCode(Method) \
{ \
nTotal += this->Method <scalar> (objects, selected); \
nTotal += this->Method <vector> (objects, selected); \
nTotal += this->Method <sphericalTensor> (objects, selected); \
nTotal += this->Method <symmTensor> (objects, selected); \
nTotal += this->Method <tensor> (objects, selected); \
}
doLocalCode(reconstructInternalFields);
doLocalCode(reconstructVolumeFields);
doLocalCode(reconstructSurfaceFields);
#undef doLocalCode
}
while (false);
return nTotal;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,12 +32,12 @@ Description
SourceFiles SourceFiles
fvFieldReconstructor.C fvFieldReconstructor.C
fvFieldReconstructorFields.C fvFieldReconstructorTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef fvFieldReconstructor_H #ifndef Foam_fvFieldReconstructor_H
#define fvFieldReconstructor_H #define Foam_fvFieldReconstructor_H
#include "PtrList.H" #include "PtrList.H"
#include "fvMesh.H" #include "fvMesh.H"
@ -56,7 +56,7 @@ namespace Foam
class fvFieldReconstructor class fvFieldReconstructor
{ {
// Private data // Private Data
//- Reconstructed mesh reference //- Reconstructed mesh reference
fvMesh& mesh_; fvMesh& mesh_;
@ -88,6 +88,8 @@ class fvFieldReconstructor
public: public:
// Public Classes
//- Mapper for sizing only - does not do any actual mapping. //- Mapper for sizing only - does not do any actual mapping.
class fvPatchFieldReconstructor class fvPatchFieldReconstructor
: :
@ -130,6 +132,12 @@ public:
}; };
// Static Data
//- Output verbosity when writing
static int verbose_;
// Constructors // Constructors
//- Construct from components //- Construct from components
@ -146,7 +154,7 @@ public:
// Member Functions // Member Functions
//- Return number of fields reconstructed //- Return number of fields reconstructed
label nReconstructed() const label nReconstructed() const noexcept
{ {
return nReconstructed_; return nReconstructed_;
} }
@ -154,76 +162,74 @@ public:
//- Reconstruct volume internal field //- Reconstruct volume internal field
template<class Type> template<class Type>
tmp<DimensionedField<Type, volMesh>> tmp<DimensionedField<Type, volMesh>>
reconstructFvVolumeInternalField reconstructField
( (
const IOobject& fieldIoObject, const IOobject& fieldObject,
const PtrList<DimensionedField<Type, volMesh>>& procFields const PtrList<DimensionedField<Type, volMesh>>& procFields
) const; ) const;
//- Read and reconstruct volume internal field //- Read and reconstruct volume internal field
template<class Type> template<class Type>
tmp<DimensionedField<Type, volMesh>> tmp<DimensionedField<Type, volMesh>>
reconstructFvVolumeInternalField(const IOobject& fieldIoObject) const; reconstructInternalField(const IOobject& fieldObject) const;
//- Reconstruct volume field //- Reconstruct volume field
template<class Type> template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>> tmp<GeometricField<Type, fvPatchField, volMesh>>
reconstructFvVolumeField reconstructField
( (
const IOobject& fieldIoObject, const IOobject& fieldObject,
const PtrList<GeometricField<Type, fvPatchField, volMesh>>& const PtrList<GeometricField<Type, fvPatchField, volMesh>>&
) const; ) const;
//- Read and reconstruct volume field //- Read and reconstruct volume field
template<class Type> template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>> tmp<GeometricField<Type, fvPatchField, volMesh>>
reconstructFvVolumeField(const IOobject& fieldIoObject) const; reconstructVolumeField(const IOobject& fieldObject) const;
//- Reconstruct surface field //- Reconstruct surface field
template<class Type> template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
reconstructFvSurfaceField reconstructField
( (
const IOobject& fieldIoObject, const IOobject& fieldObject,
const PtrList<GeometricField<Type, fvsPatchField, surfaceMesh>>& const PtrList<GeometricField<Type, fvsPatchField, surfaceMesh>>&
) const; ) const;
//- Read and reconstruct surface field //- Read and reconstruct surface field
template<class Type> template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
reconstructFvSurfaceField(const IOobject& fieldIoObject) const; reconstructSurfaceField(const IOobject& fieldObject) const;
//- Read, reconstruct and write specified volume internal fields //- Read, reconstruct and write specified volume internal fields
template<class Type> template<class Type>
label reconstructFvVolumeInternalFields label reconstructInternalFields
( (
const IOobjectList& objects, const UPtrList<const IOobject>& fieldObjects
const UList<word>& fieldNames
); );
//- Read, reconstruct and write specified volume fields //- Read, reconstruct and write specified volume fields
template<class Type> template<class Type>
label reconstructFvVolumeFields label reconstructVolumeFields
( (
const IOobjectList& objects, const UPtrList<const IOobject>& fieldObjects
const UList<word>& fieldNames
); );
//- Read, reconstruct and write specified surface fields //- Read, reconstruct and write specified surface fields
template<class Type> template<class Type>
label reconstructFvSurfaceFields label reconstructSurfaceFields
( (
const IOobjectList& objects, const UPtrList<const IOobject>& fieldObjects
const UList<word>& fieldNames
); );
//- Read, reconstruct and write all/selected volume internal fields //- Read, reconstruct and write all/selected volume internal fields
// An empty wordRes corresponds to select ALL. // An empty wordRes corresponds to select ALL.
template<class Type> template<class Type>
label reconstructFvVolumeInternalFields label reconstructInternalFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
@ -232,7 +238,7 @@ public:
//- Read, reconstruct and write all/selected volume fields //- Read, reconstruct and write all/selected volume fields
// An empty wordRes corresponds to select ALL. // An empty wordRes corresponds to select ALL.
template<class Type> template<class Type>
label reconstructFvVolumeFields label reconstructVolumeFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
@ -241,40 +247,17 @@ public:
//- Read, reconstruct and write all/selected surface fields //- Read, reconstruct and write all/selected surface fields
// An empty wordRes corresponds to select ALL. // An empty wordRes corresponds to select ALL.
template<class Type> template<class Type>
label reconstructFvSurfaceFields label reconstructSurfaceFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
); );
//- Read, reconstruct and write all/selected volume internal fields //- Reconstruct all known field types
// An empty wordHashSet corresponds to select ALL. label reconstructAllFields
// \note this may be removed in the future (2018-11)
template<class Type>
label reconstructFvVolumeInternalFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordHashSet& selectedFields const wordRes& selectedFields = wordRes()
);
//- Read, reconstruct and write all/selected volume fields
// An empty wordHashSet corresponds to select ALL.
// \note this may be removed in the future (2018-11)
template<class Type>
label reconstructFvVolumeFields
(
const IOobjectList& objects,
const wordHashSet& selectedFields
);
//- Read, reconstruct and write all/selected surface fields
// An empty wordHashSet corresponds to select ALL.
// \note this may be removed in the future (2018-11)
template<class Type>
label reconstructFvSurfaceFields
(
const IOobjectList& objects,
const wordHashSet& selectedFields
); );
}; };
@ -286,7 +269,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "fvFieldReconstructorFields.C" #include "fvFieldReconstructorTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -38,9 +38,9 @@ License
template<class Type> template<class Type>
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>> Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
Foam::fvFieldReconstructor::reconstructFvVolumeInternalField Foam::fvFieldReconstructor::reconstructField
( (
const IOobject& fieldIoObject, const IOobject& fieldObject,
const PtrList<DimensionedField<Type, volMesh>>& procFields const PtrList<DimensionedField<Type, volMesh>>& procFields
) const ) const
{ {
@ -61,7 +61,7 @@ Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
auto tfield = tmp<DimensionedField<Type, volMesh>>::New auto tfield = tmp<DimensionedField<Type, volMesh>>::New
( (
fieldIoObject, fieldObject,
mesh_, mesh_,
procFields[0].dimensions(), procFields[0].dimensions(),
internalField internalField
@ -73,59 +73,11 @@ Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
} }
template<class Type>
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
(
const IOobject& fieldIoObject
) const
{
// Read the field for all the processors
PtrList<DimensionedField<Type, volMesh>> procFields
(
procMeshes_.size()
);
forAll(procMeshes_, proci)
{
procFields.set
(
proci,
new DimensionedField<Type, volMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[proci].time().timeName(),
procMeshes_[proci],
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[proci]
)
);
}
return reconstructFvVolumeInternalField
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFields
);
}
template<class Type> template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>> Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
Foam::fvFieldReconstructor::reconstructFvVolumeField Foam::fvFieldReconstructor::reconstructField
( (
const IOobject& fieldIoObject, const IOobject& fieldObject,
const PtrList<GeometricField<Type, fvPatchField, volMesh>>& procFields const PtrList<GeometricField<Type, fvPatchField, volMesh>>& procFields
) const ) const
{ {
@ -137,8 +89,7 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
forAll(procFields, proci) forAll(procFields, proci)
{ {
const GeometricField<Type, fvPatchField, volMesh>& procField = const auto& procField = procFields[proci];
procFields[proci];
// Set the cell values in the reconstructed field // Set the cell values in the reconstructed field
internalField.rmap internalField.rmap
@ -287,7 +238,7 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
// setting the internalField and patchFields // setting the internalField and patchFields
auto tfield = tmp<GeometricField<Type, fvPatchField, volMesh>>::New auto tfield = tmp<GeometricField<Type, fvPatchField, volMesh>>::New
( (
fieldIoObject, fieldObject,
mesh_, mesh_,
procFields[0].dimensions(), procFields[0].dimensions(),
internalField, internalField,
@ -300,59 +251,11 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
} }
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
Foam::fvFieldReconstructor::reconstructFvVolumeField
(
const IOobject& fieldIoObject
) const
{
// Read the field for all the processors
PtrList<GeometricField<Type, fvPatchField, volMesh>> procFields
(
procMeshes_.size()
);
forAll(procMeshes_, proci)
{
procFields.set
(
proci,
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[proci].time().timeName(),
procMeshes_[proci],
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[proci]
)
);
}
return reconstructFvVolumeField
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFields
);
}
template<class Type> template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh>> Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh>>
Foam::fvFieldReconstructor::reconstructFvSurfaceField Foam::fvFieldReconstructor::reconstructField
( (
const IOobject& fieldIoObject, const IOobject& fieldObject,
const PtrList<GeometricField<Type, fvsPatchField, surfaceMesh>>& procFields const PtrList<GeometricField<Type, fvsPatchField, surfaceMesh>>& procFields
) const ) const
{ {
@ -365,8 +268,7 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
forAll(procMeshes_, proci) forAll(procMeshes_, proci)
{ {
const GeometricField<Type, fvsPatchField, surfaceMesh>& procField = const auto& procField = procFields[proci];
procFields[proci];
// Set the face values in the reconstructed field // Set the face values in the reconstructed field
@ -529,7 +431,7 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
// setting the internalField and patchFields // setting the internalField and patchFields
auto tfield = tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>::New auto tfield = tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>::New
( (
fieldIoObject, fieldObject,
mesh_, mesh_,
procFields[0].dimensions(), procFields[0].dimensions(),
internalField, internalField,
@ -543,10 +445,106 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
template<class Type> template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh>> Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
Foam::fvFieldReconstructor::reconstructFvSurfaceField Foam::fvFieldReconstructor::reconstructInternalField
( (
const IOobject& fieldIoObject const IOobject& fieldObject
) const
{
// Read the field for all the processors
PtrList<DimensionedField<Type, volMesh>> procFields
(
procMeshes_.size()
);
forAll(procMeshes_, proci)
{
procFields.set
(
proci,
new DimensionedField<Type, volMesh>
(
IOobject
(
fieldObject.name(),
procMeshes_[proci].thisDb().time().timeName(),
procMeshes_[proci].thisDb(),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[proci]
)
);
}
return reconstructField
(
IOobject
(
fieldObject.name(),
mesh_.thisDb().time().timeName(),
mesh_.thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFields
);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
Foam::fvFieldReconstructor::reconstructVolumeField
(
const IOobject& fieldObject
) const
{
// Read the field for all the processors
PtrList<GeometricField<Type, fvPatchField, volMesh>> procFields
(
procMeshes_.size()
);
forAll(procMeshes_, proci)
{
procFields.set
(
proci,
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
fieldObject.name(),
procMeshes_[proci].thisDb().time().timeName(),
procMeshes_[proci].thisDb(),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[proci]
)
);
}
return reconstructField
(
IOobject
(
fieldObject.name(),
mesh_.thisDb().time().timeName(),
mesh_.thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFields
);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh>>
Foam::fvFieldReconstructor::reconstructSurfaceField
(
const IOobject& fieldObject
) const ) const
{ {
// Read the field for all the processors // Read the field for all the processors
@ -564,9 +562,9 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
( (
IOobject IOobject
( (
fieldIoObject.name(), fieldObject.name(),
procMeshes_[proci].time().timeName(), procMeshes_[proci].thisDb().time().timeName(),
procMeshes_[proci], procMeshes_[proci].thisDb(),
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
@ -575,13 +573,13 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
); );
} }
return reconstructFvSurfaceField return reconstructField
( (
IOobject IOobject
( (
fieldIoObject.name(), fieldObject.name(),
mesh_.time().timeName(), mesh_.thisDb().time().timeName(),
mesh_, mesh_.thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
@ -591,103 +589,113 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
template<class Type> template<class Type>
Foam::label Foam::fvFieldReconstructor::reconstructFvVolumeInternalFields Foam::label Foam::fvFieldReconstructor::reconstructInternalFields
( (
const IOobjectList& objects, const UPtrList<const IOobject>& fieldObjects
const UList<word>& fieldNames
) )
{ {
typedef DimensionedField<Type, volMesh> fieldType; typedef DimensionedField<Type, volMesh> fieldType;
label nFields = 0; label nFields = 0;
for (const word& fieldName : fieldNames)
{
const IOobject* io = objects.cfindObject<fieldType>(fieldName);
if (io)
{
if (!nFields++)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << fieldName << endl;
reconstructFvVolumeInternalField<Type>(*io)().write(); for (const IOobject& io : fieldObjects)
{
if (io.isHeaderClass<fieldType>())
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << endl;
}
++nFields;
reconstructInternalField<Type>(io)().write();
++nReconstructed_; ++nReconstructed_;
} }
} }
if (nFields) Info<< endl; if (verbose_ && nFields) Info<< endl;
return nFields; return nFields;
} }
template<class Type> template<class Type>
Foam::label Foam::fvFieldReconstructor::reconstructFvVolumeFields Foam::label Foam::fvFieldReconstructor::reconstructVolumeFields
( (
const IOobjectList& objects, const UPtrList<const IOobject>& fieldObjects
const UList<word>& fieldNames
) )
{ {
typedef GeometricField<Type, fvPatchField, volMesh> fieldType; typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
label nFields = 0; label nFields = 0;
for (const word& fieldName : fieldNames)
{
const IOobject* io = objects.cfindObject<fieldType>(fieldName);
if (io)
{
if (!nFields++)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << fieldName << endl;
reconstructFvVolumeField<Type>(*io)().write(); for (const IOobject& io : fieldObjects)
{
if (io.isHeaderClass<fieldType>())
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << endl;
}
++nFields;
reconstructVolumeField<Type>(io)().write();
++nReconstructed_; ++nReconstructed_;
} }
} }
if (nFields) Info<< endl; if (verbose_ && nFields) Info<< endl;
return nFields; return nFields;
} }
template<class Type> template<class Type>
Foam::label Foam::fvFieldReconstructor::reconstructFvSurfaceFields Foam::label Foam::fvFieldReconstructor::reconstructSurfaceFields
( (
const IOobjectList& objects, const UPtrList<const IOobject>& fieldObjects
const UList<word>& fieldNames
) )
{ {
typedef GeometricField<Type, fvsPatchField, surfaceMesh> fieldType; typedef GeometricField<Type, fvsPatchField, surfaceMesh> fieldType;
label nFields = 0; label nFields = 0;
for (const word& fieldName : fieldNames)
{
const IOobject* io = objects.cfindObject<fieldType>(fieldName);
if (io)
{
if (!nFields++)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << fieldName << endl;
reconstructFvSurfaceField<Type>(*io)().write(); for (const IOobject& io : fieldObjects)
{
if (io.isHeaderClass<fieldType>())
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << endl;
}
++nFields;
reconstructSurfaceField<Type>(io)().write();
++nReconstructed_; ++nReconstructed_;
} }
} }
if (nFields) Info<< endl; if (verbose_ && nFields) Info<< endl;
return nFields; return nFields;
} }
template<class Type> template<class Type>
Foam::label Foam::fvFieldReconstructor::reconstructFvVolumeInternalFields Foam::label Foam::fvFieldReconstructor::reconstructInternalFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields const wordRes& selectedFields
@ -695,19 +703,19 @@ Foam::label Foam::fvFieldReconstructor::reconstructFvVolumeInternalFields
{ {
typedef DimensionedField<Type, volMesh> fieldType; typedef DimensionedField<Type, volMesh> fieldType;
const wordList fieldNames = return reconstructInternalFields<Type>
( (
selectedFields.empty() (
? objects.sortedNames<fieldType>() selectedFields.empty()
: objects.sortedNames<fieldType>(selectedFields) ? objects.sorted<fieldType>()
: objects.sorted<fieldType>(selectedFields)
)
); );
return reconstructFvVolumeInternalFields<Type>(objects, fieldNames);
} }
template<class Type> template<class Type>
Foam::label Foam::fvFieldReconstructor::reconstructFvVolumeFields Foam::label Foam::fvFieldReconstructor::reconstructVolumeFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields const wordRes& selectedFields
@ -715,19 +723,19 @@ Foam::label Foam::fvFieldReconstructor::reconstructFvVolumeFields
{ {
typedef GeometricField<Type, fvPatchField, volMesh> fieldType; typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
const wordList fieldNames = return reconstructVolumeFields<Type>
( (
selectedFields.empty() (
? objects.sortedNames<fieldType>() selectedFields.empty()
: objects.sortedNames<fieldType>(selectedFields) ? objects.sorted<fieldType>()
: objects.sorted<fieldType>(selectedFields)
)
); );
return reconstructFvVolumeFields<Type>(objects, fieldNames);
} }
template<class Type> template<class Type>
Foam::label Foam::fvFieldReconstructor::reconstructFvSurfaceFields Foam::label Foam::fvFieldReconstructor::reconstructSurfaceFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields const wordRes& selectedFields
@ -735,74 +743,14 @@ Foam::label Foam::fvFieldReconstructor::reconstructFvSurfaceFields
{ {
typedef GeometricField<Type, fvsPatchField, surfaceMesh> fieldType; typedef GeometricField<Type, fvsPatchField, surfaceMesh> fieldType;
const wordList fieldNames = return reconstructSurfaceFields<Type>
( (
selectedFields.empty() (
? objects.sortedNames<fieldType>() selectedFields.empty()
: objects.sortedNames<fieldType>(selectedFields) ? objects.sorted<fieldType>()
: objects.sorted<fieldType>(selectedFields)
)
); );
return reconstructFvSurfaceFields<Type>(objects, fieldNames);
}
template<class Type>
Foam::label Foam::fvFieldReconstructor::reconstructFvVolumeInternalFields
(
const IOobjectList& objects,
const wordHashSet& selectedFields
)
{
typedef DimensionedField<Type, volMesh> fieldType;
const wordList fieldNames =
(
selectedFields.empty()
? objects.sortedNames<fieldType>()
: objects.sortedNames<fieldType>(selectedFields)
);
return reconstructFvVolumeInternalFields<Type>(objects, fieldNames);
}
template<class Type>
Foam::label Foam::fvFieldReconstructor::reconstructFvVolumeFields
(
const IOobjectList& objects,
const wordHashSet& selectedFields
)
{
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
const wordList fieldNames =
(
selectedFields.empty()
? objects.sortedNames<fieldType>()
: objects.sortedNames<fieldType>(selectedFields)
);
return reconstructFvVolumeField<Type>(objects, fieldNames);
}
template<class Type>
Foam::label Foam::fvFieldReconstructor::reconstructFvSurfaceFields
(
const IOobjectList& objects,
const wordHashSet& selectedFields
)
{
typedef GeometricField<Type, fvsPatchField, surfaceMesh> fieldType;
const wordList fieldNames =
(
selectedFields.empty()
? objects.sortedNames<fieldType>()
: objects.sortedNames<fieldType>(selectedFields)
);
return reconstructFvSurfaceFields<Type>(objects, fieldNames);
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018,2021 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,6 +29,11 @@ License
#include "lagrangianReconstructor.H" #include "lagrangianReconstructor.H"
#include "passivePositionParticleCloud.H" #include "passivePositionParticleCloud.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::lagrangianReconstructor::verbose_ = 1;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::lagrangianReconstructor::lagrangianReconstructor Foam::lagrangianReconstructor::lagrangianReconstructor
@ -142,4 +147,44 @@ Foam::label Foam::lagrangianReconstructor::reconstructPositions
} }
void Foam::lagrangianReconstructor::reconstructAllFields
(
const word& cloudName,
const IOobjectList& cloudObjs,
const wordRes& selectedFields
)
{
do
{
#undef doLocalCode
#define doLocalCode(Type) \
{ \
this->reconstructFields<Type> \
( \
cloudName, \
cloudObjs, \
selectedFields \
); \
\
this->reconstructFieldFields<Type> \
( \
cloudName, \
cloudObjs, \
selectedFields \
); \
}
doLocalCode(label);
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
}
while (false);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,12 +32,12 @@ Description
SourceFiles SourceFiles
lagrangianReconstructor.C lagrangianReconstructor.C
lagrangianReconstructorFields.C lagrangianReconstructorTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef lagrangianReconstructor_H #ifndef Foam_lagrangianReconstructor_H
#define lagrangianReconstructor_H #define Foam_lagrangianReconstructor_H
#include "cloud.H" #include "cloud.H"
#include "polyMesh.H" #include "polyMesh.H"
@ -56,7 +56,7 @@ namespace Foam
class lagrangianReconstructor class lagrangianReconstructor
{ {
// Private data // Private Data
//- Mesh reference //- Mesh reference
const fvMesh& mesh_; const fvMesh& mesh_;
@ -82,6 +82,12 @@ class lagrangianReconstructor
public: public:
// Static Data
//- Output verbosity when writing
static int verbose_;
// Constructors // Constructors
//- Construct from components //- Construct from components
@ -101,7 +107,8 @@ public:
//- Reconstruct a single field for given cloud //- Reconstruct a single field for given cloud
template<class Type> template<class Type>
tmp<IOField<Type>> reconstructField tmp<IOField<Type>>
reconstructField
( (
const word& cloudName, const word& cloudName,
const word& fieldName const word& fieldName
@ -109,7 +116,8 @@ public:
//- Reconstruct a single field-field for given cloud //- Reconstruct a single field-field for given cloud
template<class Type> template<class Type>
tmp<CompactIOField<Field<Type>, Type>> reconstructFieldField tmp<CompactIOField<Field<Type>, Type>>
reconstructFieldField
( (
const word& cloudName, const word& cloudName,
const word& fieldName const word& fieldName
@ -120,8 +128,7 @@ public:
label reconstructFields label reconstructFields
( (
const word& cloudName, const word& cloudName,
const IOobjectList& objects, const UPtrList<const IOobject>& fieldObjects
const UList<word>& fieldNames
); );
//- Reconstruct multiple fields for given cloud //- Reconstruct multiple fields for given cloud
@ -141,6 +148,14 @@ public:
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
); );
//- Reconstruct all fields for known cloud field types
void reconstructAllFields
(
const word& cloudName,
const IOobjectList& cloudObjs,
const wordRes& selectedFields = wordRes()
);
}; };
@ -151,7 +166,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "lagrangianReconstructorFields.C" #include "lagrangianReconstructorTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -153,30 +153,33 @@ template<class Type>
Foam::label Foam::lagrangianReconstructor::reconstructFields Foam::label Foam::lagrangianReconstructor::reconstructFields
( (
const word& cloudName, const word& cloudName,
const IOobjectList& objects, const UPtrList<const IOobject>& fieldObjects
const UList<word>& fieldNames
) )
{ {
typedef IOField<Type> fieldType; typedef IOField<Type> fieldType;
label nFields = 0; label nFields = 0;
for (const word& fieldName : fieldNames)
{
const IOobject* io = objects.cfindObject<fieldType>(fieldName);
if (io)
{
if (nFields++)
{
Info<< " Reconstructing lagrangian "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << fieldName << endl;
reconstructField<Type>(cloudName, fieldName)().write(); for (const IOobject& io : fieldObjects)
{
if (io.isHeaderClass<fieldType>())
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing lagrangian "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << endl;
}
++nFields;
reconstructField<Type>(cloudName, io.name())().write();
} }
} }
if (nFields) Info<< endl; if (verbose_ && nFields) Info<< endl;
return nFields; return nFields;
} }
@ -191,14 +194,15 @@ Foam::label Foam::lagrangianReconstructor::reconstructFields
{ {
typedef IOField<Type> fieldType; typedef IOField<Type> fieldType;
const wordList fieldNames = return reconstructFields<Type>
( (
selectedFields.empty() cloudName,
? objects.sortedNames<fieldType>() (
: objects.sortedNames<fieldType>(selectedFields) selectedFields.empty()
? objects.sorted<fieldType>()
: objects.sorted<fieldType>(selectedFields)
)
); );
return reconstructFields<Type>(cloudName, objects, fieldNames);
} }
@ -211,38 +215,41 @@ Foam::label Foam::lagrangianReconstructor::reconstructFieldFields
) )
{ {
typedef CompactIOField<Field<Type>, Type> fieldType; typedef CompactIOField<Field<Type>, Type> fieldType;
typedef IOField<Field<Type>> fieldTypeB;
wordList fieldNames = UPtrList<const IOobject> fieldObjects;
(
selectedFields.empty()
? objects.names<fieldType>()
: objects.names<fieldType>(selectedFields)
);
// Append IOField Field names if (selectedFields.empty())
fieldNames.append
(
objects.empty()
? objects.names<IOField<Field<Type>>>()
: objects.names<IOField<Field<Type>>>(selectedFields)
);
Foam::sort(fieldNames);
label nFields = 0;
for (const word& fieldName : fieldNames)
{ {
if (!nFields++) fieldObjects.append(objects.sorted<fieldType>());
{ fieldObjects.append(objects.sorted<fieldTypeB>());
Info<< " Reconstructing lagrangian " }
<< fieldType::typeName << "s\n" << nl; else
} {
Info<< " " << fieldName << endl; fieldObjects.append(objects.sorted<fieldType>(selectedFields));
fieldObjects.append(objects.sorted<fieldTypeB>(selectedFields));
reconstructFieldField<Type>(cloudName, fieldName)().write();
} }
if (nFields) Info<< endl; Foam::sort(fieldObjects, nameOp<IOobject>());
label nFields = 0;
for (const IOobject& io : fieldObjects)
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing lagrangian "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << endl;
}
++nFields;
reconstructFieldField<Type>(cloudName, io.name())().write();
}
if (verbose_ && nFields) Info<< endl;
return nFields; return nFields;
} }

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -26,6 +27,12 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "pointFieldReconstructor.H" #include "pointFieldReconstructor.H"
#include "pointFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::pointFieldReconstructor::verbose_ = 1;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -95,4 +102,24 @@ Foam::pointFieldReconstructor::pointFieldReconstructor
} }
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::pointFieldReconstructor::reconstructAllFields
(
const IOobjectList& objects,
const wordRes& selected
)
{
label nTotal = 0;
nTotal += reconstructPointFields<scalar>(objects, selected);
nTotal += reconstructPointFields<vector>(objects, selected);
nTotal += reconstructPointFields<symmTensor>(objects, selected);
nTotal += reconstructPointFields<sphericalTensor>(objects, selected);
nTotal += reconstructPointFields<tensor>(objects, selected);
return nTotal;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,12 +32,12 @@ Description
SourceFiles SourceFiles
pointFieldReconstructor.C pointFieldReconstructor.C
pointFieldReconstructorFields.C pointFieldReconstructorTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef pointFieldReconstructor_H #ifndef Foam_pointFieldReconstructor_H
#define pointFieldReconstructor_H #define Foam_pointFieldReconstructor_H
#include "pointMesh.H" #include "pointMesh.H"
#include "pointFields.H" #include "pointFields.H"
@ -55,7 +55,7 @@ namespace Foam
class pointFieldReconstructor class pointFieldReconstructor
{ {
// Private data // Private Data
//- Reconstructed mesh reference //- Reconstructed mesh reference
const pointMesh& mesh_; const pointMesh& mesh_;
@ -87,6 +87,8 @@ class pointFieldReconstructor
public: public:
// Public Classes
class pointPatchFieldReconstructor class pointPatchFieldReconstructor
: :
public pointPatchFieldMapper public pointPatchFieldMapper
@ -128,6 +130,12 @@ public:
}; };
// Static Data
//- Output verbosity when writing
static int verbose_;
// Constructors // Constructors
//- Construct from components //- Construct from components
@ -143,41 +151,48 @@ public:
// Member Functions // Member Functions
//- Return number of fields reconstructed //- Return number of fields reconstructed
label nReconstructed() const label nReconstructed() const noexcept
{ {
return nReconstructed_; return nReconstructed_;
} }
//- Reconstruct field //- Reconstruct field
template<class Type> template<class Type>
tmp<GeometricField<Type, pointPatchField, pointMesh>> tmp<GeometricField<Type, pointPatchField, pointMesh>>
reconstructField(const IOobject& fieldIoObject); reconstructField
//- Reconstruct and write specified fields
template<class Type>
label reconstructFields
( (
const IOobjectList& objects, const IOobject& fieldObject,
const UList<word>& fieldNames const PtrList<GeometricField<Type, pointPatchField, pointMesh>>&
) const;
//- Read and reconstruct point field
template<class Type>
tmp<GeometricField<Type, pointPatchField, pointMesh>>
reconstructPointField(const IOobject& fieldObject);
//- Reconstruct and write specified point fields
template<class Type>
label reconstructPointFields
(
const UPtrList<const IOobject>& fieldObjects
); );
//- Reconstruct and write all or selected fields //- Reconstruct and write all or selected point fields
// An empty wordRes corresponds to select ALL. // An empty wordRes corresponds to select ALL.
template<class Type> template<class Type>
label reconstructFields label reconstructPointFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
); );
//- Reconstruct and write all or selected fields //- Reconstruct and write all known field types
// An empty wordHashSet corresponds to select ALL. label reconstructAllFields
// \note this may be removed in the future (2018-11)
template<class Type>
label reconstructFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordHashSet& selectedFields const wordRes& selectedFields = wordRes()
); );
}; };
@ -189,7 +204,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "pointFieldReconstructorFields.C" #include "pointFieldReconstructorTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,34 +32,13 @@ License
template<class Type> template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh>> Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh>>
Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject) Foam::pointFieldReconstructor::reconstructField
(
const IOobject& fieldObject,
const PtrList<GeometricField<Type, pointPatchField, pointMesh>>& procFields
) const
{ {
// Read the field for all the processors typedef GeometricField<Type, pointPatchField, pointMesh> fieldType;
PtrList<GeometricField<Type, pointPatchField, pointMesh>> procFields
(
procMeshes_.size()
);
forAll(procMeshes_, proci)
{
procFields.set
(
proci,
new GeometricField<Type, pointPatchField, pointMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[proci]().time().timeName(),
procMeshes_[proci](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[proci]
)
);
}
// Create the internalField // Create the internalField
Field<Type> internalField(mesh_.size()); Field<Type> internalField(mesh_.size());
@ -70,8 +49,7 @@ Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
forAll(procMeshes_, proci) forAll(procMeshes_, proci)
{ {
const GeometricField<Type, pointPatchField, pointMesh>& const auto& procField = procFields[proci];
procField = procFields[proci];
// Get processor-to-global addressing for use in rmap // Get processor-to-global addressing for use in rmap
const labelList& procToGlobalAddr = pointProcAddressing_[proci]; const labelList& procToGlobalAddr = pointProcAddressing_[proci];
@ -120,13 +98,13 @@ Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
// Construct and write the field // Construct and write the field
// setting the internalField and patchFields // setting the internalField and patchFields
return tmp<GeometricField<Type, pointPatchField, pointMesh>>::New return tmp<fieldType>::New
( (
IOobject IOobject
( (
fieldIoObject.name(), fieldObject.name(),
mesh_().time().timeName(), mesh_.thisDb().time().timeName(),
mesh_(), mesh_.thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
@ -139,39 +117,89 @@ Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
template<class Type> template<class Type>
Foam::label Foam::pointFieldReconstructor::reconstructFields Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh>>
Foam::pointFieldReconstructor::reconstructPointField
( (
const IOobjectList& objects, const IOobject& fieldObject
const UList<word>& fieldNames )
{
typedef GeometricField<Type, pointPatchField, pointMesh> fieldType;
// Read the field for all the processors
PtrList<fieldType> procFields(procMeshes_.size());
forAll(procMeshes_, proci)
{
procFields.set
(
proci,
new fieldType
(
IOobject
(
fieldObject.name(),
procMeshes_[proci].thisDb().time().timeName(),
procMeshes_[proci].thisDb(),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[proci]
)
);
}
return reconstructField
(
IOobject
(
fieldObject.name(),
mesh_.thisDb().time().timeName(),
mesh_.thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFields
);
}
template<class Type>
Foam::label Foam::pointFieldReconstructor::reconstructPointFields
(
const UPtrList<const IOobject>& fieldObjects
) )
{ {
typedef GeometricField<Type, pointPatchField, pointMesh> fieldType; typedef GeometricField<Type, pointPatchField, pointMesh> fieldType;
label nFields = 0; label nFields = 0;
for (const word& fieldName : fieldNames)
{
const IOobject* io = objects.cfindObject<fieldType>(fieldName);
if (io)
{
if (!nFields++)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << fieldName << endl;
reconstructField<Type>(*io)().write(); for (const IOobject& io : fieldObjects)
{
if (io.isHeaderClass<fieldType>())
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << endl;
}
++nFields;
reconstructPointField<Type>(io)().write();
++nReconstructed_; ++nReconstructed_;
} }
} }
if (nFields) Info<< endl; if (verbose_ && nFields) Info<< endl;
return nFields; return nFields;
} }
template<class Type> template<class Type>
Foam::label Foam::pointFieldReconstructor::reconstructFields Foam::label Foam::pointFieldReconstructor::reconstructPointFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields const wordRes& selectedFields
@ -179,34 +207,14 @@ Foam::label Foam::pointFieldReconstructor::reconstructFields
{ {
typedef GeometricField<Type, pointPatchField, pointMesh> fieldType; typedef GeometricField<Type, pointPatchField, pointMesh> fieldType;
const wordList fieldNames = return reconstructPointFields<Type>
( (
selectedFields.empty() (
? objects.sortedNames<fieldType>() selectedFields.empty()
: objects.sortedNames<fieldType>(selectedFields) ? objects.sorted<fieldType>()
: objects.sorted<fieldType>(selectedFields)
)
); );
return reconstructFields<Type>(objects, fieldNames);
}
template<class Type>
Foam::label Foam::pointFieldReconstructor::reconstructFields
(
const IOobjectList& objects,
const wordHashSet& selectedFields
)
{
typedef GeometricField<Type, pointPatchField, pointMesh> fieldType;
const wordList fieldNames =
(
selectedFields.empty()
? objects.sortedNames<fieldType>()
: objects.sortedNames<fieldType>(selectedFields)
);
return reconstructFields<Type>(objects, fieldNames);
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016 OpenCFD Ltd. Copyright (C) 2016-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,8 +28,9 @@ License
#include "processorMeshes.H" #include "processorMeshes.H"
#include "Time.H" #include "Time.H"
#include "IndirectList.H"
#include "primitiveMesh.H" #include "primitiveMesh.H"
#include "topoSet.H" #include "OSspecific.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -70,73 +71,33 @@ void Foam::processorMeshes::read()
) )
); );
pointProcAddressing_.set // Read the addressing information
IOobject ioAddr
( (
proci, "procAddressing",
new labelIOList meshes_[proci].facesInstance(),
( polyMesh::meshSubDir,
IOobject meshes_[proci].thisDb(),
( IOobject::MUST_READ,
"pointProcAddressing", IOobject::NO_WRITE
meshes_[proci].facesInstance(),
meshes_[proci].meshSubDir,
meshes_[proci],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
); );
faceProcAddressing_.set // pointProcAddressing (polyMesh)
( ioAddr.rename("pointProcAddressing");
proci, pointProcAddressing_.set(proci, new labelIOList(ioAddr));
new labelIOList
(
IOobject
(
"faceProcAddressing",
meshes_[proci].facesInstance(),
meshes_[proci].meshSubDir,
meshes_[proci],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
cellProcAddressing_.set // faceProcAddressing (polyMesh)
( ioAddr.rename("faceProcAddressing");
proci, faceProcAddressing_.set(proci, new labelIOList(ioAddr));
new labelIOList
(
IOobject
(
"cellProcAddressing",
meshes_[proci].facesInstance(),
meshes_[proci].meshSubDir,
meshes_[proci],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
boundaryProcAddressing_.set // cellProcAddressing (polyMesh)
( ioAddr.rename("cellProcAddressing");
proci, cellProcAddressing_.set(proci, new labelIOList(ioAddr));
new labelIOList
( // boundaryProcAddressing (polyMesh)
IOobject ioAddr.rename("boundaryProcAddressing");
( boundaryProcAddressing_.set(proci, new labelIOList(ioAddr));
"boundaryProcAddressing",
meshes_[proci].facesInstance(),
meshes_[proci].meshSubDir,
meshes_[proci],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
} }
} }
@ -163,17 +124,17 @@ Foam::processorMeshes::processorMeshes
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fvMesh::readUpdateState Foam::processorMeshes::readUpdate() Foam::polyMesh::readUpdateState Foam::processorMeshes::readUpdate()
{ {
fvMesh::readUpdateState stat = fvMesh::UNCHANGED; polyMesh::readUpdateState stat = polyMesh::UNCHANGED;
forAll(databases_, proci) forAll(databases_, proci)
{ {
// Check if any new meshes need to be read. // Check if any new meshes need to be read.
fvMesh::readUpdateState procStat = meshes_[proci].readUpdate(); polyMesh::readUpdateState procStat = meshes_[proci].readUpdate();
/* /*
if (procStat != fvMesh::UNCHANGED) if (procStat != polyMesh::UNCHANGED)
{ {
Info<< "Processor " << proci Info<< "Processor " << proci
<< " at time " << databases_[proci].timeName() << " at time " << databases_[proci].timeName()
@ -183,7 +144,7 @@ Foam::fvMesh::readUpdateState Foam::processorMeshes::readUpdate()
*/ */
// Combine into overall mesh change status // Combine into overall mesh change status
if (stat == fvMesh::UNCHANGED) if (stat == polyMesh::UNCHANGED)
{ {
stat = procStat; stat = procStat;
} }
@ -203,8 +164,8 @@ Foam::fvMesh::readUpdateState Foam::processorMeshes::readUpdate()
if if
( (
stat == fvMesh::TOPO_CHANGE stat == polyMesh::TOPO_CHANGE
|| stat == fvMesh::TOPO_PATCH_CHANGE || stat == polyMesh::TOPO_PATCH_CHANGE
) )
{ {
// Reread all meshes and addressing // Reread all meshes and addressing
@ -231,7 +192,7 @@ void Foam::processorMeshes::reconstructPoints(fvMesh& mesh)
"points", "points",
meshes_[proci].time().timeName(), meshes_[proci].time().timeName(),
polyMesh::meshSubDir, polyMesh::meshSubDir,
meshes_[proci], meshes_[proci].thisDb(),
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
false false
@ -247,23 +208,19 @@ void Foam::processorMeshes::reconstructPoints(fvMesh& mesh)
{ {
const vectorField& procPoints = procsPoints[proci]; const vectorField& procPoints = procsPoints[proci];
// Set the cell values in the reconstructed field const labelList& pointProcAddr = pointProcAddressing_[proci];
const labelList& pointProcAddressingI = pointProcAddressing_[proci]; if (pointProcAddr.size() != procPoints.size())
if (pointProcAddressingI.size() != procPoints.size())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "problem :" << "problem :"
<< " pointProcAddressingI:" << pointProcAddressingI.size() << " pointProcAddr:" << pointProcAddr.size()
<< " procPoints:" << procPoints.size() << " procPoints:" << procPoints.size()
<< abort(FatalError); << abort(FatalError);
} }
forAll(pointProcAddressingI, pointi) UIndirectList<point>(newPoints, pointProcAddr) = procPoints;
{ // or: newPoints.rmap(procPoints, pointProcAddr)
newPoints[pointProcAddressingI[pointi]] = procPoints[pointi];
}
} }
mesh.movePoints(newPoints); mesh.movePoints(newPoints);
@ -273,59 +230,35 @@ void Foam::processorMeshes::reconstructPoints(fvMesh& mesh)
void Foam::processorMeshes::removeFiles(const polyMesh& mesh) void Foam::processorMeshes::removeFiles(const polyMesh& mesh)
{ {
fileName pointPath IOobject ioAddr
( (
IOobject "procAddressing",
( mesh.facesInstance(),
"pointProcAddressing", polyMesh::meshSubDir,
mesh.facesInstance(), mesh.thisDb(),
mesh.meshSubDir, IOobject::NO_READ,
mesh IOobject::NO_WRITE,
).objectPath() false // not registered
); );
if (topoSet::debug) DebugVar(pointPath);
rm(pointPath);
rm // procAddressing
( rm(ioAddr.objectPath());
IOobject
( // pointProcAddressing
"faceProcAddressing", ioAddr.rename("pointProcAddressing");
mesh.facesInstance(), rm(ioAddr.objectPath());
mesh.meshSubDir,
mesh // faceProcAddressing
).objectPath() ioAddr.rename("faceProcAddressing");
); rm(ioAddr.objectPath());
rm
( // cellProcAddressing
IOobject ioAddr.rename("cellProcAddressing");
( rm(ioAddr.objectPath());
"cellProcAddressing",
mesh.facesInstance(), // boundaryProcAddressing
mesh.meshSubDir, ioAddr.rename("boundaryProcAddressing");
mesh rm(ioAddr.objectPath());
).objectPath()
);
rm
(
IOobject
(
"boundaryProcAddressing",
mesh.facesInstance(),
mesh.meshSubDir,
mesh
).objectPath()
);
rm
(
IOobject
(
"procAddressing",
mesh.facesInstance(),
mesh.meshSubDir,
mesh
).objectPath()
);
} }

View File

@ -35,8 +35,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef processorMeshes_H #ifndef Foam_processorMeshes_H
#define processorMeshes_H #define Foam_processorMeshes_H
#include "PtrList.H" #include "PtrList.H"
#include "fvMesh.H" #include "fvMesh.H"
@ -54,7 +54,7 @@ namespace Foam
class processorMeshes class processorMeshes
{ {
// Private data // Private Data
const word meshName_; const word meshName_;
@ -104,41 +104,42 @@ public:
// Member Functions // Member Functions
//- Update the meshes based on the mesh files saved in time directories //- Update the meshes based on the mesh files saved in time directories
fvMesh::readUpdateState readUpdate(); polyMesh::readUpdateState readUpdate();
//- Reconstruct point position after motion in parallel //- Reconstruct point position after motion in parallel
void reconstructPoints(fvMesh&); void reconstructPoints(fvMesh&);
const PtrList<fvMesh>& meshes() const const PtrList<fvMesh>& meshes() const noexcept
{ {
return meshes_; return meshes_;
} }
PtrList<fvMesh>& meshes() PtrList<fvMesh>& meshes() noexcept
{ {
return meshes_; return meshes_;
} }
const PtrList<labelIOList>& pointProcAddressing() const const PtrList<labelIOList>& pointProcAddressing() const noexcept
{ {
return pointProcAddressing_; return pointProcAddressing_;
} }
PtrList<labelIOList>& faceProcAddressing() PtrList<labelIOList>& faceProcAddressing() noexcept
{ {
return faceProcAddressing_; return faceProcAddressing_;
} }
const PtrList<labelIOList>& cellProcAddressing() const const PtrList<labelIOList>& cellProcAddressing() const noexcept
{ {
return cellProcAddressing_; return cellProcAddressing_;
} }
const PtrList<labelIOList>& boundaryProcAddressing() const const PtrList<labelIOList>& boundaryProcAddressing() const noexcept
{ {
return boundaryProcAddressing_; return boundaryProcAddressing_;
} }
//- Helper: remove all procAddressing files from mesh instance //- Helper: remove all procAddressing files from mesh instance
static void removeFiles(const polyMesh& mesh); static void removeFiles(const polyMesh& mesh);
}; };