Merge branch 'feature-redistributePar' into 'develop'

redistributePar support for point fields and area fields

See merge request Development/openfoam!538
This commit is contained in:
Andrew Heather
2022-05-25 13:13:03 +00:00
82 changed files with 9354 additions and 4336 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

@ -1,6 +1,13 @@
passivePositionParticleCloud.C passivePositionParticleCloud.C
parLagrangianRedistributor.C
parFvFieldReconstructor.C parLagrangianDistributor.C
parLagrangianDistributorFields.C
parPointFieldDistributor.C
parFaFieldDistributorCache.C
parFvFieldDistributor.C
parFvFieldDistributorFields.C
loadOrCreateMesh.C loadOrCreateMesh.C
redistributePar.C redistributePar.C

View File

@ -27,6 +27,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "loadOrCreateMesh.H" #include "loadOrCreateMesh.H"
#include "faMesh.H"
#include "Pstream.H" #include "Pstream.H"
#include "OSspecific.H" #include "OSspecific.H"
@ -66,6 +67,26 @@ Foam::boolList Foam::haveMeshFile
} }
void Foam::removeProcAddressing(const faMesh& mesh)
{
IOobject ioAddr
(
"procAddressing",
mesh.facesInstance(),
faMesh::meshSubDir,
mesh.thisDb()
);
for (const auto prefix : {"boundary", "edge", "face", "point"})
{
ioAddr.rename(prefix + word("ProcAddressing"));
const fileName procFile(ioAddr.objectPath());
Foam::rm(procFile);
}
}
void Foam::removeProcAddressing(const polyMesh& mesh) void Foam::removeProcAddressing(const polyMesh& mesh)
{ {
IOobject ioAddr IOobject ioAddr

View File

@ -45,6 +45,9 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward Declarations
class faMesh;
//- Check for availability of specified mesh file (default: "faces") //- Check for availability of specified mesh file (default: "faces")
boolList haveMeshFile boolList haveMeshFile
( (
@ -55,6 +58,9 @@ boolList haveMeshFile
); );
//- Remove procAddressing
void removeProcAddressing(const faMesh& mesh);
//- Remove procAddressing //- Remove procAddressing
void removeProcAddressing(const polyMesh& mesh); void removeProcAddressing(const polyMesh& mesh);

View File

@ -0,0 +1,164 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "parFaFieldDistributorCache.H"
#include "areaFields.H"
#include "edgeFields.H"
#include "fieldsDistributor.H"
#include "faMeshDistributor.H"
#include "faMeshSubset.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class GeoField>
void Foam::parFaFieldDistributorCache::redistributeAndWrite
(
const faMeshDistributor& distributor,
PtrList<GeoField>& fields,
const bool isWriteProc
)
{
for (GeoField& fld : fields)
{
tmp<GeoField> tfld = distributor.distributeField(fld);
if (isWriteProc)
{
tfld().write();
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::parFaFieldDistributorCache::read
(
const Time& baseRunTime,
const fileName& proc0CaseName,
const bool decompose, // i.e. read from undecomposed case
const boolList& areaMeshOnProc,
const fileName& areaMeshInstance,
faMesh& mesh
)
{
Time& runTime = const_cast<Time&>(mesh.time());
const bool oldProcCase = runTime.processorCase();
autoPtr<faMeshSubset> subsetterPtr;
// Missing an area mesh somewhere?
if (areaMeshOnProc.found(false))
{
// A zero-sized mesh with boundaries.
// This is used to create zero-sized fields.
subsetterPtr.reset(new faMeshSubset(mesh, zero{}));
// Deregister from polyMesh ...
auto& obr = const_cast<objectRegistry&>
(
subsetterPtr->subMesh().thisDb()
);
obr.checkOut(faMesh::typeName);
obr.checkOut("faBoundaryMesh");
obr.checkOut("faSchemes");
obr.checkOut("faSolution");
}
// Get original objects (before incrementing time!)
if (Pstream::master() && decompose)
{
runTime.caseName() = baseRunTime.caseName();
runTime.processorCase(false);
}
IOobjectList objects(mesh.mesh(), runTime.timeName());
if (Pstream::master() && decompose)
{
runTime.caseName() = proc0CaseName;
runTime.processorCase(oldProcCase);
}
Info<< "From time " << runTime.timeName()
<< " mesh:" << mesh.mesh().objectRegistry::objectRelPath()
<< " have objects:" << objects.names() << endl;
if (Pstream::master() && decompose)
{
runTime.caseName() = baseRunTime.caseName();
runTime.processorCase(false);
}
#undef doFieldReading
#define doFieldReading(Storage) \
fieldsDistributor::readFields \
( \
areaMeshOnProc, mesh, subsetterPtr, objects, Storage, \
true /* (deregister field) */ \
);
// areaFields
doFieldReading(scalarAreaFields_);
doFieldReading(vectorAreaFields_);
doFieldReading(sphericalTensorAreaFields_);
doFieldReading(symmTensorAreaFields_);
doFieldReading(tensorAreaFields_);
// edgeFields
doFieldReading(scalarEdgeFields_);
doFieldReading(vectorEdgeFields_);
doFieldReading(tensorEdgeFields_);
doFieldReading(sphericalTensorEdgeFields_);
doFieldReading(symmTensorEdgeFields_);
#undef doFieldReading
}
void Foam::parFaFieldDistributorCache::redistributeAndWrite
(
const faMeshDistributor& distributor,
const bool isWriteProc
)
{
redistributeAndWrite(distributor, scalarAreaFields_, isWriteProc);
redistributeAndWrite(distributor, vectorAreaFields_, isWriteProc);
redistributeAndWrite(distributor, sphericalTensorAreaFields_, isWriteProc);
redistributeAndWrite(distributor, symmTensorAreaFields_, isWriteProc);
redistributeAndWrite(distributor, tensorAreaFields_, isWriteProc);
redistributeAndWrite(distributor, scalarEdgeFields_, isWriteProc);
redistributeAndWrite(distributor, vectorEdgeFields_, isWriteProc);
redistributeAndWrite(distributor, sphericalTensorEdgeFields_, isWriteProc);
redistributeAndWrite(distributor, symmTensorEdgeFields_, isWriteProc);
redistributeAndWrite(distributor, tensorEdgeFields_, isWriteProc);
}
// ************************************************************************* //

View File

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::parFaFieldDistributorCache
Description
Simple container to manage read/write, redistribute finiteArea fields.
SourceFiles
parFaFieldDistributorCache.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_parFaFieldDistributorCache_H
#define Foam_parFaFieldDistributorCache_H
#include "faMesh.H"
#include "faMeshDistributor.H"
#include "areaFieldsFwd.H"
#include "edgeFieldsFwd.H"
#include "PtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class parFaFieldDistributorCache Declaration
\*---------------------------------------------------------------------------*/
class parFaFieldDistributorCache
{
// Private Data
#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
// Private Member Functions
//- Redistribute and write fields of given type (file-scope use)
template<class GeoField>
static void redistributeAndWrite
(
const faMeshDistributor& distributor,
PtrList<GeoField>& fields,
const bool isWriteProc
);
public:
// Constructors
//- No copy construct
parFaFieldDistributorCache(const parFaFieldDistributorCache&) = delete;
//- No copy assignment
void operator=(const parFaFieldDistributorCache&) = delete;
//- Default construct
parFaFieldDistributorCache() = default;
// Member Functions
//- Read distributed fields
void read
(
const Time& baseRunTime,
const fileName& proc0CaseName,
const bool decompose, // i.e. read from undecomposed case
const boolList& areaMeshOnProc,
const fileName& areaMeshInstance,
faMesh& mesh
);
void redistributeAndWrite
(
const faMeshDistributor& distributor,
const bool isWriteProc
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation Copyright (C) 2015 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,48 +26,47 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "parFvFieldReconstructor.H" #include "parFvFieldDistributor.H"
#include "bitSet.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::parFvFieldDistributor::verbose_ = 1;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::parFvFieldReconstructor::createPatchFaceMaps() void Foam::parFvFieldDistributor::createPatchFaceMaps()
{ {
const fvBoundaryMesh& fvb = procMesh_.boundary(); const fvBoundaryMesh& fvb = srcMesh_.boundary();
patchFaceMaps_.setSize(fvb.size()); patchFaceMaps_.resize(fvb.size());
forAll(fvb, patchI)
forAll(fvb, patchi)
{ {
if (!isA<processorFvPatch>(fvb[patchI])) if (!isA<processorFvPatch>(fvb[patchi]))
{ {
// Create map for patch faces only // Create compact map for patch faces only
// - compact for used faces only (destination patch faces)
// Mark all used elements (i.e. destination patch faces) labelList oldToNewSub;
boolList faceIsUsed(distMap_.faceMap().constructSize(), false); labelList oldToNewConstruct;
const polyPatch& basePatch = baseMesh_.boundaryMesh()[patchI];
forAll(basePatch, i)
{
faceIsUsed[basePatch.start()+i] = true;
}
// Copy face map // Copy face map
patchFaceMaps_.set patchFaceMaps_.set
( (
patchI, patchi,
new mapDistributeBase(distMap_.faceMap()) new mapDistributeBase(distMap_.faceMap())
); );
// Compact out unused elements patchFaceMaps_[patchi].compactRemoteData
labelList oldToNewSub;
labelList oldToNewConstruct;
patchFaceMaps_[patchI].compact
( (
faceIsUsed, bitSet(tgtMesh_.boundaryMesh()[patchi].range()),
procMesh_.nFaces(), // maximum index of subMap
oldToNewSub, oldToNewSub,
oldToNewConstruct, oldToNewConstruct,
srcMesh_.nFaces(), // max index of subMap
UPstream::msgType() UPstream::msgType()
); );
//Pout<< "patchMap:" << patchFaceMaps_[patchI] << endl; //Pout<< "patchMap:" << patchFaceMaps_[patchi] << endl;
} }
} }
} }
@ -74,16 +74,16 @@ void Foam::parFvFieldReconstructor::createPatchFaceMaps()
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::parFvFieldReconstructor::parFvFieldReconstructor Foam::parFvFieldDistributor::parFvFieldDistributor
( (
fvMesh& baseMesh, const fvMesh& srcMesh,
const fvMesh& procMesh, fvMesh& tgtMesh,
const mapDistributePolyMesh& distMap, const mapDistributePolyMesh& distMap,
const bool isWriteProc const bool isWriteProc
) )
: :
baseMesh_(baseMesh), srcMesh_(srcMesh),
procMesh_(procMesh), tgtMesh_(tgtMesh),
distMap_(distMap), distMap_(distMap),
isWriteProc_(isWriteProc) isWriteProc_(isWriteProc)
{ {
@ -93,7 +93,7 @@ Foam::parFvFieldReconstructor::parFvFieldReconstructor
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::parFvFieldReconstructor::reconstructPoints() void Foam::parFvFieldDistributor::reconstructPoints()
{ {
// Reconstruct the points for moving mesh cases and write them out // Reconstruct the points for moving mesh cases and write them out
distributedFieldMapper mapper distributedFieldMapper mapper
@ -101,11 +101,13 @@ void Foam::parFvFieldReconstructor::reconstructPoints()
labelUList::null(), labelUList::null(),
distMap_.pointMap() distMap_.pointMap()
); );
pointField basePoints(procMesh_.points(), mapper);
baseMesh_.movePoints(basePoints); pointField newPoints(srcMesh_.points(), mapper);
tgtMesh_.movePoints(newPoints);
if (Pstream::master()) if (Pstream::master())
{ {
baseMesh_.write(); tgtMesh_.write();
} }
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation Copyright (C) 2015 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.
@ -25,22 +25,24 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class Class
Foam::parFvFieldReconstructor Foam::parFvFieldDistributor
Description Description
Finite volume reconstructor for volume and surface fields. Finite volume reconstructor for volume and surface fields.
Runs in parallel. Reconstructs from procMesh to baseMesh. baseMesh Runs in parallel.
is non-zero cells on processor0 only. Reconstructs/redistributes from procMesh to baseMesh.
baseMesh is non-zero cells on processor0 only.
SourceFiles SourceFiles
parFvFieldReconstructor.C parFvFieldDistributor.C
parFvFieldReconstructorFields.C parFvFieldDistributorFields.C
parFvFieldDistributorTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef parFvFieldReconstructor_H #ifndef Foam_parFvFieldDistributor_H
#define parFvFieldReconstructor_H #define Foam_parFvFieldDistributor_H
#include "PtrList.H" #include "PtrList.H"
#include "fvMesh.H" #include "fvMesh.H"
@ -50,34 +52,34 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
class mapDistributePolyMesh; class mapDistributePolyMesh;
class mapDistributeBase; class mapDistributeBase;
class IOobjectList; class IOobjectList;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class parFvFieldReconstructor Declaration Class parFvFieldDistributor Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class parFvFieldReconstructor class parFvFieldDistributor
{ {
// Private data // Private Data
//- Reconstructed mesh reference //- Processor mesh reference (source mesh)
fvMesh& baseMesh_; const fvMesh& srcMesh_;
//- Processor mesh reference //- Destination mesh reference (eg, reconstructed mesh)
const fvMesh& procMesh_; fvMesh& tgtMesh_;
//- Distribution map reference //- Distribution map reference
const mapDistributePolyMesh& distMap_; const mapDistributePolyMesh& distMap_;
//- Do I need to to write (usually master only)
const bool isWriteProc_;
//- Patch mappers //- Patch mappers
PtrList<mapDistributeBase> patchFaceMaps_; PtrList<mapDistributeBase> patchFaceMaps_;
//- Do I need to write (eg, master only for reconstruct)
bool isWriteProc_;
// Private Member Functions // Private Member Functions
@ -85,21 +87,30 @@ class parFvFieldReconstructor
void createPatchFaceMaps(); void createPatchFaceMaps();
//- No copy construct //- No copy construct
parFvFieldReconstructor(const parFvFieldReconstructor&) = delete; parFvFieldDistributor(const parFvFieldDistributor&) = delete;
//- No copy assignment //- No copy assignment
void operator=(const parFvFieldReconstructor&) = delete; void operator=(const parFvFieldDistributor&) = delete;
public: public:
//- Output verbosity when writing
static int verbose_;
// Constructors // Constructors
//- Construct from components //- Construct from components
parFvFieldReconstructor //
// \param srcMesh The source mesh (eg, processor)
// \param tgtMesh The target mesh (eg, reconstructed)
// \param distMap The distribution map
// \param isWriteProc Tagged for output writing (on this proc)
parFvFieldDistributor
( (
fvMesh& baseMesh, const fvMesh& srcMesh,
const fvMesh& procMesh, fvMesh& tgtMesh,
const mapDistributePolyMesh& distMap, const mapDistributePolyMesh& distMap,
const bool isWriteProc const bool isWriteProc
); );
@ -107,61 +118,85 @@ public:
// Member Functions // Member Functions
//- Reconstruct volume internal field //- Get status of write enabled (on this proc)
bool isWriteProc() const noexcept
{
return isWriteProc_;
}
//- Change status of write enabled (on this proc)
bool isWriteProc(const bool on) noexcept
{
bool old(isWriteProc_);
isWriteProc_ = on;
return old;
}
//- Helper: reconstruct and write mesh points
// (note: should be moved to something like processorMeshes class)
void reconstructPoints();
//- Distribute all fields for known field types
void distributeAllFields
(
const IOobjectList& objects,
const wordRes& selectedFields
) const;
//- Redistribute volume internal field
template<class Type> template<class Type>
tmp<DimensionedField<Type, volMesh>> tmp<DimensionedField<Type, volMesh>>
reconstructFvVolumeInternalField distributeField
( (
const DimensionedField<Type, volMesh>& const DimensionedField<Type, volMesh>&
) const; ) const;
//- Read and reconstruct volume internal field //- Read and distribute volume internal field
template<class Type> template<class Type>
tmp<DimensionedField<Type, volMesh>> tmp<DimensionedField<Type, volMesh>>
reconstructFvVolumeInternalField(const IOobject& fieldIoObject) const; distributeInternalField(const IOobject& fieldObject) const;
//- Redistribute volume field
//- Reconstruct volume field
template<class Type> template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>> tmp<GeometricField<Type, fvPatchField, volMesh>>
reconstructFvVolumeField distributeField
( (
const GeometricField<Type, fvPatchField, volMesh>& fld const GeometricField<Type, fvPatchField, volMesh>& fld
) const; ) const;
//- Read and reconstruct volume field //- Read and distribute volume field
template<class Type> template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>> tmp<GeometricField<Type, fvPatchField, volMesh>>
reconstructFvVolumeField(const IOobject& fieldIoObject) const; distributeVolumeField(const IOobject& fieldObject) const;
//- Redistribute surface field
//- Reconstruct surface field
template<class Type> template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
reconstructFvSurfaceField distributeField
( (
const GeometricField<Type, fvsPatchField, surfaceMesh>& const GeometricField<Type, fvsPatchField, surfaceMesh>&
) const; ) const;
//- Read and reconstruct surface field //- Read and distribute surface field
template<class Type> template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
reconstructFvSurfaceField(const IOobject& fieldIoObject) const; distributeSurfaceField(const IOobject& fieldObject) const;
//- Read, reconstruct and write all/selected volume internal fields //- Read, redistribute and write all/selected volume internal fields
template<class Type> template<class Type>
label reconstructFvVolumeInternalFields label distributeInternalFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
) const; ) const;
//- Read, reconstruct and write all/selected volume fields //- Read, redistribute and write all/selected volume fields
template<class Type> template<class Type>
label reconstructFvVolumeFields label distributeVolumeFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
@ -169,15 +204,11 @@ public:
//- Read, reconstruct and write all/selected surface fields //- Read, reconstruct and write all/selected surface fields
template<class Type> template<class Type>
label reconstructFvSurfaceFields label distributeSurfaceFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
) const; ) const;
//- Helper: reconstruct and write mesh points
// (note: should be moved to something like processorMeshes class)
void reconstructPoints();
}; };
@ -188,7 +219,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
# include "parFvFieldReconstructorFields.C" # include "parFvFieldDistributorTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

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,55 +23,40 @@ 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
readFields
Description
SourceFiles
readFields.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef readFields_H #include "parFvFieldDistributor.H"
#define readFields_H #include "volFields.H"
#include "surfaceFields.H"
#include "IOobjectList.H" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
#include "PtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void Foam::parFvFieldDistributor::distributeAllFields
(
namespace Foam const IOobjectList& objects,
const wordRes& selectedFields
) const
{ {
// Read the fields and hold on the pointer list do
template<class Type, template<class> class PatchField, class GeoMesh> {
void readFields #undef doLocalCode
( #define doLocalCode(Method) \
const typename GeoMesh::Mesh& mesh, { \
const IOobjectList& objects, this->Method <scalar> (objects, selectedFields); \
PtrList<GeometricField<Type, PatchField, GeoMesh>>& fields, this->Method <vector> (objects, selectedFields); \
const bool readOldTime this->Method <sphericalTensor> (objects, selectedFields); \
); this->Method <symmTensor> (objects, selectedFields); \
this->Method <tensor> (objects, selectedFields); \
}
// Read the fields and hold on the pointer list doLocalCode(distributeInternalFields);
template<class Mesh, class GeoField> doLocalCode(distributeVolumeFields);
void readFields doLocalCode(distributeSurfaceFields);
(
const Mesh& mesh, #undef doLocalCode
const IOobjectList& objects, }
PtrList<GeoField>& fields while (false);
);
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "readFields.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -26,7 +26,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "parFvFieldReconstructor.H" #include "parFvFieldDistributor.H"
#include "Time.H" #include "Time.H"
#include "PtrList.H" #include "PtrList.H"
#include "fvPatchFields.H" #include "fvPatchFields.H"
@ -44,36 +44,33 @@ License
template<class Type> template<class Type>
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>> Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
Foam::parFvFieldReconstructor::reconstructFvVolumeInternalField Foam::parFvFieldDistributor::distributeField
( (
const DimensionedField<Type, volMesh>& fld const DimensionedField<Type, volMesh>& fld
) const ) const
{ {
// Create internalField by remote mapping
distributedFieldMapper mapper distributedFieldMapper mapper
( (
labelUList::null(), labelUList::null(),
distMap_.cellMap() distMap_.cellMap()
); );
Field<Type> internalField(fld, mapper);
// Construct a volField
IOobject baseIO
(
fld.name(),
baseMesh_.time().timeName(),
fld.local(),
baseMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
);
auto tfield = tmp<DimensionedField<Type, volMesh>>::New auto tfield = tmp<DimensionedField<Type, volMesh>>::New
( (
baseIO, IOobject
baseMesh_, (
fld.name(),
tgtMesh_.time().timeName(),
fld.local(),
tgtMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
tgtMesh_,
fld.dimensions(), fld.dimensions(),
internalField Field<Type>(fld, mapper)
); );
tfield.ref().oriented() = fld.oriented(); tfield.ref().oriented() = fld.oriented();
@ -82,98 +79,86 @@ Foam::parFvFieldReconstructor::reconstructFvVolumeInternalField
} }
template<class Type>
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
Foam::parFvFieldReconstructor::reconstructFvVolumeInternalField
(
const IOobject& fieldIoObject
) const
{
// Read the field
DimensionedField<Type, volMesh> fld
(
fieldIoObject,
procMesh_
);
// Distribute onto baseMesh
return reconstructFvVolumeInternalField(fld);
}
// Reconstruct a field onto the baseMesh
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::parFvFieldReconstructor::reconstructFvVolumeField Foam::parFvFieldDistributor::distributeField
( (
const GeometricField<Type, fvPatchField, volMesh>& fld const GeometricField<Type, fvPatchField, volMesh>& fld
) const ) const
{ {
// Create the internalField by remote mapping // Create internalField by remote mapping
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
distributedFieldMapper mapper distributedFieldMapper mapper
( (
labelUList::null(), labelUList::null(),
distMap_.cellMap() distMap_.cellMap()
); );
Field<Type> internalField(fld.internalField(), mapper); DimensionedField<Type, volMesh> internalField
(
IOobject
(
fld.name(),
tgtMesh_.time().timeName(),
fld.local(),
tgtMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
tgtMesh_,
fld.dimensions(),
Field<Type>(fld.internalField(), mapper)
);
internalField.oriented() = fld.oriented();
// Create patchFields by remote mapping
// Note: patchFields still on source mesh, not target mesh
// Create the patchFields by remote mapping PtrList<fvPatchField<Type>> oldPatchFields(fld.mesh().boundary().size());
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Note: patchFields still on mesh, not baseMesh
PtrList<fvPatchField<Type>> patchFields(fld.mesh().boundary().size());
const auto& bfld = fld.boundaryField(); const auto& bfld = fld.boundaryField();
forAll(bfld, patchI) forAll(bfld, patchi)
{ {
if (patchFaceMaps_.set(patchI)) if (patchFaceMaps_.set(patchi))
{ {
// Clone local patch field // Clone local patch field
patchFields.set(patchI, bfld[patchI].clone()); oldPatchFields.set(patchi, bfld[patchi].clone());
distributedFvPatchFieldMapper mapper distributedFvPatchFieldMapper mapper
( (
labelUList::null(), labelUList::null(),
patchFaceMaps_[patchI] patchFaceMaps_[patchi]
); );
// Map into local copy // Map into local copy
patchFields[patchI].autoMap(mapper); oldPatchFields[patchi].autoMap(mapper);
} }
} }
PtrList<fvPatchField<Type>> basePatchFields // Clone the oldPatchFields onto the target patches. This is just to reset
(
baseMesh_.boundary().size()
);
// Clone the patchFields onto the base patches. This is just to reset
// the reference to the patch, size and content stay the same. // the reference to the patch, size and content stay the same.
forAll(patchFields, patchI)
{
if (patchFields.set(patchI))
{
const fvPatch& basePatch = baseMesh_.boundary()[patchI];
const fvPatchField<Type>& pfld = patchFields[patchI]; PtrList<fvPatchField<Type>> newPatchFields(tgtMesh_.boundary().size());
forAll(oldPatchFields, patchi)
{
if (oldPatchFields.set(patchi))
{
const auto& pfld = oldPatchFields[patchi];
labelList dummyMap(identity(pfld.size())); labelList dummyMap(identity(pfld.size()));
directFvPatchFieldMapper dummyMapper(dummyMap); directFvPatchFieldMapper dummyMapper(dummyMap);
basePatchFields.set newPatchFields.set
( (
patchI, patchi,
fvPatchField<Type>::New fvPatchField<Type>::New
( (
pfld, pfld,
basePatch, tgtMesh_.boundary()[patchi],
DimensionedField<Type, volMesh>::null(), DimensionedField<Type, volMesh>::null(),
dummyMapper dummyMapper
) )
@ -181,162 +166,143 @@ Foam::parFvFieldReconstructor::reconstructFvVolumeField
} }
} }
// Add some empty patches on remaining patches (tbd.probably processor // Add some empty patches on remaining patches
// patches) // (... probably processor patches)
forAll(basePatchFields, patchI)
forAll(newPatchFields, patchi)
{ {
if (patchI >= patchFields.size() || !patchFields.set(patchI)) if (!newPatchFields.set(patchi))
{ {
basePatchFields.set newPatchFields.set
( (
patchI, patchi,
fvPatchField<Type>::New fvPatchField<Type>::New
( (
emptyFvPatchField<Type>::typeName, emptyFvPatchField<Type>::typeName,
baseMesh_.boundary()[patchI], tgtMesh_.boundary()[patchi],
DimensionedField<Type, volMesh>::null() DimensionedField<Type, volMesh>::null()
) )
); );
} }
} }
// Construct a volField // Return geometric field
IOobject baseIO
return tmp<GeometricField<Type, fvPatchField, volMesh>>::New
( (
fld.name(), std::move(internalField),
baseMesh_.time().timeName(), newPatchFields
fld.local(),
baseMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
); );
auto tfield = tmp<GeometricField<Type, fvPatchField, volMesh>>::New
(
baseIO,
baseMesh_,
fld.dimensions(),
internalField,
basePatchFields
);
tfield.ref().oriented()= fld.oriented();
return tfield;
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
Foam::parFvFieldReconstructor::reconstructFvVolumeField
(
const IOobject& fieldIoObject
) const
{
// Read the field
GeometricField<Type, fvPatchField, volMesh> fld
(
fieldIoObject,
procMesh_
);
// Distribute onto baseMesh
return reconstructFvVolumeField(fld);
} }
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::parFvFieldReconstructor::reconstructFvSurfaceField Foam::parFvFieldDistributor::distributeField
( (
const GeometricField<Type, fvsPatchField, surfaceMesh>& fld const GeometricField<Type, fvsPatchField, surfaceMesh>& fld
) const ) const
{ {
// Create the internalField by remote mapping // Create internalField by remote mapping
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
distributedFieldMapper mapper distributedFieldMapper mapper
( (
labelUList::null(), labelUList::null(),
distMap_.faceMap() distMap_.faceMap()
); );
// Create flat field of internalField + all patch fields
Field<Type> flatFld(fld.mesh().nFaces(), Type(Zero));
SubList<Type>(flatFld, fld.internalField().size()) = fld.internalField();
forAll(fld.boundaryField(), patchI)
{
const fvsPatchField<Type>& fvp = fld.boundaryField()[patchI];
SubList<Type>(flatFld, fvp.size(), fvp.patch().start()) = fvp; Field<Type> primitiveField;
{
// Create flat field of internalField + all patch fields
Field<Type> flatFld(fld.mesh().nFaces(), Type(Zero));
SubList<Type>(flatFld, fld.internalField().size())
= fld.internalField();
for (const fvsPatchField<Type>& fvp : fld.boundaryField())
{
SubList<Type>(flatFld, fvp.size(), fvp.patch().start()) = fvp;
}
// Map all faces
primitiveField = Field<Type>(flatFld, mapper, fld.oriented()());
// Trim to internal faces (note: could also have special mapper)
primitiveField.resize
(
min
(
primitiveField.size(),
tgtMesh_.nInternalFaces()
)
);
} }
// Map all faces
Field<Type> internalField(flatFld, mapper, fld.oriented()());
// Trim to internal faces (note: could also have special mapper) DimensionedField<Type, surfaceMesh> internalField
internalField.setSize
( (
min IOobject
( (
internalField.size(), fld.name(),
baseMesh_.nInternalFaces() tgtMesh_.time().timeName(),
) fld.local(),
tgtMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
tgtMesh_,
fld.dimensions(),
std::move(primitiveField)
); );
internalField.oriented() = fld.oriented();
// Create the patchFields by remote mapping
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Note: patchFields still on mesh, not baseMesh
PtrList<fvsPatchField<Type>> patchFields(fld.mesh().boundary().size()); // Create patchFields by remote mapping
// Note: patchFields still on source mesh, not target mesh
PtrList<fvsPatchField<Type>> oldPatchFields(fld.mesh().boundary().size());
const auto& bfld = fld.boundaryField(); const auto& bfld = fld.boundaryField();
forAll(bfld, patchI) forAll(bfld, patchi)
{ {
if (patchFaceMaps_.set(patchI)) if (patchFaceMaps_.set(patchi))
{ {
// Clone local patch field // Clone local patch field
patchFields.set(patchI, bfld[patchI].clone()); oldPatchFields.set(patchi, bfld[patchi].clone());
distributedFvPatchFieldMapper mapper distributedFvPatchFieldMapper mapper
( (
labelUList::null(), labelUList::null(),
patchFaceMaps_[patchI] patchFaceMaps_[patchi]
); );
// Map into local copy // Map into local copy
patchFields[patchI].autoMap(mapper); oldPatchFields[patchi].autoMap(mapper);
} }
} }
PtrList<fvsPatchField<Type>> basePatchFields PtrList<fvsPatchField<Type>> newPatchFields(tgtMesh_.boundary().size());
(
baseMesh_.boundary().size()
);
// Clone the patchFields onto the base patches. This is just to reset // Clone the patchFields onto the base patches. This is just to reset
// the reference to the patch, size and content stay the same. // the reference to the patch, size and content stay the same.
forAll(patchFields, patchI) forAll(oldPatchFields, patchi)
{ {
if (patchFields.set(patchI)) if (oldPatchFields.set(patchi))
{ {
const fvPatch& basePatch = baseMesh_.boundary()[patchI]; const fvsPatchField<Type>& pfld = oldPatchFields[patchi];
const fvsPatchField<Type>& pfld = patchFields[patchI];
labelList dummyMap(identity(pfld.size())); labelList dummyMap(identity(pfld.size()));
directFvPatchFieldMapper dummyMapper(dummyMap); directFvPatchFieldMapper dummyMapper(dummyMap);
basePatchFields.set newPatchFields.set
( (
patchI, patchi,
fvsPatchField<Type>::New fvsPatchField<Type>::New
( (
pfld, pfld,
basePatch, tgtMesh_.boundary()[patchi],
DimensionedField<Type, surfaceMesh>::null(), DimensionedField<Type, surfaceMesh>::null(),
dummyMapper dummyMapper
) )
@ -344,71 +310,94 @@ Foam::parFvFieldReconstructor::reconstructFvSurfaceField
} }
} }
// Add some empty patches on remaining patches (tbd.probably processor // Add some empty patches on remaining patches
// patches) // (... probably processor patches)
forAll(basePatchFields, patchI) forAll(newPatchFields, patchi)
{ {
if (patchI >= patchFields.size() || !patchFields.set(patchI)) if (!newPatchFields.set(patchi))
{ {
basePatchFields.set newPatchFields.set
( (
patchI, patchi,
fvsPatchField<Type>::New fvsPatchField<Type>::New
( (
emptyFvsPatchField<Type>::typeName, emptyFvsPatchField<Type>::typeName,
baseMesh_.boundary()[patchI], tgtMesh_.boundary()[patchi],
DimensionedField<Type, surfaceMesh>::null() DimensionedField<Type, surfaceMesh>::null()
) )
); );
} }
} }
// Construct a volField
IOobject baseIO // Return geometric field
return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>::New
( (
fld.name(), std::move(internalField),
baseMesh_.time().timeName(), newPatchFields
fld.local(), );
baseMesh_, }
IOobject::NO_READ,
IOobject::NO_WRITE
template<class Type>
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
Foam::parFvFieldDistributor::distributeInternalField
(
const IOobject& fieldObject
) const
{
// Read field
DimensionedField<Type, volMesh> fld
(
fieldObject,
srcMesh_
); );
auto tfield = tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>::New // Distribute
return distributeField(fld);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
Foam::parFvFieldDistributor::distributeVolumeField
(
const IOobject& fieldObject
) const
{
// Read field
GeometricField<Type, fvPatchField, volMesh> fld
( (
baseIO, fieldObject,
baseMesh_, srcMesh_
fld.dimensions(),
internalField,
basePatchFields
); );
tfield.ref().oriented() = fld.oriented(); // Distribute
return distributeField(fld);
return tfield;
} }
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::parFvFieldReconstructor::reconstructFvSurfaceField Foam::parFvFieldDistributor::distributeSurfaceField
( (
const IOobject& fieldIoObject const IOobject& fieldObject
) const ) const
{ {
// Read the field // Read field
GeometricField<Type, fvsPatchField, surfaceMesh> fld GeometricField<Type, fvsPatchField, surfaceMesh> fld
( (
fieldIoObject, fieldObject,
procMesh_ srcMesh_
); );
return reconstructFvSurfaceField(fld); // Distribute
return distributeField(fld);
} }
template<class Type> template<class Type>
Foam::label Foam::parFvFieldReconstructor::reconstructFvVolumeInternalFields Foam::label Foam::parFvFieldDistributor::distributeInternalFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields const wordRes& selectedFields
@ -427,17 +416,25 @@ Foam::label Foam::parFvFieldReconstructor::reconstructFvVolumeInternalFields
label nFields = 0; label nFields = 0;
for (const word& fieldName : fieldNames) for (const word& fieldName : fieldNames)
{ {
if (!nFields++) if ("cellDist" == fieldName)
{ {
Info<< " Reconstructing " // There is an odd chance this is an internal field
<< fieldType::typeName << "s\n" << nl; continue;
} }
if (verbose_)
Info<< " " << fieldName << nl; {
if (!nFields)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << fieldName << nl;
}
++nFields;
tmp<fieldType> tfld tmp<fieldType> tfld
( (
reconstructFvVolumeInternalField<Type>(*(objects[fieldName])) distributeInternalField<Type>(*(objects[fieldName]))
); );
if (isWriteProc_) if (isWriteProc_)
{ {
@ -445,13 +442,13 @@ Foam::label Foam::parFvFieldReconstructor::reconstructFvVolumeInternalFields
} }
} }
if (nFields) Info<< endl; if (nFields && verbose_) Info<< endl;
return nFields; return nFields;
} }
template<class Type> template<class Type>
Foam::label Foam::parFvFieldReconstructor::reconstructFvVolumeFields Foam::label Foam::parFvFieldDistributor::distributeVolumeFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields const wordRes& selectedFields
@ -474,16 +471,20 @@ Foam::label Foam::parFvFieldReconstructor::reconstructFvVolumeFields
{ {
continue; continue;
} }
if (!nFields++) if (verbose_)
{ {
Info<< " Reconstructing " if (!nFields)
<< fieldType::typeName << "s\n" << nl; {
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << fieldName << nl;
} }
Info<< " " << fieldName << nl; ++nFields;
tmp<fieldType> tfld tmp<fieldType> tfld
( (
reconstructFvVolumeField<Type>(*(objects[fieldName])) distributeVolumeField<Type>(*(objects[fieldName]))
); );
if (isWriteProc_) if (isWriteProc_)
{ {
@ -491,13 +492,13 @@ Foam::label Foam::parFvFieldReconstructor::reconstructFvVolumeFields
} }
} }
if (nFields) Info<< endl; if (nFields && verbose_) Info<< endl;
return nFields; return nFields;
} }
template<class Type> template<class Type>
Foam::label Foam::parFvFieldReconstructor::reconstructFvSurfaceFields Foam::label Foam::parFvFieldDistributor::distributeSurfaceFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields const wordRes& selectedFields
@ -516,16 +517,20 @@ Foam::label Foam::parFvFieldReconstructor::reconstructFvSurfaceFields
label nFields = 0; label nFields = 0;
for (const word& fieldName : fieldNames) for (const word& fieldName : fieldNames)
{ {
if (!nFields++) if (verbose_)
{ {
Info<< " Reconstructing " if (!nFields)
<< fieldType::typeName << "s\n" << nl; {
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << fieldName << nl;
} }
Info<< " " << fieldName << nl; ++nFields;
tmp<fieldType> tfld tmp<fieldType> tfld
( (
reconstructFvSurfaceField<Type>(*(objects[fieldName])) distributeSurfaceField<Type>(*(objects[fieldName]))
); );
if (isWriteProc_) if (isWriteProc_)
{ {
@ -533,7 +538,7 @@ Foam::label Foam::parFvFieldReconstructor::reconstructFvSurfaceFields
} }
} }
if (nFields) Info<< endl; if (nFields && verbose_) Info<< endl;
return nFields; return nFields;
} }

View File

@ -27,12 +27,12 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "ListOps.H" #include "ListOps.H"
#include "parLagrangianRedistributor.H" #include "parLagrangianDistributor.H"
#include "passivePositionParticleCloud.H" #include "passivePositionParticleCloud.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::parLagrangianRedistributor::parLagrangianRedistributor Foam::parLagrangianDistributor::parLagrangianDistributor
( (
const fvMesh& srcMesh, const fvMesh& srcMesh,
const fvMesh& tgtMesh, const fvMesh& tgtMesh,
@ -59,7 +59,7 @@ Foam::parLagrangianRedistributor::parLagrangianRedistributor
// Find all clouds (on all processors) and for each cloud all the objects. // Find all clouds (on all processors) and for each cloud all the objects.
// Result will be synchronised on all processors // Result will be synchronised on all processors
void Foam::parLagrangianRedistributor::findClouds void Foam::parLagrangianDistributor::findClouds
( (
const fvMesh& mesh, const fvMesh& mesh,
wordList& cloudNames, wordList& cloudNames,
@ -129,7 +129,7 @@ void Foam::parLagrangianRedistributor::findClouds
Foam::autoPtr<Foam::mapDistributeBase> Foam::autoPtr<Foam::mapDistributeBase>
Foam::parLagrangianRedistributor::redistributeLagrangianPositions Foam::parLagrangianDistributor::distributeLagrangianPositions
( (
passivePositionParticleCloud& lpi passivePositionParticleCloud& lpi
) const ) const
@ -314,7 +314,7 @@ Foam::parLagrangianRedistributor::redistributeLagrangianPositions
Foam::autoPtr<Foam::mapDistributeBase> Foam::autoPtr<Foam::mapDistributeBase>
Foam::parLagrangianRedistributor::redistributeLagrangianPositions Foam::parLagrangianDistributor::distributeLagrangianPositions
( (
const word& cloudName const word& cloudName
) const ) const
@ -322,7 +322,7 @@ Foam::parLagrangianRedistributor::redistributeLagrangianPositions
// Load cloud and send particle // Load cloud and send particle
passivePositionParticleCloud lpi(srcMesh_, cloudName, false); passivePositionParticleCloud lpi(srcMesh_, cloudName, false);
return redistributeLagrangianPositions(lpi); return distributeLagrangianPositions(lpi);
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation Copyright (C) 2015 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.
@ -25,7 +25,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class Class
Foam::parLagrangianRedistributor Foam::parLagrangianDistributor
Description Description
Lagrangian field redistributor. Lagrangian field redistributor.
@ -33,13 +33,14 @@ Description
Runs in parallel. Redistributes from fromMesh to toMesh. Runs in parallel. Redistributes from fromMesh to toMesh.
SourceFiles SourceFiles
parLagrangianRedistributor.C parLagrangianDistributor.C
parLagrangianRedistributorFields.C parLagrangianDistributorFields.C
parLagrangianDistributorTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef parLagrangianRedistributor_H #ifndef Foam_parLagrangianDistributor_H
#define parLagrangianRedistributor_H #define Foam_parLagrangianDistributor_H
#include "PtrList.H" #include "PtrList.H"
#include "fvMesh.H" #include "fvMesh.H"
@ -49,19 +50,19 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
class mapDistributePolyMesh; class mapDistributePolyMesh;
class mapDistributeBase; class mapDistributeBase;
class IOobjectList; class IOobjectList;
class passivePositionParticleCloud; class passivePositionParticleCloud;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class parLagrangianRedistributor Declaration Class parLagrangianDistributor Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class parLagrangianRedistributor class parLagrangianDistributor
{ {
// Private data // Private Data
//- Source mesh reference //- Source mesh reference
const fvMesh& srcMesh_; const fvMesh& srcMesh_;
@ -82,10 +83,10 @@ class parLagrangianRedistributor
// Private Member Functions // Private Member Functions
//- No copy construct //- No copy construct
parLagrangianRedistributor(const parLagrangianRedistributor&) = delete; parLagrangianDistributor(const parLagrangianDistributor&) = delete;
//- No copy assignment //- No copy assignment
void operator=(const parLagrangianRedistributor&) = delete; void operator=(const parLagrangianDistributor&) = delete;
public: public:
@ -93,7 +94,7 @@ public:
// Constructors // Constructors
//- Construct from components //- Construct from components
parLagrangianRedistributor parLagrangianDistributor
( (
const fvMesh& srcMesh, const fvMesh& srcMesh,
const fvMesh& tgtMesh, const fvMesh& tgtMesh,
@ -102,10 +103,10 @@ public:
); );
// Member Functions // Static Functions
//- Find all clouds (on all processors) and for each cloud all //- Find all clouds (on all processors) and for each cloud all
// the objects. Result will be synchronised on all processors //- the objects. Result will be synchronised on all processors
static void findClouds static void findClouds
( (
const fvMesh&, const fvMesh&,
@ -113,18 +114,6 @@ public:
List<wordList>& objectNames List<wordList>& objectNames
); );
//- Redistribute and write lagrangian positions
autoPtr<mapDistributeBase> redistributeLagrangianPositions
(
passivePositionParticleCloud& cloud
) const;
//- Read, redistribute and write lagrangian positions
autoPtr<mapDistributeBase> redistributeLagrangianPositions
(
const word& cloudName
) const;
//- Pick up any fields of a given type //- Pick up any fields of a given type
template<class Type> template<class Type>
static wordList filterObjects static wordList filterObjects
@ -133,26 +122,6 @@ public:
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
); );
//- Read, redistribute and write all/selected lagrangian fields
template<class Type>
label redistributeFields
(
const mapDistributeBase& map,
const word& cloudName,
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
) const;
//- Read, redistribute and write all/selected lagrangian fieldFields
template<class Type>
label redistributeFieldFields
(
const mapDistributeBase& map,
const word& cloudName,
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
) const;
//- Read and store all fields of a cloud //- Read and store all fields of a cloud
template<class Container> template<class Container>
static label readFields static label readFields
@ -162,14 +131,81 @@ public:
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
); );
//- Read and store all fields for known cloud field types
static label readAllFields
(
const passivePositionParticleCloud& cloud,
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
);
//- Read and store all fields for known cloud field types
// Uses the current cloud instance to obtain the IOobjectList
static label readAllFields
(
const passivePositionParticleCloud& cloud,
const wordRes& selectedFields = wordRes()
);
// Member Functions
//- Redistribute and write lagrangian positions
autoPtr<mapDistributeBase> distributeLagrangianPositions
(
passivePositionParticleCloud& cloud
) const;
//- Read, redistribute and write lagrangian positions
autoPtr<mapDistributeBase> distributeLagrangianPositions
(
const word& cloudName
) const;
//- Redistribute all fields for known cloud field types
label distributeAllFields
(
const mapDistributeBase& lagrangianMap,
const word& cloudName,
const IOobjectList& cloudObjs,
const wordRes& selectedFields
) const;
//- Redistribute and write all stored lagrangian fields
label distributeAllStoredFields
(
const mapDistributeBase& lagrangianMap,
passivePositionParticleCloud& cloud
) const;
//- Read, redistribute and write all/selected lagrangian fields
template<class Type>
label distributeFields
(
const mapDistributeBase& map,
const word& cloudName,
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
) const;
//- Read, redistribute and write all/selected lagrangian fieldFields
template<class Type>
label distributeFieldFields
(
const mapDistributeBase& map,
const word& cloudName,
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
) const;
//- Redistribute and write stored lagrangian fields //- Redistribute and write stored lagrangian fields
template<class Container> template<class Container>
label redistributeStoredFields label distributeStoredFields
( (
const mapDistributeBase& map, const mapDistributeBase& map,
passivePositionParticleCloud& cloud passivePositionParticleCloud& cloud
) const; ) const;
}; };
@ -180,7 +216,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
# include "parLagrangianRedistributorFields.C" # include "parLagrangianDistributorTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,195 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "parLagrangianDistributor.H"
#include "unmappedPassivePositionParticleCloud.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::parLagrangianDistributor::readAllFields
(
const passivePositionParticleCloud& cloud,
const IOobjectList& cloudObjs,
const wordRes& selectedFields
)
{
label nTotal = 0;
do
{
#undef doLocalCode
#define doLocalCode(Type) \
{ \
nTotal += parLagrangianDistributor::readFields \
<IOField<Type>> \
( \
cloud, \
cloudObjs, \
selectedFields \
); \
\
nTotal += parLagrangianDistributor::readFields \
<IOField<Field<Type>>> \
( \
cloud, \
cloudObjs, \
selectedFields \
); \
\
nTotal += parLagrangianDistributor::readFields \
<CompactIOField<Field<Type>, Type>> \
( \
cloud, \
cloudObjs, \
selectedFields \
); \
}
doLocalCode(label);
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
}
while (false);
return nTotal;
}
Foam::label Foam::parLagrangianDistributor::readAllFields
(
const passivePositionParticleCloud& cloud,
const wordRes& selectedFields
)
{
IOobjectList cloudObjs(cloud, cloud.time().timeName());
return readAllFields(cloud, cloudObjs, selectedFields);
}
Foam::label Foam::parLagrangianDistributor::distributeAllFields
(
const mapDistributeBase& lagrangianMap,
const word& cloudName,
const IOobjectList& cloudObjs,
const wordRes& selectedFields
) const
{
label nTotal = 0;
do
{
#undef doLocalCode
#define doLocalCode(Type) \
{ \
nTotal += this->distributeFields<Type> \
( \
lagrangianMap, \
cloudName, \
cloudObjs, \
selectedFields \
); \
\
nTotal += this->distributeFieldFields<Type> \
( \
lagrangianMap, \
cloudName, \
cloudObjs, \
selectedFields \
); \
}
doLocalCode(label);
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
}
while (false);
return nTotal;
}
Foam::label Foam::parLagrangianDistributor::distributeAllStoredFields
(
const mapDistributeBase& lagrangianMap,
passivePositionParticleCloud& cloud
) const
{
label nTotal = 0;
do
{
#undef doLocalCode
#define doLocalCode(Type) \
{ \
nTotal += this->distributeStoredFields \
<IOField<Type>> \
( \
lagrangianMap, \
cloud \
); \
\
nTotal += this->distributeStoredFields \
<IOField<Field<Type>>> \
( \
lagrangianMap, \
cloud \
); \
\
nTotal += this->distributeStoredFields \
<CompactIOField<Field<Type>, Type>> \
( \
lagrangianMap, \
cloud \
); \
}
doLocalCode(label);
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
}
while (false);
return nTotal;
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation Copyright (C) 2015 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.
@ -26,18 +26,19 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "parLagrangianRedistributor.H" #include "parLagrangianDistributor.H"
#include "Time.H" #include "Time.H"
#include "IOobjectList.H" #include "IOobjectList.H"
#include "mapDistributePolyMesh.H" #include "mapDistributePolyMesh.H"
#include "cloud.H" #include "cloud.H"
#include "CompactIOField.H" #include "CompactIOField.H"
#include "DynamicList.H"
#include "passivePositionParticleCloud.H" #include "passivePositionParticleCloud.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Container> template<class Container>
Foam::wordList Foam::parLagrangianRedistributor::filterObjects Foam::wordList Foam::parLagrangianDistributor::filterObjects
( (
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields const wordRes& selectedFields
@ -64,7 +65,7 @@ Foam::wordList Foam::parLagrangianRedistributor::filterObjects
template<class Type> template<class Type>
Foam::label Foam::parLagrangianRedistributor::redistributeFields Foam::label Foam::parLagrangianDistributor::distributeFields
( (
const mapDistributeBase& map, const mapDistributeBase& map,
const word& cloudName, const word& cloudName,
@ -76,7 +77,7 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFields
const wordList fieldNames const wordList fieldNames
( (
filterObjects<IOField<Type>> filterObjects<fieldType>
( (
objects, objects,
selectedFields selectedFields
@ -88,7 +89,7 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFields
{ {
if (!nFields) if (!nFields)
{ {
Info<< " Redistributing lagrangian " Info<< " Distributing lagrangian "
<< fieldType::typeName << "s\n" << endl; << fieldType::typeName << "s\n" << endl;
} }
Info<< " " << objectName << endl; Info<< " " << objectName << endl;
@ -125,11 +126,7 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFields
if (field.size()) if (field.size())
{ {
IOField<Type> IOField<Type>(fieldIO, std::move(field)).write();
(
fieldIO,
std::move(field)
).write();
} }
else else
{ {
@ -146,7 +143,7 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFields
template<class Type> template<class Type>
Foam::label Foam::parLagrangianRedistributor::redistributeFieldFields Foam::label Foam::parLagrangianDistributor::distributeFieldFields
( (
const mapDistributeBase& map, const mapDistributeBase& map,
const word& cloudName, const word& cloudName,
@ -156,7 +153,9 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFieldFields
{ {
typedef CompactIOField<Field<Type>, Type> fieldType; typedef CompactIOField<Field<Type>, Type> fieldType;
wordList fieldNames DynamicList<word> fieldNames;
fieldNames.append
( (
filterObjects<fieldType> filterObjects<fieldType>
( (
@ -166,27 +165,30 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFieldFields
); );
// Append IOField Field names // Append IOField Field names
{ fieldNames.append
wordList ioFieldNames (
filterObjects<IOField<Field<Type>>>
( (
filterObjects<IOField<Field<Type>>> objects,
( selectedFields
objects, )
selectedFields );
)
); const bool verbose_ = true;
fieldNames.append(ioFieldNames);
}
label nFields = 0; label nFields = 0;
for (const word& objectName : fieldNames) for (const word& objectName : fieldNames)
{ {
if (!nFields++) if (verbose_)
{ {
Info<< " Redistributing lagrangian " if (!nFields)
<< fieldType::typeName << "s\n" << nl; {
Info<< " Distributing lagrangian "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << objectName << nl;
} }
Info<< " " << objectName << nl; ++nFields;
// Read if present // Read if present
CompactIOField<Field<Type>, Type> field CompactIOField<Field<Type>, Type> field
@ -237,13 +239,13 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFieldFields
} }
} }
if (nFields) Info<< endl; if (nFields && verbose_) Info<< endl;
return nFields; return nFields;
} }
template<class Container> template<class Container>
Foam::label Foam::parLagrangianRedistributor::readFields Foam::label Foam::parLagrangianDistributor::readFields
( (
const passivePositionParticleCloud& cloud, const passivePositionParticleCloud& cloud,
const IOobjectList& objects, const IOobjectList& objects,
@ -261,15 +263,21 @@ Foam::label Foam::parLagrangianRedistributor::readFields
) )
); );
const bool verbose_ = true;
label nFields = 0; label nFields = 0;
for (const word& objectName : fieldNames) for (const word& objectName : fieldNames)
{ {
if (!nFields++) if (verbose_)
{ {
Info<< " Reading lagrangian " if (!nFields)
<< Container::typeName << "s\n" << nl; {
Info<< " Reading lagrangian "
<< Container::typeName << "s\n" << nl;
}
Info<< " " << objectName << nl;
} }
Info<< " " << objectName << nl; ++nFields;
// Read if present // Read if present
Container* fieldPtr = new Container Container* fieldPtr = new Container
@ -288,12 +296,13 @@ Foam::label Foam::parLagrangianRedistributor::readFields
fieldPtr->store(); fieldPtr->store();
} }
if (nFields && verbose_) Info<< endl;
return nFields; return nFields;
} }
template<class Container> template<class Container>
Foam::label Foam::parLagrangianRedistributor::redistributeStoredFields Foam::label Foam::parLagrangianDistributor::distributeStoredFields
( (
const mapDistributeBase& map, const mapDistributeBase& map,
passivePositionParticleCloud& cloud passivePositionParticleCloud& cloud
@ -304,17 +313,23 @@ Foam::label Foam::parLagrangianRedistributor::redistributeStoredFields
cloud.lookupClass<Container>() cloud.lookupClass<Container>()
); );
const bool verbose_ = true;
label nFields = 0; label nFields = 0;
forAllIters(fields, iter) forAllIters(fields, iter)
{ {
Container& field = *(iter.val()); Container& field = *(iter.val());
if (!nFields++) if (verbose_)
{ {
Info<< " Redistributing lagrangian " if (!nFields)
<< Container::typeName << "s\n" << endl; {
Info<< " Distributing lagrangian "
<< Container::typeName << "s\n" << endl;
}
Info<< " " << field.name() << endl;
} }
Info<< " " << field.name() << endl; ++nFields;
map.distribute(field); map.distribute(field);
@ -331,11 +346,7 @@ Foam::label Foam::parLagrangianRedistributor::redistributeStoredFields
if (field.size()) if (field.size())
{ {
Container Container(fieldIO, std::move(field)).write();
(
fieldIO,
std::move(field)
).write();
} }
else else
{ {
@ -347,6 +358,7 @@ Foam::label Foam::parLagrangianRedistributor::redistributeStoredFields
} }
} }
if (nFields && verbose_) Info<< endl;
return nFields; return nFields;
} }

View File

@ -0,0 +1,238 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "parPointFieldDistributor.H"
#include "processorPointPatch.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::parPointFieldDistributor::verbose_ = 0;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::parPointFieldDistributor::parPointFieldDistributor
(
const pointMesh& srcMesh,
const bool savePoints,
const bool isWriteProc
)
:
srcMesh_(srcMesh),
nOldPoints_(srcMesh.size()),
patchMeshPoints_(),
tgtMeshRef_(nullptr),
distMapRef_(nullptr),
patchPointMaps_(),
isWriteProc_(isWriteProc)
{
if (savePoints)
{
saveMeshPoints();
}
}
Foam::parPointFieldDistributor::parPointFieldDistributor
(
const pointMesh& srcMesh,
const pointMesh& tgtMesh,
const mapDistributePolyMesh& distMap,
const bool savePoints,
const bool isWriteProc
)
:
srcMesh_(srcMesh),
nOldPoints_(srcMesh.size()),
patchMeshPoints_(),
tgtMeshRef_(tgtMesh),
distMapRef_(distMap),
patchPointMaps_(),
isWriteProc_(isWriteProc)
{
if (savePoints)
{
saveMeshPoints();
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::parPointFieldDistributor::hasMeshPoints() const
{
return !patchMeshPoints_.empty();
}
bool Foam::parPointFieldDistributor::hasPatchPointMaps() const
{
return !patchPointMaps_.empty();
}
bool Foam::parPointFieldDistributor::hasTarget() const
{
return (tgtMeshRef_ && distMapRef_);
}
void Foam::parPointFieldDistributor::clearMeshPoints()
{
patchMeshPoints_.clear();
}
void Foam::parPointFieldDistributor::clearPatchPointMaps()
{
patchPointMaps_.clear();
}
void Foam::parPointFieldDistributor::saveMeshPoints()
{
const pointBoundaryMesh& patches = srcMesh_.boundary();
patchMeshPoints_.clear();
patchMeshPoints_.resize(patches.size());
forAll(patches, patchi)
{
if (!isA<processorPointPatch>(patches[patchi]))
{
// Copy meshPoints
patchMeshPoints_.set
(
patchi,
new labelList(patches[patchi].meshPoints())
);
}
}
}
void Foam::parPointFieldDistributor::createPatchPointMaps()
{
if (!tgtMeshRef_ || !distMapRef_)
{
FatalErrorInFunction
<< "Cannot create maps without target mesh and/or distribution!"
<< abort(FatalError);
}
const auto& tgtMesh = tgtMeshRef_();
const auto& distMap = distMapRef_();
const auto& newPatches = tgtMesh.boundary();
const auto& oldPatches = srcMesh_.boundary();
patchPointMaps_.clear();
patchPointMaps_.resize(oldPatches.size());
// if (patchPointMaps_.size() != patchMeshPoints_.size())
// {
// // Warn?
// }
forAll(oldPatches, patchi)
{
if (!isA<processorPointPatch>(oldPatches[patchi]))
{
// Create map for patch points only
labelList oldToNewSub;
labelList oldToNewConstruct;
// Copy point map
patchPointMaps_.set
(
patchi,
new mapDistributeBase(distMap.pointMap())
);
const labelList& oldMeshPoints =
(
patchMeshPoints_.test(patchi)
? patchMeshPoints_[patchi]
: oldPatches[patchi].meshPoints() // <- Questionable!
);
patchPointMaps_[patchi].compactData
(
oldMeshPoints,
newPatches[patchi].meshPoints(),
oldToNewSub,
oldToNewConstruct,
nOldPoints_,
UPstream::msgType()
);
}
}
}
void Foam::parPointFieldDistributor::resetTarget()
{
tgtMeshRef_.reset(nullptr);
distMapRef_.reset(nullptr);
// Old maps are now invalid
clearPatchPointMaps();
}
void Foam::parPointFieldDistributor::resetTarget
(
const pointMesh& tgtMesh,
const mapDistributePolyMesh& distMap
)
{
tgtMeshRef_.cref(tgtMesh);
distMapRef_.cref(distMap);
// Old maps are now invalid
clearPatchPointMaps();
}
Foam::label Foam::parPointFieldDistributor::distributeAllFields
(
const IOobjectList& objects,
const wordRes& selected
) const
{
label nTotal = 0;
nTotal += distributePointFields<scalar>(objects, selected);
nTotal += distributePointFields<vector>(objects, selected);
nTotal += distributePointFields<symmTensor>(objects, selected);
nTotal += distributePointFields<sphericalTensor>(objects, selected);
nTotal += distributePointFields<tensor>(objects, selected);
return nTotal;
}
// ************************************************************************* //

View File

@ -0,0 +1,255 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::parPointFieldDistributor
Description
Distributor/redistributor for point fields,
uses a two (or three) stage construction.
The inconvenient multi-stage construction is needed since the
pointMesh is directly associated with a polyMesh, which will probably
have changed while creating the target mesh. This means that it is
necessary to save the size of the source mesh and all of its
patch meshPoints prior to making any changes (eg, creating the target
mesh).
-# Create with specified source mesh
-# Save the meshPoints (per boundary) for the source mesh
-# Attach a target mesh and mesh distribution
-# Map the point fields
.
Runs in parallel. Redistributes from srcMesh to tgtMesh.
SourceFiles
parPointFieldDistributor.C
parPointFieldDistributorTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_parPointFieldDistributor_H
#define Foam_parPointFieldDistributor_H
#include "PtrList.H"
#include "pointMesh.H"
#include "pointFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class mapDistributePolyMesh;
class mapDistributeBase;
class IOobjectList;
/*---------------------------------------------------------------------------*\
Class parPointFieldDistributor Declaration
\*---------------------------------------------------------------------------*/
class parPointFieldDistributor
{
// Private Data
//- The source mesh reference
const pointMesh& srcMesh_;
//- Number of points in the old (source) mesh
const label nOldPoints_;
//- The pointPatch mesh points
PtrList<labelList> patchMeshPoints_;
//- The target (destination) mesh reference
refPtr<pointMesh> tgtMeshRef_;
//- Distribution map reference
refPtr<mapDistributePolyMesh> distMapRef_;
//- Point patch mappers
PtrList<mapDistributeBase> patchPointMaps_;
//- Do I need to write (eg, master only for reconstruct)
bool isWriteProc_;
// Private Member Functions
//- No copy construct
parPointFieldDistributor(const parPointFieldDistributor&) = delete;
//- No copy assignment
void operator=(const parPointFieldDistributor&) = delete;
public:
//- Output verbosity when writing
static int verbose_;
// Constructors
//- Basic construction
//
// \param srcMesh The source pointMesh
// \param savePoints Call saveMeshPoints() immediately
// \param isWriteProc Tagged for output writing (on this proc)
explicit parPointFieldDistributor
(
const pointMesh& srcMesh,
const bool savePoints = false,
const bool isWriteProc = false
);
//- Full construction of source/target
//
// \param srcMesh The source pointMesh
// \param tgtMesh The target pointMesh
// \param distMap The distribution map
// \param savePoints Call saveMeshPoints() immediately
// \param isWriteProc Tagged for output writing (on this proc)
explicit parPointFieldDistributor
(
const pointMesh& srcMesh,
const pointMesh& tgtMesh,
const mapDistributePolyMesh& distMap,
const bool savePoints = false,
const bool isWriteProc = false
);
// Member Functions
//- True if meshPoints (per boundary) for the source mesh
//- have been saved
bool hasMeshPoints() const;
//- True if patch maps (per boundary) exist
bool hasPatchPointMaps() const;
//- True if a target mesh/distribution map has been attached
bool hasTarget() const;
//- Clear out meshPoints (per boundary) for the source mesh
void clearMeshPoints();
//- Clear out patch maps (per boundary)
void clearPatchPointMaps();
//- Create/recreate meshPoints (per boundary) for the source mesh
void saveMeshPoints();
//- Construct per-patch addressing
void createPatchPointMaps();
//- Clear target mesh / distribution map
void resetTarget();
//- Reset target mesh / distribution map
void resetTarget
(
const pointMesh& tgtMesh,
const mapDistributePolyMesh& distMap
);
//- Get status of write enabled (on this proc)
bool isWriteProc() const noexcept
{
return isWriteProc_;
}
//- Change status of write enabled (on this proc)
bool isWriteProc(const bool on) noexcept
{
bool old(isWriteProc_);
isWriteProc_ = on;
return old;
}
// Field Mapping
//- Read, distribute and write all/selected point field types
//- (scalar, vector, ... types)
label distributeAllFields
(
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
) const;
//- Distribute point field
template<class Type>
tmp<GeometricField<Type, pointPatchField, pointMesh>>
distributeField
(
const GeometricField<Type, pointPatchField, pointMesh>& fld
) const;
//- Read and distribute point field
template<class Type>
tmp<GeometricField<Type, pointPatchField, pointMesh>>
distributePointField
(
const IOobject& fieldObject
) const;
//- Read, distribute and write all/selected point fields
template<class Type>
label distributePointFields
(
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
) const;
//- Distributed each (unregistered!) point field
//- and store the result on its objectRegistry
template<class Type>
void distributeAndStore
(
const PtrList<GeometricField<Type, pointPatchField, pointMesh>>&
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "parPointFieldDistributorTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,239 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "Time.H"
#include "emptyPointPatchField.H"
#include "IOobjectList.H"
#include "mapDistributePolyMesh.H"
#include "distributedFieldMapper.H"
#include "distributedPointPatchFieldMapper.H"
#include "pointFields.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh>>
Foam::parPointFieldDistributor::distributeField
(
const GeometricField<Type, pointPatchField, pointMesh>& fld
) const
{
if (!tgtMeshRef_ || !distMapRef_)
{
FatalErrorInFunction
<< "Cannot map field without target mesh and/or distribution!"
<< abort(FatalError);
}
if (!hasPatchPointMaps())
{
const_cast<parPointFieldDistributor&>(*this).createPatchPointMaps();
}
const auto& tgtMesh = tgtMeshRef_();
const auto& distMap = distMapRef_();
// Create internalField by remote mapping
distributedFieldMapper mapper
(
labelUList::null(),
distMap.pointMap()
);
DimensionedField<Type, pointMesh> internalField
(
IOobject
(
fld.name(),
tgtMesh.time().timeName(),
fld.local(),
tgtMesh.thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
tgtMesh,
fld.dimensions(),
Field<Type>(fld.internalField(), mapper)
);
internalField.oriented() = fld.oriented();
// Create patchFields by remote mapping
PtrList<pointPatchField<Type>> newPatchFields(tgtMesh.boundary().size());
const auto& bfld = fld.boundaryField();
forAll(bfld, patchi)
{
if (patchPointMaps_.set(patchi))
{
// Clone local patch field
const distributedPointPatchFieldMapper mapper
(
labelUList::null(),
patchPointMaps_[patchi]
);
// Map into local copy
newPatchFields.set
(
patchi,
pointPatchField<Type>::New
(
bfld[patchi],
tgtMesh.boundary()[patchi], // pointPatch
DimensionedField<Type, pointMesh>::null(),
mapper
)
);
// Note: below alternative, 'clone' method will not work since
// there is no clone to reset both internalField reference and
// patch reference. TBD.
//newPatchFields.set
//(
// patchi,
// bfld[patchi].clone
// (
// tgtMesh.boundary()[patchi],
// DimensionedField<Type, pointMesh>::null(),
// mapper
// )
//);
}
}
// Add some empty patchFields on remaining patches (this also handles
// e.g. processorPatchFields or any other constraint type patches)
forAll(newPatchFields, patchi)
{
if (!newPatchFields.set(patchi))
{
newPatchFields.set
(
patchi,
pointPatchField<Type>::New
(
emptyPointPatchField<Type>::typeName,
tgtMesh.boundary()[patchi],
DimensionedField<Type, pointMesh>::null()
)
);
}
}
return
tmp<GeometricField<Type, pointPatchField, pointMesh>>::New
(
std::move(internalField),
newPatchFields
);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh>>
Foam::parPointFieldDistributor::distributePointField
(
const IOobject& fieldObject
) const
{
// Read field
GeometricField<Type, pointPatchField, pointMesh> fld
(
fieldObject,
srcMesh_
);
// Redistribute
return distributeField(fld);
}
template<class Type>
Foam::label Foam::parPointFieldDistributor::distributePointFields
(
const IOobjectList& objects,
const wordRes& selectedFields
) const
{
typedef GeometricField<Type, pointPatchField, pointMesh> fieldType;
UPtrList<const IOobject> fieldObjects
(
selectedFields.empty()
? objects.sorted<fieldType>()
: objects.sorted<fieldType>(selectedFields)
);
label nFields = 0;
for (const IOobject& io : fieldObjects)
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << nl;
}
++nFields;
tmp<fieldType> tfld(distributePointField<Type>(io));
if (isWriteProc_)
{
tfld().write();
}
}
if (nFields && verbose_) Info<< endl;
return nFields;
}
template<class Type>
void Foam::parPointFieldDistributor::distributeAndStore
(
const PtrList<GeometricField<Type, pointPatchField, pointMesh>>& fields
) const
{
for (const auto& fld : fields)
{
// Distribute and store
auto tfld = distributeField(fld);
tfld.ref().writeOpt(IOobject::AUTO_WRITE);
tfld().mesh().thisDb().store(tfld);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,230 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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) 2015-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/>.
Description
Reading, reconstruct, redistribution of lagrangian fields.
\*---------------------------------------------------------------------------*/
#ifndef Foam_redistributeLagrangian_H
#define Foam_redistributeLagrangian_H
#include "parLagrangianDistributor.H"
#include "unmappedPassivePositionParticleCloud.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Read clouds (note: might not be present on all processors)
PtrList<unmappedPassivePositionParticleCloud>
readLagrangian
(
const fvMesh& mesh,
const wordList& cloudNames,
const wordRes& selectedFields
)
{
PtrList<unmappedPassivePositionParticleCloud> clouds(cloudNames.size());
if (!cloudNames.empty())
{
(void)mesh.tetBasePtIs();
}
// Setup clouds
forAll(cloudNames, i)
{
//Pout<< "Loading cloud " << cloudNames[i] << endl;
clouds.set
(
i,
new unmappedPassivePositionParticleCloud(mesh, cloudNames[i], false)
);
//for (passivePositionParticle& p : clouds[i]))
//{
// Pout<< "Particle position:" << p.position()
// << " cell:" << p.cell()
// << " with cc:" << mesh.cellCentres()[p.cell()]
// << endl;
//}
IOobjectList cloudObjs(clouds[i], clouds[i].time().timeName());
//Pout<< "Found cloud objects:" << cloudObjs.names() << endl;
parLagrangianDistributor::readAllFields
(
clouds[i],
cloudObjs,
selectedFields
);
}
return clouds;
}
// Read clouds (note: might not be present on all processors)
PtrList<unmappedPassivePositionParticleCloud>
readLagrangian
(
const fvMesh& mesh,
const wordRes& selectedFields
)
{
wordList cloudNames;
List<wordList> fieldNames;
// Find all cloudNames on all processors
parLagrangianDistributor::findClouds(mesh, cloudNames, fieldNames);
return readLagrangian(mesh, cloudNames, selectedFields);
}
void reconstructLagrangian
(
autoPtr<parLagrangianDistributor>& distributorPtr,
const fvMesh& baseMesh,
const fvMesh& mesh,
const mapDistributePolyMesh& distMap,
const wordRes& selectedFields
)
{
// Clouds (note: might not be present on all processors)
wordList cloudNames;
List<wordList> fieldNames;
// Find all cloudNames on all processors
parLagrangianDistributor::findClouds(mesh, cloudNames, fieldNames);
if (cloudNames.empty())
{
// Nothing to do
return;
}
// Use existing or create distributor
if (!distributorPtr)
{
distributorPtr.reset
(
new parLagrangianDistributor
(
mesh,
baseMesh,
mesh.nCells(), // range of cell indices in clouds
distMap
)
);
}
const auto& distributor = *distributorPtr;
for (const word& cloudName : cloudNames)
{
Info<< "Reconstructing lagrangian fields for cloud "
<< cloudName << nl << endl;
IOobjectList cloudObjs
(
mesh,
mesh.time().timeName(),
cloud::prefix/cloudName
);
autoPtr<mapDistributeBase> lagrangianMapPtr =
distributor.distributeLagrangianPositions
(
cloudName
);
distributor.distributeAllFields
(
lagrangianMapPtr(),
cloudName,
cloudObjs,
selectedFields
);
}
}
void redistributeLagrangian
(
autoPtr<parLagrangianDistributor>& distributorPtr,
const fvMesh& mesh,
const label nOldCells,
const mapDistributePolyMesh& distMap,
PtrList<unmappedPassivePositionParticleCloud>& clouds
)
{
if (clouds.empty())
{
// Nothing to do
return;
}
// Use existing or create distributor
if (!distributorPtr)
{
distributorPtr.reset
(
new parLagrangianDistributor
(
mesh,
mesh,
nOldCells, // range of cell indices in clouds
distMap
)
);
}
const auto& distributor = *distributorPtr;
for (auto& cloud : clouds)
{
autoPtr<mapDistributeBase> lagrangianMapPtr =
distributor.distributeLagrangianPositions(cloud);
distributor.distributeAllStoredFields
(
lagrangianMapPtr(),
cloud
);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
#endif
// ************************************************************************* //

View File

@ -944,37 +944,29 @@ Foam::mapDistributeBase::mapDistributeBase
Pstream::exchangeSizes(subMap_, recvSizes, comm_); Pstream::exchangeSizes(subMap_, recvSizes, comm_);
// Determine order of receiving // Determine order of receiving
labelListList constructMap(nProcs); constructSize_ = 0;
constructMap_.resize(nProcs);
// My local segments first
label nLocal = recvSizes[myRank]; // My data first
{ {
labelList& myMap = constructMap[myRank]; const label len = recvSizes[myRank];
myMap.setSize(nLocal);
forAll(myMap, i) constructMap_[myRank] = identity(len, constructSize_);
{ constructSize_ += len;
myMap[i] = i;
}
} }
label segmenti = nLocal; // What the other processors are sending to me
forAll(constructMap, proci) forAll(constructMap_, proci)
{ {
if (proci != myRank) if (proci != myRank)
{ {
// What i need to receive is what other processor is sending to me. const label len = recvSizes[proci];
label nRecv = recvSizes[proci];
constructMap[proci].setSize(nRecv);
for (label i = 0; i < nRecv; i++) constructMap_[proci] = identity(len, constructSize_);
{ constructSize_ += len;
constructMap[proci][i] = segmenti++;
}
} }
} }
constructSize_ = segmenti;
constructMap_.transfer(constructMap);
} }
@ -1062,402 +1054,6 @@ Foam::label Foam::mapDistributeBase::renumber
} }
void Foam::mapDistributeBase::compact
(
const boolList& elemIsUsed,
const int tag
)
{
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// 1. send back to sender. Have sender delete the corresponding element
// from the submap and do the same to the constructMap locally
// (and in same order).
// Send elemIsUsed field to neighbour. Use nonblocking code from
// mapDistributeBase but in reverse order.
if (Pstream::parRun())
{
label startOfRequests = Pstream::nRequests();
// Set up receives from neighbours
List<boolList> recvFields(nProcs);
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = subMap_[domain];
if (domain != myRank && map.size())
{
recvFields[domain].setSize(map.size());
IPstream::read
(
Pstream::commsTypes::nonBlocking,
domain,
recvFields[domain].data_bytes(),
recvFields[domain].size_bytes(),
tag,
comm_
);
}
}
List<boolList> sendFields(nProcs);
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = constructMap_[domain];
if (domain != myRank && map.size())
{
boolList& subField = sendFields[domain];
subField.setSize(map.size());
forAll(map, i)
{
subField[i] = accessAndFlip
(
elemIsUsed,
map[i],
constructHasFlip_,
identityOp() // Do not flip elemIsUsed value
);
}
OPstream::write
(
Pstream::commsTypes::nonBlocking,
domain,
subField.cdata_bytes(),
subField.size_bytes(),
tag,
comm_
);
}
}
// Set up 'send' to myself - write directly into recvFields
{
const labelList& map = constructMap_[myRank];
recvFields[myRank].setSize(map.size());
forAll(map, i)
{
recvFields[myRank][i] = accessAndFlip
(
elemIsUsed,
map[i],
constructHasFlip_,
identityOp() // Do not flip elemIsUsed value
);
}
}
// Wait for all to finish
Pstream::waitRequests(startOfRequests);
// Compact out all submap entries that are referring to unused elements
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = subMap_[domain];
labelList newMap(map.size());
label newI = 0;
forAll(map, i)
{
if (recvFields[domain][i])
{
// So element is used on destination side
newMap[newI++] = map[i];
}
}
if (newI < map.size())
{
newMap.setSize(newI);
subMap_[domain].transfer(newMap);
}
}
}
// 2. remove from construct map - since end-result (element in elemIsUsed)
// not used.
label maxConstructIndex = -1;
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = constructMap_[domain];
labelList newMap(map.size());
label newI = 0;
forAll(map, i)
{
label destinationI = map[i];
if (constructHasFlip_)
{
destinationI = mag(destinationI)-1;
}
// Is element is used on destination side
if (elemIsUsed[destinationI])
{
maxConstructIndex = max(maxConstructIndex, destinationI);
newMap[newI++] = map[i];
}
}
if (newI < map.size())
{
newMap.setSize(newI);
constructMap_[domain].transfer(newMap);
}
}
constructSize_ = maxConstructIndex+1;
// Clear the schedule (note:not necessary if nothing changed)
schedulePtr_.clear();
}
void Foam::mapDistributeBase::compact
(
const boolList& elemIsUsed,
const label localSize, // max index for subMap
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const int tag
)
{
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// 1. send back to sender. Have sender delete the corresponding element
// from the submap and do the same to the constructMap locally
// (and in same order).
// Send elemIsUsed field to neighbour. Use nonblocking code from
// mapDistributeBase but in reverse order.
if (Pstream::parRun())
{
label startOfRequests = Pstream::nRequests();
// Set up receives from neighbours
List<boolList> recvFields(nProcs);
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = subMap_[domain];
if (domain != myRank && map.size())
{
recvFields[domain].setSize(map.size());
IPstream::read
(
Pstream::commsTypes::nonBlocking,
domain,
recvFields[domain].data_bytes(),
recvFields[domain].size_bytes(),
tag,
comm_
);
}
}
List<boolList> sendFields(nProcs);
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = constructMap_[domain];
if (domain != myRank && map.size())
{
boolList& subField = sendFields[domain];
subField.setSize(map.size());
forAll(map, i)
{
label index = map[i];
if (constructHasFlip_)
{
index = mag(index)-1;
}
subField[i] = elemIsUsed[index];
}
OPstream::write
(
Pstream::commsTypes::nonBlocking,
domain,
subField.cdata_bytes(),
subField.size_bytes(),
tag,
comm_
);
}
}
// Set up 'send' to myself - write directly into recvFields
{
const labelList& map = constructMap_[myRank];
recvFields[myRank].setSize(map.size());
forAll(map, i)
{
label index = map[i];
if (constructHasFlip_)
{
index = mag(index)-1;
}
recvFields[myRank][i] = elemIsUsed[index];
}
}
// Wait for all to finish
Pstream::waitRequests(startOfRequests);
// Work out which elements on the sending side are needed
{
oldToNewSub.setSize(localSize, -1);
boolList sendElemIsUsed(localSize, false);
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = subMap_[domain];
forAll(map, i)
{
if (recvFields[domain][i])
{
label index = map[i];
if (subHasFlip_)
{
index = mag(index)-1;
}
sendElemIsUsed[index] = true;
}
}
}
label newI = 0;
forAll(sendElemIsUsed, i)
{
if (sendElemIsUsed[i])
{
oldToNewSub[i] = newI++;
}
}
}
// Compact out all submap entries that are referring to unused elements
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = subMap_[domain];
labelList newMap(map.size());
label newI = 0;
forAll(map, i)
{
if (recvFields[domain][i])
{
// So element is used on destination side
label index = map[i];
label sign = 1;
if (subHasFlip_)
{
if (index < 0)
{
sign = -1;
}
index = mag(index)-1;
}
label newIndex = oldToNewSub[index];
if (subHasFlip_)
{
newIndex = sign*(newIndex+1);
}
newMap[newI++] = newIndex;
}
}
newMap.setSize(newI);
subMap_[domain].transfer(newMap);
}
}
// 2. remove from construct map - since end-result (element in elemIsUsed)
// not used.
oldToNewConstruct.setSize(elemIsUsed.size(), -1);
constructSize_ = 0;
forAll(elemIsUsed, i)
{
if (elemIsUsed[i])
{
oldToNewConstruct[i] = constructSize_++;
}
}
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = constructMap_[domain];
labelList newMap(map.size());
label newI = 0;
forAll(map, i)
{
label destinationI = map[i];
label sign = 1;
if (constructHasFlip_)
{
if (destinationI < 0)
{
sign = -1;
}
destinationI = mag(destinationI)-1;
}
// Is element is used on destination side
if (elemIsUsed[destinationI])
{
label newIndex = oldToNewConstruct[destinationI];
if (constructHasFlip_)
{
newIndex = sign*(newIndex+1);
}
newMap[newI++] = newIndex;
}
}
newMap.setSize(newI);
constructMap_[domain].transfer(newMap);
}
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::mapDistributeBase::operator=(const mapDistributeBase& rhs) void Foam::mapDistributeBase::operator=(const mapDistributeBase& rhs)

View File

@ -186,6 +186,34 @@ protected:
labelList& compactStart labelList& compactStart
); );
//- Synchronize send/recv mask buffers as a 'copy' operation.
// Somewhat similar to Pstream::exchangeContainer
//
// The masks must be properly sized by the caller, which avoids
// a needless all-to-all for the sizes and the sizing is already
// given by the maps.
static void exchangeMasks
(
const UList<bitSet>& sendMasks,
UList<bitSet>& recvMasks,
const int tag,
const label comm
);
//- Bi-direction sync of send/recv buffers using bitwise '&='
//- combine operation.
//
// The masks must be properly sized by the caller, which avoids
// a needless all-to-all for the sizes and the sizing is already
// given by the maps.
static void unionCombineMasks
(
UList<bitSet>& sendMasks,
UList<bitSet>& recvMasks,
const int tag,
const label comm
);
template<class T, class CombineOp, class NegateOp> template<class T, class CombineOp, class NegateOp>
static void flipAndCombine static void flipAndCombine
@ -225,6 +253,88 @@ private:
// Private Member Functions // Private Member Functions
//- Helper for compactData (private: filescope only!)
// Establishes the exact send/recv elements used after masking.
//
// \param allowedLocalElems Permissible local mapped elements
// (true/false). Can be longer/shorter than actual number
// of mapped elements.
// \param allowedRemoteElems Permissible remote mapped elements
// (true/false). Can be longer/shorter than actual number
// of mapped elements.
// \param[out] sendMasks Mask of local elements sent to procs.
// \param[out] recvMasks Mask of remote elements received
// from procs
// \param tag The message tag
void calcCompactDataRequirements
(
const bitSet& allowedLocalElems,
const bitSet& allowedRemoteElems,
List<bitSet>& sendMasks, // [out]
List<bitSet>& recvMasks, // [out]
const int tag
);
//- Helper for compactLocalData (private: filescope only!)
// Establishes the exact send/recv elements used after masking.
//
// \param allowedLocalElems Permissible local mapped elements
// (true/false). Can be longer/shorter than actual number
// of mapped elements.
// \param[out] sendMasks Mask of local elements sent to procs.
// \param[out] recvMasks Mask of remote elements received by proc.
// from procs
// \param tag The message tag
void calcCompactLocalDataRequirements
(
const bitSet& allowedLocalElems,
List<bitSet>& sendMasks, // [out]
List<bitSet>& recvMasks, // [out]
const int tag
);
//- Helper for compactRemoteData (private: filescope only!)
// Establishes the exact send/recv elements used after masking.
//
// \param allowedRemoteElems Permissible remote mapped elements
// (true/false). Can be longer/shorter than actual number
// of mapped elements.
// \param[out] sendMasks Mask of local elements sent to procs.
// \param[out] recvMasks Mask of remote elements received by proc.
// \param tag The message tag
void calcCompactRemoteDataRequirements
(
const bitSet& allowedRemoteElems,
List<bitSet>& sendMasks, // [out]
List<bitSet>& recvMasks, // [out]
const int tag
);
//- Implementation for compact{Local,Remote}Data (private).
// Also renumbers the subMap/constructMap if oldToNew maps
// are notNull().
//
// No communication
void compactData
(
const UList<bitSet>& sendMasks,
const UList<bitSet>& recvMasks,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const label localSize = -1
);
//- Wrapper for compactData (private) that supplies oldToNew
//- maps for renumbering if doRenumber is true.
// No communication
void compactDataImpl
(
const UList<bitSet>& sendMasks,
const UList<bitSet>& recvMasks,
const bool doRenumber
);
//- Helper for renumbering compacted map elements and updating the //- Helper for renumbering compacted map elements and updating the
//- supplied old-to-new mapping to account for the visit order of //- supplied old-to-new mapping to account for the visit order of
//- the original elements //- the original elements
@ -509,22 +619,163 @@ public:
// Compaction // Compaction
//- Compact all maps and layout. //- Compact send/receive maps based on selection of
// Returns compaction maps for subMap and constructMap //- originating local (send) elements.
void compact // Determines and removes the correspondingly unneeded elements
// in the send/receive maps.
// Only compacts the maps, does not change the local layout.
//
// \param allowedLocalElems Permissible local mapped elements
// (true/false). Can be longer/shorter than actual number
// of mapped elements.
// \param tag The message tag
// \param doRenumber Apply oldToNew internally to renumber
// entries (uses renumberMap) and adjust the constructSize
//
// \note generally preferable to compact based on remote data
// (ie, the actual receiver)
void compactLocalData
( (
const boolList& elemIsUsed, const bitSet& allowedLocalElems,
const int tag = UPstream::msgType(),
const bool doRenumber = false
);
//- Compact send/receive maps based on selection of
//- remote (receive) elements.
// Determines and removes the correspondingly unneeded elements
// in the send/receive maps.
// Only compacts the maps, does not change the local layout.
//
// \param allowedRemoteElems Permissible remote mapped elements
// (true/false). Can be longer/shorter than actual number
// of mapped elements.
// \param tag The message tag
// \param doRenumber Apply oldToNew internally to renumber
// entries (uses renumberMap) and adjust the constructSize
void compactRemoteData
(
const bitSet& allowedRemoteElems,
const int tag = UPstream::msgType(),
const bool doRenumber = false
);
//- Compact send/receive maps based on selection of
//- originating local (send) elements.
//- Returns compaction mappings for subMap and constructMap.
//
// \param allowedLocalElems Permissible local mapped elements
// (true/false). Can be longer/shorter than actual number
// of mapped elements.
// \param[out] oldToNewSub Old-to-new mapping: subMap
// Disabled if labelList::null(),
// \param[out] oldToNewConstruct Old-to-new mapping: constructMap
// Disabled if labelList::null(),
// \param localSize The max index for subMap (-1: auto-detect)
// \param tag The message tag
//
// \note Applies oldToNew to renumber entries
// (uses renumberMap) and adjust constructSize
//
// \note generally preferable to compact based on remote data
// (ie, the actual receiver)
void compactLocalData
(
const bitSet& allowedLocalElems,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const label localSize = -1,
const int tag = UPstream::msgType() const int tag = UPstream::msgType()
); );
//- Compact all maps and layout. //- Compact send/receive maps based on selection of
// Returns compaction maps for subMap and constructMap //- remote (receive) elements.
void compact //- Returns compaction mappings for subMap and constructMap.
//
// \param allowedRemoteElems Permissible remote mapped elements
// (true/false). Can be longer/shorter than actual number
// of mapped elements.
// \param[out] oldToNewSub Old-to-new mapping: subMap
// Disabled if labelList::null(),
// \param[out] oldToNewConstruct Old-to-new mapping: constructMap
// Disabled if labelList::null(),
// \param localSize The max index for subMap (-1: auto-detect)
// \param tag The message tag
//
// \note Applies oldToNew to renumber entries
// (uses renumberMap) and adjust constructSize
void compactRemoteData
( (
const boolList& elemIsUsed, const bitSet& allowedRemoteElems,
const label localSize, // max index for subMap
labelList& oldToNewSub, labelList& oldToNewSub,
labelList& oldToNewConstruct, labelList& oldToNewConstruct,
const label localSize = -1,
const int tag = UPstream::msgType()
);
//- Compact send/receive maps based on selection of
//- originating local (send) and remote (receive) elements.
//
// The resulting compact numbering:
// - \c subMap (and \c oldToNewSub) :
// will follow the original ordering of \c localElements.
// - \c constructMap (and \c oldToNewConstruct) :
// will follow the original ordering of \c remoteElements.
// .
// \warning ill-defined behaviour if \c localElements
// or \c remoteElements contains duplicates.
void compactData
(
const labelUList& localElements,
const labelUList& remoteElements,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const label localSize = -1,
const int tag = UPstream::msgType()
);
//- Compact send/receive maps based on selection of
//- originating local (send) elements.
//
// The resulting compact numbering:
// - \c subMap (and \c oldToNewSub) :
// will follow the original ordering of \c localElements.
// - \c constructMap (and \c oldToNewConstruct) :
// numbered in simple ascending order.
// .
// \warning ill-defined behaviour if \c localElements
// contains duplicates.
//
// \note generally preferable to compact based on remote data
// (ie, the actual receiver)
void compactLocalData
(
const labelUList& localElements,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const label localSize = -1,
const int tag = UPstream::msgType()
);
//- Compact send/receive maps based on selection of
//- remote (receive) elements.
//
// The resulting compact numbering:
// - \c subMap (and \c oldToNewSub) :
// numbered in simple ascending order.
// - \c constructMap (and \c oldToNewConstruct) :
// will follow the original ordering of \c remoteElements.
// .
// \warning ill-defined behaviour if \c remoteElements
// contains duplicates.
void compactRemoteData
(
const labelUList& remoteElements,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const label localSize = -1,
const int tag = UPstream::msgType() const int tag = UPstream::msgType()
); );
@ -745,6 +996,25 @@ public:
{ {
NotImplemented; NotImplemented;
} }
//- OpenFOAM-v2112 and earlier naming for compactRemoteData()
//- using boolList.
void compact
(
const boolList& remoteElemUsed,
const int tag = UPstream::msgType()
);
//- OpenFOAM-v2112 and earlier naming for compactRemoteData().
//- using boolList.
void compact
(
const boolList& remoteElemUsed,
const label localSize,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const int tag = UPstream::msgType()
);
}; };

View File

@ -36,25 +36,39 @@ namespace Foam
// The maps (labelListList) are not human-modifiable but if we need to // The maps (labelListList) are not human-modifiable but if we need to
// inspect them in ASCII, it is much more convenient if each sub-list // inspect them in ASCII, it is much more convenient if each sub-list
// is flattened on a single line. // is flattened on a single line.
static Ostream& printMaps(Ostream& os, const labelListList& maps)
{
if (os.format() == IOstream::BINARY || maps.empty())
{
os << maps;
}
else
{
os << nl << maps.size() << nl
<< token::BEGIN_LIST << nl;
// Compact single-line output for each labelList
for (const labelList& map : maps)
{
map.writeList(os) << nl;
}
os << token::END_LIST;
}
return os;
}
static void writeMaps(Ostream& os, const word& key, const labelListList& maps) static void writeMaps(Ostream& os, const word& key, const labelListList& maps)
{ {
if (os.format() == IOstream::BINARY) if (os.format() == IOstream::BINARY || maps.empty())
{ {
os.writeEntry(key, maps); os.writeEntry(key, maps);
} }
else else
{ {
os << indent << key << nl os << indent << key;
<< maps.size() << nl printMaps(os, maps) << token::END_STATEMENT << nl;
<< token::BEGIN_LIST << nl;
// Single-line output
for (const labelList& map : maps)
{
map.writeList(os) << nl;
}
os << token::END_LIST << token::END_STATEMENT << nl;
} }
} }
@ -129,7 +143,8 @@ Foam::Istream& Foam::operator>>(Istream& is, mapDistributeBase& map)
{ {
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
is >> map.constructSize_ >> map.subMap_ >> map.constructMap_ is >> map.constructSize_
>> map.subMap_ >> map.constructMap_
>> map.subHasFlip_ >> map.constructHasFlip_ >> map.subHasFlip_ >> map.constructHasFlip_
>> map.comm_; >> map.comm_;
@ -139,11 +154,14 @@ Foam::Istream& Foam::operator>>(Istream& is, mapDistributeBase& map)
Foam::Ostream& Foam::operator<<(Ostream& os, const mapDistributeBase& map) Foam::Ostream& Foam::operator<<(Ostream& os, const mapDistributeBase& map)
{ {
os << map.constructSize_ << token::NL os << map.constructSize_ << token::NL;
<< map.subMap_ << token::NL
<< map.constructMap_ << token::NL printMaps(os, map.subMap_) << token::NL;
<< map.subHasFlip_ << token::SPACE << map.constructHasFlip_ printMaps(os, map.constructMap_) << token::NL;
<< token::SPACE << map.comm_ << token::NL;
os << map.subHasFlip_ << token::SPACE
<< map.constructHasFlip_ << token::SPACE
<< map.comm_ << token::NL;
return os; return os;
} }

View File

@ -29,6 +29,252 @@ License
#include "bitSet.H" #include "bitSet.H"
#include "ListOps.H" #include "ListOps.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Setup array of element masks to match maps sizes
//
// \param[out] masks Sized for each position in the maps
// \param maps The element maps
static void blankElementMasks(List<bitSet>& masks, const labelListList& maps)
{
// If base container not already sized
if (masks.empty())
{
masks.resize(maps.size());
}
forAll(masks, proci)
{
masks[proci].reset(); // zero all bits
masks[proci].resize(maps[proci].size());
}
}
// Calculate the element mask correspondig to allowedElems in the maps
//
// \param allowedElems Permissible mapped elements (true/false)
// \param[out] masks True/false for each position within the maps
// \param maps The element maps
// \param hasFlip Map has flip indexing
//
// \return the max index used.
static label calcElementMasks
(
const bitSet& allowedElems,
List<bitSet>& masks, // [out] - often presized before calling
const labelListList& maps,
const bool hasFlip
)
{
// Index after flipping
const auto unflippedIndex =
(
hasFlip
? [](label idx) -> label { return mag(idx)-1; }
: [](label idx) -> label { return idx; }
);
// If not already sized
if (masks.empty())
{
masks.resize(maps.size());
}
label maxIndex = -1;
forAll(masks, proci)
{
bitSet& mask = masks[proci];
const labelList& map = maps[proci];
mask.reset(); // zero all bits
mask.resize(map.size());
forAll(map, i)
{
// Element is used (or not)
const label index = unflippedIndex(map[i]);
if (allowedElems.test(index))
{
mask.set(i);
maxIndex = max(maxIndex, index);
}
}
}
return maxIndex;
}
} // End namespace Foam
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
void Foam::mapDistributeBase::exchangeMasks
(
const UList<bitSet>& sendMasks,
UList<bitSet>& recvMasks,
const int tag,
const label comm
)
{
// Require properly sized mask buffers.
// The information *is* known from the maps, so always use that
// instead having a needless all-to-all for the sizes.
if (sendMasks.size() != recvMasks.size())
{
FatalErrorInFunction
<< "Mismatched mask sizes: "
<< sendMasks.size() << " != "
<< recvMasks.size() << nl
<< Foam::abort(FatalError);
}
const label myRank = UPstream::myProcNo(comm);
if (UPstream::parRun())
{
#ifdef FULLDEBUG
if (sendMasks.size() > UPstream::nProcs(comm))
{
FatalErrorInFunction
<< "Mask sizes (" << sendMasks.size()
<< ") are larger than number of procs:"
<< UPstream::nProcs(comm) << nl
<< Foam::abort(FatalError);
}
#endif
const label startOfRequests = UPstream::nRequests();
forAll(recvMasks, proci)
{
if (proci != myRank && recvMasks[proci].size())
{
IPstream::read
(
UPstream::commsTypes::nonBlocking,
proci,
recvMasks[proci].data_bytes(),
recvMasks[proci].size_bytes(),
tag,
comm
);
}
}
forAll(sendMasks, proci)
{
if (proci != myRank && sendMasks[proci].size())
{
OPstream::write
(
UPstream::commsTypes::nonBlocking,
proci,
sendMasks[proci].cdata_bytes(),
sendMasks[proci].size_bytes(),
tag,
comm
);
}
}
// Wait for all to finish
Pstream::waitRequests(startOfRequests);
}
// Receiving myself is just a copy
recvMasks[myRank] = sendMasks[myRank];
}
void Foam::mapDistributeBase::unionCombineMasks
(
UList<bitSet>& sendMasks,
UList<bitSet>& recvMasks,
const int tag,
const label comm
)
{
// Require properly sized mask buffers.
// The information *is* known from the maps, so always use that
// instead having a needless all-to-all for the sizes.
if (sendMasks.size() != recvMasks.size())
{
FatalErrorInFunction
<< "Mismatched mask sizes: "
<< sendMasks.size() << " != "
<< recvMasks.size() << nl
<< Foam::abort(FatalError);
}
if (Pstream::parRun())
{
// Scratch buffers for union operations
List<bitSet> scratch(recvMasks.size());
// Size for receives
forAll(scratch, proci)
{
scratch[proci].resize(recvMasks[proci].size());
}
// Exchange: from sendMasks -> scratch (intermediate receive)
exchangeMasks(sendMasks, scratch, tag, comm);
// Update recvMasks (as union)
forAll(recvMasks, proci)
{
recvMasks[proci] &= scratch[proci];
}
// Size for sends
forAll(scratch, proci)
{
scratch[proci].resize(sendMasks[proci].size());
}
// Exchange: from recvMasks -> scratch (intermediate send)
exchangeMasks(recvMasks, scratch, tag, comm);
// Final synchronization
forAll(sendMasks, proci)
{
sendMasks[proci] &= scratch[proci];
}
}
else
{
// Non-parallel: 'synchronize' myself
const label myRank = Pstream::myProcNo(comm);
recvMasks[myRank] &= sendMasks[myRank];
sendMasks[myRank] = recvMasks[myRank];
}
// Done with parallel exchanges so can shrink the masks to
// the min-size actually needed.
for (auto& mask : sendMasks)
{
mask.resize_last();
}
for (auto& mask : recvMasks)
{
mask.resize_last();
}
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::label Foam::mapDistributeBase::renumberMap Foam::label Foam::mapDistributeBase::renumberMap
@ -128,4 +374,568 @@ void Foam::mapDistributeBase::renumberVisitOrder
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::mapDistributeBase::calcCompactDataRequirements
(
const bitSet& allowedLocalElems,
const bitSet& allowedRemoteElems,
List<bitSet>& sendMasks, // [out]
List<bitSet>& recvMasks, // [out]
const int tag
)
{
sendMasks.resize_nocopy(UPstream::nProcs(comm_));
recvMasks.resize_nocopy(UPstream::nProcs(comm_));
// Determine local elements sent to which procs
calcElementMasks
(
allowedLocalElems,
sendMasks,
subMap_,
subHasFlip_
);
// Determine remote elements received from which procs
calcElementMasks
(
allowedRemoteElems,
recvMasks,
constructMap_,
constructHasFlip_
);
// Synchronize - combine as '&' union
unionCombineMasks(sendMasks, recvMasks, tag, comm_);
}
void Foam::mapDistributeBase::calcCompactLocalDataRequirements
(
const bitSet& allowedLocalElems,
List<bitSet>& sendMasks, // [out]
List<bitSet>& recvMasks, // [out]
const int tag
)
{
sendMasks.resize_nocopy(UPstream::nProcs(comm_));
recvMasks.resize_nocopy(UPstream::nProcs(comm_));
// Determine local elements sent to which procs
calcElementMasks
(
allowedLocalElems,
sendMasks,
subMap_,
subHasFlip_
);
blankElementMasks(recvMasks, constructMap_);
// Exchange: from sendMasks -> recvMasks
exchangeMasks(sendMasks, recvMasks, tag, comm_);
}
void Foam::mapDistributeBase::calcCompactRemoteDataRequirements
(
const bitSet& allowedRemoteElems,
List<bitSet>& sendMasks, // [out]
List<bitSet>& recvMasks, // [out]
const int tag
)
{
sendMasks.resize_nocopy(UPstream::nProcs(comm_));
recvMasks.resize_nocopy(UPstream::nProcs(comm_));
// Determine remote elements received from which procs
calcElementMasks
(
allowedRemoteElems,
recvMasks,
constructMap_,
constructHasFlip_
);
blankElementMasks(sendMasks, subMap_);
// Exchange: from recvMasks -> sendMasks
exchangeMasks(recvMasks, sendMasks, tag, comm_);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::mapDistributeBase::compactData
(
const UList<bitSet>& sendMasks,
const UList<bitSet>& recvMasks,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const label localSize // (known) max sizing for subMap
)
{
// Linear address (subMap) after any flipping
const auto unflippedSendIndex =
(
subHasFlip_
? [](label idx) -> label { return mag(idx)-1; }
: [](label idx) -> label { return idx; }
);
// Linear address (constructMap) after any flipping
const auto unflippedRecvIndex =
(
constructHasFlip_
? [](label idx) -> label { return mag(idx)-1; }
: [](label idx) -> label { return idx; }
);
// Compact renumbering enabled if oldToNew maps are notNull
bitSet indexUsed;
// The subMap old-to-new mapping
if (notNull(oldToNewSub))
{
label subMapSize(localSize);
if (subMapSize < 0)
{
subMapSize = getMappedSize(subMap_, subHasFlip_);
}
oldToNewSub.resize_nocopy(subMapSize);
oldToNewSub = -1;
indexUsed.reset(); // zero all bits
indexUsed.resize(subMapSize);
forAll(sendMasks, proci)
{
const bitSet& mask = sendMasks[proci];
const auto& map = subMap_[proci];
for (const label i : mask)
{
const label index = unflippedSendIndex(map[i]);
indexUsed.set(index);
}
}
label nCompact = 0;
for (const label i : indexUsed)
{
oldToNewSub[i] = nCompact++;
}
}
// The constructMap old-to-new mapping
if (notNull(oldToNewConstruct))
{
oldToNewConstruct.resize_nocopy(constructSize_);
oldToNewConstruct = -1;
indexUsed.reset(); // zero all bits
indexUsed.resize(constructSize_);
forAll(recvMasks, proci)
{
const bitSet& mask = recvMasks[proci];
const auto& map = constructMap_[proci];
for (const label i : mask)
{
const label index = unflippedRecvIndex(map[i]);
indexUsed.set(index);
}
}
label nCompact = 0;
for (const label i : indexUsed)
{
oldToNewConstruct[i] = nCompact++;
}
}
// Compact out subMap entries referring to unused elements
forAll(sendMasks, proci)
{
const bitSet& mask = sendMasks[proci];
labelList& map = subMap_[proci];
label nCompact = 0;
for (const label i : mask)
{
// const label index = unflippedSendIndex(map[i]);
// maxLocalIndex = max(maxLocalIndex, index);
map[nCompact++] = map[i];
}
map.resize(nCompact);
}
// Compact out constructMap entries referring to unused elements
label maxRemoteIndex = -1;
forAll(recvMasks, proci)
{
const bitSet& mask = recvMasks[proci];
labelList& map = constructMap_[proci];
label nCompact = 0;
for (const label i : mask)
{
const label index = unflippedRecvIndex(map[i]);
maxRemoteIndex = max(maxRemoteIndex, index);
map[nCompact++] = map[i];
}
map.resize(nCompact);
}
constructSize_ = maxRemoteIndex+1;
// Do compact renumbering...
if (notNull(oldToNewSub))
{
renumberMap(subMap_, oldToNewSub, subHasFlip_);
}
if (notNull(oldToNewConstruct))
{
constructSize_ =
renumberMap(constructMap_, oldToNewConstruct, constructHasFlip_);
}
// Clear the schedule (note:not necessary if nothing changed)
schedulePtr_.reset(nullptr);
}
void Foam::mapDistributeBase::compactData
(
const labelUList& localElements,
const labelUList& remoteElements,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const label localSize,
const int tag
)
{
List<bitSet> sendMasks;
List<bitSet> recvMasks;
calcCompactDataRequirements
(
bitSet(localElements),
bitSet(remoteElements),
sendMasks,
recvMasks,
tag
);
// Perform compaction and renumbering
compactData
(
sendMasks,
recvMasks,
oldToNewSub,
oldToNewConstruct,
localSize
);
// Renumber according to visit order
renumberVisitOrder
(
localElements,
oldToNewSub,
subMap_,
subHasFlip_
);
// Renumber according to visit order
renumberVisitOrder
(
remoteElements,
oldToNewConstruct,
constructMap_,
constructHasFlip_
);
}
void Foam::mapDistributeBase::compactLocalData
(
const labelUList& localElements,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const label localSize,
const int tag
)
{
List<bitSet> sendMasks;
List<bitSet> recvMasks;
calcCompactLocalDataRequirements
(
// Retain items required on the local side
bitSet(localElements),
sendMasks,
recvMasks,
tag
);
// Perform compaction and renumbering
compactData
(
sendMasks,
recvMasks,
oldToNewSub,
oldToNewConstruct,
localSize
);
// Renumber according to visit order
renumberVisitOrder
(
localElements,
oldToNewSub,
subMap_,
subHasFlip_
);
}
void Foam::mapDistributeBase::compactRemoteData
(
const labelUList& remoteElements,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const label localSize,
const int tag
)
{
List<bitSet> sendMasks;
List<bitSet> recvMasks;
calcCompactRemoteDataRequirements
(
// Retain items required on the remote side
bitSet(remoteElements),
sendMasks,
recvMasks,
tag
);
// Perform compaction and renumbering
compactData
(
sendMasks,
recvMasks,
oldToNewSub,
oldToNewConstruct,
localSize
);
// Renumber according to visit order
renumberVisitOrder
(
remoteElements,
oldToNewConstruct,
constructMap_,
constructHasFlip_
);
}
void Foam::mapDistributeBase::compactDataImpl
(
const UList<bitSet>& sendMasks,
const UList<bitSet>& recvMasks,
const bool doRenumber
)
{
if (doRenumber)
{
labelList oldToNewSub;
labelList oldToNewConstruct;
compactData
(
sendMasks,
recvMasks,
oldToNewSub,
oldToNewConstruct,
-1 // localSize: automatic
);
}
else
{
// Call with placeholder values
compactData
(
sendMasks,
recvMasks,
const_cast<labelList&>(labelList::null()), // disabled
const_cast<labelList&>(labelList::null()), // disabled
-1 // localSize: automatic
);
}
}
void Foam::mapDistributeBase::compactLocalData
(
const bitSet& allowedLocalElems,
const int tag,
const bool doRenumber
)
{
List<bitSet> sendMasks;
List<bitSet> recvMasks;
calcCompactLocalDataRequirements
(
allowedLocalElems,
sendMasks,
recvMasks,
tag
);
compactDataImpl(sendMasks, recvMasks, doRenumber);
}
void Foam::mapDistributeBase::compactRemoteData
(
const bitSet& allowedRemoteElems,
const int tag,
const bool doRenumber
)
{
List<bitSet> sendMasks;
List<bitSet> recvMasks;
calcCompactRemoteDataRequirements
(
allowedRemoteElems,
sendMasks,
recvMasks,
tag
);
compactDataImpl(sendMasks, recvMasks, doRenumber);
}
void Foam::mapDistributeBase::compactLocalData
(
const bitSet& allowedLocalElems,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const label localSize,
const int tag
)
{
List<bitSet> sendMasks;
List<bitSet> recvMasks;
calcCompactLocalDataRequirements
(
allowedLocalElems,
sendMasks,
recvMasks,
tag
);
compactData
(
sendMasks,
recvMasks,
oldToNewSub,
oldToNewConstruct,
localSize
);
}
void Foam::mapDistributeBase::compactRemoteData
(
const bitSet& allowedRemoteElems,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const label localSize,
const int tag
)
{
List<bitSet> sendMasks;
List<bitSet> recvMasks;
calcCompactRemoteDataRequirements
(
allowedRemoteElems,
sendMasks,
recvMasks,
tag
);
compactData
(
sendMasks,
recvMasks,
oldToNewSub,
oldToNewConstruct,
localSize
);
}
// * * * * * * * * * * * * * * * Housekeeping * * * * * * * * * * * * * * * //
void Foam::mapDistributeBase::compact
(
const boolList& remoteElemUsed,
const int tag
)
{
// Forward to bitSet version
compactRemoteData(bitSet(remoteElemUsed), tag);
}
void Foam::mapDistributeBase::compact
(
const boolList& remoteElemUsed,
const label localSize,
labelList& oldToNewSub,
labelList& oldToNewConstruct,
const int tag
)
{
// Forward to bitSet version
compactRemoteData
(
bitSet(remoteElemUsed),
oldToNewSub,
oldToNewConstruct,
localSize,
tag
);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -150,9 +150,11 @@ Foam::Istream& Foam::operator>>(Istream& is, mapDistributePolyMesh& map)
is >> map.nOldPoints_ is >> map.nOldPoints_
>> map.nOldFaces_ >> map.nOldFaces_
>> map.nOldCells_ >> map.nOldCells_
>> map.oldPatchSizes_ >> map.oldPatchSizes_
>> map.oldPatchStarts_ >> map.oldPatchStarts_
>> map.oldPatchNMeshPoints_ >> map.oldPatchNMeshPoints_
>> map.pointMap_ >> map.pointMap_
>> map.faceMap_ >> map.faceMap_
>> map.cellMap_ >> map.cellMap_
@ -171,6 +173,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const mapDistributePolyMesh& map)
<< map.oldPatchSizes_ << token::NL << map.oldPatchSizes_ << token::NL
<< map.oldPatchStarts_ << token::NL << map.oldPatchStarts_ << token::NL
<< map.oldPatchNMeshPoints_ << token::NL << map.oldPatchNMeshPoints_ << token::NL
<< map.pointMap_ << token::NL << map.pointMap_ << token::NL
<< map.faceMap_ << token::NL << map.faceMap_ << token::NL
<< map.cellMap_ << token::NL << map.cellMap_ << token::NL

View File

@ -0,0 +1,135 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
fieldsDistributor
Description
Common methods/utilities for field decomposers/distributors etc.
SourceFiles
fieldsDistributorTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_fieldsDistributor_H
#define Foam_fieldsDistributor_H
#include "IOobjectList.H"
#include "boolList.H"
#include "PtrList.H"
#include "GeometricField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
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>
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 IOobjectList& objects,
PtrList<GeometricField<Type, PatchField, GeoMesh>>& fields,
const bool readOldTime
);
//- Read fields and hold on the pointer list
template<class Mesh, class GeoField>
static void readFields
(
const Mesh& mesh,
const IOobjectList& objects,
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
#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

@ -24,6 +24,9 @@ $(faPatches)/constraint/wedge/wedgeFaPatch.C
$(faPatches)/constraint/cyclic/cyclicFaPatch.C $(faPatches)/constraint/cyclic/cyclicFaPatch.C
$(faPatches)/constraint/symmetry/symmetryFaPatch.C $(faPatches)/constraint/symmetry/symmetryFaPatch.C
distributed/faMeshDistributor.C
distributed/faMeshDistributorNew.C
ensight = output/ensight ensight = output/ensight
$(ensight)/ensightFaMesh.C $(ensight)/ensightFaMesh.C

View File

@ -0,0 +1,200 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "faMeshDistributor.H"
#include "BitOps.H"
#include "fileOperation.H"
#include "areaFields.H"
#include "edgeFields.H"
#include "faMeshTools.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::faMeshDistributor::verbose_ = 0;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::faMeshDistributor::createPatchMaps() const
{
const faBoundaryMesh& oldPatches = srcMesh_.boundary();
const faBoundaryMesh& newPatches = tgtMesh_.boundary();
patchEdgeMaps_.clear();
patchEdgeMaps_.resize(oldPatches.size());
// area: edgeMap (volume: faceMap)
const auto& faEdgeMap = distMap_.faceMap();
// The logical edge ranges per patch [target mesh]
List<labelRange> ranges = newPatches.patchRanges();
forAll(oldPatches, patchi)
{
if (!isA<processorFaPatch>(oldPatches[patchi]))
{
// Map non-processor only
// Copy full map
patchEdgeMaps_.set
(
patchi,
new mapDistributeBase(faEdgeMap)
);
// Retain patch elements
patchEdgeMaps_[patchi].compactRemoteData
(
bitSet(ranges[patchi]),
UPstream::msgType(),
true // Also renumber/resize the compact maps
);
}
}
}
void Foam::faMeshDistributor::createInternalEdgeMap() const
{
// area: edgeMap (volume: faceMap)
const auto& faEdgeMap = distMap_.faceMap();
// Copy full map
internalEdgeMap_.reset(new mapDistributeBase(faEdgeMap));
// Retain internal edges
internalEdgeMap_->compactRemoteData
(
bitSet(tgtMesh_.nInternalEdges(), true),
UPstream::msgType(),
true // Also renumber/resize the compact maps
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faMeshDistributor::faMeshDistributor
(
const faMesh& srcMesh,
const faMesh& tgtMesh,
const mapDistributePolyMesh& distMap,
const bool isWriteProc
)
:
srcMesh_(srcMesh),
tgtMesh_(tgtMesh),
distMap_(distMap),
internalEdgeMap_(),
patchEdgeMaps_(),
isWriteProc_(isWriteProc)
{
#ifdef FULLDEBUG
{
Pout<< "Create from nFaces:" << srcMesh.faceLabels().size()
<< " to:" << tgtMesh.faceLabels().size() << endl;
vectorField oldFaceCentres(srcMesh_.areaCentres());
vectorField newFaceCentres(tgtMesh_.areaCentres());
// volume: cells, area: faces
distMap_.distributeCellData(oldFaceCentres);
vectorField diff(newFaceCentres - oldFaceCentres);
Pout<< "diff faces: " << diff << endl;
vectorField oldEdgeCentres
(
faMeshTools::flattenEdgeField(srcMesh_.edgeCentres())
);
vectorField newEdgeCentres
(
faMeshTools::flattenEdgeField(tgtMesh_.edgeCentres())
);
Pout<< "distributed edges: " << oldEdgeCentres.size() << " from "
<< srcMesh.nEdges() << " to " << tgtMesh.nEdges() << endl;
// volume: faces, area: edges
distMap_.distributeFaceData(oldEdgeCentres);
diff = (newEdgeCentres - oldEdgeCentres);
Pout<< "diff edges: " << diff << endl;
Info<< "Patch edge maps" << endl;
forAll(patchEdgeMaps_, patchi)
{
if (patchEdgeMaps_.set(patchi))
{
Pout<< "patch " << patchi << " : "
<< patchEdgeMaps_[patchi].info() << endl;
}
}
Info<< nl << "Detailed patch maps" << endl;
forAll(patchEdgeMaps_, patchi)
{
if (patchEdgeMaps_.set(patchi))
{
Info<< "patch " << patchi << " : "
<< patchEdgeMaps_[patchi] << endl;
}
}
}
#endif
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::faMeshDistributor::distributeAllFields
(
const IOobjectList& objects,
const wordRes& selected
) const
{
label nTotal = 0;
nTotal += distributeAreaFields<scalar>(objects, selected);
nTotal += distributeAreaFields<vector>(objects, selected);
nTotal += distributeAreaFields<symmTensor>(objects, selected);
nTotal += distributeAreaFields<sphericalTensor>(objects, selected);
nTotal += distributeAreaFields<tensor>(objects, selected);
nTotal += distributeEdgeFields<scalar>(objects, selected);
nTotal += distributeEdgeFields<vector>(objects, selected);
nTotal += distributeEdgeFields<symmTensor>(objects, selected);
nTotal += distributeEdgeFields<sphericalTensor>(objects, selected);
nTotal += distributeEdgeFields<tensor>(objects, selected);
return nTotal;
}
// ************************************************************************* //

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/>.
Class
Foam::faMeshDistributor
Description
Holds a reference to the original mesh (the baseMesh)
and optionally to a subset of that mesh (the subMesh)
with mapping lists for points, faces, and cells.
SourceFiles
faMeshDistributor.C
faMeshDistributorNew.C
faMeshDistributorTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_faMeshDistributor_H
#define Foam_faMeshDistributor_H
#include "faMesh.H"
#include "mapDistributePolyMesh.H"
#include "areaFieldsFwd.H"
#include "edgeFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class IOobjectList;
/*---------------------------------------------------------------------------*\
Class faMeshDistributor Declaration
\*---------------------------------------------------------------------------*/
class faMeshDistributor
{
// Private Data
//- The source mesh reference
const faMesh& srcMesh_;
//- The destination mesh reference
const faMesh& tgtMesh_;
//- Distribution map reference (faMesh)
const mapDistributePolyMesh& distMap_;
//- Internal edge mapper
mutable std::unique_ptr<mapDistributeBase> internalEdgeMap_;
//- Patch edge mappers
mutable PtrList<mapDistributeBase> patchEdgeMaps_;
//- Do I need to write (eg, master only for reconstruct)
bool isWriteProc_;
// Private Member Functions
//- Construct internal edge mapping
void createInternalEdgeMap() const;
//- Construct per-patch edge mapping
void createPatchMaps() const;
static mapDistributePolyMesh createReconstructMap
(
const faMesh& mesh,
const autoPtr<faMesh>& baseMeshPtr,
const labelUList& faceProcAddr,
const labelUList& edgeProcAddr,
const labelUList& pointProcAddr,
const labelUList& boundaryProcAddr
);
//- No copy construct
faMeshDistributor(const faMeshDistributor&) = delete;
//- No copy assignment
void operator=(const faMeshDistributor&) = delete;
public:
//- Output verbosity when writing
static int verbose_;
// Constructors
//- Construct from components
faMeshDistributor
(
const faMesh& srcMesh,
const faMesh& tgtMesh,
const mapDistributePolyMesh& faDistMap,
const bool isWriteProc = false
);
// Static Methods
//- Distribute mesh according to the given (volume) mesh distribution.
// Uses 'tgtPolyMesh' for the new mesh
static mapDistributePolyMesh distribute
(
const faMesh& oldMesh,
const mapDistributePolyMesh& distMap, //! From polyMesh
const polyMesh& tgtPolyMesh,
autoPtr<faMesh>& newMeshPtr
);
//- Distribute mesh according to the given (volume) mesh distribution.
// Re-uses polyMesh from oldMesh for the new mesh
static mapDistributePolyMesh distribute
(
const faMesh& oldMesh,
const mapDistributePolyMesh& distMap, //! From polyMesh
autoPtr<faMesh>& newMeshPtr
);
// Member Functions
//- Get status of write enabled (on this proc)
bool isWriteProc() const noexcept
{
return isWriteProc_;
}
//- Change status of write enabled (on this proc)
bool isWriteProc(const bool on) noexcept
{
bool old(isWriteProc_);
isWriteProc_ = on;
return old;
}
// Field Mapping
//- Read, distribute and write all/selected point field types
//- (scalar, vector, ... types)
label distributeAllFields
(
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
) const;
//- Distribute area field
template<class Type>
tmp<GeometricField<Type, faPatchField, areaMesh>>
distributeField
(
const GeometricField<Type, faPatchField, areaMesh>& fld
) const;
//- Distribute edge field
template<class Type>
tmp<GeometricField<Type, faePatchField, edgeMesh>>
distributeField
(
const GeometricField<Type, faePatchField, edgeMesh>& fld
) const;
//- Read and distribute area field
template<class Type>
tmp<GeometricField<Type, faPatchField, areaMesh>>
distributeAreaField
(
const IOobject& fieldObject
) const;
//- Read and distribute edge field
template<class Type>
tmp<GeometricField<Type, faePatchField, edgeMesh>>
distributeEdgeField
(
const IOobject& fieldObject
) const;
//- Read, distribute and write all/selected area fields
template<class Type>
label distributeAreaFields
(
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
) const;
//- Read, distribute and write all/selected area fields
template<class Type>
label distributeEdgeFields
(
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "faMeshDistributorTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,916 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "faMeshDistributor.H"
#include "globalIndex.H"
#include "BitOps.H"
#include "ListOps.H"
#include "mapDistributePolyMesh.H"
#include "processorFaPatch.H"
#include "labelPairHashes.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::mapDistributePolyMesh
Foam::faMeshDistributor::distribute
(
const faMesh& oldMesh,
const mapDistributePolyMesh& distMap,
const polyMesh& tgtPolyMesh,
autoPtr<faMesh>& newMeshPtr
)
{
newMeshPtr.reset(nullptr);
const uindirectPrimitivePatch& oldAreaPatch = oldMesh.patch();
// Original (patch) sizes before any changes
const label nOldPoints = oldAreaPatch.nPoints();
const label nOldEdges = oldAreaPatch.nEdges();
const label nOldFaces = oldAreaPatch.nFaces();
// ------------------------
// Step 1: The face mapping
// ------------------------
// Relatively straightforward.
// - a subset of face selections on the polyMesh faceMap
mapDistributeBase faFaceMap(distMap.faceMap());
{
// Retain faces needed for the faMesh - preserve original order
// Note can use compactLocalData without problem since
// finiteArea is only defined on real boundary faces so there
// is no danger of sending an internal or processor face.
labelList oldToNewSub;
labelList oldToNewConstruct;
faFaceMap.compactLocalData
(
oldMesh.faceLabels(),
oldToNewSub,
oldToNewConstruct,
distMap.nOldFaces(),
UPstream::msgType()
);
// The receiving side:
// Mapped faces (>= 0) are the polyMesh face labels that define
// the faMesh. Since the compact order is implicitly sorted in
// ascending order, it tends to form contiguous ranges on the
// polyPatches, which serves our purpose nicely.
labelList newFaceLabels
(
ListOps::findIndices(oldToNewConstruct, labelRange::ge0())
);
// Set up to read-if-present
IOobject io(tgtPolyMesh);
io.readOpt(IOobject::READ_IF_PRESENT);
newMeshPtr.reset
(
new faMesh(tgtPolyMesh, std::move(newFaceLabels), io)
);
}
// The face map is now complete.
// The new faMesh and the corresponding primitive patch
auto& newMesh = newMeshPtr();
const uindirectPrimitivePatch& newAreaPatch = newMesh.patch();
// ------------------------
// Step 2: The edge mapping
// ------------------------
// Use globally unique addressing to identify both sides of the edges.
// A local bookkeeping struct of (face0 face1 edge0 edge1)
// selected for a stable and unique sort
struct faceEdgeTuple : public FixedList<label, 4>
{
// Inherit constructors
using FixedList<label, 4>::FixedList;
// Default construct as 'invalid'
faceEdgeTuple() : FixedList<label, 4>(-1) {}
// Is empty if face indices are negative
bool empty() const
{
return (face0() < 0 && face1() < 0);
}
// Global face numbers are the first sort index
label face0() const { return (*this)[0]; }
label face1() const { return (*this)[1]; }
// Additional sorting based on edges
label edge0() const { return (*this)[2]; }
label edge1() const { return (*this)[3]; }
label getFace(int i) const { return (*this)[(i ? 1 : 0)]; }
label getEdge(int i) const { return (*this)[(i ? 3 : 2)]; }
labelPair getFaces() const { return labelPair(face0(), face1()); }
labelPair getPair0() const { return labelPair(face0(), edge0()); }
// labelPair getPair1() const { return labelPair(face1(), edge1()); }
// Canonically sorted order
void canonical()
{
if (face1() >= 0 && face0() >= face1())
{
std::swap((*this)[0], (*this)[1]);
std::swap((*this)[2], (*this)[3]);
}
}
// Slot a face-edge pair into a free location in the tuple
void add(const labelPair& faceEdge)
{
if ((*this)[0] < 0) // face0
{
(*this)[0] = faceEdge.first(); // face
(*this)[2] = faceEdge.second(); // edge
}
else if ((*this)[1] < 0) // face1
{
(*this)[1] = faceEdge.first(); // face
(*this)[3] = faceEdge.second(); // edge
}
}
// Combine operation
void combine(const faceEdgeTuple& y)
{
auto& x = *this;
if (y.empty() || x == y)
{
// Nothing to do
}
else if (x.empty())
{
x = y;
}
else // Both non-empty, but non-identical (should not occur)
{
FatalErrorInFunction
<< "Unexpected edge matching: "
<< x << " vs. " << y << endl
<< exit(FatalError);
}
}
// Combine operation
void operator()(faceEdgeTuple& x, const faceEdgeTuple& y) const
{
x.combine(y);
}
};
// ------------------------
// (Edge mapping)
// ------------------------
// 1.
// Create a list of destination edges for each face,
// appended by a unique face identifier.
// Using global face numbering from the *target* mesh.
const globalIndex uniqFaceIndex(newAreaPatch.nFaces());
labelListList dstFaceEdgeIds(newAreaPatch.nFaces());
forAll(newAreaPatch.faceEdges(), facei)
{
const labelList& fEdges = newAreaPatch.faceEdges()[facei];
labelList& dstEdges = dstFaceEdgeIds[facei];
dstEdges.resize(fEdges.size() + 1);
// Leading entries are the destination (patch) edge indices
labelSubList(dstEdges, fEdges.size()) = fEdges;
// Last entry is the face id
dstEdges.last() = uniqFaceIndex.toGlobal(facei);
}
// Send back to the original mesh locations
faFaceMap.reverseDistribute(nOldFaces, dstFaceEdgeIds);
// 2.
// Walk all original faces and their edges to generate a edge lookup
// table with the destination face/edge information.
// Eg ((globFacei, localEdgei), (globFacei, localEdgei))
// NB: currently no provision for face flips, which would potentially
// reverse the local edge order.
List<faceEdgeTuple> halfEdgeLookup(nOldEdges, faceEdgeTuple());
forAll(oldAreaPatch.faceEdges(), facei)
{
const labelList& fEdges = oldAreaPatch.faceEdges()[facei];
// The corresponding destination edges (+ uniqFacei).
const labelList& dstFaceEdges = dstFaceEdgeIds[facei];
// Last entry has the unique destination face id
const label uniqFacei = dstFaceEdges.last();
forAll(fEdges, faceEdgei)
{
const label srcEdgei = fEdges[faceEdgei];
const label dstEdgei = dstFaceEdges[faceEdgei];
halfEdgeLookup[srcEdgei].add(labelPair(uniqFacei, dstEdgei));
}
}
// 3.
// Add patch indices - encoded as '-(patchId + 2)' for
// non-processor boundaries (will be needed later).
// Also record which procs get patches from here [proc] -> [patches]
// Use for building patchMap
Map<labelHashSet> patchMapInfo;
label nNonProcessor(0);
{
const faBoundaryMesh& oldBndMesh = oldMesh.boundary();
forAll(oldBndMesh, patchi)
{
const faPatch& fap = oldBndMesh[patchi];
if (isA<processorFaPatch>(fap))
{
break;
}
++nNonProcessor;
// Encoded as -(patchId + 2)
const labelPair encodedPatchId(-(patchi+2), -(patchi+2));
for (const label srcEdgei : fap.edgeLabels())
{
faceEdgeTuple& facePairings = halfEdgeLookup[srcEdgei];
facePairings.add(encodedPatchId);
label dstFacei = facePairings.face0();
label proci = uniqFaceIndex.whichProcID(dstFacei);
patchMapInfo(proci).insert(patchi);
}
}
Pstream::broadcast(nNonProcessor);
}
// Processor-processor connections
if (Pstream::parRun())
{
const label startOfRequests = Pstream::nRequests();
const faBoundaryMesh& oldBndMesh = oldMesh.boundary();
// Setup sends
for (const faPatch& fap : oldBndMesh)
{
const auto* fapp = isA<processorFaPatch>(fap);
if (fapp)
{
// Send (dstFacei dstEdgei) per patch edge.
// Since we are walking a boundary edge, the first location
// from the previously established lookup provides
// our information.
List<labelPair> edgeTuples(fap.edgeLabels().size());
label edgeTuplei = 0;
for (const label edgei : fap.edgeLabels())
{
edgeTuples[edgeTuplei] = halfEdgeLookup[edgei].getPair0();
++edgeTuplei;
}
fapp->send<labelPair>
(
Pstream::commsTypes::nonBlocking,
edgeTuples
);
}
}
// Wait for all to finish
Pstream::waitRequests(startOfRequests);
// Receive values
for (const faPatch& fap : oldBndMesh)
{
const auto* fapp = isA<processorFaPatch>(fap);
if (fapp)
{
// Receive (dstFacei dstEdgei) per patch edge.
// - slot into the second location of the lookup
List<labelPair> edgeTuples(fap.edgeLabels().size());
fapp->receive<labelPair>
(
Pstream::commsTypes::nonBlocking,
edgeTuples
);
label edgeTuplei = 0;
for (const label srcEdgei : fap.edgeLabels())
{
halfEdgeLookup[srcEdgei].add(edgeTuples[edgeTuplei]);
++edgeTuplei;
}
}
}
}
// Globally consistent order
for (auto& tuple : halfEdgeLookup)
{
tuple.canonical();
}
// Now ready to actually construct the edgeMap
mapDistributeBase faEdgeMap
(
newAreaPatch.nEdges(), // constructSize
labelListList(), // subMap
labelListList(), // constructMap
false, // subHasFlip
false, // constructHasFlip
faFaceMap.comm()
);
{
// Pass 1.
// Count the number of edges to be sent to each proc
labelList nProcEdges(Pstream::nProcs(faFaceMap.comm()), Zero);
forAll(halfEdgeLookup, srcEdgei)
{
const faceEdgeTuple& facePairings = halfEdgeLookup[srcEdgei];
labelPair dstProcs(-1, -1);
for (int sidei = 0; sidei < 2; ++sidei)
{
const label dstFacei = facePairings.getFace(sidei);
//const label dstEdgei = facePairings.getEdge(sidei);
if (dstFacei < 0)
{
continue;
}
label proci = uniqFaceIndex.whichProcID(dstFacei);
dstProcs[sidei] = proci;
if (proci != -1 && dstProcs[0] != dstProcs[1])
{
++nProcEdges[proci];
}
}
}
auto& edgeSubMap = faEdgeMap.subMap();
auto& edgeCnstrMap = faEdgeMap.constructMap();
edgeSubMap.resize(nProcEdges.size());
edgeCnstrMap.resize(nProcEdges.size());
labelListList remoteEdges(nProcEdges.size());
forAll(nProcEdges, proci)
{
edgeSubMap[proci].resize(nProcEdges[proci], -1);
remoteEdges[proci].resize(nProcEdges[proci], -1);
}
// Pass 2.
// Fill in the maps
nProcEdges = Zero; // Reset counter
forAll(halfEdgeLookup, srcEdgei)
{
const faceEdgeTuple& facePairings = halfEdgeLookup[srcEdgei];
labelPair dstProcs(-1, -1);
for (int sidei = 0; sidei < 2; ++sidei)
{
const label dstFacei = facePairings.getFace(sidei);
const label dstEdgei = facePairings.getEdge(sidei);
if (dstFacei < 0)
{
continue;
}
label proci = uniqFaceIndex.whichProcID(dstFacei);
dstProcs[sidei] = proci;
if (proci != -1 && dstProcs[0] != dstProcs[1])
{
edgeSubMap[proci][nProcEdges[proci]] = srcEdgei;
remoteEdges[proci][nProcEdges[proci]] = dstEdgei;
++nProcEdges[proci];
}
}
}
// The remoteEdges are what we know locally about what will be
// received, but not what is actually received.
// So need an all-to-all exchange
Pstream::exchange<labelList, label>
(
remoteEdges,
edgeCnstrMap,
UPstream::msgType(),
faEdgeMap.comm()
);
}
// The edge map is now complete [in PrimitivePatch edge order]
if (oldMesh.hasInternalEdgeLabels())
{
// If there are gaps in the edge numbering or the
// internal edge labels are out of sequence would
// have to use compactLocalData etc before sending
// But just issue an error for now
FatalErrorInFunction
<< "Originating faMesh has gaps in the edge addressing"
<< " this is currently unsupported"
<< abort(FatalError);
}
// ------------------------
// Patch edge labels
// ------------------------
faPatchList newFaPatches;
// Distribute the edge lookups.
// Needs full version for the combine operation
mapDistributeBase::distribute<faceEdgeTuple, faceEdgeTuple, identityOp>
(
Pstream::commsTypes::nonBlocking,
List<labelPair>::null(),
faEdgeMap.constructSize(),
faEdgeMap.subMap(),
faEdgeMap.subHasFlip(),
faEdgeMap.constructMap(),
faEdgeMap.constructHasFlip(),
halfEdgeLookup,
faceEdgeTuple(), // nullValue
faceEdgeTuple(), // CombineOp
identityOp(), // NegateOp
UPstream::msgType(),
faEdgeMap.comm()
);
{
// Pass 1.
// Count the number of edges for each patch type
Map<label> nNonProcEdges(2*nNonProcessor);
LabelPairMap<label> nProcEdges(2*nNonProcessor);
forAll(halfEdgeLookup, edgei)
{
const auto& tuple = halfEdgeLookup[edgei];
labelPair target(tuple.getFaces());
if (target[1] < -1)
{
// Neighbour face was patchId encoded value
label patchi = mag(target[1])-2;
++nNonProcEdges(patchi);
}
else if (target[0] >= 0 && target[1] >= 0)
{
// From global face to proc id
target[0] = uniqFaceIndex.whichProcID(target[0]);
target[1] = uniqFaceIndex.whichProcID(target[1]);
// A connection between different procs but involving
// myProc?
if
(
target[0] != target[1]
&&
(
target[0] == Pstream::myProcNo()
|| target[1] == Pstream::myProcNo()
)
)
{
++nProcEdges(target);
}
}
}
label nPatches = (nNonProcessor + nProcEdges.size());
newFaPatches.resize(nPatches);
labelList nEdgeLabels(nPatches, Zero);
labelListList newEdgeLabels(nPatches);
LabelPairMap<label> procPairToPatchId(2*nProcEdges.size());
// Map processor-pair to index in patches
{
nPatches = nNonProcessor;
for (const labelPair& twoProcs : nProcEdges.sortedToc())
{
procPairToPatchId.set(twoProcs, nPatches);
++nPatches;
}
}
// Presize edgeLabels arrays
{
nPatches = 0;
for (label patchi = 0; patchi < nNonProcessor; ++patchi)
{
label nLabels = nNonProcEdges.lookup(nPatches, 0);
nEdgeLabels[nPatches] = nLabels;
newEdgeLabels[nPatches].resize(nLabels);
++nPatches;
}
// Processor patches
for (const labelPair& twoProcs : nProcEdges.sortedToc())
{
label nLabels = nProcEdges.lookup(twoProcs, 0);
nEdgeLabels[nPatches] = nLabels;
newEdgeLabels[nPatches].resize(nLabels);
++nPatches;
}
}
nEdgeLabels = Zero;
// Populate edgeLabels arrays - walk in canonically sorted
// order to ensure that both sides of processor edges
// correspond.
const labelList order(Foam::sortedOrder(halfEdgeLookup));
for (const label edgei : order)
{
const auto& tuple = halfEdgeLookup[edgei];
labelPair target(tuple.getFaces());
label patchi = -1;
if (target[1] < -1)
{
// Neighbour face was patchId encoded value
patchi = mag(target[1])-2;
}
else if (target[0] >= 0 && target[1] >= 0)
{
// From global face to proc id
target[0] = uniqFaceIndex.whichProcID(target[0]);
target[1] = uniqFaceIndex.whichProcID(target[1]);
// A connection between different procs but involving
// myProc?
if
(
target[0] != target[1]
&&
(
target[0] == Pstream::myProcNo()
|| target[1] == Pstream::myProcNo()
)
)
{
patchi = procPairToPatchId.lookup(target, -1);
}
}
if (patchi >= 0)
{
const label idx = nEdgeLabels[patchi]++;
newEdgeLabels[patchi][idx] = edgei;
}
}
// Clone all non-processor patches
nPatches = 0;
for (label patchi = 0; patchi < nNonProcessor; ++patchi)
{
newFaPatches.set
(
nPatches,
oldMesh.boundary()[patchi].clone
(
newMesh.boundary(),
newEdgeLabels[nPatches], // edgeLabels
nPatches,
oldMesh.boundary()[patchi].ngbPolyPatchIndex()
)
);
++nPatches;
}
// Any processor patches
for (const labelPair& twoProcs : nProcEdges.sortedToc())
{
label nbrProcNo =
(
twoProcs[1] == Pstream::myProcNo()
? twoProcs[0] : twoProcs[1]
);
newFaPatches.set
(
nPatches,
new processorFaPatch
(
newEdgeLabels[nPatches], // edgeLabels
nPatches,
newMesh.boundary(),
-1, // nbrPolyPatchi
Pstream::myProcNo(),
nbrProcNo
)
);
++nPatches;
}
}
newMesh.addFaPatches(newFaPatches);
newMesh.init(true);
// At this stage we now have a complete mapping overview in
// terms of the PrimitivePatch edge ordering which now must be
// changed into faMesh edge ordering.
{
labelList oldToNewSub;
labelList oldToNewConstruct;
// Assume we use all patch edges for the faMesh too.
oldToNewSub.resize(oldAreaPatch.nEdges(), -1);
oldToNewConstruct.resize(newAreaPatch.nEdges(), -1);
// Remap old edges
label nEdges = 0;
// Internal edgeLabels
for
(
label edgei = 0;
edgei < oldAreaPatch.nInternalEdges();
++edgei
)
{
oldToNewSub[edgei] = nEdges++;
}
// Boundary edgeLabels
for (const faPatch& fap : oldMesh.boundary())
{
for (const label edgei : fap.edgeLabels())
{
oldToNewSub[edgei] = nEdges++;
}
}
// New edges
nEdges = 0;
// Internal edgeLabels
for
(
label edgei = 0;
edgei < newAreaPatch.nInternalEdges();
++edgei
)
{
oldToNewConstruct[edgei] = nEdges++;
}
// Boundary edgeLabels
for (const faPatch& fap : newMesh.boundary())
{
for (const label edgei : fap.edgeLabels())
{
oldToNewConstruct[edgei] = nEdges++;
}
}
mapDistributeBase::renumberMap
(
faEdgeMap.subMap(),
oldToNewSub,
faEdgeMap.subHasFlip()
);
mapDistributeBase::renumberMap
(
faEdgeMap.constructMap(),
oldToNewConstruct,
faEdgeMap.constructHasFlip()
);
}
// ------------------------
// Patch mapping
// ------------------------
mapDistributeBase faPatchMap
(
newMesh.boundary().size(), // constructSize
labelListList(), // subMap
labelListList(), // constructMap
false, // subHasFlip
false, // constructHasFlip
faFaceMap.comm()
);
// For patch maps, would normally transcribe from patchMapInfo
// gathered earlier. However, existing practice (APR-2022) for
// faMesh decomposition is to map all non-processor patches
{
// Map all non-processor patches
const label nProcs = UPstream::nProcs(faPatchMap.comm());
faPatchMap.subMap().resize(nProcs, identity(nNonProcessor));
faPatchMap.constructMap().resize(nProcs, identity(nNonProcessor));
}
/// {
/// // Transcribe from patchMapInfo gathered earlier.
/// // - transform Map of labelHashSet to labelListList
///
/// labelListList sendToRemote(Pstream::nProcs(faPatchMap.comm()));
///
/// forAllConstIters(patchMapInfo, iter)
/// {
/// const label proci = iter.key();
/// sendToRemote[proci] = iter.val().sortedToc();
/// }
///
/// auto& patchSubMap = faPatchMap.subMap();
/// auto& patchCnstrMap = faPatchMap.constructMap();
///
/// patchSubMap = sendToRemote;
/// patchCnstrMap.resize(patchSubMap.size());
///
/// // Change sendToRemote into recv-from-remote by using
/// // all-to-all exchange
///
/// Pstream::exchange<labelList, label>
/// (
/// sendToRemote,
/// patchCnstrMap,
/// UPstream::msgType(),
/// faPatchMap.comm()
/// );
/// }
// ------------------------
// Point mapping
// ------------------------
mapDistributeBase faPointMap(distMap.pointMap());
{
// Retain meshPoints needed for the faMesh - preserve original order
// Need both sides (local/remote) for correct compaction maps
// without dangling points.
labelList oldToNewSub;
labelList oldToNewConstruct;
faPointMap.compactData
(
oldAreaPatch.meshPoints(),
newAreaPatch.meshPoints(),
oldToNewSub,
oldToNewConstruct,
distMap.nOldPoints(),
UPstream::msgType()
);
}
return mapDistributePolyMesh
(
// Mesh before changes
nOldPoints,
nOldEdges, // area: nOldEdges (volume: nOldFaces)
nOldFaces, // area: nOldFaces (volume: nOldCells)
labelList(oldMesh.boundary().patchStarts()),
labelList(), // oldPatchNMeshPoints [unused]
mapDistribute(std::move(faPointMap)),
mapDistribute(std::move(faEdgeMap)), // area: edgeMap (volume: faceMap)
mapDistribute(std::move(faFaceMap)), // area: faceMap (volume: cellMap)
mapDistribute(std::move(faPatchMap))
);
}
Foam::mapDistributePolyMesh
Foam::faMeshDistributor::distribute
(
const faMesh& oldMesh,
const mapDistributePolyMesh& distMap,
autoPtr<faMesh>& newMeshPtr
)
{
return faMeshDistributor::distribute
(
oldMesh,
distMap,
oldMesh.mesh(), // polyMesh
newMeshPtr
);
}
// ************************************************************************* //

View File

@ -0,0 +1,428 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "Time.H"
#include "emptyFaPatchField.H"
#include "emptyFaePatchField.H"
#include "IOobjectList.H"
#include "polyMesh.H"
#include "polyPatch.H"
#include "processorFaPatch.H"
#include "mapDistribute.H"
#include "mapDistributePolyMesh.H"
#include "areaFields.H"
#include "edgeFields.H"
#include "distributedFieldMapper.H"
#include "distributedFaPatchFieldMapper.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh>>
Foam::faMeshDistributor::distributeField
(
const GeometricField<Type, faPatchField, areaMesh>& fld
) const
{
typedef typename
GeometricField<Type, faPatchField, areaMesh>::Patch
PatchFieldType;
if (tgtMesh_.boundary().size() && patchEdgeMaps_.empty())
{
createPatchMaps();
}
// Create internalField by remote mapping
const distributedFieldMapper mapper
(
labelUList::null(),
distMap_.cellMap() // area: faceMap (volume: cellMap)
);
DimensionedField<Type, areaMesh> internalField
(
IOobject
(
fld.name(),
tgtMesh_.time().timeName(),
fld.local(),
tgtMesh_.thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
tgtMesh_,
fld.dimensions(),
Field<Type>(fld.internalField(), mapper)
);
internalField.oriented() = fld.oriented();
// Create patchFields by remote mapping
PtrList<PatchFieldType> newPatchFields(tgtMesh_.boundary().size());
const auto& bfld = fld.boundaryField();
forAll(bfld, patchi)
{
if (patchEdgeMaps_.set(patchi))
{
// Clone local patch field
const distributedFaPatchFieldMapper mapper
(
labelUList::null(),
patchEdgeMaps_[patchi]
);
// Map into local copy
newPatchFields.set
(
patchi,
PatchFieldType::New
(
bfld[patchi],
tgtMesh_.boundary()[patchi],
DimensionedField<Type, areaMesh>::null(),
mapper
)
);
}
}
// Add empty patchFields on remaining patches (this also handles
// e.g. processorPatchFields or any other constraint type patches)
forAll(newPatchFields, patchi)
{
if (!newPatchFields.set(patchi))
{
newPatchFields.set
(
patchi,
PatchFieldType::New
(
emptyFaPatchField<Type>::typeName,
tgtMesh_.boundary()[patchi],
DimensionedField<Type, areaMesh>::null()
)
);
}
}
auto tresult = tmp<GeometricField<Type, faPatchField, areaMesh>>::New
(
std::move(internalField),
newPatchFields
);
auto& result = tresult.ref();
result.boundaryFieldRef().template evaluateCoupled<processorFaPatch>();
return tresult;
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh>>
Foam::faMeshDistributor::distributeField
(
const GeometricField<Type, faePatchField, edgeMesh>& fld
) const
{
typedef typename
GeometricField<Type, faePatchField, edgeMesh>::Patch
PatchFieldType;
if (!internalEdgeMap_)
{
createInternalEdgeMap();
}
// Create internalField by remote mapping
const distributedFieldMapper mapper
(
labelUList::null(),
*(internalEdgeMap_)
);
DimensionedField<Type, edgeMesh> internalField
(
IOobject
(
fld.name(),
tgtMesh_.time().timeName(),
fld.local(),
tgtMesh_.thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
tgtMesh_,
fld.dimensions(),
Field<Type>(fld.internalField(), mapper)
);
internalField.oriented() = fld.oriented();
// Create patchFields by remote mapping
PtrList<PatchFieldType> newPatchFields(tgtMesh_.boundary().size());
const auto& bfld = fld.boundaryField();
forAll(bfld, patchi)
{
if (patchEdgeMaps_.set(patchi))
{
// Clone local patch field
const distributedFaPatchFieldMapper mapper
(
labelUList::null(),
patchEdgeMaps_[patchi]
);
// Map into local copy
newPatchFields.set
(
patchi,
PatchFieldType::New
(
bfld[patchi],
tgtMesh_.boundary()[patchi],
DimensionedField<Type, edgeMesh>::null(),
mapper
)
);
}
}
// Add empty patchFields on remaining patches (this also handles
// e.g. processorPatchFields or any other constraint type patches)
forAll(newPatchFields, patchi)
{
if (!newPatchFields.set(patchi))
{
newPatchFields.set
(
patchi,
PatchFieldType::New
(
emptyFaePatchField<Type>::typeName,
tgtMesh_.boundary()[patchi],
DimensionedField<Type, edgeMesh>::null()
)
);
}
}
return tmp<GeometricField<Type, faePatchField, edgeMesh>>::New
(
std::move(internalField),
newPatchFields
);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh>>
Foam::faMeshDistributor::distributeAreaField
(
const IOobject& fieldObject
) const
{
// Read field
GeometricField<Type, faPatchField, areaMesh> fld
(
fieldObject,
srcMesh_
);
// Redistribute
return distributeField(fld);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh>>
Foam::faMeshDistributor::distributeEdgeField
(
const IOobject& fieldObject
) const
{
// Read field
GeometricField<Type, faePatchField, edgeMesh> fld
(
fieldObject,
srcMesh_
);
// Redistribute
return distributeField(fld);
}
template<class Type>
Foam::label Foam::faMeshDistributor::distributeAreaFields
(
const IOobjectList& objects,
const wordRes& selectedFields
) const
{
typedef GeometricField<Type, faPatchField, areaMesh> fieldType;
label nFields = 0;
for
(
const IOobject& io :
(
selectedFields.empty()
? objects.sorted<fieldType>()
: objects.sorted<fieldType>(selectedFields)
)
)
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << nl;
}
++nFields;
tmp<fieldType> tfld(distributeAreaField<Type>(io));
if (isWriteProc_)
{
tfld().write();
}
}
if (nFields && verbose_) Info<< endl;
return nFields;
}
template<class Type>
Foam::label Foam::faMeshDistributor::distributeEdgeFields
(
const IOobjectList& objects,
const wordRes& selectedFields
) const
{
typedef GeometricField<Type, faePatchField, edgeMesh> fieldType;
label nFields = 0;
for
(
const IOobject& io :
(
selectedFields.empty()
? objects.sorted<fieldType>()
: objects.sorted<fieldType>(selectedFields)
)
)
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << nl;
}
++nFields;
tmp<fieldType> tfld(distributeEdgeField<Type>(io));
if (isWriteProc_)
{
tfld().write();
}
}
if (nFields && verbose_) Info<< endl;
return nFields;
}
#if 0
template<class Type>
void Foam::faMeshDistributor::redistributeAndWrite
(
PtrList<GeometricField<Type, faPatchField, areaMesh>>& flds
) const
{
for (auto& fld : flds)
{
Pout<< "process: " << fld.name() << endl;
tmp<GeometricField<Type, faPatchField, areaMesh>> tfld =
this->distributeField(fld);
if (isWriteProc_)
{
tfld().write();
}
}
}
template<class Type>
void Foam::faMeshDistributor::redistributeAndWrite
(
PtrList<GeometricField<Type, faePatchField, edgeMesh>>& flds
) const
{
for (auto& fld : flds)
{
tmp<GeometricField<Type, faePatchField, edgeMesh>> tfld =
this->distributeField(fld);
if (isWriteProc_)
{
tfld().write();
}
}
}
#endif
// ************************************************************************* //

View File

@ -186,6 +186,16 @@ public:
const bool allowUnmapped = false const bool allowUnmapped = false
); );
//- Map edge field.
// Optionally allow unmapped faces not to produce a warning
template<class Type>
static tmp<GeometricField<Type, faePatchField, edgeMesh>>
interpolate
(
const GeometricField<Type, faePatchField, edgeMesh>&,
const faMesh& sMesh
);
// Field Mapping // Field Mapping
@ -198,6 +208,15 @@ public:
const GeometricField<Type, faPatchField, areaMesh>&, const GeometricField<Type, faPatchField, areaMesh>&,
const bool allowUnmapped = false const bool allowUnmapped = false
) const; ) const;
//- Map edge field.
template<class Type>
tmp<GeometricField<Type, faePatchField, edgeMesh>>
interpolate
(
const GeometricField<Type, faePatchField, edgeMesh>&,
const bool allowUnmapped = false
) const;
}; };

View File

@ -144,6 +144,88 @@ Foam::faMeshSubset::interpolate
} }
template<class Type>
Foam::tmp
<
Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh>
>
Foam::faMeshSubset::interpolate
(
const GeometricField<Type, faePatchField, edgeMesh>& vf,
const faMesh& sMesh
)
{
// 1. Create the complete field with dummy patch fields
PtrList<faePatchField<Type>> patchFields(sMesh.boundary().size());
forAll(patchFields, patchi)
{
patchFields.set
(
patchi,
faePatchField<Type>::New
(
calculatedFaePatchField<Type>::typeName,
sMesh.boundary()[patchi],
DimensionedField<Type, edgeMesh>::null()
)
);
}
auto tresult = tmp<GeometricField<Type, faePatchField, edgeMesh>>::New
(
IOobject
(
"subset"+vf.name(),
sMesh.time().timeName(),
sMesh.thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
sMesh,
vf.dimensions(),
Field<Type>(),
// Field<Type>
// (
// vf.primitiveField(),
// SubList<label>(edgeMap, sMesh.nInternalEdges())
// ),
patchFields
);
auto& result = tresult.ref();
result.oriented() = vf.oriented();
// 2. Change the faePatchFields to the correct type using a mapper
// constructor (with reference to the now correct internal field)
auto& bf = result.boundaryFieldRef();
forAll(bf, patchi)
{
// Construct addressing
const faPatch& subPatch = sMesh.boundary()[patchi];
labelList directAddressing;
directFaPatchFieldMapper mapper(directAddressing);
bf.set
(
patchi,
faePatchField<Type>::New
(
vf.boundaryField()[patchi],
subPatch,
result(),
mapper
)
);
}
return tresult;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
@ -166,4 +248,24 @@ Foam::faMeshSubset::interpolate
} }
template<class Type>
Foam::tmp
<
Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh>
>
Foam::faMeshSubset::interpolate
(
const GeometricField<Type, faePatchField, edgeMesh>& vf,
const bool allowUnmapped
) const
{
if (subMeshPtr_)
{
return interpolate(vf, *subMeshPtr_);
}
return vf;
}
// ************************************************************************* // // ************************************************************************* //

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);
}; };

View File

@ -22,7 +22,7 @@ referenceLevel 0;
boundaryField boundaryField
{ {
fontAndBack frontAndBack
{ {
type empty; type empty;
} }

View File

@ -18,7 +18,8 @@ solvers
{ {
Cs Cs
{ {
solver PBiCG; //solver PBiCG;
solver PBiCGStab;
preconditioner DILU; preconditioner DILU;
minIter 0; minIter 0;
maxIter 2000; maxIter 2000;