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

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -35,94 +35,13 @@ License
namespace Foam 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> template<class Type>
void mapVolTypeFields void mapVolTypeFields
( (
const IOobjectList& objects, const fvMeshToFvMesh& interp,
const wordReList& cuttingPatches,
const HashSet<word>& selectedFields, const HashSet<word>& selectedFields,
const fvMeshToFvMesh& interp const IOobjectList& objects
) )
{ {
const fvMesh& srcMesh = static_cast<const fvMesh&>(interp.srcMesh()); const fvMesh& srcMesh = static_cast<const fvMesh&>(interp.srcMesh());
@ -134,106 +53,95 @@ void mapVolTypeFields
{ {
const word& fieldName = fieldIter()->name(); 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, interp.srcToTgt(fieldSource, fieldTarget, cuttingPatches)
tgtMesh.time().name(),
tgtMesh,
IOobject::MUST_READ
); );
if (targetIO.headerOk()) fieldTarget.write();
{ }
Info<< " interpolating onto existing field " else
<< fieldName << endl; {
VolField<Type> fieldTarget(targetIO, tgtMesh); Info<< " creating new field " << fieldName << endl;
interp.mapSrcToTgt(fieldSource, fieldTarget); VolField<Type>(targetIO, interp.srcToTgt(fieldSource)).write();
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();
}
} }
} }
} }
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 void Foam::mapGeometricFields
( (
const fvMeshToFvMesh& interp, const fvMeshToFvMesh& interp,
const wordReList& cuttingPatches,
const HashSet<word>& selectedFields, const HashSet<word>& selectedFields,
const bool noLagrangian const bool noLagrangian
) )
{ {
// Search for list of source objects for this time
const polyMesh& srcMesh = interp.srcMesh(); const polyMesh& srcMesh = interp.srcMesh();
const polyMesh& tgtMesh = interp.tgtMesh(); IOobjectList objects(srcMesh, srcMesh.time().name());
{ // Map the fields
// Search for list of source objects for this time #define MapVolTypeFields(Type, nullArg) \
IOobjectList objects(srcMesh, srcMesh.time().name()); mapVolTypeFields<Type> \
( \
// Map the fields interp, \
#define MapVolTypeFields(Type, nullArg) \ cuttingPatches, \
mapVolTypeFields<Type> \ selectedFields, \
( \ objects \
objects, \ );
selectedFields, \ FOR_ALL_FIELD_TYPES(MapVolTypeFields);
interp \ #undef MapVolTypeFields
);
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
}
} }

View File

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

View File

@ -517,5 +517,7 @@ solver/solverNew.C
fvMeshToFvMesh/fvMeshToFvMesh.C fvMeshToFvMesh/fvMeshToFvMesh.C
fvMeshToFvMesh/patchToPatchFvPatchFieldMapper.C fvMeshToFvMesh/patchToPatchFvPatchFieldMapper.C
fvMeshToFvMesh/patchToPatchLeftOverFvPatchFieldMapper.C
fvMeshToFvMesh/patchToPatchNormalisedFvPatchFieldMapper.C
LIB = $(FOAM_LIBBIN)/libfiniteVolume LIB = $(FOAM_LIBBIN)/libfiniteVolume

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -50,6 +50,15 @@ class fvMeshToFvMesh
: :
public meshToMesh public meshToMesh
{ {
private:
// Private Member Functions
//- Evaluate constraint types for the given vol field
template<class Type>
static void evaluateConstraintTypes(VolField<Type>& fld);
public: public:
//- Run-time type information //- Run-time type information
@ -68,48 +77,47 @@ public:
// Member Functions // Member Functions
// Evaluation // Interpolation
// Source-to-target volume field mapping //- Interpolate a source vol field to the target with no left
// over values specified. If the interpolation weight sum is less
// than one for a face then they will be normalised. If the
// interpolation weight sum is zero for a face then that face's
// value will be NaN.
template<class Type>
tmp<VolField<Type>> srcToTgt
(
const VolField<Type>& srcFld
) const;
//- Interpolate a field with a defined operation. Values //- Interpolate a source vol field to the target with left over
// passed in via 'result' are used to initialise the return // values specified. If the interpolation weight sum is less than
// value. // one for a face then the average will include the left over
template<class Type> // value multiplied by one minus the weight sum.
void mapSrcToTgt template<class Type>
( tmp<VolField<Type>> srcToTgt
const VolField<Type>& field, (
VolField<Type>& result const VolField<Type>& srcFld,
) const; const VolField<Type>& leftOverTgtFld,
const UList<wordRe>& tgtCuttingPatches
) const;
//- Interpolate a field with a defined operation. The initial //- Interpolate a source vol internal field to the target with no
// values of the result are set to zero. // left over values specified. As the corresponding srcToTgt.
template<class Type> template<class Type>
tmp<VolField<Type>> mapSrcToTgt tmp<VolInternalField<Type>> srcToTgt
( (
const VolField<Type>& field const VolInternalField<Type>& srcFld
) const; ) const;
//- Interpolate a source vol internal field to the target with left
// Source-to-target volume internal field mapping // over values specified. As the corresponding srcToTgt.
template<class Type>
//- Interpolate a field with a defined operation. Values tmp<VolInternalField<Type>> srcToTgt
// passed in via 'result' are used to initialise the return (
// value. const VolInternalField<Type>& srcFld,
template<class Type> const VolInternalField<Type>& leftOverTgtFld
void mapSrcToTgt ) const;
(
const VolInternalField<Type>& field,
VolInternalField<Type>& result
) const;
//- Interpolate a field with a defined operation. The initial
// values of the result are set to zero.
template<class Type>
tmp<VolInternalField<Type>> mapSrcToTgt
(
const VolInternalField<Type>& field
) const;
}; };

View File

