meshToMesh, mapFieldsPar: Rationalisation

Cell-to-cell interpolation has been moved to a hierarchy separate from
meshToMesh, called cellsToCells. The meshToMesh class is now a
combination of a cellsToCells object and multiple patchToPatch objects.
This means that when only cell-to-cell interpolation is needed a basic
cellsToCells object can be selected.

Cell-to-cell and vol-field-to-vol-field interpolation now has two well
defined sets of functions, with a clear distinction in how weights that
do not sum to unity are handled. Non-unity weights are either
normalised, or a left-over field is provided with which to complete the
weighted sum.

The left-over approach is now consistently applied in mapFieldsPar,
across both the internal and patch fields, if mapping onto an existing
field in the target case. Warning are now generated for invalid
combinations of settings, such as mapping between inconsistent meshes
without a pre-existing target field.

All mapping functions now take fields as const references and return tmp
fields. This avoids the pattern in which non-const fields are provided
which relate to the source, and at some point in the function transfer
to the target. This pattern is difficult to reason about and does not
provide any actual computational advantage, as the fields invariably get
re-allocated as part of the process anyway.

MeshToMesh no longer stores the cutting patches. The set of cutting
patches is not needed anywhere except at the point of mapping a field,
so it is now supplied to the mapping functions as an argument.

The meshToMesh topology changer no longer supports cutting patch
information. This did not previously work. Cutting patches either get
generated as calculated, or they require a pre-existing field to specify
their boundary condition. Neither of these options is suitable for a
run-time mesh change.