@ -26,78 +26,105 @@ License
#include "fvMeshToFvMesh.H" #include "fvMeshToFvMesh.H"
#include "directFvPatchFieldMapper.H" #include "directFvPatchFieldMapper.H"
#include "identityFvPatchFieldMapper.H" #include "identityFvPatchFieldMapper.H"
#include "patchToPatchFvPatchFieldMapper.H" #include "patchToPatchNormalisedFvPatchFieldMapper.H"
#include "patchToPatchLeftOverFvPatchFieldMapper.H"
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type> template<class Type>
void Foam::fvMeshToFvMesh::mapSrcToTgt void Foam::fvMeshToFvMesh::evaluateConstraintTypes(VolField<Type>& fld)
(
const VolField<Type>& field,
VolField<Type>& result
) const
{ {
meshToMesh::mapSrcToTgt(field, result.primitiveFieldRef()); typename VolField<Type>::Boundary& fldBf = fld.boundaryFieldRef();
typename VolField<Type>:: if
Boundary& resultBf = result.boundaryFieldRef(); (
Pstream::defaultCommsType == Pstream::commsTypes::blocking
forAll(srcToTgtPatchIDs(), i) || Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking
)
{ {
const label srcPatchi = srcToTgtPatchIDs()[i].first(); label nReq = Pstream::nRequests();
const label tgtPatchi = srcToTgtPatchIDs()[i].second();
const fvPatchField<Type>& srcField = field.boundaryField()[srcPatchi]; forAll(fldBf, patchi)
fvPatchField<Type>& tgtField = resultBf[tgtPatchi]; {
fvPatchField<Type>& tgtField = fldBf[patchi];
// Clone and map if
tmp<fvPatchField<Type>> tnewTgt
(
fvPatchField<Type>::New
( (
srcField, tgtField.type() == tgtField.patch().patch().type()
tgtField.patch(), && polyPatch::constraintType(tgtField.patch().patch().type())
result(),
patchToPatchFvPatchFieldMapper
(
srcToTgtPatchToPatches()[i],
true
)
) )
); {
tgtField.initEvaluate(Pstream::defaultCommsType);
}
}
// Transfer all mapped quantities (value and e.g. gradient) onto // Block for any outstanding requests
// tgtField. Value will get overwritten below. if
tgtField.map(tnewTgt(), identityFvPatchFieldMapper()); (
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)
forAll(tgtCuttingPatchIDs(), i)
{ {
const label patchi = tgtCuttingPatchIDs()[i]; const lduSchedule& patchSchedule =
fvPatchField<Type>& pf = resultBf[patchi]; fld.mesh().globalData().patchSchedule();
pf == pf.patchInternalField();
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);
}
}
}
} }
} }
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class Type> template<class Type>
Foam::tmp<Foam::VolField<Type>> Foam::tmp<Foam::VolField<Type>> Foam::fvMeshToFvMesh::srcToTgt
Foam::fvMeshToFvMesh::mapSrcToTgt
( (
const VolField<Type>& field const VolField<Type>& srcFld
) const ) const
{ {
const fvMesh& tgtMesh = static_cast<const fvMesh&>(meshToMesh::tgtMesh()); const fvMesh& tgtMesh = static_cast<const fvMesh&>(meshToMesh::tgtMesh());
const fvBoundaryMesh& tgtBm = tgtMesh.boundary(); // Construct target patch fields as copies of source patch fields, but do
const typename VolField<Type>::Boundary& srcBfld = // not map values yet
field.boundaryField(); PtrList<fvPatchField<Type>> tgtPatchFields(tgtMesh.boundary().size());
PtrList<fvPatchField<Type>> tgtPatchFields(tgtBm.size());
// construct tgt boundary patch types as copy of 'field' boundary types
// note: this will provide place holders for fields with additional
// entries, but these values will need to be reset
forAll(srcToTgtPatchIDs(), i) forAll(srcToTgtPatchIDs(), i)
{ {
const label srcPatchi = srcToTgtPatchIDs()[i].first(); const label srcPatchi = srcToTgtPatchIDs()[i].first();
@ -110,7 +137,7 @@ Foam::fvMeshToFvMesh::mapSrcToTgt
tgtPatchi, tgtPatchi,
fvPatchField<Type>::New fvPatchField<Type>::New
( (
srcBfld[srcPatchi], srcFld.boundaryField()[srcPatchi],
tgtMesh.boundary()[tgtPatchi], tgtMesh.boundary()[tgtPatchi],
DimensionedField<Type, volMesh>::null(), DimensionedField<Type, volMesh>::null(),
directFvPatchFieldMapper directFvPatchFieldMapper
@ -122,13 +149,14 @@ Foam::fvMeshToFvMesh::mapSrcToTgt
} }
} }
// Any unset tgtPatchFields become calculated // Create calculated patch fields for any unset target patches. Use
// fvPatchField<Type>::New to construct these, rather than using the
// calculated constructor directly, so that constraints are maintained.
labelList tgtPatchFieldIsUnMapped(tgtPatchFields.size(), false);
forAll(tgtPatchFields, tgtPatchi) forAll(tgtPatchFields, tgtPatchi)
{ {
if (!tgtPatchFields.set(tgtPatchi)) if (!tgtPatchFields.set(tgtPatchi))
{ {
// Note: use factory New method instead of direct generation of
// calculated so we keep constraints
tgtPatchFields.set tgtPatchFields.set
( (
tgtPatchi, tgtPatchi,
@ -139,75 +167,148 @@ Foam::fvMeshToFvMesh::mapSrcToTgt
DimensionedField<Type, volMesh>::null() DimensionedField<Type, volMesh>::null()
) )
); );
tgtPatchFieldIsUnMapped[tgtPatchi] =
polyPatch::constraintType
(
tgtMesh.boundary()[tgtPatchi].patch().type()
);
} }
} }
tmp<VolField<Type>> tresult // Construct the result field
( tmp<VolField<Type>> ttgtFld =
new VolField<Type> VolField<Type>::New
( (
IOobject typedName("interpolate(" + srcFld.name() + ")"),
( srcToTgt<Type>(srcFld.internalField())(),
typedName("interpolate(" + field.name() + ")"),
tgtMesh.time().name(),
tgtMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
tgtMesh,
field.dimensions(),
Field<Type>(tgtMesh.nCells(), Zero),
tgtPatchFields tgtPatchFields
) );
); typename VolField<Type>::Boundary& tgtBfld =
ttgtFld.ref().boundaryFieldRef();
fvMeshToFvMesh::mapSrcToTgt<Type>(field, tresult.ref()); // Mapped patches
forAll(srcToTgtPatchIDs(), i)
{
const label srcPatchi = srcToTgtPatchIDs()[i].first();
const label tgtPatchi = srcToTgtPatchIDs()[i].second();
return tresult; tgtBfld[tgtPatchi].map
}
template<class Type>
void Foam::fvMeshToFvMesh::mapSrcToTgt
(
const VolInternalField<Type>& field,
VolInternalField<Type>& result
) const
{
meshToMesh::mapSrcToTgt(field, result);
}
template<class Type>
Foam::tmp<Foam::VolInternalField<Type>>
Foam::fvMeshToFvMesh::mapSrcToTgt
(
const VolInternalField<Type>& field
) const
{
const fvMesh& tgtMesh = static_cast<const fvMesh&>(meshToMesh::tgtMesh());
tmp<VolInternalField<Type>> tresult
(
new VolInternalField<Type>
( (
IOobject srcFld.boundaryField()[srcPatchi],
patchToPatchNormalisedFvPatchFieldMapper
( (
typedName("interpolate(" + field.name() + ")"), srcToTgtPatchToPatches()[i],
tgtMesh.time().name(), true
tgtMesh, )
IOobject::NO_READ, );
IOobject::NO_WRITE }
),
tgtMesh,
field.dimensions(),
Field<Type>(tgtMesh.nCells(), Zero)
)
);
fvMeshToFvMesh::mapSrcToTgt<Type>(field, tresult.ref()); // Un-mapped patches. Set values to that of the internal cell field.
forAll(tgtBfld, patchi)
{
if (tgtPatchFieldIsUnMapped[patchi])
{
fvPatchField<Type>& tgtPfld = tgtBfld[patchi];
tgtPfld == tgtPfld.patchInternalField();
}
}
return tresult; // Evaluate constraints
evaluateConstraintTypes(ttgtFld.ref());
return ttgtFld;
}
template<class Type>
Foam::tmp<Foam::VolField<Type>> Foam::fvMeshToFvMesh::srcToTgt
(
const VolField<Type>& srcFld,
const VolField<Type>& leftOverTgtFld,
const UList<wordRe>& tgtCuttingPatchNames
) const
{
// Construct the result field
tmp<VolField<Type>> ttgtFld =
VolField<Type>::New
(
typedName("interpolate(" + srcFld.name() + ")"),
srcToTgt<Type>(srcFld.v(), leftOverTgtFld.v())(),
leftOverTgtFld.boundaryField()
);
typename VolField<Type>::Boundary& tgtBfld =
ttgtFld.ref().boundaryFieldRef();
// Mapped patches
forAll(srcToTgtPatchIDs(), i)
{
const label srcPatchi = srcToTgtPatchIDs()[i].first();
const label tgtPatchi = srcToTgtPatchIDs()[i].second();
tgtBfld[tgtPatchi].map
(
leftOverTgtFld.boundaryField()[tgtPatchi],
identityFvPatchFieldMapper()
);
tgtBfld[tgtPatchi].map
(
srcFld.boundaryField()[srcPatchi],
patchToPatchLeftOverFvPatchFieldMapper
(
srcToTgtPatchToPatches()[i],
true
)
);
}
// Cutting patches. Set values to that of the internal cell field.
const labelHashSet tgtCuttingPatchIDs =
leftOverTgtFld.mesh().boundaryMesh().patchSet(tgtCuttingPatchNames);
forAllConstIter(labelHashSet, tgtCuttingPatchIDs, iter)
{
tgtBfld[iter.key()] == tgtBfld[iter.key()].patchInternalField();
}
// Evaluate constraints
evaluateConstraintTypes(ttgtFld.ref());
return ttgtFld;
}
template<class Type>
Foam::tmp<Foam::VolInternalField<Type>> Foam::fvMeshToFvMesh::srcToTgt
(
const VolInternalField<Type>& srcFld
) const
{
return
VolInternalField<Type>::New
(
typedName("interpolate(" + srcFld.name() + ")"),
static_cast<const fvMesh&>(meshToMesh::tgtMesh()),
srcFld.dimensions(),
srcToTgtCellsToCells().srcToTgt(srcFld)
);
}
template<class Type>
Foam::tmp<Foam::VolInternalField<Type>> Foam::fvMeshToFvMesh::srcToTgt
(
const VolInternalField<Type>& srcFld,
const VolInternalField<Type>& leftOverTgtFld
) const
{
return
VolInternalField<Type>::New
(
typedName("interpolate(" + srcFld.name() + ")"),
static_cast<const fvMesh&>(meshToMesh::tgtMesh()),
leftOverTgtFld.dimensions(),
srcToTgtCellsToCells().srcToTgt(srcFld, leftOverTgtFld)
);
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -27,13 +27,6 @@ License
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
FOR_ALL_FIELD_TYPES
(
IMPLEMENT_FIELD_MAPPER_OPERATOR,
patchToPatchFvPatchFieldMapper
)
void Foam::patchToPatchFvPatchFieldMapper::operator() void Foam::patchToPatchFvPatchFieldMapper::operator()
( (
Field<label>& f, Field<label>& f,

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -50,7 +50,9 @@ class patchToPatchFvPatchFieldMapper
: :
public fvPatchFieldMapper public fvPatchFieldMapper
{ {
// Private Data protected:
// Protected Data
//- Patch-to-patch mapping engine //- Patch-to-patch mapping engine
const patchToPatch& pToP_; const patchToPatch& pToP_;
@ -65,17 +67,6 @@ class patchToPatchFvPatchFieldMapper
bool hasUnmapped_; bool hasUnmapped_;
// Private Member Functions
//- Map from one field to another
template<class Type>
void map(Field<Type>& f, const Field<Type>& mapF) const;
//- Map a field and return the result as tmp
template<class Type>
tmp<Field<Type>> map(const Field<Type>& mapF) const;
public: public:
// Constructors // Constructors
@ -124,9 +115,6 @@ public:
// Member Operators // Member Operators
//- Map a field
FOR_ALL_FIELD_TYPES(DEFINE_FIELD_MAPPER_OPERATOR, );
//- Map a label field //- Map a label field
DEFINE_FIELD_MAPPER_OPERATOR(label, ); DEFINE_FIELD_MAPPER_OPERATOR(label, );

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -27,29 +27,6 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::patchToPatchFvPatchFieldMapper::map
(
Field<Type>& f,
const Field<Type>& mapF
) const
{
f = forward_ ? pToP_.srcToTgt(mapF) : pToP_.tgtToSrc(mapF);
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::patchToPatchFvPatchFieldMapper::map
(
const Field<Type>& mapF
) const
{
tmp<Field<Type>> tf(new Field<Type>(size_));
map(tf.ref(), mapF);
return tf;
}
template<class Type> template<class Type>
void Foam::patchToPatchFvPatchFieldMapper::operator() void Foam::patchToPatchFvPatchFieldMapper::operator()
( (
@ -57,7 +34,7 @@ void Foam::patchToPatchFvPatchFieldMapper::operator()
const tmp<Field<Type>>& tmapF const tmp<Field<Type>>& tmapF
) const ) const
{ {
map(f, tmapF()); operator()(f, tmapF());
tmapF.clear(); tmapF.clear();
} }
@ -69,7 +46,7 @@ Foam::patchToPatchFvPatchFieldMapper::operator()
const tmp<Field<Type>>& tmapF const tmp<Field<Type>>& tmapF
) const ) const
{ {
tmp<Foam::Field<Type>> tf(map(tmapF())); tmp<Foam::Field<Type>> tf(operator()(tmapF()));
tmapF.clear(); tmapF.clear();
return tf; return tf;
} }

View File

@ -0,0 +1,37 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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 "patchToPatchLeftOverFvPatchFieldMapper.H"
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
FOR_ALL_FIELD_TYPES
(
IMPLEMENT_FIELD_MAPPER_OPERATOR,
patchToPatchLeftOverFvPatchFieldMapper
)
// ************************************************************************* //

View File

@ -0,0 +1,104 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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::patchToPatchLeftOverFvPatchFieldMapper
Description
FieldMapper which uses a patchToPatch object to map from another patch. The
source patch may be differently decomposed and/or geometrically and
topologically different from the target.
\*---------------------------------------------------------------------------*/
#ifndef patchToPatchLeftOverFvPatchFieldMapper_H
#define patchToPatchLeftOverFvPatchFieldMapper_H
#include "patchToPatchFvPatchFieldMapper.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class patchToPatchLeftOverFvPatchFieldMapper Declaration
\*---------------------------------------------------------------------------*/
class patchToPatchLeftOverFvPatchFieldMapper
:
public patchToPatchFvPatchFieldMapper
{
// Private Member Functions
//- Map from one field to another
template<class Type>
void map(Field<Type>& f, const Field<Type>& mapF) const;
//- Map a field and return the result as tmp
template<class Type>
tmp<Field<Type>> map(const Field<Type>& mapF) const;
public:
// Constructors
//- Construct given a patch-to-patch and a mapping direction
patchToPatchLeftOverFvPatchFieldMapper
(
const patchToPatch& pToP,
const bool forward
)
:
patchToPatchFvPatchFieldMapper(pToP, forward)
{}
//- Destructor
virtual ~patchToPatchLeftOverFvPatchFieldMapper()
{}
// Member Operators
//- Map a field
FOR_ALL_FIELD_TYPES(DEFINE_FIELD_MAPPER_OPERATOR, );
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "patchToPatchLeftOverFvPatchFieldMapperTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -23,35 +23,30 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "meshToMeshMethod.H" #include "patchToPatchLeftOverFvPatchFieldMapper.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::autoPtr<Foam::meshToMeshMethod> Foam::meshToMeshMethod::New template<class Type>
void Foam::patchToPatchLeftOverFvPatchFieldMapper::map
( (
const word& methodName, Field<Type>& f,
const polyMesh& src, const Field<Type>& mapF
const polyMesh& tgt ) const
)
{ {
if (debug) f = forward_ ? pToP_.srcToTgt(mapF, f) : pToP_.tgtToSrc(mapF, f);
{ }
Info<< "Selecting meshToMeshMethod " << methodName << endl;
}
componentsConstructorTable::iterator cstrIter =
componentsConstructorTablePtr_->find(methodName);
if (cstrIter == componentsConstructorTablePtr_->end()) template<class Type>
{ Foam::tmp<Foam::Field<Type>>
FatalErrorInFunction Foam::patchToPatchLeftOverFvPatchFieldMapper::map
<< "Unknown meshToMesh type " (
<< methodName << nl << nl const Field<Type>& mapF
<< "Valid meshToMesh types are:" << nl ) const
<< componentsConstructorTablePtr_->sortedToc() << exit(FatalError); {
} NotImplemented;
return tmp<Field<Type>>(nullptr);
return autoPtr<meshToMeshMethod>(cstrIter()(src, tgt));
} }

View File

@ -0,0 +1,37 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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 "patchToPatchNormalisedFvPatchFieldMapper.H"
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
FOR_ALL_FIELD_TYPES
(
IMPLEMENT_FIELD_MAPPER_OPERATOR,
patchToPatchNormalisedFvPatchFieldMapper
)
// ************************************************************************* //

View File

@ -0,0 +1,104 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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::patchToPatchNormalisedFvPatchFieldMapper
Description
FieldMapper which uses a patchToPatch object to map from another patch. The
source patch may be differently decomposed and/or geometrically and
topologically different from the target.
\*---------------------------------------------------------------------------*/
#ifndef patchToPatchNormalisedFvPatchFieldMapper_H
#define patchToPatchNormalisedFvPatchFieldMapper_H
#include "patchToPatchFvPatchFieldMapper.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class patchToPatchNormalisedFvPatchFieldMapper Declaration
\*---------------------------------------------------------------------------*/
class patchToPatchNormalisedFvPatchFieldMapper
:
public patchToPatchFvPatchFieldMapper
{
// Private Member Functions
//- Map from one field to another
template<class Type>
void map(Field<Type>& f, const Field<Type>& mapF) const;
//- Map a field and return the result as tmp
template<class Type>
tmp<Field<Type>> map(const Field<Type>& mapF) const;
public:
// Constructors
//- Construct given a patch-to-patch and a mapping direction
patchToPatchNormalisedFvPatchFieldMapper
(
const patchToPatch& pToP,
const bool forward
)
:
patchToPatchFvPatchFieldMapper(pToP, forward)
{}
//- Destructor
virtual ~patchToPatchNormalisedFvPatchFieldMapper()
{}
// Member Operators
//- Map a field
FOR_ALL_FIELD_TYPES(DEFINE_FIELD_MAPPER_OPERATOR, );
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "patchToPatchNormalisedFvPatchFieldMapperTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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 "patchToPatchNormalisedFvPatchFieldMapper.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::patchToPatchNormalisedFvPatchFieldMapper::map
(
Field<Type>& f,
const Field<Type>& mapF
) const
{
f = forward_ ? pToP_.srcToTgt(mapF) : pToP_.tgtToSrc(mapF);
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::patchToPatchNormalisedFvPatchFieldMapper::map
(
const Field<Type>& mapF
) const
{
tmp<Field<Type>> tf(new Field<Type>(size_));
map(tf.ref(), mapF);
return tf;
}
// ************************************************************************* //

View File

@ -46,87 +46,6 @@ Description
namespace Foam 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> template<class Type>
void MeshToMeshMapVolFields void MeshToMeshMapVolFields
( (
@ -169,8 +88,7 @@ void MeshToMeshMapVolFields
) )
{ {
VolField<Type>& field = VolField<Type>& field =
const_cast<VolField<Type>&> const_cast<VolField<Type>&>(*fieldIter());
(*fieldIter());
if (fvMeshToFvMesh::debug) if (fvMeshToFvMesh::debug)
{ {
@ -178,8 +96,8 @@ void MeshToMeshMapVolFields
<< endl; << endl;
} }
field.reset(mapper.mapSrcToTgt(field)); field.reset(mapper.srcToTgt(field));
evaluateConstraintTypes(field);
field.instance() = field.time().name(); field.instance() = field.time().name();
} }
} }
@ -207,8 +125,7 @@ void MeshToMeshMapVolInternalFields
) )
{ {
VolInternalField<Type>& field = VolInternalField<Type>& field =
const_cast<VolInternalField<Type>&> const_cast<VolInternalField<Type>&>(*fieldIter());
(*fieldIter());
if (fvMeshToFvMesh::debug) if (fvMeshToFvMesh::debug)
{ {
@ -216,7 +133,8 @@ void MeshToMeshMapVolInternalFields
<< endl; << endl;
} }
field.reset(mapper.mapSrcToTgt<Type>(field)); field.reset(mapper.srcToTgt<Type>(field));
field.instance() = field.time().name(); field.instance() = field.time().name();
} }
} }

View File

@ -30,7 +30,7 @@ License
#include "pointFields.H" #include "pointFields.H"
#include "meshToMeshAdjustTimeStepFunctionObject.H" #include "meshToMeshAdjustTimeStepFunctionObject.H"
#include "fvMeshToFvMesh.H" #include "fvMeshToFvMesh.H"
#include "cellVolumeWeightMethod.H" #include "intersectionCellsToCells.H"
#include "surfaceToVolVelocity.H" #include "surfaceToVolVelocity.H"
#include "MeshToMeshMapGeometricFields.H" #include "MeshToMeshMapGeometricFields.H"
#include "polyMeshMap.H" #include "polyMeshMap.H"
@ -86,7 +86,6 @@ Foam::fvMeshTopoChangers::meshToMesh::meshToMesh
: :
fvMeshTopoChanger(mesh), fvMeshTopoChanger(mesh),
dict_(dict), dict_(dict),
cuttingPatches_(dict.lookupOrDefault("cuttingPatches", wordList::null())),
times_(dict.lookup("times")), times_(dict.lookup("times")),
timeDelta_(dict.lookup<scalar>("timeDelta")), timeDelta_(dict.lookup<scalar>("timeDelta")),
timeIndex_(-1) timeIndex_(-1)
@ -121,8 +120,6 @@ bool Foam::fvMeshTopoChangers::meshToMesh::update()
); );
} }
bool hasChanged = false;
// Only refine on the first call in a time-step // Only refine on the first call in a time-step
if (timeIndex_ != mesh().time().timeIndex()) if (timeIndex_ != mesh().time().timeIndex())
{ {
@ -130,7 +127,7 @@ bool Foam::fvMeshTopoChangers::meshToMesh::update()
} }
else else
{ {
return hasChanged; return false;
} }
const scalar userTime = mesh().time().userTimeValue(); const scalar userTime = mesh().time().userTimeValue();
@ -141,8 +138,6 @@ bool Foam::fvMeshTopoChangers::meshToMesh::update()
Info << "Mapping to mesh " << meshDir << endl; Info << "Mapping to mesh " << meshDir << endl;
hasChanged = true;
fvMesh newMesh fvMesh newMesh
( (
IOobject IOobject
@ -156,52 +151,12 @@ bool Foam::fvMeshTopoChangers::meshToMesh::update()
fvMesh::stitchType::none fvMesh::stitchType::none
); );
autoPtr<Foam::fvMeshToFvMesh> mapper; fvMeshToFvMesh mapper
(
// Create mesh-to-mesh mapper with support for cuttingPatches mesh(),
// if specified newMesh,
if (cuttingPatches_.size()) cellsToCellss::intersection::typeName
{ );
HashSet<word> cuttingPatchTable;
forAll(cuttingPatches_, i)
{
cuttingPatchTable.insert(cuttingPatches_[i]);
}
HashTable<word> patchMap(mesh().boundary().size());
const polyBoundaryMesh& pbm = mesh().boundaryMesh();
forAll(pbm, i)
{
if
(
!cuttingPatchTable.found(pbm[i].name())
&& !isA<processorPolyPatch>(pbm[i])
)
{
patchMap.insert(pbm[i].name(), pbm[i].name());
}
}
mapper = new Foam::fvMeshToFvMesh
(
mesh(),
newMesh,
cellVolumeWeightMethod::typeName,
patchMap,
cuttingPatches_
);
}
else
{
mapper = new Foam::fvMeshToFvMesh
(
mesh(),
newMesh,
cellVolumeWeightMethod::typeName
);
}
mesh().reset(newMesh); mesh().reset(newMesh);
@ -234,11 +189,16 @@ bool Foam::fvMeshTopoChangers::meshToMesh::update()
// Interpolate U's to Uf's // Interpolate U's to Uf's
interpolateUfs(); interpolateUfs();
polyMeshMap map(mesh(), mapper()); polyMeshMap map(mesh(), mapper);
mesh().mapMesh(map);
}
return hasChanged; mesh().mapMesh(map);
return true;
}
else
{
return false;
}
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -57,10 +57,6 @@ class meshToMesh
//- Mesh-to-mesh control dictionary //- Mesh-to-mesh control dictionary
dictionary dict_; dictionary dict_;
//- Optional names of the patches which "cut" the internal mesh
// and hence cannot be mapped from existing patches
wordList cuttingPatches_;
//- List of mesh mapping times //- List of mesh mapping times
scalarList times_; scalarList times_;

View File

@ -48,7 +48,7 @@ Usage
nbrRegion other; nbrRegion other;
interpolationMethod cellVolumeWeight; interpolationMethod intersection;
master true; master true;
semiImplicit no; semiImplicit no;

View File

@ -25,7 +25,7 @@ License
#include "interRegionModel.H" #include "interRegionModel.H"
#include "fvModels.H" #include "fvModels.H"
#include "directMethod.H" #include "matchingCellsToCells.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -55,47 +55,44 @@ void Foam::fv::interRegionModel::readCoeffs()
} }
void Foam::fv::interRegionModel::setMapper() const const Foam::cellsToCells& Foam::fv::interRegionModel::interpolation() const
{ {
Info<< incrIndent; if (!interpolationPtr_.valid())
if (master_)
{ {
Info<< indent << "- selecting inter region mapping" << endl; Info<< incrIndent;
if (mesh().name() == nbrMesh().name()) if (master_)
{ {
FatalErrorInFunction Info<< indent << "- selecting inter region mapping" << endl;
<< "Inter-region model selected, but local and "
<< "neighbour regions are the same: " << nl if (mesh().name() == nbrMesh().name())
<< " local region: " << mesh().name() << nl {
<< " secondary region: " << nbrMesh().name() << nl FatalErrorInFunction
<< exit(FatalError); << "Inter-region model selected, but local and "
<< "neighbour regions are the same: " << nl
<< " local region: " << mesh().name() << nl
<< " secondary region: " << nbrMesh().name() << nl
<< exit(FatalError);
}
if (mesh().bounds().overlaps(nbrMesh().bounds()))
{
interpolationPtr_ = cellsToCells::New(interpolationMethod_);
interpolationPtr_->update(mesh(), nbrMesh());
}
else
{
FatalErrorInFunction
<< "regions " << mesh().name() << " and "
<< nbrMesh().name() << " do not intersect"
<< exit(FatalError);
}
} }
if (mesh().bounds().overlaps(nbrMesh().bounds())) Info<< decrIndent;
{
meshInterpPtr_.reset
(
new meshToMesh
(
mesh(),
nbrMesh(),
interpolationMethod_,
false // not interpolating patches
)
);
}
else
{
FatalErrorInFunction
<< "regions " << mesh().name() << " and "
<< nbrMesh().name() << " do not intersect"
<< exit(FatalError);
}
} }
Info<< decrIndent; return interpolationPtr_();
} }
@ -140,8 +137,8 @@ Foam::fv::interRegionModel::interRegionModel
fvModel(name, modelType, mesh, dict), fvModel(name, modelType, mesh, dict),
master_(false), master_(false),
nbrRegionName_(word::null), nbrRegionName_(word::null),
interpolationMethod_(directMethod::typeName), interpolationMethod_(cellsToCellss::matching::typeName),
meshInterpPtr_() interpolationPtr_()
{ {
readCoeffs(); readCoeffs();
} }
@ -160,7 +157,7 @@ bool Foam::fv::interRegionModel::read(const dictionary& dict)
if (fvModel::read(dict)) if (fvModel::read(dict))
{ {
readCoeffs(); readCoeffs();
setMapper(); interpolationPtr_.clear();
return true; return true;
} }
else else

View File

@ -29,14 +29,12 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef interRegionModel_H
#define interRegionModel_H
#include "fvModel.H" #include "fvModel.H"
#include "volFields.H" #include "volFields.H"
#include "autoPtr.H" #include "cellsToCells.H"
#include "meshToMesh.H"
#ifndef interRegionModel_H
#define interRegionModel_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -65,7 +63,7 @@ class interRegionModel
word interpolationMethod_; word interpolationMethod_;
//- Mesh to mesh interpolation object //- Mesh to mesh interpolation object
mutable autoPtr<meshToMesh> meshInterpPtr_; mutable autoPtr<cellsToCells> interpolationPtr_;
// Private member functions // Private member functions
@ -73,9 +71,6 @@ class interRegionModel
//- Non-virtual read //- Non-virtual read
void readCoeffs(); void readCoeffs();
//- Set the mesh to mesh interpolation object
void setMapper() const;
protected: protected:
@ -120,8 +115,8 @@ public:
//- Return const access to the neighbour mesh //- Return const access to the neighbour mesh
inline const fvMesh& nbrMesh() const; inline const fvMesh& nbrMesh() const;
//- Return const access to the mapToMap pointer //- Return const access to the interpolation engine
inline const meshToMesh& meshInterp() const; const cellsToCells& interpolation() const;
// Interpolation // Interpolation

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2021 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -23,6 +23,8 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "interRegionModel.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::fv::interRegionModel::master() const inline bool Foam::fv::interRegionModel::master() const
@ -43,15 +45,4 @@ inline const Foam::fvMesh& Foam::fv::interRegionModel::nbrMesh() const
} }
inline const Foam::meshToMesh& Foam::fv::interRegionModel::meshInterp() const
{
if (!meshInterpPtr_.valid())
{
setMapper();
}
return meshInterpPtr_();
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -36,11 +36,11 @@ Foam::fv::interRegionModel::interpolate
{ {
if (master()) if (master())
{ {
return meshInterp().mapTgtToSrc(field); return interpolation().tgtToSrc(field);
} }
else else
{ {
return nbrModel().meshInterp().mapSrcToTgt(field); return nbrModel().interpolation().srcToTgt(field);
} }
} }
@ -54,11 +54,11 @@ void Foam::fv::interRegionModel::interpolate
{ {
if (master()) if (master())
{ {
meshInterp().mapTgtToSrc(field, result); result = interpolation().tgtToSrc(field, result);
} }
else else
{ {
nbrModel().meshInterp().mapSrcToTgt(field, result); result = nbrModel().interpolation().srcToTgt(field, result);
} }
} }

View File

@ -226,13 +226,13 @@ patchToPatch/inverseDistance/inverseDistancePatchToPatch.C
patchToPatch/intersection/intersectionPatchToPatch.C patchToPatch/intersection/intersectionPatchToPatch.C
patchToPatch/rays/raysPatchToPatch.C patchToPatch/rays/raysPatchToPatch.C
cellsToCells/cellsToCells/cellsToCells.C
cellsToCells/cellsToCells/cellsToCellsParallelOps.C
cellsToCells/matching/matchingCellsToCells.C
cellsToCells/nearest/nearestCellsToCells.C
cellsToCells/intersection/intersectionCellsToCells.C
meshToMesh/meshToMesh.C meshToMesh/meshToMesh.C
meshToMesh/meshToMeshParallelOps.C
meshToMesh/calcMethod/meshToMeshMethod/meshToMeshMethod.C
meshToMesh/calcMethod/meshToMeshMethod/meshToMeshMethodNew.C
meshToMesh/calcMethod/cellVolumeWeight/cellVolumeWeightMethod.C
meshToMesh/calcMethod/direct/directMethod.C
meshToMesh/calcMethod/mapNearest/mapNearestMethod.C
mappedPatches/mappedPatchBase/mappedPatchBase.C mappedPatches/mappedPatchBase/mappedPatchBase.C
mappedPatches/mappedPolyPatch/mappedPolyPatch.C mappedPatches/mappedPolyPatch/mappedPolyPatch.C

View File

@ -0,0 +1,368 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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 "cellsToCells.H"
#include "globalIndex.H"
#include "PatchTools.H"
#include "patchToPatchTools.H"
#include "emptyPolyPatch.H"
#include "wedgePolyPatch.H"
#include "processorPolyPatch.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cellsToCells, 0);
defineRunTimeSelectionTable(cellsToCells, word);
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::cellsToCells::initialise
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh
)
{
srcLocalTgtCells_.setSize(srcMesh.nCells());
srcWeights_.setSize(srcMesh.nCells());
forAll(srcLocalTgtCells_, srcCelli)
{
srcLocalTgtCells_[srcCelli].clear();
srcWeights_[srcCelli].clear();
}
tgtLocalSrcCells_.setSize(tgtMesh.nCells());
tgtWeights_.setSize(tgtMesh.nCells());
forAll(tgtLocalSrcCells_, tgtCelli)
{
tgtLocalSrcCells_[tgtCelli].clear();
tgtWeights_[tgtCelli].clear();
}
}
Foam::labelList Foam::cellsToCells::maskCells
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh
) const
{
boundBox meshBb
(
max(srcMesh.bounds().min(), tgtMesh.bounds().min()),
min(srcMesh.bounds().max(), tgtMesh.bounds().max())
);
meshBb.inflate(0.01);
const cellList& srcCells = srcMesh.cells();
const faceList& srcFaces = srcMesh.faces();
const pointField& srcPts = srcMesh.points();
DynamicList<label> resultDyn(srcMesh.nCells());
forAll(srcCells, srcCelli)
{
const boundBox cellBb
(
srcCells[srcCelli].points(srcFaces, srcPts),
false
);
if (meshBb.overlaps(cellBb))
{
resultDyn.append(srcCelli);
}
}
labelList result;
result.transfer(resultDyn);
return result;
}
void Foam::cellsToCells::appendNbrCells
(
const label celli,
const polyMesh& mesh,
const DynamicList<label>& visitedCells,
DynamicList<label>& nbrCells
) const
{
// Get all cell-cells
const labelList& allNbrCells = mesh.cellCells()[celli];
// Filter out cells already visited
forAll(allNbrCells, i)
{
const label nbrCelli = allNbrCells[i];
if
(
findIndex(visitedCells, nbrCelli) == -1
&& findIndex(nbrCells, nbrCelli) == -1
)
{
nbrCells.append(nbrCelli);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellsToCells::cellsToCells()
:
singleProcess_(-1),
srcLocalTgtCells_(),
tgtLocalSrcCells_(),
srcWeights_(),
tgtWeights_(),
srcMapPtr_(nullptr),
tgtMapPtr_(nullptr),
localSrcProcCellsPtr_(nullptr),
localTgtProcCellsPtr_(nullptr),
localTgtMeshPtr_(nullptr)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellsToCells::~cellsToCells()
{}
// * * * * * * * * * * * * * * * * Selector * * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::cellsToCells> Foam::cellsToCells::New
(
const word& cellsToCellsType
)
{
wordConstructorTable::iterator cstrIter =
wordConstructorTablePtr_->find(cellsToCellsType);
if (cstrIter == wordConstructorTablePtr_->end())
{
FatalErrorInFunction
<< "Unknown " << typeName << " type "
<< cellsToCellsType << endl << endl
<< "Valid " << typeName << " types are : " << endl
<< wordConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return cstrIter()();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::remote Foam::cellsToCells::srcToTgtPoint
(
const polyMesh& tgtMesh,
const label srcCelli,
const point& p
) const
{
forAll(srcLocalTgtCells_[srcCelli], i)
{
const label tgtCelli = srcLocalTgtCells_[srcCelli][i];
const polyMesh& localTgtMesh =
singleProcess_ == -1 ? localTgtMeshPtr_() : tgtMesh;
if (localTgtMesh.pointInCell(p, tgtCelli))
{
return
singleProcess_ == -1
? localTgtProcCellsPtr_()[tgtCelli]
: remote(Pstream::myProcNo(), tgtCelli);
}
}
return remote();
}
Foam::scalar Foam::cellsToCells::update
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh
)
{
cpuTime time;
// Determine numbers of faces on both sides, report, and quit if either
// side is empty
const label srcTotalSize = returnReduce(srcMesh.nCells(), sumOp<label>());
const label tgtTotalSize = returnReduce(tgtMesh.nCells(), sumOp<label>());
if (srcTotalSize == 0 || tgtTotalSize == 0)
{
return 0;
}
Info<< indent << typeName << ": Calculating couplings between "
<< srcTotalSize << " source cells and " << tgtTotalSize
<< " target cells" << incrIndent << endl;
singleProcess_ =
patchToPatchTools::singleProcess
(
srcMesh.nCells(),
tgtMesh.nCells()
);
scalar V = 0;
if (isSingleProcess())
{
// Do the intersection
V = calculate(srcMesh, tgtMesh);
// Normalise the weights
normalise(srcMesh, srcLocalTgtCells_, srcWeights_);
normalise(tgtMesh, tgtLocalSrcCells_, tgtWeights_);
}
else
{
// Create the target map of overlapping cells. This map gets remote
// parts of the target mesh so that everything needed to compute an
// intersection is available locally to the source. Use it to create a
// source-local target mesh.
tgtMapPtr_ =
patchToPatchTools::constructDistributionMap
(
tgtMeshSendCells(srcMesh, tgtMesh)
);
localTgtProcCellsPtr_.reset
(
new List<remote>
(
distributeMesh
(
tgtMapPtr_(),
tgtMesh,
localTgtMeshPtr_
)
)
);
const polyMesh& localTgtMesh = localTgtMeshPtr_();
if (debug > 1)
{
Pout<< "Writing local target mesh: "
<< localTgtMesh.name() << endl;
localTgtMesh.write();
}
// Do the intersection
V = calculate(srcMesh, localTgtMesh);
// Trim the local target mesh
trimLocalTgt();
if (debug > 1)
{
Pout<< "Writing trimmed local target mesh: "
<< localTgtMesh.name() << endl;
localTgtMesh.write();
}
// Construct the source map
srcMapPtr_ =
patchToPatchTools::constructDistributionMap
(
patchToPatchTools::procSendIndices
(
tgtLocalSrcCells_,
localTgtProcCellsPtr_()
)
);
localSrcProcCellsPtr_.reset
(
new List<remote>
(
patchToPatchTools::distributeAddressing(srcMapPtr_())
)
);
// Collect the addressing on the target
patchToPatchTools::rDistributeTgtAddressing
(
tgtMesh.nCells(),
tgtMapPtr_(),
localSrcProcCellsPtr_(),
tgtLocalSrcCells_
);
// Collect the weights on the target
patchToPatchTools::rDistributeListList
(
tgtMesh.nCells(),
tgtMapPtr_(),
tgtWeights_
);
// Normalise the weights
normalise(srcMesh, srcLocalTgtCells_, srcWeights_);
normalise(tgtMesh, tgtLocalSrcCells_, tgtWeights_);
// Collect volume intersection contributions
reduce(V, sumOp<scalar>());
}
label nCouples = 0;
forAll(srcLocalTgtCells_, srcCelli)
{
nCouples += srcLocalTgtCells_[srcCelli].size();
}
forAll(tgtLocalSrcCells_, tgtCelli)
{
nCouples += tgtLocalSrcCells_[tgtCelli].size();
}
reduce(nCouples, sumOp<label>());
if (nCouples != 0)
{
Info<< indent << "Overlapping volume = " << V << endl
<< indent << nCouples << " couplings calculated in "
<< time.cpuTimeIncrement() << 's' << endl;
}
else
{
Info<< indent << "No couplings found" << endl;
}
Info<< decrIndent;
return V;
}
// ************************************************************************* //

View File

@ -0,0 +1,301 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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::cellsToCells
Description
Class to calculate interpolative addressing and weights between the cells
of two overlapping meshes
SourceFiles
cellsToCells.C
cellsToCellsParallelOps.C
cellsToCellsTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef cellsToCells_H
#define cellsToCells_H
#include "remote.H"
#include "distributionMap.H"
#include "polyMesh.H"
#include "runTimeSelectionTables.H"
#include "treeBoundBox.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cellsToCells Declaration
\*---------------------------------------------------------------------------*/
class cellsToCells
{
protected:
// Protected Data
//- Index of processor that holds all of both sides, or -1
label singleProcess_;
//- For each source cell, the coupled local target cells
labelListList srcLocalTgtCells_;
//- For each target cell, the coupled local source cells
labelListList tgtLocalSrcCells_;
//- For each source cell, the coupled target weights
scalarListList srcWeights_;
//- For each target cell, the coupled source weights
scalarListList tgtWeights_;
//- Map from source patch cells to target-local source patch cells
autoPtr<distributionMap> srcMapPtr_;
//- Map from target patch cells to source-local target patch cells
autoPtr<distributionMap> tgtMapPtr_;
//- When running in parallel, a map from local source cell index to
// source processor and cell index
autoPtr<List<remote>> localSrcProcCellsPtr_;
//- When running in parallel, a map from local target cell index to
// target processor and cell index
autoPtr<List<remote>> localTgtProcCellsPtr_;
//- The target mesh, distributed locally to the source
autoPtr<polyMesh> localTgtMeshPtr_;
// Protected Member Functions
// Intersection
//- Initialise the addressing and weights
void initialise
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh
);
//- Calculate the addressing and weights
virtual scalar calculate
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh
) = 0;
//- Normalise the weights for a given mesh
virtual void normalise
(
const polyMesh& mesh,
labelListList& localOtherCells,
scalarListList& weights
) const = 0;
// Helpers
//- Return src cell IDs for the overlap region
labelList maskCells
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh
) const;
//- Append target cell neighbour cells to cellIDs list
void appendNbrCells
(
const label tgtCelli,
const polyMesh& mesh,
const DynamicList<label>& visitedTgtCells,
DynamicList<label>& nbrTgtCellIDs
) const;
// Parallel operations
//- Determine which target cells need to be sent to the source.
// This is done before intersection. Bound boxes are used to
// estimate what cells will intersect.
labelListList tgtMeshSendCells
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh
) const;
//- Distribute a mesh given its distribution map
static List<remote> distributeMesh
(
const distributionMap& map,
const polyMesh& mesh,
autoPtr<polyMesh>& localMeshPtr
);
//- Trim the local target addressing and mesh so that communication
// from the target to the source is optimised
void trimLocalTgt();
public:
//- Run-time type information
TypeName("cellsToCells");
//- Declare runtime constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
cellsToCells,
word,
(),
()
);
// Constructors
//- Construct null
cellsToCells();
//- Disallow default bitwise copy construction
cellsToCells(const cellsToCells&) = delete;
//- Destructor
virtual ~cellsToCells();
// Selector
//- Select from name
static autoPtr<cellsToCells> New(const word& cellsToCellsType);
// Member Functions
// Access
//- Index of the processor holding all cells of the cellsToCells,
// or -1 if spread across multiple processors
inline label singleProcess() const;
//- Is this intersection on a single process?
inline bool isSingleProcess() const;
// Interpolation
//- Interpolate a source cell field to the target with no left
// over values specified. If the interpolation weight sum is less
// than one for a face then they will be normalised. If the
// interpolation weight sum is zero for a face then that face's
// value will be NaN.
template<class Type>
tmp<Field<Type>> srcToTgt(const Field<Type>& srcFld) const;
//- Interpolate a source cell field to the target with left over
// values specified. If the interpolation weight sum is less than
// one for a face then the average will include the left over
// value multiplied by one minus the weight sum.
template<class Type>
tmp<Field<Type>> srcToTgt
(
const Field<Type>& srcFld,
const Field<Type>& leftOverTgtFld
) const;
//- Interpolate a target cell field to the source with no left
// over values specified. As the corresponding srcToTgt.
template<class Type>
tmp<Field<Type>> tgtToSrc(const Field<Type>& tgtFld) const;
//- Interpolate a target cell field to the source with left
// over values specified. As the corresponding srcToTgt.
template<class Type>
tmp<Field<Type>> tgtToSrc
(
const Field<Type>& tgtFld,
const Field<Type>& leftOverSrcFld
) const;
// Source-to-target point finding
//- Find the target processor and cell associated with a point in a
// source cell. Note that this will only work with derivations
// that fill a cell's stencil with everything that overlaps that
// cell. qt present this is just cellsToCellss::intersection, but
// we might add a cheaper bound-box based method like
// patchToPatches::rays in future.
remote srcToTgtPoint
(
const polyMesh& tgtMesh,
const label srcCelli,
const point& p
) const;
// Manipulation
//- Update addressing and weights for the given meshes. Returns the
// overlapping volume (if that is relevant to the method).
scalar update
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh
);
// Member Operators
//- Disallow default bitwise assignment
void operator=(const cellsToCells&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "cellsToCellsI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "cellsToCellsTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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 "cellsToCells.H"
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
inline Foam::label Foam::cellsToCells::singleProcess() const
{
return singleProcess_;
}
inline bool Foam::cellsToCells::isSingleProcess() const
{
return singleProcess_ != -1;
}
// ************************************************************************* //

View File

@ -23,16 +23,36 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "meshToMesh.H" #include "cellsToCells.H"
#include "OFstream.H"
#include "Time.H"
#include "globalIndex.H"
#include "processorPolyPatch.H" #include "processorPolyPatch.H"
#include "SubField.H" #include "SubField.H"
#include "Time.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
inline void offset(label& lst, const label o)
{
lst += o;
}
template<class ListType>
void offset(ListType& lst, const label o)
{
forAll(lst, i)
{
offset(lst[i], o);
}
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::labelListList Foam::meshToMesh::tgtMeshSendCells Foam::labelListList Foam::cellsToCells::tgtMeshSendCells
( (
const polyMesh& srcMesh, const polyMesh& srcMesh,
const polyMesh& tgtMesh const polyMesh& tgtMesh
@ -85,7 +105,7 @@ Foam::labelListList Foam::meshToMesh::tgtMeshSendCells
} }
Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh Foam::List<Foam::remote> Foam::cellsToCells::distributeMesh
( (
const distributionMap& map, const distributionMap& map,
const polyMesh& mesh, const polyMesh& mesh,
@ -414,10 +434,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
internalFaceOffset[proci] internalFaceOffset[proci]
); );
slice = SubList<face>(fcs, allNInternalFaces[proci]); slice = SubList<face>(fcs, allNInternalFaces[proci]);
forAll(slice, i) offset(slice, pointOffset[proci]);
{
add(slice[i], pointOffset[proci]);
}
SubField<label> ownSlice SubField<label> ownSlice
( (
@ -426,7 +443,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
internalFaceOffset[proci] internalFaceOffset[proci]
); );
ownSlice = SubField<label>(faceOs, allNInternalFaces[proci]); ownSlice = SubField<label>(faceOs, allNInternalFaces[proci]);
add(ownSlice, cellOffset[proci]); offset(ownSlice, cellOffset[proci]);
SubField<label> nbrSlice SubField<label> nbrSlice
( (
@ -435,7 +452,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
internalFaceOffset[proci] internalFaceOffset[proci]
); );
nbrSlice = SubField<label>(faceNs, allNInternalFaces[proci]); nbrSlice = SubField<label>(faceNs, allNInternalFaces[proci]);
add(nbrSlice, cellOffset[proci]); offset(nbrSlice, cellOffset[proci]);
internalFaceOffset[proci] += allNInternalFaces[proci]; internalFaceOffset[proci] += allNInternalFaces[proci];
} }
@ -499,7 +516,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
localFaceNeighbours[localFacei] = newOwn; localFaceNeighbours[localFacei] = newOwn;
} }
add(localFaces[localFacei], pointOffset[proci]); offset(localFaces[localFacei], pointOffset[proci]);
// mark with unique value // mark with unique value
fnd() = -2; fnd() = -2;
@ -549,7 +566,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
} }
localFaces[localFacei] = fcs[i]; localFaces[localFacei] = fcs[i];
add(localFaces[localFacei], pointOffset[proci]); offset(localFaces[localFacei], pointOffset[proci]);
localFaceOwners[localFacei] = newOwn; localFaceOwners[localFacei] = newOwn;
localFaceNeighbours[localFacei] = -1; localFaceNeighbours[localFacei] = -1;
@ -568,7 +585,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
const label localFacei = nIntFaces++; const label localFacei = nIntFaces++;
localFaces[localFacei] = fcs[i]; localFaces[localFacei] = fcs[i];
add(localFaces[localFacei], pointOffset[proci]); offset(localFaces[localFacei], pointOffset[proci]);
localFaceOwners[localFacei] = newOwn; localFaceOwners[localFacei] = newOwn;
localFaceNeighbours[localFacei] = -1; localFaceNeighbours[localFacei] = -1;
@ -617,7 +634,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
} }
void Foam::meshToMesh::trimLocalTgt() void Foam::cellsToCells::trimLocalTgt()
{ {
// Determine which local target cells are actually used // Determine which local target cells are actually used
boolList oldLocalTgtCellIsUsed(localTgtProcCellsPtr_().size(), false); boolList oldLocalTgtCellIsUsed(localTgtProcCellsPtr_().size(), false);

View File

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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 "cellsToCells.H"
#include "patchToPatchTools.H"
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cellsToCells::srcToTgt(const Field<Type>& srcFld) const
{
return
patchToPatchTools::interpolate
(
tgtLocalSrcCells_,
tgtWeights_,
srcMapPtr_,
srcFld
);
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::cellsToCells::srcToTgt
(
const Field<Type>& srcFld,
const Field<Type>& leftOverTgtFld
) const
{
return
patchToPatchTools::interpolate
(
tgtLocalSrcCells_,
tgtWeights_,
srcMapPtr_,
srcFld,
leftOverTgtFld
);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cellsToCells::tgtToSrc(const Field<Type>& tgtFld) const
{
return
patchToPatchTools::interpolate
(
srcLocalTgtCells_,
srcWeights_,
tgtMapPtr_,
tgtFld
);
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::cellsToCells::tgtToSrc
(
const Field<Type>& tgtFld,
const Field<Type>& leftOverSrcFld
) const
{
return
patchToPatchTools::interpolate
(
srcLocalTgtCells_,
srcWeights_,
tgtMapPtr_,
tgtFld,
leftOverSrcFld
);
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -23,8 +23,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "cellVolumeWeightMethod.H" #include "intersectionCellsToCells.H"
#include "intersectionPatchToPatch.H"
#include "indexedOctree.H" #include "indexedOctree.H"
#include "treeDataCell.H" #include "treeDataCell.H"
#include "tetOverlapVolume.H" #include "tetOverlapVolume.H"
@ -34,70 +33,64 @@ License
namespace Foam namespace Foam
{ {
defineTypeNameAndDebug(cellVolumeWeightMethod, 0); namespace cellsToCellss
addToRunTimeSelectionTable {
( defineTypeNameAndDebug(intersection, 0);
meshToMeshMethod, addToRunTimeSelectionTable(cellsToCells, intersection, word);
cellVolumeWeightMethod, }
components
);
} }
const Foam::scalar Foam::cellVolumeWeightMethod::tolerance_ = 1e-6; const Foam::scalar Foam::cellsToCellss::intersection::tolerance_ = 1e-6;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::cellVolumeWeightMethod::intersect bool Foam::cellsToCellss::intersection::intersect
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label srcCelli, const label srcCelli,
const label tgtCelli const label tgtCelli
) const ) const
{ {
scalar threshold = tolerance_*src_.cellVolumes()[srcCelli]; return
tetOverlapVolume().cellCellOverlapMinDecomp
tetOverlapVolume overlapEngine; (
srcMesh,
treeBoundBox bbTgtCell(tgt_.points(), tgt_.cellPoints()[tgtCelli]); srcCelli,
tgtMesh,
return overlapEngine.cellCellOverlapMinDecomp tgtCelli,
( treeBoundBox(tgtMesh.points(), tgtMesh.cellPoints()[tgtCelli]),
src_, tolerance_*srcMesh.cellVolumes()[srcCelli]
srcCelli, );
tgt_,
tgtCelli,
bbTgtCell,
threshold
);
} }
Foam::scalar Foam::cellVolumeWeightMethod::interVol Foam::scalar Foam::cellsToCellss::intersection::interVol
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label srcCelli, const label srcCelli,
const label tgtCelli const label tgtCelli
) const ) const
{ {
tetOverlapVolume overlapEngine; return
tetOverlapVolume().cellCellOverlapVolumeMinDecomp
treeBoundBox bbTgtCell(tgt_.points(), tgt_.cellPoints()[tgtCelli]); (
srcMesh,
scalar vol = overlapEngine.cellCellOverlapVolumeMinDecomp srcCelli,
( tgtMesh,
src_, tgtCelli,
srcCelli, treeBoundBox(tgtMesh.points(), tgtMesh.cellPoints()[tgtCelli])
tgt_, );
tgtCelli,
bbTgtCell
);
return vol;
} }
bool Foam::cellVolumeWeightMethod::findInitialSeeds bool Foam::cellsToCellss::intersection::findInitialSeeds
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const labelList& srcCellIDs, const labelList& srcCellIDs,
const boolList& mapFlag, const boolList& mapFlag,
const label startSeedI, const label startSeedI,
@ -105,9 +98,9 @@ bool Foam::cellVolumeWeightMethod::findInitialSeeds
label& tgtSeedI label& tgtSeedI
) const ) const
{ {
const cellList& srcCells = src_.cells(); const cellList& srcCells = srcMesh.cells();
const faceList& srcFaces = src_.faces(); const faceList& srcFaces = srcMesh.faces();
const pointField& srcPts = src_.points(); const pointField& srcPts = srcMesh.points();
for (label i = startSeedI; i < srcCellIDs.size(); i++) for (label i = startSeedI; i < srcCellIDs.size(); i++)
{ {
@ -117,7 +110,7 @@ bool Foam::cellVolumeWeightMethod::findInitialSeeds
{ {
const labelList tgtIDs const labelList tgtIDs
( (
tgt_.cellTree().findBox tgtMesh.cellTree().findBox
( (
treeBoundBox(srcCells[srcI].bb(srcPts, srcFaces)) treeBoundBox(srcCells[srcI].bb(srcPts, srcFaces))
) )
@ -127,7 +120,7 @@ bool Foam::cellVolumeWeightMethod::findInitialSeeds
{ {
const label tgtI = tgtIDs[j]; const label tgtI = tgtIDs[j];
if (intersect(srcI, tgtI)) if (intersect(srcMesh, tgtMesh, srcI, tgtI))
{ {
srcSeedI = srcI; srcSeedI = srcI;
tgtSeedI = tgtI; tgtSeedI = tgtI;
@ -147,8 +140,10 @@ bool Foam::cellVolumeWeightMethod::findInitialSeeds
} }
Foam::scalar Foam::cellVolumeWeightMethod::calculateAddressing Foam::scalar Foam::cellsToCellss::intersection::calculateAddressing
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
labelListList& srcToTgtCellAddr, labelListList& srcToTgtCellAddr,
scalarListList& srcToTgtCellWght, scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr, labelListList& tgtToSrcCellAddr,
@ -165,11 +160,11 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculateAddressing
label srcCelli = srcSeedI; label srcCelli = srcSeedI;
label tgtCelli = tgtSeedI; label tgtCelli = tgtSeedI;
List<DynamicList<label>> srcToTgtAddr(src_.nCells()); List<DynamicList<label>> srcToTgtAddr(srcMesh.nCells());
List<DynamicList<scalar>> srcToTgtWght(src_.nCells()); List<DynamicList<scalar>> srcToTgtWght(srcMesh.nCells());
List<DynamicList<label>> tgtToSrcAddr(tgt_.nCells()); List<DynamicList<label>> tgtToSrcAddr(tgtMesh.nCells());
List<DynamicList<scalar>> tgtToSrcWght(tgt_.nCells()); List<DynamicList<scalar>> tgtToSrcWght(tgtMesh.nCells());
// list of tgt cell neighbour cells // list of tgt cell neighbour cells
DynamicList<label> nbrTgtCells(10); DynamicList<label> nbrTgtCells(10);
@ -178,10 +173,10 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculateAddressing
DynamicList<label> visitedTgtCells(10); DynamicList<label> visitedTgtCells(10);
// list to keep track of tgt cells used to seed src cells // list to keep track of tgt cells used to seed src cells
labelList seedCells(src_.nCells(), -1); labelList seedCells(srcMesh.nCells(), -1);
seedCells[srcCelli] = tgtCelli; seedCells[srcCelli] = tgtCelli;
const scalarField& srcVol = src_.cellVolumes(); const scalarField& srcVol = srcMesh.cellVolumes();
do do
{ {
@ -190,14 +185,14 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculateAddressing
// append initial target cell and neighbours // append initial target cell and neighbours
nbrTgtCells.append(tgtCelli); nbrTgtCells.append(tgtCelli);
appendNbrCells(tgtCelli, tgt_, visitedTgtCells, nbrTgtCells); appendNbrCells(tgtCelli, tgtMesh, visitedTgtCells, nbrTgtCells);
do do
{ {
tgtCelli = nbrTgtCells.remove(); tgtCelli = nbrTgtCells.remove();
visitedTgtCells.append(tgtCelli); visitedTgtCells.append(tgtCelli);
scalar vol = interVol(srcCelli, tgtCelli); scalar vol = interVol(srcMesh, tgtMesh, srcCelli, tgtCelli);
// accumulate addressing and weights for valid intersection // accumulate addressing and weights for valid intersection
if (vol/srcVol[srcCelli] > tolerance_) if (vol/srcVol[srcCelli] > tolerance_)
@ -209,7 +204,7 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculateAddressing
tgtToSrcAddr[tgtCelli].append(srcCelli); tgtToSrcAddr[tgtCelli].append(srcCelli);
tgtToSrcWght[tgtCelli].append(vol); tgtToSrcWght[tgtCelli].append(vol);
appendNbrCells(tgtCelli, tgt_, visitedTgtCells, nbrTgtCells); appendNbrCells(tgtCelli, tgtMesh, visitedTgtCells, nbrTgtCells);
// accumulate intersection volume // accumulate intersection volume
V += vol; V += vol;
@ -222,6 +217,8 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculateAddressing
// find new source seed cell // find new source seed cell
setNextCells setNextCells
( (
srcMesh,
tgtMesh,
startSeedI, startSeedI,
srcCelli, srcCelli,
tgtCelli, tgtCelli,
@ -250,8 +247,10 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculateAddressing
} }
void Foam::cellVolumeWeightMethod::setNextCells void Foam::cellsToCellss::intersection::setNextCells
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
label& startSeedI, label& startSeedI,
label& srcCelli, label& srcCelli,
label& tgtCelli, label& tgtCelli,
@ -261,7 +260,7 @@ void Foam::cellVolumeWeightMethod::setNextCells
labelList& seedCells labelList& seedCells
) const ) const
{ {
const labelList& srcNbrCells = src_.cellCells()[srcCelli]; const labelList& srcNbrCells = srcMesh.cellCells()[srcCelli];
// set possible seeds for later use by querying all src cell neighbours // set possible seeds for later use by querying all src cell neighbours
// with all visited target cells // with all visited target cells
@ -276,7 +275,7 @@ void Foam::cellVolumeWeightMethod::setNextCells
{ {
label cellT = visitedCells[j]; label cellT = visitedCells[j];
if (intersect(cellS, cellT)) if (intersect(srcMesh, tgtMesh, cellS, cellT))
{ {
seedCells[cellS] = cellT; seedCells[cellS] = cellT;
@ -332,6 +331,8 @@ void Foam::cellVolumeWeightMethod::setNextCells
bool restart = bool restart =
findInitialSeeds findInitialSeeds
( (
srcMesh,
tgtMesh,
srcCellIDs, srcCellIDs,
mapFlag, mapFlag,
startSeedI, startSeedI,
@ -352,68 +353,32 @@ void Foam::cellVolumeWeightMethod::setNextCells
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
Foam::cellVolumeWeightMethod::cellVolumeWeightMethod Foam::scalar Foam::cellsToCellss::intersection::calculate
( (
const polyMesh& src, const polyMesh& srcMesh,
const polyMesh& tgt const polyMesh& tgtMesh
)
:
meshToMeshMethod(src, tgt)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellVolumeWeightMethod::~cellVolumeWeightMethod()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::word& Foam::cellVolumeWeightMethod::patchToPatchMethod() const
{
return patchToPatches::intersection::typeName;
}
Foam::scalar Foam::cellVolumeWeightMethod::calculate
(
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght,
labelListList& tgtToSrcAddr,
scalarListList& tgtToSrcWght
) )
{ {
bool ok = initialise initialise(srcMesh, tgtMesh);
(
srcToTgtAddr,
srcToTgtWght,
tgtToSrcAddr,
tgtToSrcWght
);
if (!ok) // Determine (potentially) participating source mesh cells
{ const labelList srcCellIDs(maskCells(srcMesh, tgtMesh));
return 0;
}
// (potentially) participating source mesh cells // Initialise list to keep track of whether src cell can be mapped
const labelList srcCellIDs(maskCells()); boolList mapFlag(srcMesh.nCells(), false);
// list to keep track of whether src cell can be mapped
boolList mapFlag(src_.nCells(), false);
UIndirectList<bool>(mapFlag, srcCellIDs) = true; UIndirectList<bool>(mapFlag, srcCellIDs) = true;
// find initial point in tgt mesh // Find initial point in tgt mesh
label srcSeedI = -1; label srcSeedI = -1;
label tgtSeedI = -1; label tgtSeedI = -1;
label startSeedI = 0; label startSeedI = 0;
bool startWalk = bool startWalk =
findInitialSeeds findInitialSeeds
( (
srcMesh,
tgtMesh,
srcCellIDs, srcCellIDs,
mapFlag, mapFlag,
startSeedI, startSeedI,
@ -423,26 +388,21 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculate
if (startWalk) if (startWalk)
{ {
const scalar V = return
calculateAddressing calculateAddressing
( (
srcToTgtAddr, srcMesh,
srcToTgtWght, tgtMesh,
tgtToSrcAddr, srcLocalTgtCells_,
tgtToSrcWght, srcWeights_,
tgtLocalSrcCells_,
tgtWeights_,
srcSeedI, srcSeedI,
tgtSeedI, tgtSeedI,
srcCellIDs, srcCellIDs,
mapFlag, mapFlag,
startSeedI startSeedI
); );
if (debug > 1)
{
writeConnectivity(src_, tgt_, srcToTgtAddr);
}
return V;
} }
else else
{ {
@ -451,7 +411,7 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculate
} }
void Foam::cellVolumeWeightMethod::normalise void Foam::cellsToCellss::intersection::normalise
( (
const polyMesh& srcMesh, const polyMesh& srcMesh,
labelListList& srcToTgtAddr, labelListList& srcToTgtAddr,
@ -472,4 +432,18 @@ void Foam::cellVolumeWeightMethod::normalise
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellsToCellss::intersection::intersection()
:
cellsToCells()
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellsToCellss::intersection::~intersection()
{}
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -22,39 +22,39 @@ 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::cellVolumeWeightMethod Foam::cellsToCellss::intersection
Description Description
Cell-volume-weighted mesh-to-mesh interpolation class Intersection-based cells-to-cells interpolation class. Volume conservative.
Volume conservative.
SourceFiles SourceFiles
cellVolumeWeightMethod.C intersectionCellsToCells.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef cellVolumeWeightMethod_H #ifndef intersectionCellsToCells_H
#define cellVolumeWeightMethod_H #define intersectionCellsToCells_H
#include "meshToMeshMethod.H" #include "cellsToCells.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
namespace cellsToCellss
{
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class cellVolumeWeightMethod Declaration Class intersection Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class cellVolumeWeightMethod class intersection
: :
public meshToMeshMethod public cellsToCells
{ {
private: private:
// Private static data // Private Static Data
//- Tolerance used in volume overlap calculations //- Tolerance used in volume overlap calculations
static const scalar tolerance_; static const scalar tolerance_;
@ -63,15 +63,29 @@ private:
// Private Member Functions // Private Member Functions
//- Return the true if cells intersect //- Return the true if cells intersect
bool intersect(const label srcCelli, const label tgtCelli) const; bool intersect
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label srcCelli,
const label tgtCelli
) const;
//- Return the intersection volume between two cells //- Return the intersection volume between two cells
scalar interVol(const label srcCelli, const label tgtCelli) const; scalar interVol
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label srcCelli,
const label tgtCelli
) const;
//- Find indices of overlapping cells in src and tgt meshes - returns //- Find indices of overlapping cells in src and tgt meshes - returns
// true if found a matching pair // true if found a matching pair
bool findInitialSeeds bool findInitialSeeds
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const labelList& srcCellIDs, const labelList& srcCellIDs,
const boolList& mapFlag, const boolList& mapFlag,
const label startSeedI, const label startSeedI,
@ -82,6 +96,8 @@ private:
//- Calculate the mesh-to-mesh addressing and weights //- Calculate the mesh-to-mesh addressing and weights
scalar calculateAddressing scalar calculateAddressing
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
labelListList& srcToTgtCellAddr, labelListList& srcToTgtCellAddr,
scalarListList& srcToTgtCellWght, scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr, labelListList& tgtToSrcCellAddr,
@ -96,6 +112,8 @@ private:
//- Set the next cells in the advancing front algorithm //- Set the next cells in the advancing front algorithm
void setNextCells void setNextCells
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
label& startSeedI, label& startSeedI,
label& srcCelli, label& srcCelli,
label& tgtCelli, label& tgtCelli,
@ -106,48 +124,48 @@ private:
) const; ) const;
protected:
// Protected Member Functions
// Intersection
//- Calculate the addressing and weights
virtual scalar calculate
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh
);
//- Normalise the weights for a given mesh
virtual void normalise
(
const polyMesh& mesh,
labelListList& localOtherCells,
scalarListList& weights
) const;
public: public:
//- Run-time type information //- Run-time type information
TypeName("cellVolumeWeight"); TypeName("intersection");
// Constructors // Constructors
//- Construct from source and target meshes //- Construct null
cellVolumeWeightMethod(const polyMesh& src, const polyMesh& tgt); intersection();
//- Destructor //- Destructor
virtual ~cellVolumeWeightMethod(); virtual ~intersection();
// Member Functions
//- Get the corresponding patchToPatch method
virtual const word& patchToPatchMethod() const;
//- Calculate addressing and weights
virtual scalar calculate
(
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght,
labelListList& tgtToTgtAddr,
scalarListList& tgtToTgtWght
);
//- Normalise the weights for a given mesh
virtual void normalise
(
const polyMesh& srcMesh,
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght
) const;
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace cellsToCellss
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -23,8 +23,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "directMethod.H" #include "matchingCellsToCells.H"
#include "matchingPatchToPatch.H"
#include "indexedOctree.H" #include "indexedOctree.H"
#include "treeDataCell.H" #include "treeDataCell.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
@ -33,30 +32,37 @@ License
namespace Foam namespace Foam
{ {
defineTypeNameAndDebug(directMethod, 0); namespace cellsToCellss
addToRunTimeSelectionTable(meshToMeshMethod, directMethod, components); {
defineTypeNameAndDebug(matching, 0);
addToRunTimeSelectionTable(cellsToCells, matching, word);
}
} }
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::directMethod::intersect bool Foam::cellsToCellss::matching::intersect
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label srcCelli, const label srcCelli,
const label tgtCelli const label tgtCelli
) const ) const
{ {
return tgt_.pointInCell return tgtMesh.pointInCell
( (
src_.cellCentres()[srcCelli], srcMesh.cellCentres()[srcCelli],
tgtCelli, tgtCelli,
polyMesh::FACE_PLANES polyMesh::FACE_PLANES
); );
} }
bool Foam::directMethod::findInitialSeeds bool Foam::cellsToCellss::matching::findInitialSeeds
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const labelList& srcCellIDs, const labelList& srcCellIDs,
const boolList& mapFlag, const boolList& mapFlag,
const label startSeedI, const label startSeedI,
@ -64,9 +70,9 @@ bool Foam::directMethod::findInitialSeeds
label& tgtSeedI label& tgtSeedI
) const ) const
{ {
const cellList& srcCells = src_.cells(); const cellList& srcCells = srcMesh.cells();
const faceList& srcFaces = src_.faces(); const faceList& srcFaces = srcMesh.faces();
const pointField& srcPts = src_.points(); const pointField& srcPts = srcMesh.points();
for (label i = startSeedI; i < srcCellIDs.size(); i++) for (label i = startSeedI; i < srcCellIDs.size(); i++)
{ {
@ -75,9 +81,9 @@ bool Foam::directMethod::findInitialSeeds
if (mapFlag[srcI]) if (mapFlag[srcI])
{ {
const point srcCtr(srcCells[srcI].centre(srcPts, srcFaces)); const point srcCtr(srcCells[srcI].centre(srcPts, srcFaces));
label tgtI = tgt_.cellTree().findInside(srcCtr); label tgtI = tgtMesh.cellTree().findInside(srcCtr);
if (tgtI != -1 && intersect(srcI, tgtI)) if (tgtI != -1 && intersect(srcMesh, tgtMesh, srcI, tgtI))
{ {
srcSeedI = srcI; srcSeedI = srcI;
tgtSeedI = tgtI; tgtSeedI = tgtI;
@ -96,8 +102,10 @@ bool Foam::directMethod::findInitialSeeds
} }
Foam::scalar Foam::directMethod::calculateAddressing Foam::scalar Foam::cellsToCellss::matching::calculateAddressing
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
labelListList& srcToTgtCellAddr, labelListList& srcToTgtCellAddr,
scalarListList& srcToTgtCellWght, scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr, labelListList& tgtToSrcCellAddr,
@ -112,15 +120,15 @@ Foam::scalar Foam::directMethod::calculateAddressing
scalar V = 0; scalar V = 0;
// store a list of src cells already mapped // store a list of src cells already mapped
labelList srcTgtSeed(src_.nCells(), -1); labelList srcTgtSeed(srcMesh.nCells(), -1);
List<DynamicList<label>> srcToTgt(src_.nCells()); List<DynamicList<label>> srcToTgt(srcMesh.nCells());
List<DynamicList<label>> tgtToSrc(tgt_.nCells()); List<DynamicList<label>> tgtToSrc(tgtMesh.nCells());
DynamicList<label> srcSeeds(10); DynamicList<label> srcSeeds(10);
const scalarField& srcVc = src_.cellVolumes(); const scalarField& srcVc = srcMesh.cellVolumes();
const scalarField& tgtVc = tgt_.cellVolumes(); const scalarField& tgtVc = tgtMesh.cellVolumes();
label srcCelli = srcSeedI; label srcCelli = srcSeedI;
label tgtCelli = tgtSeedI; label tgtCelli = tgtSeedI;
@ -140,6 +148,8 @@ Foam::scalar Foam::directMethod::calculateAddressing
// find new source seed cell // find new source seed cell
appendToDirectSeeds appendToDirectSeeds
( (
srcMesh,
tgtMesh,
mapFlag, mapFlag,
srcTgtSeed, srcTgtSeed,
srcSeeds, srcSeeds,
@ -166,8 +176,10 @@ Foam::scalar Foam::directMethod::calculateAddressing
} }
void Foam::directMethod::appendToDirectSeeds void Foam::cellsToCellss::matching::appendToDirectSeeds
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
boolList& mapFlag, boolList& mapFlag,
labelList& srcTgtSeed, labelList& srcTgtSeed,
DynamicList<label>& srcSeeds, DynamicList<label>& srcSeeds,
@ -175,8 +187,8 @@ void Foam::directMethod::appendToDirectSeeds
label& tgtSeedI label& tgtSeedI
) const ) const
{ {
const labelList& srcNbr = src_.cellCells()[srcSeedI]; const labelList& srcNbr = srcMesh.cellCells()[srcSeedI];
const labelList& tgtNbr = tgt_.cellCells()[tgtSeedI]; const labelList& tgtNbr = tgtMesh.cellCells()[tgtSeedI];
forAll(srcNbr, i) forAll(srcNbr, i)
{ {
@ -192,7 +204,7 @@ void Foam::directMethod::appendToDirectSeeds
{ {
label tgtI = tgtNbr[j]; label tgtI = tgtNbr[j];
if (intersect(srcI, tgtI)) if (intersect(srcMesh, tgtMesh, srcI, tgtI))
{ {
// new match - append to lists // new match - append to lists
found = true; found = true;
@ -224,67 +236,32 @@ void Foam::directMethod::appendToDirectSeeds
} }
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
Foam::directMethod::directMethod Foam::scalar Foam::cellsToCellss::matching::calculate
( (
const polyMesh& src, const polyMesh& srcMesh,
const polyMesh& tgt const polyMesh& tgtMesh
)
:
meshToMeshMethod(src, tgt)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::directMethod::~directMethod()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::word& Foam::directMethod::patchToPatchMethod() const
{
return patchToPatches::matching::typeName;
}
Foam::scalar Foam::directMethod::calculate
(
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght,
labelListList& tgtToSrcAddr,
scalarListList& tgtToSrcWght
) )
{ {
bool ok = initialise initialise(srcMesh, tgtMesh);
(
srcToTgtAddr,
srcToTgtWght,
tgtToSrcAddr,
tgtToSrcWght
);
if (!ok) // Determine (potentially) participating source mesh cells
{ const labelList srcCellIDs(maskCells(srcMesh, tgtMesh));
return 0;
}
// (potentially) participating source mesh cells // Initialise list to keep track of whether src cell can be mapped
const labelList srcCellIDs(maskCells()); boolList mapFlag(srcMesh.nCells(), false);
// list to keep track of whether src cell can be mapped
boolList mapFlag(src_.nCells(), false);
UIndirectList<bool>(mapFlag, srcCellIDs) = true; UIndirectList<bool>(mapFlag, srcCellIDs) = true;
// find initial point in tgt mesh // Find initial point in tgt mesh
label srcSeedI = -1; label srcSeedI = -1;
label tgtSeedI = -1; label tgtSeedI = -1;
label startSeedI = 0; label startSeedI = 0;
bool startWalk = bool startWalk =
findInitialSeeds findInitialSeeds
( (
srcMesh,
tgtMesh,
srcCellIDs, srcCellIDs,
mapFlag, mapFlag,
startSeedI, startSeedI,
@ -294,26 +271,21 @@ Foam::scalar Foam::directMethod::calculate
if (startWalk) if (startWalk)
{ {
const scalar V = return
calculateAddressing calculateAddressing
( (
srcToTgtAddr, srcMesh,
srcToTgtWght, tgtMesh,
tgtToSrcAddr, srcLocalTgtCells_,
tgtToSrcWght, srcWeights_,
tgtLocalSrcCells_,
tgtWeights_,
srcSeedI, srcSeedI,
tgtSeedI, tgtSeedI,
srcCellIDs, srcCellIDs,
mapFlag, mapFlag,
startSeedI startSeedI
); );
if (debug > 1)
{
writeConnectivity(src_, tgt_, srcToTgtAddr);
}
return V;
} }
else else
{ {
@ -322,7 +294,7 @@ Foam::scalar Foam::directMethod::calculate
} }
void Foam::directMethod::normalise void Foam::cellsToCellss::matching::normalise
( (
const polyMesh& srcMesh, const polyMesh& srcMesh,
labelListList& srcToTgtAddr, labelListList& srcToTgtAddr,
@ -341,4 +313,18 @@ void Foam::directMethod::normalise
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellsToCellss::matching::matching()
:
cellsToCells()
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellsToCellss::matching::~matching()
{}
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -22,35 +22,35 @@ 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::directMethod Foam::cellsToCellss::matching
Description Description
Direct (one-to-one cell correspondence) mesh-to-mesh interpolation class Matching, one-to-one, cells-to-cells interpolation class.
Volume conservative.
SourceFiles SourceFiles
directMethod.C matchingCellsToCells.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef directMethod_H #ifndef matchingCellsToCells_H
#define directMethod_H #define matchingCellsToCells_H
#include "meshToMeshMethod.H" #include "cellsToCells.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
namespace cellsToCellss
{
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class directMethod Declaration Class matching Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class directMethod class matching
: :
public meshToMeshMethod public cellsToCells
{ {
private: private:
@ -59,6 +59,8 @@ private:
//- Return the true if cells intersect //- Return the true if cells intersect
bool intersect bool intersect
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label srcCelli, const label srcCelli,
const label tgtCelli const label tgtCelli
) const; ) const;
@ -67,6 +69,8 @@ private:
// true if found a matching pair // true if found a matching pair
bool findInitialSeeds bool findInitialSeeds
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const labelList& srcCellIDs, const labelList& srcCellIDs,
const boolList& mapFlag, const boolList& mapFlag,
const label startSeedI, const label startSeedI,
@ -77,6 +81,8 @@ private:
//- Calculate the mesh-to-mesh addressing and weights //- Calculate the mesh-to-mesh addressing and weights
scalar calculateAddressing scalar calculateAddressing
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
labelListList& srcToTgtCellAddr, labelListList& srcToTgtCellAddr,
scalarListList& srcToTgtCellWght, scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr, labelListList& tgtToSrcCellAddr,
@ -91,6 +97,8 @@ private:
//- Append to list of src mesh seed indices //- Append to list of src mesh seed indices
void appendToDirectSeeds void appendToDirectSeeds
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
boolList& mapFlag, boolList& mapFlag,
labelList& srcTgtSeed, labelList& srcTgtSeed,
DynamicList<label>& srcSeeds, DynamicList<label>& srcSeeds,
@ -99,48 +107,48 @@ private:
) const; ) const;
protected:
// Protected Member Functions
// Intersection
//- Calculate the addressing and weights
virtual scalar calculate
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh
);
//- Normalise the weights for a given mesh
virtual void normalise
(
const polyMesh& mesh,
labelListList& localOtherCells,
scalarListList& weights
) const;
public: public:
//- Run-time type information //- Run-time type information
TypeName("direct"); TypeName("matching");
// Constructors // Constructors
//- Construct from source and target meshes //- Construct null
directMethod(const polyMesh& src, const polyMesh& tgt); matching();
//- Destructor //- Destructor
virtual ~directMethod(); virtual ~matching();
// Member Functions
//- Get the corresponding patchToPatch method
virtual const word& patchToPatchMethod() const;
//- Calculate addressing and weights
virtual scalar calculate
(
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght,
labelListList& tgtToTgtAddr,
scalarListList& tgtToTgtWght
);
//- Normalise the weights for a given mesh
virtual void normalise
(
const polyMesh& srcMesh,
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght
) const;
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace cellsToCellss
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -23,8 +23,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "mapNearestMethod.H" #include "nearestCellsToCells.H"
#include "nearestPatchToPatch.H"
#include "pointIndexHit.H" #include "pointIndexHit.H"
#include "indexedOctree.H" #include "indexedOctree.H"
#include "treeDataCell.H" #include "treeDataCell.H"
@ -34,15 +33,20 @@ License
namespace Foam namespace Foam
{ {
defineTypeNameAndDebug(mapNearestMethod, 0); namespace cellsToCellss
addToRunTimeSelectionTable(meshToMeshMethod, mapNearestMethod, components); {
defineTypeNameAndDebug(nearest, 0);
addToRunTimeSelectionTable(cellsToCells, nearest, word);
}
} }
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::mapNearestMethod::findInitialSeeds bool Foam::cellsToCellss::nearest::findInitialSeeds
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const labelList& srcCellIDs, const labelList& srcCellIDs,
const boolList& mapFlag, const boolList& mapFlag,
const label startSeedI, const label startSeedI,
@ -50,7 +54,7 @@ bool Foam::mapNearestMethod::findInitialSeeds
label& tgtSeedI label& tgtSeedI
) const ) const
{ {
const vectorField& srcCcs = src_.cellCentres(); const vectorField& srcCcs = srcMesh.cellCentres();
for (label i = startSeedI; i < srcCellIDs.size(); i++) for (label i = startSeedI; i < srcCellIDs.size(); i++)
{ {
@ -60,7 +64,7 @@ bool Foam::mapNearestMethod::findInitialSeeds
{ {
const point& srcCc = srcCcs[srcI]; const point& srcCc = srcCcs[srcI];
pointIndexHit hit = pointIndexHit hit =
tgt_.cellTree().findNearest(srcCc, great); tgtMesh.cellTree().findNearest(srcCc, great);
if (hit.hit()) if (hit.hit())
{ {
@ -91,8 +95,10 @@ bool Foam::mapNearestMethod::findInitialSeeds
} }
Foam::scalar Foam::mapNearestMethod::calculateAddressing Foam::scalar Foam::cellsToCellss::nearest::calculateAddressing
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
labelListList& srcToTgtCellAddr, labelListList& srcToTgtCellAddr,
scalarListList& srcToTgtCellWght, scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr, labelListList& tgtToSrcCellAddr,
@ -106,11 +112,11 @@ Foam::scalar Foam::mapNearestMethod::calculateAddressing
{ {
scalar V = 0; scalar V = 0;
List<DynamicList<label>> srcToTgt(src_.nCells()); List<DynamicList<label>> srcToTgt(srcMesh.nCells());
List<DynamicList<label>> tgtToSrc(tgt_.nCells()); List<DynamicList<label>> tgtToSrc(tgtMesh.nCells());
const scalarField& srcVc = src_.cellVolumes(); const scalarField& srcVc = srcMesh.cellVolumes();
const scalarField& tgtVc = tgt_.cellVolumes(); const scalarField& tgtVc = tgtMesh.cellVolumes();
{ {
label srcCelli = srcSeedI; label srcCelli = srcSeedI;
@ -119,7 +125,7 @@ Foam::scalar Foam::mapNearestMethod::calculateAddressing
do do
{ {
// find nearest tgt cell // find nearest tgt cell
findNearestCell(src_, tgt_, srcCelli, tgtCelli); findNearestCell(srcMesh, tgtMesh, srcCelli, tgtCelli);
// store src/tgt cell pair // store src/tgt cell pair
srcToTgt[srcCelli].append(tgtCelli); srcToTgt[srcCelli].append(tgtCelli);
@ -134,6 +140,8 @@ Foam::scalar Foam::mapNearestMethod::calculateAddressing
// find new source cell // find new source cell
setNextNearestCells setNextNearestCells
( (
srcMesh,
tgtMesh,
startSeedI, startSeedI,
srcCelli, srcCelli,
tgtCelli, tgtCelli,
@ -146,8 +154,8 @@ Foam::scalar Foam::mapNearestMethod::calculateAddressing
// for the case of multiple source cells per target cell, select the // for the case of multiple source cells per target cell, select the
// nearest source cell only and discard the others // nearest source cell only and discard the others
const vectorField& srcCc = src_.cellCentres(); const vectorField& srcCc = srcMesh.cellCentres();
const vectorField& tgtCc = tgt_.cellCentres(); const vectorField& tgtCc = tgtMesh.cellCentres();
forAll(tgtToSrc, targetCelli) forAll(tgtToSrc, targetCelli)
{ {
@ -182,9 +190,10 @@ Foam::scalar Foam::mapNearestMethod::calculateAddressing
{ {
if (tgtToSrc[tgtCelli].empty()) if (tgtToSrc[tgtCelli].empty())
{ {
label srcCelli = findMappedSrcCell(tgtCelli, tgtToSrc); label srcCelli =
findMappedSrcCell(srcMesh, tgtMesh, tgtCelli, tgtToSrc);
findNearestCell(tgt_, src_, tgtCelli, srcCelli); findNearestCell(tgtMesh, srcMesh, tgtCelli, srcCelli);
tgtToSrc[tgtCelli].append(srcCelli); tgtToSrc[tgtCelli].append(srcCelli);
} }
@ -207,7 +216,7 @@ Foam::scalar Foam::mapNearestMethod::calculateAddressing
} }
void Foam::mapNearestMethod::findNearestCell void Foam::cellsToCellss::nearest::findNearestCell
( (
const polyMesh& mesh1, const polyMesh& mesh1,
const polyMesh& mesh2, const polyMesh& mesh2,
@ -244,8 +253,10 @@ void Foam::mapNearestMethod::findNearestCell
} }
void Foam::mapNearestMethod::setNextNearestCells void Foam::cellsToCellss::nearest::setNextNearestCells
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
label& startSeedI, label& startSeedI,
label& srcCelli, label& srcCelli,
label& tgtCelli, label& tgtCelli,
@ -253,7 +264,7 @@ void Foam::mapNearestMethod::setNextNearestCells
const labelList& srcCellIDs const labelList& srcCellIDs
) const ) const
{ {
const labelList& srcNbr = src_.cellCells()[srcCelli]; const labelList& srcNbr = srcMesh.cellCells()[srcCelli];
srcCelli = -1; srcCelli = -1;
forAll(srcNbr, i) forAll(srcNbr, i)
@ -276,8 +287,10 @@ void Foam::mapNearestMethod::setNextNearestCells
} }
} }
(void)findInitialSeeds findInitialSeeds
( (
srcMesh,
tgtMesh,
srcCellIDs, srcCellIDs,
mapFlag, mapFlag,
startSeedI, startSeedI,
@ -287,8 +300,10 @@ void Foam::mapNearestMethod::setNextNearestCells
} }
Foam::label Foam::mapNearestMethod::findMappedSrcCell Foam::label Foam::cellsToCellss::nearest::findMappedSrcCell
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label tgtCelli, const label tgtCelli,
const List<DynamicList<label>>& tgtToSrc const List<DynamicList<label>>& tgtToSrc
) const ) const
@ -313,7 +328,7 @@ Foam::label Foam::mapNearestMethod::findMappedSrcCell
} }
else else
{ {
const labelList& nbrCells = tgt_.cellCells()[tgtI]; const labelList& nbrCells = tgtMesh.cellCells()[tgtI];
forAll(nbrCells, i) forAll(nbrCells, i)
{ {
@ -331,68 +346,32 @@ Foam::label Foam::mapNearestMethod::findMappedSrcCell
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
Foam::mapNearestMethod::mapNearestMethod Foam::scalar Foam::cellsToCellss::nearest::calculate
( (
const polyMesh& src, const polyMesh& srcMesh,
const polyMesh& tgt const polyMesh& tgtMesh
)
:
meshToMeshMethod(src, tgt)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::mapNearestMethod::~mapNearestMethod()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::word& Foam::mapNearestMethod::patchToPatchMethod() const
{
return patchToPatches::nearest::typeName;
}
Foam::scalar Foam::mapNearestMethod::calculate
(
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght,
labelListList& tgtToSrcAddr,
scalarListList& tgtToSrcWght
) )
{ {
bool ok = initialise initialise(srcMesh, tgtMesh);
(
srcToTgtAddr,
srcToTgtWght,
tgtToSrcAddr,
tgtToSrcWght
);
if (!ok) // Determine (potentially) participating source mesh cells
{ const labelList srcCellIDs(maskCells(srcMesh, tgtMesh));
return 0;
}
// (potentially) participating source mesh cells // Initialise list to keep track of whether src cell can be mapped
const labelList srcCellIDs(maskCells()); boolList mapFlag(srcMesh.nCells(), false);
// list to keep track of whether src cell can be mapped
boolList mapFlag(src_.nCells(), false);
UIndirectList<bool>(mapFlag, srcCellIDs) = true; UIndirectList<bool>(mapFlag, srcCellIDs) = true;
// find initial point in tgt mesh // Find initial point in tgt mesh
label srcSeedI = -1; label srcSeedI = -1;
label tgtSeedI = -1; label tgtSeedI = -1;
label startSeedI = 0; label startSeedI = 0;
bool startWalk = bool startWalk =
findInitialSeeds findInitialSeeds
( (
srcMesh,
tgtMesh,
srcCellIDs, srcCellIDs,
mapFlag, mapFlag,
startSeedI, startSeedI,
@ -402,26 +381,21 @@ Foam::scalar Foam::mapNearestMethod::calculate
if (startWalk) if (startWalk)
{ {
const scalar V = return
calculateAddressing calculateAddressing
( (
srcToTgtAddr, srcMesh,
srcToTgtWght, tgtMesh,
tgtToSrcAddr, srcLocalTgtCells_,
tgtToSrcWght, srcWeights_,
tgtLocalSrcCells_,
tgtWeights_,
srcSeedI, srcSeedI,
tgtSeedI, tgtSeedI,
srcCellIDs, srcCellIDs,
mapFlag, mapFlag,
startSeedI startSeedI
); );
if (debug > 1)
{
writeConnectivity(src_, tgt_, srcToTgtAddr);
}
return V;
} }
else else
{ {
@ -430,7 +404,7 @@ Foam::scalar Foam::mapNearestMethod::calculate
} }
void Foam::mapNearestMethod::normalise void Foam::cellsToCellss::nearest::normalise
( (
const polyMesh& srcMesh, const polyMesh& srcMesh,
labelListList& srcToTgtAddr, labelListList& srcToTgtAddr,
@ -449,4 +423,18 @@ void Foam::mapNearestMethod::normalise
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellsToCellss::nearest::nearest()
:
cellsToCells()
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellsToCellss::nearest::~nearest()
{}
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -22,39 +22,35 @@ 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::mapNearestMethod Foam::cellsToCellss::nearest
Description Description
Map nearest mesh-to-mesh interpolation class Nearest cells-to-cells interpolation class.
Not volume conservative.
- cells outside other meshes bounding box do not get mapped
(initial filtering)
- all remaining cells will be mapped (with weight 1!)
- so take care when mapping meshes with different bounding boxes!
SourceFiles SourceFiles
mapNearestMethod.C nearestCellsToCells.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef mapNearestMethod_H #ifndef nearestCellsToCells_H
#define mapNearestMethod_H #define nearestCellsToCells_H
#include "meshToMeshMethod.H" #include "cellsToCells.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
namespace cellsToCellss
{
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class mapNearestMethod Declaration Class nearest Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class mapNearestMethod class nearest
: :
public meshToMeshMethod public cellsToCells
{ {
private: private:
@ -64,6 +60,8 @@ private:
// true if found a matching pair // true if found a matching pair
bool findInitialSeeds bool findInitialSeeds
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const labelList& srcCellIDs, const labelList& srcCellIDs,
const boolList& mapFlag, const boolList& mapFlag,
const label startSeedI, const label startSeedI,
@ -74,6 +72,8 @@ private:
//- Calculate the mesh-to-mesh addressing and weights //- Calculate the mesh-to-mesh addressing and weights
scalar calculateAddressing scalar calculateAddressing
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
labelListList& srcToTgtCellAddr, labelListList& srcToTgtCellAddr,
scalarListList& srcToTgtCellWght, scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr, labelListList& tgtToSrcCellAddr,
@ -97,6 +97,8 @@ private:
//- Set the next cells for the marching front algorithm //- Set the next cells for the marching front algorithm
void setNextNearestCells void setNextNearestCells
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
label& startSeedI, label& startSeedI,
label& srcCelli, label& srcCelli,
label& tgtCelli, label& tgtCelli,
@ -107,53 +109,55 @@ private:
//- Find a source cell mapped to target cell tgtCelli //- Find a source cell mapped to target cell tgtCelli
label findMappedSrcCell label findMappedSrcCell
( (
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label tgtCelli, const label tgtCelli,
const List<DynamicList<label>>& tgtToSrc const List<DynamicList<label>>& tgtToSrc
) const; ) const;
protected:
// Protected Member Functions
// Intersection
//- Calculate the addressing and weights
virtual scalar calculate
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh
);
//- Normalise the weights for a given mesh
virtual void normalise
(
const polyMesh& mesh,
labelListList& localOtherCells,
scalarListList& weights
) const;
public: public:
//- Run-time type information //- Run-time type information
TypeName("mapNearest"); TypeName("nearest");
// Constructors // Constructors
//- Construct from source and target meshes //- Construct null
mapNearestMethod(const polyMesh& src, const polyMesh& tgt); nearest();
//- Destructor //- Destructor
virtual ~mapNearestMethod(); virtual ~nearest();
// Member Functions
//- Get the corresponding patchToPatch method
virtual const word& patchToPatchMethod() const;
//- Calculate addressing and weights
virtual scalar calculate
(
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght,
labelListList& tgtToTgtAddr,
scalarListList& tgtToTgtWght
);
//- Normalise the weights for a given mesh
virtual void normalise
(
const polyMesh& srcMesh,
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght
) const;
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace cellsToCellss
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -1,184 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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 "HashTable.H"
#include "meshToMeshMethod.H"
#include "OFstream.H"
#include "Time.H"
#include "treeBoundBox.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(meshToMeshMethod, 0);
defineRunTimeSelectionTable(meshToMeshMethod, components);
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
Foam::labelList Foam::meshToMeshMethod::maskCells() const
{
boundBox intersectBb
(
max(src_.bounds().min(), tgt_.bounds().min()),
min(src_.bounds().max(), tgt_.bounds().max())
);
intersectBb.inflate(0.01);
const cellList& srcCells = src_.cells();
const faceList& srcFaces = src_.faces();
const pointField& srcPts = src_.points();
DynamicList<label> cells(src_.nCells());
forAll(srcCells, srcI)
{
boundBox cellBb(srcCells[srcI].points(srcFaces, srcPts), false);
if (intersectBb.overlaps(cellBb))
{
cells.append(srcI);
}
}
if (debug)
{
Pout<< "participating source mesh cells: " << cells.size() << endl;
}
return move(cells);
}
void Foam::meshToMeshMethod::appendNbrCells
(
const label celli,
const polyMesh& mesh,
const DynamicList<label>& visitedCells,
DynamicList<label>& nbrCellIDs
) const
{
const labelList& nbrCells = mesh.cellCells()[celli];
// filter out cells already visited from cell neighbours
forAll(nbrCells, i)
{
label nbrCelli = nbrCells[i];
if
(
(findIndex(visitedCells, nbrCelli) == -1)
&& (findIndex(nbrCellIDs, nbrCelli) == -1)
)
{
nbrCellIDs.append(nbrCelli);
}
}
}
bool Foam::meshToMeshMethod::initialise
(
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght,
labelListList& tgtToSrcAddr,
scalarListList& tgtToSrcWght
) const
{
srcToTgtAddr.setSize(src_.nCells());
srcToTgtWght.setSize(src_.nCells());
tgtToSrcAddr.setSize(tgt_.nCells());
tgtToSrcWght.setSize(tgt_.nCells());
return src_.nCells() && tgt_.nCells();
}
void Foam::meshToMeshMethod::writeConnectivity
(
const polyMesh& mesh1,
const polyMesh& mesh2,
const labelListList& mesh1ToMesh2Addr
) const
{
Pout<< "Source size = " << mesh1.nCells() << endl;
Pout<< "Target size = " << mesh2.nCells() << endl;
word fName("addressing_" + mesh1.name() + "_to_" + mesh2.name());
if (Pstream::parRun())
{
fName = fName + "_proc" + Foam::name(Pstream::myProcNo());
}
OFstream os(src_.time().path()/fName + ".obj");
label vertI = 0;
forAll(mesh1ToMesh2Addr, i)
{
const labelList& addr = mesh1ToMesh2Addr[i];
forAll(addr, j)
{
label celli = addr[j];
const vector& c0 = mesh1.cellCentres()[i];
const cell& c = mesh2.cells()[celli];
const pointField pts(c.points(mesh2.faces(), mesh2.points()));
forAll(pts, j)
{
const point& p = pts[j];
os << "v " << p.x() << ' ' << p.y() << ' ' << p.z() << nl;
vertI++;
os << "v " << c0.x() << ' ' << c0.y() << ' ' << c0.z()
<< nl;
vertI++;
os << "l " << vertI - 1 << ' ' << vertI << nl;
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::meshToMeshMethod::meshToMeshMethod
(
const polyMesh& src,
const polyMesh& tgt
)
:
src_(src),
tgt_(tgt)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::meshToMeshMethod::~meshToMeshMethod()
{}
// ************************************************************************* //

View File

@ -1,199 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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::meshToMeshMethod
Description
Base class for mesh-to-mesh calculation methods
SourceFiles
meshToMeshMethod.C
\*---------------------------------------------------------------------------*/
#ifndef meshToMeshMethod_H
#define meshToMeshMethod_H
#include "polyMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class meshToMeshMethod Declaration
\*---------------------------------------------------------------------------*/
class meshToMeshMethod
{
// Private static data
//- Map from mesh-to-mesh method to patch-to-patch method
static HashTable<word> meshToMeshToPatchToPatchMethod_;
protected:
// Protected data
//- Reference to the source mesh
const polyMesh& src_;
//- Reference to the target mesh
const polyMesh& tgt_;
// Protected Member Functions
//- Return src cell IDs for the overlap region
labelList maskCells() const;
//- Append target cell neighbour cells to cellIDs list
void appendNbrCells
(
const label tgtCelli,
const polyMesh& mesh,
const DynamicList<label>& visitedTgtCells,
DynamicList<label>& nbrTgtCellIDs
) const;
//- Initialise the arrays used to store the intersection result. Return
// whether or not an intersection is possible.
bool initialise
(
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght,
labelListList& tgtToTgtAddr,
scalarListList& tgtToTgtWght
) const;
//- Write the connectivity for debugging
void writeConnectivity
(
const polyMesh& mesh1,
const polyMesh& mesh2,
const labelListList& mesh1ToMesh2Addr
) const;
public:
//- Run-time type information
TypeName("meshToMeshMethod");
//- Declare runtime constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
meshToMeshMethod,
components,
(
const polyMesh& src,
const polyMesh& tgt
),
(src, tgt)
);
// Constructors
//- Construct from source and target meshes
meshToMeshMethod(const polyMesh& src, const polyMesh& tgt);
//- Disallow default bitwise copy construction
meshToMeshMethod(const meshToMeshMethod&) = delete;
//- Selector
static autoPtr<meshToMeshMethod> New
(
const word& methodName,
const polyMesh& src,
const polyMesh& tgt
);
//- Destructor
virtual ~meshToMeshMethod();
// Member Functions
//- Get the corresponding patch-to-patch method
virtual const word& patchToPatchMethod() const = 0;
// Evaluate
//- Calculate addressing and weights
virtual scalar calculate
(
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght,
labelListList& tgtToTgtAddr,
scalarListList& tgtToTgtWght
) = 0;
//- Normalise the weights for a given mesh
virtual void normalise
(
const polyMesh& srcMesh,
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght
) const = 0;
// Access
//- Return const access to the source mesh
inline const polyMesh& src() const
{
return src_;
}
//- Return const access to the target mesh
inline const polyMesh& tgt() const
{
return tgt_;
}
// Member Operators
//- Disallow default bitwise assignment
void operator=(const meshToMeshMethod&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -24,12 +24,10 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "meshToMesh.H" #include "meshToMesh.H"
#include "globalIndex.H"
#include "meshToMeshMethod.H"
#include "PatchTools.H" #include "PatchTools.H"
#include "patchToPatchTools.H" #include "emptyPolyPatch.H"
#include "wedgePolyPatch.H"
#include "processorPolyPatch.H" #include "processorPolyPatch.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -39,200 +37,25 @@ namespace Foam
} }
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::scalar Foam::meshToMesh::calculateCellToCells(const word& methodName) Foam::meshToMesh::meshToMesh
{
Info<< "Creating mesh-to-mesh addressing for " << srcMesh_.name()
<< " and " << tgtMesh_.name() << " regions using "
<< methodName << endl;
singleProcess_ =
patchToPatchTools::singleProcess
(
srcMesh_.nCells(),
tgtMesh_.nCells()
);
autoPtr<meshToMeshMethod> methodPtr;
scalar V = 0;
if (isSingleProcess())
{
// Do the intersection
methodPtr = meshToMeshMethod::New(methodName, srcMesh_, tgtMesh_);
V = methodPtr->calculate
(
srcLocalTgtCells_,
srcWeights_,
tgtLocalSrcCells_,
tgtWeights_
);
// Normalise the weights
methodPtr->normalise(srcMesh_, srcLocalTgtCells_, srcWeights_);
methodPtr->normalise(tgtMesh_, tgtLocalSrcCells_, tgtWeights_);
}
else
{
// Create the target map of overlapping cells. This map gets remote
// parts of the target mesh so that everything needed to compute an
// intersection is available locally to the source. Use it to create a
// source-local target mesh.
tgtMapPtr_ =
patchToPatchTools::constructDistributionMap
(
tgtMeshSendCells(srcMesh_, tgtMesh_)
);
localTgtProcCellsPtr_.reset
(
new List<remote>
(
distributeMesh
(
tgtMapPtr_(),
tgtMesh_,
localTgtMeshPtr_
)
)
);
const polyMesh& localTgtMesh = localTgtMeshPtr_();
if (debug > 1)
{
Pout<< "Writing local target mesh: "
<< localTgtMesh.name() << endl;
localTgtMesh.write();
}
// Do the intersection
methodPtr = meshToMeshMethod::New(methodName, srcMesh_, localTgtMesh);
V = methodPtr->calculate
(
srcLocalTgtCells_,
srcWeights_,
tgtLocalSrcCells_,
tgtWeights_
);
// Trim the local target mesh
trimLocalTgt();
if (debug > 1)
{
Pout<< "Writing trimmed local target mesh: "
<< localTgtMesh.name() << endl;
localTgtMesh.write();
}
// Construct the source map
srcMapPtr_ =
patchToPatchTools::constructDistributionMap
(
patchToPatchTools::procSendIndices
(
tgtLocalSrcCells_,
localTgtProcCellsPtr_()
)
);
localSrcProcCellsPtr_.reset
(
new List<remote>
(
patchToPatchTools::distributeAddressing(srcMapPtr_())
)
);
// Collect the addressing on the target
patchToPatchTools::rDistributeTgtAddressing
(
tgtMesh_.nCells(),
tgtMapPtr_(),
localSrcProcCellsPtr_(),
tgtLocalSrcCells_
);
// Collect the weights on the target
patchToPatchTools::rDistributeListList
(
tgtMesh_.nCells(),
tgtMapPtr_(),
tgtWeights_
);
// Normalise the weights
methodPtr->normalise(srcMesh_, srcLocalTgtCells_, srcWeights_);
methodPtr->normalise(tgtMesh_, tgtLocalSrcCells_, tgtWeights_);
// collect volume intersection contributions
reduce(V, sumOp<scalar>());
}
Info<< " Overlap volume: " << V << endl;
return V;
}
void Foam::meshToMesh::calculatePatchToPatches(const word& methodName)
{
if (!srcToTgtPatchToPatches_.empty())
{
FatalErrorInFunction
<< "srcToTgtPatchToPatches already calculated"
<< exit(FatalError);
}
const word& patchToPatchType =
meshToMeshMethod::New
(
methodName,
NullObjectRef<polyMesh>(),
NullObjectRef<polyMesh>()
)->patchToPatchMethod();
srcToTgtPatchToPatches_.setSize(srcToTgtPatchIDs_.size());
forAll(srcToTgtPatchIDs_, i)
{
const label srcPatchi = srcToTgtPatchIDs_[i].first();
const label tgtPatchi = srcToTgtPatchIDs_[i].second();
const polyPatch& srcPP = srcMesh_.boundaryMesh()[srcPatchi];
const polyPatch& tgtPP = tgtMesh_.boundaryMesh()[tgtPatchi];
Info<< "Creating patchToPatch between source patch "
<< srcPP.name() << " and target patch " << tgtPP.name()
<< " using " << patchToPatchType << endl;
Info<< incrIndent;
srcToTgtPatchToPatches_.set
(
i,
patchToPatch::New(patchToPatchType, true)
);
srcToTgtPatchToPatches_[i].update
(
srcPP,
PatchTools::pointNormals(srcMesh_, srcPP),
tgtPP
);
Info<< decrIndent;
}
}
void Foam::meshToMesh::constructNoCuttingPatches
( (
const word& methodName, const polyMesh& srcMesh,
const bool interpAllPatches const polyMesh& tgtMesh,
const word& engineType,
const HashTable<word>& patchMap
) )
:
srcMesh_(srcMesh),
tgtMesh_(tgtMesh),
srcToTgtCellsToCells_(),
srcToTgtPatchIDs_(),
srcToTgtPatchToPatches_()
{ {
if (interpAllPatches) // If no patch map was supplied, then assume a consistent pair of meshes in
// which corresponding patches have the same name
if (isNull(patchMap))
{ {
DynamicList<labelPair> srcToTgtPatchIDs; DynamicList<labelPair> srcToTgtPatchIDs;
@ -240,10 +63,18 @@ void Foam::meshToMesh::constructNoCuttingPatches
{ {
const polyPatch& srcPp = srcMesh_.boundaryMesh()[srcPatchi]; const polyPatch& srcPp = srcMesh_.boundaryMesh()[srcPatchi];
// We want to map all the global patches, including constraint // We don't want to map empty or wedge patches, as by definition
// patches (since they might have mappable properties, e.g. // these do not hold relevant values. We also don't want to map
// jumpCyclic). We'll fix the value afterwards. // processor patches as these are likely to differ between cases.
if (!isA<processorPolyPatch>(srcPp)) // In general, though, we do want to map constraint patches as they
// might have additional mappable properties; e.g., the jump field
// of a jump cyclic.
if
(
!isA<emptyPolyPatch>(srcPp)
&& !isA<wedgePolyPatch>(srcPp)
&& !isA<processorPolyPatch>(srcPp)
)
{ {
const label tgtPatchi = const label tgtPatchi =
tgtMesh_.boundaryMesh().findPatchID(srcPp.name()); tgtMesh_.boundaryMesh().findPatchID(srcPp.name());
@ -265,118 +96,86 @@ void Foam::meshToMesh::constructNoCuttingPatches
srcToTgtPatchIDs_.transfer(srcToTgtPatchIDs); srcToTgtPatchIDs_.transfer(srcToTgtPatchIDs);
} }
// calculate patch addressing and weights // If a patch mas was supplied then convert it to pairs of patch indices
calculatePatchToPatches(methodName); else
// calculate cell addressing and weights
calculateCellToCells(methodName);
}
void Foam::meshToMesh::constructFromCuttingPatches
(
const word& methodName,
const HashTable<word>& patchMap,
const wordList& tgtCuttingPatches
)
{
srcToTgtPatchIDs_.setSize(patchMap.size());
label i = 0;
forAllConstIter(HashTable<word>, patchMap, iter)
{ {
const word& tgtPatchName = iter.key(); srcToTgtPatchIDs_.setSize(patchMap.size());
const word& srcPatchName = iter(); label i = 0;
forAllConstIter(HashTable<word>, patchMap, iter)
{
const word& tgtPatchName = iter.key();
const word& srcPatchName = iter();
srcToTgtPatchIDs_[i++] = const label srcPatchi =
labelPair srcMesh_.boundaryMesh().findPatchID(srcPatchName);
( const label tgtPatchi =
srcMesh_.boundaryMesh().findPatchID(srcPatchName), tgtMesh_.boundaryMesh().findPatchID(tgtPatchName);
tgtMesh_.boundaryMesh().findPatchID(tgtPatchName)
); if (srcPatchi == -1)
{
FatalErrorInFunction
<< "Patch " << srcPatchName
<< " not found in source mesh. "
<< "Available source patches are "
<< srcMesh_.boundaryMesh().names()
<< exit(FatalError);
}
if (tgtPatchi == -1)
{
FatalErrorInFunction
<< "Patch " << tgtPatchName
<< " not found in target mesh. "
<< "Available target patches are "
<< tgtMesh_.boundaryMesh().names()
<< exit(FatalError);
}
srcToTgtPatchIDs_[i ++] = labelPair(srcPatchi, tgtPatchi);
}
} }
// calculate patch addressing and weights // Calculate cell addressing and weights
calculatePatchToPatches(methodName); Info<< "Creating cellsToCells between source mesh "
<< srcMesh_.name() << " and target mesh " << tgtMesh_.name()
<< " using " << engineType << endl << incrIndent;
// calculate cell addressing and weights srcToTgtCellsToCells_ = cellsToCells::New(engineType);
calculateCellToCells(methodName); srcToTgtCellsToCells_->update(srcMesh_, tgtMesh_);
// set IDs of cutting patches on target mesh Info<< decrIndent;
tgtCuttingPatchIDs_.setSize(tgtCuttingPatches.size());
forAll(tgtCuttingPatchIDs_, i) // Calculate patch addressing and weights
srcToTgtPatchToPatches_.setSize(srcToTgtPatchIDs_.size());
forAll(srcToTgtPatchIDs_, i)
{ {
const word& patchName = tgtCuttingPatches[i]; const label srcPatchi = srcToTgtPatchIDs_[i].first();
tgtCuttingPatchIDs_[i] = tgtMesh_.boundaryMesh().findPatchID(patchName); const label tgtPatchi = srcToTgtPatchIDs_[i].second();
const polyPatch& srcPP = srcMesh_.boundaryMesh()[srcPatchi];
const polyPatch& tgtPP = tgtMesh_.boundaryMesh()[tgtPatchi];
Info<< "Creating patchToPatch between source patch "
<< srcPP.name() << " and target patch " << tgtPP.name()
<< " using " << engineType << endl << incrIndent;
srcToTgtPatchToPatches_.set
(
i,
patchToPatch::New(engineType, true)
);
srcToTgtPatchToPatches_[i].update
(
srcPP,
PatchTools::pointNormals(srcMesh_, srcPP),
tgtPP
);
Info<< decrIndent;
} }
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::meshToMesh::meshToMesh
(
const polyMesh& src,
const polyMesh& tgt,
const word& methodName,
bool interpAllPatches
)
:
srcMesh_(src),
tgtMesh_(tgt),
srcToTgtPatchIDs_(),
srcToTgtPatchToPatches_(),
tgtCuttingPatchIDs_(),
srcLocalTgtCells_(),
tgtLocalSrcCells_(),
srcWeights_(),
tgtWeights_(),
singleProcess_(-1),
srcMapPtr_(nullptr),
tgtMapPtr_(nullptr),
localSrcProcCellsPtr_(nullptr),
localTgtProcCellsPtr_(nullptr),
localTgtMeshPtr_(nullptr)
{
constructNoCuttingPatches
(
methodName,
interpAllPatches
);
}
Foam::meshToMesh::meshToMesh
(
const polyMesh& src,
const polyMesh& tgt,
const word& methodName,
const HashTable<word>& patchMap,
const wordList& tgtCuttingPatches
)
:
srcMesh_(src),
tgtMesh_(tgt),
srcToTgtPatchIDs_(),
srcToTgtPatchToPatches_(),
tgtCuttingPatchIDs_(),
srcLocalTgtCells_(),
tgtLocalSrcCells_(),
srcWeights_(),
tgtWeights_(),
singleProcess_(-1),
srcMapPtr_(nullptr),
tgtMapPtr_(nullptr),
localTgtMeshPtr_(nullptr)
{
constructFromCuttingPatches
(
methodName,
patchMap,
tgtCuttingPatches
);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::meshToMesh::~meshToMesh() Foam::meshToMesh::~meshToMesh()
@ -385,29 +184,65 @@ Foam::meshToMesh::~meshToMesh()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::meshToMesh::consistent() const
{
boolList srcPatchIsMapped(srcMesh_.boundaryMesh().size(), false);
boolList tgtPatchIsMapped(tgtMesh_.boundaryMesh().size(), false);
// Mark anything paired as mapped
forAll(srcToTgtPatchIDs_, i)
{
const label srcPatchi = srcToTgtPatchIDs_[i].first();
const label tgtPatchi = srcToTgtPatchIDs_[i].second();
srcPatchIsMapped[srcPatchi] = true;
tgtPatchIsMapped[tgtPatchi] = true;
}
// Filter out un-mappable patches
forAll(srcMesh_.boundaryMesh(), srcPatchi)
{
const polyPatch& srcPp = srcMesh_.boundaryMesh()[srcPatchi];
if
(
isA<emptyPolyPatch>(srcPp)
|| isA<wedgePolyPatch>(srcPp)
|| isA<processorPolyPatch>(srcPp)
)
{
srcPatchIsMapped[srcPp.index()] = true;
}
}
forAll(tgtMesh_.boundaryMesh(), tgtPatchi)
{
const polyPatch& tgtPp = tgtMesh_.boundaryMesh()[tgtPatchi];
if
(
isA<emptyPolyPatch>(tgtPp)
|| isA<wedgePolyPatch>(tgtPp)
|| isA<processorPolyPatch>(tgtPp)
)
{
tgtPatchIsMapped[tgtPp.index()] = true;
}
}
// Return whether or not everything is mapped
return
findIndex(srcPatchIsMapped, false) == -1
&& findIndex(tgtPatchIsMapped, false) == -1;
}
Foam::remote Foam::meshToMesh::srcToTgtPoint Foam::remote Foam::meshToMesh::srcToTgtPoint
( (
const label srcCelli, const label srcCelli,
const point& p const point& p
) const ) const
{ {
forAll(srcLocalTgtCells_[srcCelli], i) return srcToTgtCellsToCells_().srcToTgtPoint(tgtMesh_, srcCelli, p);
{
const label tgtCelli = srcLocalTgtCells_[srcCelli][i];
const polyMesh& tgtMesh =
singleProcess_ == -1 ? localTgtMeshPtr_() : tgtMesh_;
if (tgtMesh.pointInCell(p, tgtCelli))
{
return
singleProcess_ == -1
? localTgtProcCellsPtr_()[tgtCelli]
: remote(Pstream::myProcNo(), tgtCelli);
}
}
return remote();
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -25,17 +25,11 @@ Class
Foam::meshToMesh Foam::meshToMesh
Description Description
Class to calculate the cell-addressing between two overlapping meshes Class to calculate interpolative addressing and weights between the cells
and patches of two overlapping meshes
Mapping is performed using a run-time selectable interpolation mothod
See also
meshToMeshMethod
SourceFiles SourceFiles
meshToMesh.C meshToMesh.C
meshToMeshParallelOps.C
meshToMeshTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -43,10 +37,8 @@ SourceFiles
#define meshToMesh_H #define meshToMesh_H
#include "polyMesh.H" #include "polyMesh.H"
#include "boundBox.H"
#include "distributionMap.H"
#include "NamedEnum.H"
#include "patchToPatch.H" #include "patchToPatch.H"
#include "cellsToCells.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -67,6 +59,9 @@ class meshToMesh
//- Reference to the target mesh //- Reference to the target mesh
const polyMesh& tgtMesh_; const polyMesh& tgtMesh_;
//- Interpolation engine between source and target cells
autoPtr<cellsToCells> srcToTgtCellsToCells_;
//- List of corresponding source and target patches that are to be //- List of corresponding source and target patches that are to be
// mapped to each other // mapped to each other
List<labelPair> srcToTgtPatchIDs_; List<labelPair> srcToTgtPatchIDs_;
@ -75,93 +70,6 @@ class meshToMesh
// target patches // target patches
PtrList<patchToPatch> srcToTgtPatchToPatches_; PtrList<patchToPatch> srcToTgtPatchToPatches_;
//- Cutting patches whose values are set using a zero-gradient condition
labelList tgtCuttingPatchIDs_;
//- For each source cell, the coupled local target cells
labelListList srcLocalTgtCells_;
//- For each target cell, the coupled local source cells
labelListList tgtLocalSrcCells_;
//- For each source cell, the coupled target weights
scalarListList srcWeights_;
//- For each target cell, the coupled source weights
scalarListList tgtWeights_;
//- Index of processor that holds all of both sides, or -1
label singleProcess_;
//- Map from source patch cells to target-local source patch cells
autoPtr<distributionMap> srcMapPtr_;
//- Map from target patch cells to source-local target patch cells
autoPtr<distributionMap> tgtMapPtr_;
//- When running in parallel, a map from local source cell index to
// source processor and cell index
autoPtr<List<remote>> localSrcProcCellsPtr_;
//- When running in parallel, a map from local target cell index to
// target processor and cell index
autoPtr<List<remote>> localTgtProcCellsPtr_;
//- The target mesh, distributed locally to the source
autoPtr<polyMesh> localTgtMeshPtr_;
// Private Member Functions
//- Helper function to add a constant offset to a list
template<class Type>
static void add(UList<Type>& fld, const label offset);
//- Calculate the cell intersections. Returns the overlap volume.
scalar calculateCellToCells(const word& methodName);
//- Calculate patch intersections
void calculatePatchToPatches(const word& patchToPatchType);
//- Constructor helper
void constructNoCuttingPatches
(
const word& methodName,
const bool interpAllPatches
);
//- Constructor helper
void constructFromCuttingPatches
(
const word& methodName,
const HashTable<word>& patchMap,
const wordList& tgtCuttingPatches
);
// Parallel operations
//- Determine which target cells need to be sent to the source.
// This is done before intersection. Bound boxes are used to
// estimate what cells will intersect.
labelListList tgtMeshSendCells
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh
) const;
//- Distribute a mesh given its distribution map
static List<remote> distributeMesh
(
const distributionMap& map,
const polyMesh& mesh,
autoPtr<polyMesh>& localMeshPtr
);
//- Trim the local target addressing and mesh so that communication
// from the target to the source is optimised
void trimLocalTgt();
protected: protected:
@ -169,6 +77,9 @@ protected:
// Access // Access
//- Return the interpolation engine between source and target cells
inline const cellsToCells& srcToTgtCellsToCells() const;
//- Return the source patch indices //- Return the source patch indices
inline const List<labelPair>& srcToTgtPatchIDs() const; inline const List<labelPair>& srcToTgtPatchIDs() const;
@ -176,9 +87,6 @@ protected:
// source and target patches // source and target patches
inline const PtrList<patchToPatch>& srcToTgtPatchToPatches() const; inline const PtrList<patchToPatch>& srcToTgtPatchToPatches() const;
//- Return the cutting patch indices
inline const labelList& tgtCuttingPatchIDs() const;
public: public:
@ -188,23 +96,15 @@ public:
// Constructors // Constructors
//- Construct from source and target meshes, generic mapping methods //- Construct from source and target meshes. If a patchMap is supplied,
// then map between the specified patches. If not, then assume a
// consistent mesh and map all patches 1-to-1.
meshToMesh meshToMesh
( (
const polyMesh& src, const polyMesh& srcMesh,
const polyMesh& tgt, const polyMesh& tgtMesh,
const word& methodName, const word& engineType,
const bool interpAllPatches = true const HashTable<word>& patchMap = NullObjectRef<HashTable<word>>()
);
//- Construct from source and target meshes, generic mapping methods
meshToMesh
(
const polyMesh& src,
const polyMesh& tgt,
const word& methodName,
const HashTable<word>& patchMap,
const wordList& cuttingPatches
); );
//- Disallow default bitwise copy construction //- Disallow default bitwise copy construction
@ -225,63 +125,16 @@ public:
//- Return const access to the target mesh //- Return const access to the target mesh
inline const polyMesh& tgtMesh() const; inline const polyMesh& tgtMesh() const;
//- Index of the processor holding all cells of the meshToMesh, //- Is the map between consistent meshes? I.e., are all
// or -1 if spread across multiple processors // (non-processor) patches mapped one-to-one?
inline label singleProcess() const; bool consistent() const;
//- Is this intersection on a single process?
inline bool isSingleProcess() const;
// Evaluation // Source-to-target point finding
// Source-to-target field mapping //- Find the target processor and cell associated with a point in a
// source cell. See cellsToCells::srcToTgtPoint.
//- Map field from src to tgt mesh. Values passed in via remote srcToTgtPoint(const label srcCelli, const point& p) const;
// 'result' are used to initialise the return value.
template<class Type>
void mapSrcToTgt
(
const UList<Type>& srcFld,
List<Type>& result
) const;
//- Return the src field mapped to the tgt mesh. Initial values
// of the result are set to zero.
template<class Type>
tmp<Field<Type>> mapSrcToTgt(const Field<Type>& srcFld) const;
// Target-to-source field mapping
//- Map field from tgt to src mesh. Values passed in via
// 'result' are used to initialise the return value.
template<class Type>
void mapTgtToSrc
(
const UList<Type>& tgtFld,
List<Type>& result
) const;
//- Return the tgt field mapped to the src mesh. Initial values
// of the result are set to zero.
template<class Type>
tmp<Field<Type>> mapTgtToSrc(const Field<Type>& tgtFld) const;
// Source-to-target point finding
//- Find the target processor and cell associated with a point
// in a source cell. Note that this will only work with
// methods that fill a cell's stencil with everything that
// overlaps that cell. At present this is just
// cellVolumeWeightMethod, but we might add a cheaper
// bound-box based method like patchToPatches::rays in future.
remote srcToTgtPoint
(
const label srcCelli,
const point& p
) const;
// Member Operators // Member Operators
@ -301,12 +154,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "meshToMeshTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -27,6 +27,12 @@ License
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
inline const Foam::cellsToCells& Foam::meshToMesh::srcToTgtCellsToCells() const
{
return srcToTgtCellsToCells_();
}
inline const Foam::List<Foam::labelPair>& inline const Foam::List<Foam::labelPair>&
Foam::meshToMesh::srcToTgtPatchIDs() const Foam::meshToMesh::srcToTgtPatchIDs() const
{ {
@ -41,12 +47,6 @@ Foam::meshToMesh::srcToTgtPatchToPatches() const
} }
inline const Foam::labelList& Foam::meshToMesh::tgtCuttingPatchIDs() const
{
return tgtCuttingPatchIDs_;
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
inline const Foam::polyMesh& Foam::meshToMesh::srcMesh() const inline const Foam::polyMesh& Foam::meshToMesh::srcMesh() const
@ -61,16 +61,4 @@ inline const Foam::polyMesh& Foam::meshToMesh::tgtMesh() const
} }
inline Foam::label Foam::meshToMesh::singleProcess() const
{
return singleProcess_;
}
inline bool Foam::meshToMesh::isSingleProcess() const
{
return singleProcess_ != -1;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -1,200 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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 "meshToMesh.H"
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class Type>
void Foam::meshToMesh::add
(
UList<Type>& fld,
const label offset
)
{
forAll(fld, i)
{
fld[i] += offset;
}
}
template<class Type>
void Foam::meshToMesh::mapSrcToTgt
(
const UList<Type>& srcField,
List<Type>& result
) const
{
if (result.size() != tgtLocalSrcCells_.size())
{
FatalErrorInFunction
<< "Supplied field size is not equal to target mesh size" << nl
<< " source mesh = " << srcLocalTgtCells_.size() << nl
<< " target mesh = " << tgtLocalSrcCells_.size() << nl
<< " supplied field = " << result.size()
<< abort(FatalError);
}
if (!isSingleProcess())
{
const distributionMap& map = srcMapPtr_();
List<Type> work(srcField);
map.distribute(work);
forAll(result, tgtCelli)
{
if (tgtLocalSrcCells_[tgtCelli].size())
{
result[tgtCelli] *= (1.0 - sum(tgtWeights_[tgtCelli]));
forAll(tgtLocalSrcCells_[tgtCelli], i)
{
result[tgtCelli] +=
tgtWeights_[tgtCelli][i]
*work[tgtLocalSrcCells_[tgtCelli][i]];
}
}
}
}
else
{
forAll(result, tgtCelli)
{
if (tgtLocalSrcCells_[tgtCelli].size())
{
result[tgtCelli] *= (1.0 - sum(tgtWeights_[tgtCelli]));
forAll(tgtLocalSrcCells_[tgtCelli], i)
{
result[tgtCelli] +=
tgtWeights_[tgtCelli][i]
*srcField[tgtLocalSrcCells_[tgtCelli][i]];
}
}
}
}
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::meshToMesh::mapSrcToTgt
(
const Field<Type>& srcField
) const
{
tmp<Field<Type>> tresult
(
new Field<Type>
(
tgtLocalSrcCells_.size(),
Zero
)
);
mapSrcToTgt(srcField, tresult.ref());
return tresult;
}
template<class Type>
void Foam::meshToMesh::mapTgtToSrc
(
const UList<Type>& tgtField,
List<Type>& result
) const
{
if (result.size() != srcLocalTgtCells_.size())
{
FatalErrorInFunction
<< "Supplied field size is not equal to source mesh size" << nl
<< " source mesh = " << srcLocalTgtCells_.size() << nl
<< " target mesh = " << tgtLocalSrcCells_.size() << nl
<< " supplied field = " << result.size()
<< abort(FatalError);
}
if (!isSingleProcess())
{
const distributionMap& map = tgtMapPtr_();
List<Type> work(tgtField);
map.distribute(work);
forAll(result, srcCelli)
{
if (srcLocalTgtCells_[srcCelli].size())
{
result[srcCelli] *= (1.0 - sum(srcWeights_[srcCelli]));
forAll(srcLocalTgtCells_[srcCelli], i)
{
result[srcCelli] +=
srcWeights_[srcCelli][i]
*work[srcLocalTgtCells_[srcCelli][i]];
}
}
}
}
else
{
forAll(result, srcCelli)
{
if (srcLocalTgtCells_[srcCelli].size())
{
result[srcCelli] *= (1.0 - sum(srcWeights_[srcCelli]));
forAll(srcLocalTgtCells_[srcCelli], i)
{
result[srcCelli] +=
srcWeights_[srcCelli][i]
*tgtField[srcLocalTgtCells_[srcCelli][i]];
}
}
}
}
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::meshToMesh::mapTgtToSrc
(
const Field<Type>& tgtField
) const
{
tmp<Field<Type>> tresult
(
new Field<Type>
(
srcLocalTgtCells_.size(),
Zero
)
);
mapTgtToSrc(tgtField, tresult.ref());
return tresult;
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2021-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -75,7 +75,7 @@ public:
part() part()
: :
area(Zero), area(Zero),
centre(NaN<point>()) centre(patchToPatchTools::NaN<point>())
{} {}
//- Default construct //- Default construct

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -30,16 +30,17 @@ Description
SourceFiles SourceFiles
patchToPatch.C patchToPatch.C
patchToPatchParallelOps.C patchToPatchParallelOps.C
patchToPatchTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef patchToPatch_H #ifndef patchToPatch_H
#define patchToPatch_H #define patchToPatch_H
#include "remote.H"
#include "distributionMap.H" #include "distributionMap.H"
#include "primitivePatch.H" #include "primitivePatch.H"
#include "primitiveOldTimePatch.H" #include "primitiveOldTimePatch.H"
#include "remote.H"
#include "runTimeSelectionTables.H" #include "runTimeSelectionTables.H"
#include "treeBoundBox.H" #include "treeBoundBox.H"
@ -254,31 +255,6 @@ protected:
//- For each target face, the coupled source weights //- For each target face, the coupled source weights
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights() const = 0; virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights() const = 0;
//- Return a primitive with all components set to NaN
template<class Type>
static Type NaN();
//- Interpolate with normalisation
template<class Type>
static tmp<Field<Type>> interpolate
(
const List<DynamicList<label>>& localOtherFaces,
const List<DynamicList<scalar>>& weights,
const autoPtr<distributionMap>& otherMapPtr,
const Field<Type>& otherFld
);
//- Interpolate without normalisation
template<class Type>
static tmp<Field<Type>> interpolate
(
const List<DynamicList<label>>& localOtherFaces,
const List<DynamicList<scalar>>& weights,
const autoPtr<distributionMap>& otherMapPtr,
const Field<Type>& otherFld,
const Field<Type>& leftOverFld
);
public: public:

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -23,9 +23,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "autoPtr.H"
#include "patchToPatch.H" #include "patchToPatch.H"
#include "treeBoundBoxList.H"
#include "uindirectPrimitivePatch.H" #include "uindirectPrimitivePatch.H"
#include "uindirectPrimitiveOldTimePatch.H" #include "uindirectPrimitiveOldTimePatch.H"
@ -40,11 +38,11 @@ Foam::labelListList Foam::patchToPatch::tgtPatchSendFaces
) const ) const
{ {
// Get the bound boxes for the source patch. Just a single box for now. // Get the bound boxes for the source patch. Just a single box for now.
List<treeBoundBoxList> srcPatchProcBbs(Pstream::nProcs()); List<List<treeBoundBox>> srcPatchProcBbs(Pstream::nProcs());
if (srcPatch.size()) if (srcPatch.size())
{ {
srcPatchProcBbs[Pstream::myProcNo()] = srcPatchProcBbs[Pstream::myProcNo()] =
treeBoundBoxList List<treeBoundBox>
( (
1, 1,
srcBox(srcPatch, srcPointNormals, srcPointNormals0) srcBox(srcPatch, srcPointNormals, srcPointNormals0)
@ -52,7 +50,7 @@ Foam::labelListList Foam::patchToPatch::tgtPatchSendFaces
} }
else else
{ {
srcPatchProcBbs[Pstream::myProcNo()] = treeBoundBoxList(); srcPatchProcBbs[Pstream::myProcNo()] = List<treeBoundBox>();
} }
// Distribute the boxes // Distribute the boxes

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -24,111 +24,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "patchToPatch.H" #include "patchToPatch.H"
#include "patchToPatchTools.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Type Foam::patchToPatch::NaN()
{
Type result;
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
setComponent(result, cmpt) = Foam::NaN;
}
return result;
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::patchToPatch::interpolate
(
const List<DynamicList<label>>& localOtherFaces,
const List<DynamicList<scalar>>& weights,
const autoPtr<distributionMap>& otherMapPtr,
const Field<Type>& otherFld
)
{
// Distribute the other field if necessary
tmp<Field<Type>> tLocalOtherFld;
if (otherMapPtr.valid())
{
tLocalOtherFld = tmp<Field<Type>>(new Field<Type>(otherFld));
otherMapPtr->distribute(tLocalOtherFld.ref());
}
const Field<Type>& localOtherFld =
otherMapPtr.valid() ? tLocalOtherFld() : otherFld;
// Allocate the result
tmp<Field<Type>> tFld(new Field<Type>(localOtherFaces.size(), NaN<Type>()));
Field<Type>& fld = tFld.ref();
// Compute the result as a weighted sum
forAll(localOtherFaces, facei)
{
scalar sumW = 0;
Type sumWF = Zero;
forAll(localOtherFaces[facei], i)
{
const scalar w = weights[facei][i];
sumW += w;
sumWF += w*localOtherFld[localOtherFaces[facei][i]];
}
if (localOtherFaces[facei].size())
{
fld[facei] = sumWF/sumW;
}
}
return tFld;
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::patchToPatch::interpolate
(
const List<DynamicList<label>>& localOtherFaces,
const List<DynamicList<scalar>>& weights,
const autoPtr<distributionMap>& otherMapPtr,
const Field<Type>& otherFld,
const Field<Type>& leftOverFld
)
{
// Distribute the other field if necessary
tmp<Field<Type>> tLocalOtherFld;
if (otherMapPtr.valid())
{
tLocalOtherFld = tmp<Field<Type>>(new Field<Type>(otherFld));
otherMapPtr->distribute(tLocalOtherFld.ref());
}
const Field<Type>& localOtherFld =
otherMapPtr.valid() ? tLocalOtherFld() : otherFld;
// Allocate the result
tmp<Field<Type>> tFld(new Field<Type>(localOtherFaces.size(), NaN<Type>()));
Field<Type>& fld = tFld.ref();
// Compute the result as a weighted sum
forAll(localOtherFaces, facei)
{
scalar sumW = 0;
Type sumWF = Zero;
forAll(localOtherFaces[facei], i)
{
const scalar w = weights[facei][i];
sumW += w;
sumWF += w*localOtherFld[localOtherFaces[facei][i]];
}
fld[facei] = sumWF + (1 - sumW)*leftOverFld[facei];
}
return tFld;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -137,10 +33,10 @@ Foam::tmp<Foam::Field<Type>>
Foam::patchToPatch::srcToTgt(const Field<Type>& srcFld) const Foam::patchToPatch::srcToTgt(const Field<Type>& srcFld) const
{ {
return return
interpolate patchToPatchTools::interpolate
( (
tgtLocalSrcFaces_, tgtLocalSrcFaces_,
tgtWeights(), tgtWeights()(),
srcMapPtr_, srcMapPtr_,
srcFld srcFld
); );
@ -155,10 +51,10 @@ Foam::tmp<Foam::Field<Type>> Foam::patchToPatch::srcToTgt
) const ) const
{ {
return return
interpolate patchToPatchTools::interpolate
( (
tgtLocalSrcFaces_, tgtLocalSrcFaces_,
tgtWeights(), tgtWeights()(),
srcMapPtr_, srcMapPtr_,
srcFld, srcFld,
leftOverTgtFld leftOverTgtFld
@ -171,10 +67,10 @@ Foam::tmp<Foam::Field<Type>>
Foam::patchToPatch::tgtToSrc(const Field<Type>& tgtFld) const Foam::patchToPatch::tgtToSrc(const Field<Type>& tgtFld) const
{ {
return return
interpolate patchToPatchTools::interpolate
( (
srcLocalTgtFaces_, srcLocalTgtFaces_,
srcWeights(), srcWeights()(),
tgtMapPtr_, tgtMapPtr_,
tgtFld tgtFld
); );
@ -189,10 +85,10 @@ Foam::tmp<Foam::Field<Type>> Foam::patchToPatch::tgtToSrc
) const ) const
{ {
return return
interpolate patchToPatchTools::interpolate
( (
srcLocalTgtFaces_, srcLocalTgtFaces_,
srcWeights(), srcWeights()(),
tgtMapPtr_, tgtMapPtr_,
tgtFld, tgtFld,
leftOverSrcFld leftOverSrcFld

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -137,6 +137,31 @@ void rDistributeTgtAddressing
List<DynamicList<label>>& tgtLocalSrcFaces List<DynamicList<label>>& tgtLocalSrcFaces
); );
//- Return a primitive with all components set to NaN
template<class Type>
static Type NaN();
//- Interpolate with normalisation
template<class Type, class LabelList, class ScalarList>
static tmp<Field<Type>> interpolate
(
const List<LabelList>& localOtherFaces,
const List<ScalarList>& weights,
const autoPtr<distributionMap>& otherMapPtr,
const Field<Type>& otherFld
);
//- Interpolate without normalisation
template<class Type, class LabelList, class ScalarList>
static tmp<Field<Type>> interpolate
(
const List<LabelList>& localOtherFaces,
const List<ScalarList>& weights,
const autoPtr<distributionMap>& otherMapPtr,
const Field<Type>& otherFld,
const Field<Type>& leftOverFld
);
} // End namespace patchToPatchTools } // End namespace patchToPatchTools
} // End namespace Foam } // End namespace Foam

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -82,4 +82,108 @@ void Foam::patchToPatchTools::rDistributeListList
} }
template<class Type>
Type Foam::patchToPatchTools::NaN()
{
Type result;
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
setComponent(result, cmpt) = Foam::NaN;
}
return result;
}
template<class Type, class LabelList, class ScalarList>
Foam::tmp<Foam::Field<Type>> Foam::patchToPatchTools::interpolate
(
const List<LabelList>& localOtherFaces,
const List<ScalarList>& weights,
const autoPtr<distributionMap>& otherMapPtr,
const Field<Type>& otherFld
)
{
// Distribute the other field if necessary
tmp<Field<Type>> tLocalOtherFld;
if (otherMapPtr.valid())
{
tLocalOtherFld = tmp<Field<Type>>(new Field<Type>(otherFld));
otherMapPtr->distribute(tLocalOtherFld.ref());
}
const Field<Type>& localOtherFld =
otherMapPtr.valid() ? tLocalOtherFld() : otherFld;
// Allocate the result
tmp<Field<Type>> tFld(new Field<Type>(localOtherFaces.size(), NaN<Type>()));
Field<Type>& fld = tFld.ref();
// Compute the result as a weighted sum
forAll(localOtherFaces, facei)
{
scalar sumW = 0;
Type sumWF = Zero;
forAll(localOtherFaces[facei], i)
{
const scalar w = weights[facei][i];
sumW += w;
sumWF += w*localOtherFld[localOtherFaces[facei][i]];
}
if (localOtherFaces[facei].size())
{
fld[facei] = sumWF/sumW;
}
}
return tFld;
}
template<class Type, class LabelList, class ScalarList>
Foam::tmp<Foam::Field<Type>> Foam::patchToPatchTools::interpolate
(
const List<LabelList>& localOtherFaces,
const List<ScalarList>& weights,
const autoPtr<distributionMap>& otherMapPtr,
const Field<Type>& otherFld,
const Field<Type>& leftOverFld
)
{
// Distribute the other field if necessary
tmp<Field<Type>> tLocalOtherFld;
if (otherMapPtr.valid())
{
tLocalOtherFld = tmp<Field<Type>>(new Field<Type>(otherFld));
otherMapPtr->distribute(tLocalOtherFld.ref());
}
const Field<Type>& localOtherFld =
otherMapPtr.valid() ? tLocalOtherFld() : otherFld;
// Allocate the result
tmp<Field<Type>> tFld(new Field<Type>(localOtherFaces.size(), NaN<Type>()));
Field<Type>& fld = tFld.ref();
// Compute the result as a weighted sum
forAll(localOtherFaces, facei)
{
scalar sumW = 0;
Type sumWF = Zero;
forAll(localOtherFaces[facei], i)
{
const scalar w = weights[facei][i];
sumW += w;
sumWF += w*localOtherFld[localOtherFaces[facei][i]];
}
fld[facei] = sumWF + (1 - sumW)*leftOverFld[facei];
}
return tFld;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -21,7 +21,7 @@ airToporous
nbrRegion porous; nbrRegion porous;
master false; master false;
interpolationMethod cellVolumeWeight; interpolationMethod intersection;
semiImplicit no; semiImplicit no;
} }
@ -34,7 +34,7 @@ porosityBlockage
{ {
nbrRegion porous; nbrRegion porous;
interpolationMethod cellVolumeWeight; interpolationMethod intersection;
type DarcyForchheimer; type DarcyForchheimer;

View File

@ -21,7 +21,7 @@ porousToair
nbrRegion air; nbrRegion air;
master true; master true;
interpolationMethod cellVolumeWeight; interpolationMethod intersection;
semiImplicit no; semiImplicit no;