More code has been shared with patchToPatch, reducing duplication.
This commit is contained in:
Will Bainbridge
2023-02-03 13:14:00 +00:00
parent c8f177e453
commit f95eb5fd11
49 changed files with 2356 additions and 2317 deletions

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -34,7 +34,7 @@ Description
#include "fvMeshToFvMesh.H"
#include "mapGeometricFields.H"
#include "mapClouds.H"
#include "cellVolumeWeightMethod.H"
#include "intersectionCellsToCells.H"
using namespace Foam;
@ -56,12 +56,7 @@ void mapConsistentMesh
Info<< nl << "Mapping geometric fields" << endl;
mapGeometricFields
(
interp,
selectedFields,
noLagrangian
);
mapGeometricFields(interp, wordReList(), selectedFields, noLagrangian);
if (!noLagrangian)
{
@ -70,12 +65,12 @@ void mapConsistentMesh
}
void mapSubMesh
void mapMesh
(
const fvMesh& srcMesh,
const fvMesh& tgtMesh,
const HashTable<word>& patchMap,
const wordList& cuttingPatches,
const wordReList& cuttingPatches,
const word& mapMethod,
const HashSet<word>& selectedFields,
const bool noLagrangian
@ -84,23 +79,11 @@ void mapSubMesh
Info<< nl << "Creating and mapping fields for time "
<< srcMesh.time().name() << nl << endl;
fvMeshToFvMesh interp
(
srcMesh,
tgtMesh,
mapMethod,
patchMap,
cuttingPatches
);
fvMeshToFvMesh interp(srcMesh, tgtMesh, mapMethod, patchMap);
Info<< nl << "Mapping geometric fields" << endl;
mapGeometricFields
(
interp,
selectedFields,
noLagrangian
);
mapGeometricFields(interp, cuttingPatches, selectedFields, noLagrangian);
if (!noLagrangian)
{
@ -194,7 +177,7 @@ int main(int argc, char *argv[])
args.optionLookupOrDefault<word>
(
"mapMethod",
cellVolumeWeightMethod::typeName
cellsToCellss::intersection::typeName
)
);
Info<< "Mapping method: " << mapMethod << endl;
@ -210,7 +193,7 @@ int main(int argc, char *argv[])
#include "createTimes.H"
HashTable<word> patchMap;
wordList cuttingPatches;
wordReList cuttingPatches;
if (!consistent)
{
@ -276,7 +259,7 @@ int main(int argc, char *argv[])
}
else
{
mapSubMesh
mapMesh
(
srcMesh,
tgtMesh,

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -35,94 +35,13 @@ License
namespace Foam
{
template<class Type>
void evaluateConstraintTypes(VolField<Type>& fld)
{
typename VolField<Type>::
Boundary& fldBf = fld.boundaryFieldRef();
if
(
Pstream::defaultCommsType == Pstream::commsTypes::blocking
|| Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking
)
{
label nReq = Pstream::nRequests();
forAll(fldBf, patchi)
{
fvPatchField<Type>& tgtField = fldBf[patchi];
if
(
tgtField.type() == tgtField.patch().patch().type()
&& polyPatch::constraintType(tgtField.patch().patch().type())
)
{
tgtField.initEvaluate(Pstream::defaultCommsType);
}
}
// Block for any outstanding requests
if
(
Pstream::parRun()
&& Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking
)
{
Pstream::waitRequests(nReq);
}
forAll(fldBf, patchi)
{
fvPatchField<Type>& tgtField = fldBf[patchi];
if
(
tgtField.type() == tgtField.patch().patch().type()
&& polyPatch::constraintType(tgtField.patch().patch().type())
)
{
tgtField.evaluate(Pstream::defaultCommsType);
}
}
}
else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled)
{
const lduSchedule& patchSchedule =
fld.mesh().globalData().patchSchedule();
forAll(patchSchedule, patchEvali)
{
label patchi = patchSchedule[patchEvali].patch;
fvPatchField<Type>& tgtField = fldBf[patchi];
if
(
tgtField.type() == tgtField.patch().patch().type()
&& polyPatch::constraintType(tgtField.patch().patch().type())
)
{
if (patchSchedule[patchEvali].init)
{
tgtField.initEvaluate(Pstream::commsTypes::scheduled);
}
else
{
tgtField.evaluate(Pstream::commsTypes::scheduled);
}
}
}
}
}
template<class Type>
void mapVolTypeFields
(
const IOobjectList& objects,
const fvMeshToFvMesh& interp,
const wordReList& cuttingPatches,
const HashSet<word>& selectedFields,
const fvMeshToFvMesh& interp
const IOobjectList& objects
)
{
const fvMesh& srcMesh = static_cast<const fvMesh&>(interp.srcMesh());
@ -134,106 +53,95 @@ void mapVolTypeFields
{
const word& fieldName = fieldIter()->name();
if (selectedFields.empty() || selectedFields.found(fieldName))
if (!selectedFields.empty() && !selectedFields.found(fieldName))
{
const VolField<Type> fieldSource(*fieldIter(), srcMesh);
continue;
}
typeIOobject<VolField<Type>> targetIO
const VolField<Type> fieldSource(*fieldIter(), srcMesh);
typeIOobject<VolField<Type>> targetIO
(
fieldName,
tgtMesh.time().name(),
tgtMesh,
IOobject::READ_IF_PRESENT
);
// Warnings about inconsistent execution
if (targetIO.headerOk() && interp.consistent())
{
WarningInFunction
<< "Mapping of field " << fieldName << " will not utilise "
<< "the corresponding field in the target case, as the map is "
<< "consistent (i.e., all patches are mapped)" << endl;
}
if (!targetIO.headerOk() && !interp.consistent())
{
WarningInFunction
<< "Cannot map field " << fieldName << " because the "
<< "map is not consistent (i.e., not all patches are "
<< "mapped), and there is no corresponding field in "
<< "the target case" << endl;
continue;
}
if (!targetIO.headerOk() && !cuttingPatches.empty())
{
WarningInFunction
<< "Cutting patches will not be used for field " << fieldName
<< " because no there is no corresponding field in the target "
<< "case" << endl;
}
if (targetIO.headerOk())
{
Info<< " mapping into existing field " << fieldName << endl;
VolField<Type> fieldTarget(targetIO, tgtMesh);
fieldTarget.reset
(
fieldName,
tgtMesh.time().name(),
tgtMesh,
IOobject::MUST_READ
interp.srcToTgt(fieldSource, fieldTarget, cuttingPatches)
);
if (targetIO.headerOk())
{
Info<< " interpolating onto existing field "
<< fieldName << endl;
VolField<Type> fieldTarget(targetIO, tgtMesh);
fieldTarget.write();
}
else
{
Info<< " creating new field " << fieldName << endl;
interp.mapSrcToTgt(fieldSource, fieldTarget);
evaluateConstraintTypes(fieldTarget);
fieldTarget.write();
}
else
{
Info<< " creating new field "
<< fieldName << endl;
targetIO.readOpt() = IOobject::NO_READ;
tmp<VolField<Type>> tfieldTarget
(
interp.mapSrcToTgt(fieldSource)
);
VolField<Type> fieldTarget(targetIO, tfieldTarget);
evaluateConstraintTypes(fieldTarget);
fieldTarget.write();
}
VolField<Type>(targetIO, interp.srcToTgt(fieldSource)).write();
}
}
}
template<class Type, template<class> class GeoField>
void unMappedTypeFields(const IOobjectList& objects)
{
IOobjectList fields = objects.lookupClass(GeoField<Type>::typeName);
forAllConstIter(IOobjectList, fields, fieldIter)
{
mvBak(fieldIter()->objectPath(false), "unmapped");
}
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::mapGeometricFields
(
const fvMeshToFvMesh& interp,
const wordReList& cuttingPatches,
const HashSet<word>& selectedFields,
const bool noLagrangian
)
{
// Search for list of source objects for this time
const polyMesh& srcMesh = interp.srcMesh();
const polyMesh& tgtMesh = interp.tgtMesh();
IOobjectList objects(srcMesh, srcMesh.time().name());
{
// Search for list of source objects for this time
IOobjectList objects(srcMesh, srcMesh.time().name());
// Map the fields
#define MapVolTypeFields(Type, nullArg) \
mapVolTypeFields<Type> \
( \
objects, \
selectedFields, \
interp \
);
FOR_ALL_FIELD_TYPES(MapVolTypeFields);
#undef MapVolTypeFields
}
{
// Search for list of target objects for this time
IOobjectList objects(tgtMesh, tgtMesh.time().name());
// Mark surface and point fields as unmapped
#define UnMappedTypeFields(Type, GeoField) \
unMappedTypeFields<Type, GeoField>(objects);
FOR_ALL_FIELD_TYPES(UnMappedTypeFields, SurfaceField);
FOR_ALL_FIELD_TYPES(UnMappedTypeFields, PointField);
#undef UnMappedTypeFields
}
// Map the fields
#define MapVolTypeFields(Type, nullArg) \
mapVolTypeFields<Type> \
( \
interp, \
cuttingPatches, \
selectedFields, \
objects \
);
FOR_ALL_FIELD_TYPES(MapVolTypeFields);
#undef MapVolTypeFields
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -47,6 +47,7 @@ class fvMeshToFvMesh;
void mapGeometricFields
(
const fvMeshToFvMesh& interp,
const wordReList& cuttingPatches,
const HashSet<word>& selectedFields,
const bool noLagrangian
);