meshToMesh, mapFieldsPar: Rationalisation

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

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

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

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

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

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

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

View File

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

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -35,94 +35,13 @@ License
namespace Foam
{
template<class Type>
void evaluateConstraintTypes(VolField<Type>& fld)
{
typename VolField<Type>::
Boundary& fldBf = fld.boundaryFieldRef();
if
(
Pstream::defaultCommsType == Pstream::commsTypes::blocking
|| Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking
)
{
label nReq = Pstream::nRequests();
forAll(fldBf, patchi)
{
fvPatchField<Type>& tgtField = fldBf[patchi];
if
(
tgtField.type() == tgtField.patch().patch().type()
&& polyPatch::constraintType(tgtField.patch().patch().type())
)
{
tgtField.initEvaluate(Pstream::defaultCommsType);
}
}
// Block for any outstanding requests
if
(
Pstream::parRun()
&& Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking
)
{
Pstream::waitRequests(nReq);
}
forAll(fldBf, patchi)
{
fvPatchField<Type>& tgtField = fldBf[patchi];
if
(
tgtField.type() == tgtField.patch().patch().type()
&& polyPatch::constraintType(tgtField.patch().patch().type())
)
{
tgtField.evaluate(Pstream::defaultCommsType);
}
}
}
else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled)
{
const lduSchedule& patchSchedule =
fld.mesh().globalData().patchSchedule();
forAll(patchSchedule, patchEvali)
{
label patchi = patchSchedule[patchEvali].patch;
fvPatchField<Type>& tgtField = fldBf[patchi];
if
(
tgtField.type() == tgtField.patch().patch().type()
&& polyPatch::constraintType(tgtField.patch().patch().type())
)
{
if (patchSchedule[patchEvali].init)
{
tgtField.initEvaluate(Pstream::commsTypes::scheduled);
}
else
{
tgtField.evaluate(Pstream::commsTypes::scheduled);
}
}
}
}
}
template<class Type>
void mapVolTypeFields
(
const IOobjectList& objects,
const fvMeshToFvMesh& interp,
const wordReList& cuttingPatches,
const HashSet<word>& selectedFields,
const fvMeshToFvMesh& interp
const IOobjectList& objects
)
{
const fvMesh& srcMesh = static_cast<const fvMesh&>(interp.srcMesh());
@ -134,8 +53,11 @@ void mapVolTypeFields
{
const word& fieldName = fieldIter()->name();
if (selectedFields.empty() || selectedFields.found(fieldName))
if (!selectedFields.empty() && !selectedFields.found(fieldName))
{
continue;
}
const VolField<Type> fieldSource(*fieldIter(), srcMesh);
typeIOobject<VolField<Type>> targetIO
@ -143,97 +65,83 @@ void mapVolTypeFields
fieldName,
tgtMesh.time().name(),
tgtMesh,
IOobject::MUST_READ
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<< " interpolating onto existing field "
<< fieldName << endl;
Info<< " mapping into existing field " << fieldName << endl;
VolField<Type> fieldTarget(targetIO, tgtMesh);
interp.mapSrcToTgt(fieldSource, fieldTarget);
evaluateConstraintTypes(fieldTarget);
fieldTarget.reset
(
interp.srcToTgt(fieldSource, fieldTarget, cuttingPatches)
);
fieldTarget.write();
}
else
{
Info<< " creating new field "
<< fieldName << endl;
Info<< " creating new field " << fieldName << endl;
targetIO.readOpt() = IOobject::NO_READ;
tmp<VolField<Type>> tfieldTarget
(
interp.mapSrcToTgt(fieldSource)
);
VolField<Type> fieldTarget(targetIO, tfieldTarget);
evaluateConstraintTypes(fieldTarget);
fieldTarget.write();
}
VolField<Type>(targetIO, interp.srcToTgt(fieldSource)).write();
}
}
}
template<class Type, template<class> class GeoField>
void unMappedTypeFields(const IOobjectList& objects)
{
IOobjectList fields = objects.lookupClass(GeoField<Type>::typeName);
forAllConstIter(IOobjectList, fields, fieldIter)
{
mvBak(fieldIter()->objectPath(false), "unmapped");
}
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::mapGeometricFields
(
const fvMeshToFvMesh& interp,
const wordReList& cuttingPatches,
const HashSet<word>& selectedFields,
const bool noLagrangian
)
{
const polyMesh& srcMesh = interp.srcMesh();
const polyMesh& tgtMesh = interp.tgtMesh();
{
// Search for list of source objects for this time
const polyMesh& srcMesh = interp.srcMesh();
IOobjectList objects(srcMesh, srcMesh.time().name());
// Map the fields
#define MapVolTypeFields(Type, nullArg) \
mapVolTypeFields<Type> \
( \
objects, \
interp, \
cuttingPatches, \
selectedFields, \
interp \
objects \
);
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
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -47,6 +47,7 @@ class fvMeshToFvMesh;
void mapGeometricFields
(
const fvMeshToFvMesh& interp,
const wordReList& cuttingPatches,
const HashSet<word>& selectedFields,
const bool noLagrangian
);

View File

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

View File

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

View File

@ -26,78 +26,105 @@ License
#include "fvMeshToFvMesh.H"
#include "directFvPatchFieldMapper.H"
#include "identityFvPatchFieldMapper.H"
#include "patchToPatchFvPatchFieldMapper.H"
#include "patchToPatchNormalisedFvPatchFieldMapper.H"
#include "patchToPatchLeftOverFvPatchFieldMapper.H"
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::fvMeshToFvMesh::mapSrcToTgt
(
const VolField<Type>& field,
VolField<Type>& result
) const
void Foam::fvMeshToFvMesh::evaluateConstraintTypes(VolField<Type>& fld)
{
meshToMesh::mapSrcToTgt(field, result.primitiveFieldRef());
typename VolField<Type>::Boundary& fldBf = fld.boundaryFieldRef();
typename VolField<Type>::
Boundary& resultBf = result.boundaryFieldRef();
forAll(srcToTgtPatchIDs(), i)
if
(
Pstream::defaultCommsType == Pstream::commsTypes::blocking
|| Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking
)
{
const label srcPatchi = srcToTgtPatchIDs()[i].first();
const label tgtPatchi = srcToTgtPatchIDs()[i].second();
label nReq = Pstream::nRequests();
const fvPatchField<Type>& srcField = field.boundaryField()[srcPatchi];
fvPatchField<Type>& tgtField = resultBf[tgtPatchi];
forAll(fldBf, patchi)
{
fvPatchField<Type>& tgtField = fldBf[patchi];
// Clone and map
tmp<fvPatchField<Type>> tnewTgt
if
(
fvPatchField<Type>::New
(
srcField,
tgtField.patch(),
result(),
patchToPatchFvPatchFieldMapper
(
srcToTgtPatchToPatches()[i],
true
tgtField.type() == tgtField.patch().patch().type()
&& polyPatch::constraintType(tgtField.patch().patch().type())
)
)
);
// Transfer all mapped quantities (value and e.g. gradient) onto
// tgtField. Value will get overwritten below.
tgtField.map(tnewTgt(), identityFvPatchFieldMapper());
{
tgtField.initEvaluate(Pstream::defaultCommsType);
}
}
forAll(tgtCuttingPatchIDs(), i)
// Block for any outstanding requests
if
(
Pstream::parRun()
&& Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking
)
{
const label patchi = tgtCuttingPatchIDs()[i];
fvPatchField<Type>& pf = resultBf[patchi];
pf == pf.patchInternalField();
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);
}
}
}
}
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::VolField<Type>>
Foam::fvMeshToFvMesh::mapSrcToTgt
Foam::tmp<Foam::VolField<Type>> Foam::fvMeshToFvMesh::srcToTgt
(
const VolField<Type>& field
const VolField<Type>& srcFld
) const
{
const fvMesh& tgtMesh = static_cast<const fvMesh&>(meshToMesh::tgtMesh());
const fvBoundaryMesh& tgtBm = tgtMesh.boundary();
const typename VolField<Type>::Boundary& srcBfld =
field.boundaryField();
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
// Construct target patch fields as copies of source patch fields, but do
// not map values yet
PtrList<fvPatchField<Type>> tgtPatchFields(tgtMesh.boundary().size());
forAll(srcToTgtPatchIDs(), i)
{
const label srcPatchi = srcToTgtPatchIDs()[i].first();
@ -110,7 +137,7 @@ Foam::fvMeshToFvMesh::mapSrcToTgt
tgtPatchi,
fvPatchField<Type>::New
(
srcBfld[srcPatchi],
srcFld.boundaryField()[srcPatchi],
tgtMesh.boundary()[tgtPatchi],
DimensionedField<Type, volMesh>::null(),
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)
{
if (!tgtPatchFields.set(tgtPatchi))
{
// Note: use factory New method instead of direct generation of
// calculated so we keep constraints
tgtPatchFields.set
(
tgtPatchi,
@ -139,75 +167,148 @@ Foam::fvMeshToFvMesh::mapSrcToTgt
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 =
VolField<Type>::New
(
new VolField<Type>
(
IOobject
(
typedName("interpolate(" + field.name() + ")"),
tgtMesh.time().name(),
tgtMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
tgtMesh,
field.dimensions(),
Field<Type>(tgtMesh.nCells(), Zero),
typedName("interpolate(" + srcFld.name() + ")"),
srcToTgt<Type>(srcFld.internalField())(),
tgtPatchFields
);
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
(
srcFld.boundaryField()[srcPatchi],
patchToPatchNormalisedFvPatchFieldMapper
(
srcToTgtPatchToPatches()[i],
true
)
);
}
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>
void Foam::fvMeshToFvMesh::mapSrcToTgt
Foam::tmp<Foam::VolField<Type>> Foam::fvMeshToFvMesh::srcToTgt
(
const VolInternalField<Type>& field,
VolInternalField<Type>& result
const VolField<Type>& srcFld,
const VolField<Type>& leftOverTgtFld,
const UList<wordRe>& tgtCuttingPatchNames
) const
{
meshToMesh::mapSrcToTgt(field, result);
// 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::mapSrcToTgt
Foam::tmp<Foam::VolInternalField<Type>> Foam::fvMeshToFvMesh::srcToTgt
(
const VolInternalField<Type>& field
const VolInternalField<Type>& srcFld
) const
{
const fvMesh& tgtMesh = static_cast<const fvMesh&>(meshToMesh::tgtMesh());
tmp<VolInternalField<Type>> tresult
return
VolInternalField<Type>::New
(
new VolInternalField<Type>
(
IOobject
(
typedName("interpolate(" + field.name() + ")"),
tgtMesh.time().name(),
tgtMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
tgtMesh,
field.dimensions(),
Field<Type>(tgtMesh.nCells(), Zero)
)
typedName("interpolate(" + srcFld.name() + ")"),
static_cast<const fvMesh&>(meshToMesh::tgtMesh()),
srcFld.dimensions(),
srcToTgtCellsToCells().srcToTgt(srcFld)
);
}
fvMeshToFvMesh::mapSrcToTgt<Type>(field, tresult.ref());
return tresult;
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
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -27,13 +27,6 @@ License
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
FOR_ALL_FIELD_TYPES
(
IMPLEMENT_FIELD_MAPPER_OPERATOR,
patchToPatchFvPatchFieldMapper
)
void Foam::patchToPatchFvPatchFieldMapper::operator()
(
Field<label>& f,

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -50,7 +50,9 @@ class patchToPatchFvPatchFieldMapper
:
public fvPatchFieldMapper
{
// Private Data
protected:
// Protected Data
//- Patch-to-patch mapping engine
const patchToPatch& pToP_;
@ -65,17 +67,6 @@ class patchToPatchFvPatchFieldMapper
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:
// Constructors
@ -124,9 +115,6 @@ public:
// Member Operators
//- Map a field
FOR_ALL_FIELD_TYPES(DEFINE_FIELD_MAPPER_OPERATOR, );
//- Map a label field
DEFINE_FIELD_MAPPER_OPERATOR(label, );

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -27,29 +27,6 @@ License
// * * * * * * * * * * * * * 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>
void Foam::patchToPatchFvPatchFieldMapper::operator()
(
@ -57,7 +34,7 @@ void Foam::patchToPatchFvPatchFieldMapper::operator()
const tmp<Field<Type>>& tmapF
) const
{
map(f, tmapF());
operator()(f, tmapF());
tmapF.clear();
}
@ -69,7 +46,7 @@ Foam::patchToPatchFvPatchFieldMapper::operator()
const tmp<Field<Type>>& tmapF
) const
{
tmp<Foam::Field<Type>> tf(map(tmapF()));
tmp<Foam::Field<Type>> tf(operator()(tmapF()));
tmapF.clear();
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
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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,
const polyMesh& src,
const polyMesh& tgt
)
Field<Type>& f,
const Field<Type>& mapF
) const
{
if (debug)
{
Info<< "Selecting meshToMeshMethod " << methodName << endl;
}
f = forward_ ? pToP_.srcToTgt(mapF, f) : pToP_.tgtToSrc(mapF, f);
}
componentsConstructorTable::iterator cstrIter =
componentsConstructorTablePtr_->find(methodName);
if (cstrIter == componentsConstructorTablePtr_->end())
{
FatalErrorInFunction
<< "Unknown meshToMesh type "
<< methodName << nl << nl
<< "Valid meshToMesh types are:" << nl
<< componentsConstructorTablePtr_->sortedToc() << exit(FatalError);
}
return autoPtr<meshToMeshMethod>(cstrIter()(src, tgt));
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::patchToPatchLeftOverFvPatchFieldMapper::map
(
const Field<Type>& mapF
) const
{
NotImplemented;
return tmp<Field<Type>>(nullptr);
}

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
{
template<class Type>
void evaluateConstraintTypes(VolField<Type>& fld)
{
typename VolField<Type>::Boundary& fldBf = fld.boundaryFieldRef();
if
(
Pstream::defaultCommsType == Pstream::commsTypes::blocking
|| Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking
)
{
label nReq = Pstream::nRequests();
forAll(fldBf, patchi)
{
fvPatchField<Type>& tgtField = fldBf[patchi];
if
(
tgtField.type() == tgtField.patch().patch().type()
&& polyPatch::constraintType(tgtField.patch().patch().type())
)
{
tgtField.initEvaluate(Pstream::defaultCommsType);
}
}
// Block for any outstanding requests
if
(
Pstream::parRun()
&& Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking
)
{
Pstream::waitRequests(nReq);
}
forAll(fldBf, patchi)
{
fvPatchField<Type>& tgtField = fldBf[patchi];
if
(
tgtField.type() == tgtField.patch().patch().type()
&& polyPatch::constraintType(tgtField.patch().patch().type())
)
{
tgtField.evaluate(Pstream::defaultCommsType);
}
}
}
else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled)
{
const lduSchedule& patchSchedule =
fld.mesh().globalData().patchSchedule();
forAll(patchSchedule, patchEvali)
{
label patchi = patchSchedule[patchEvali].patch;
fvPatchField<Type>& tgtField = fldBf[patchi];
if
(
tgtField.type() == tgtField.patch().patch().type()
&& polyPatch::constraintType(tgtField.patch().patch().type())
)
{
if (patchSchedule[patchEvali].init)
{
tgtField.initEvaluate(Pstream::commsTypes::scheduled);
}
else
{
tgtField.evaluate(Pstream::commsTypes::scheduled);
}
}
}
}
}
template<class Type>
void MeshToMeshMapVolFields
(
@ -169,8 +88,7 @@ void MeshToMeshMapVolFields
)
{
VolField<Type>& field =
const_cast<VolField<Type>&>
(*fieldIter());
const_cast<VolField<Type>&>(*fieldIter());
if (fvMeshToFvMesh::debug)
{
@ -178,8 +96,8 @@ void MeshToMeshMapVolFields
<< endl;
}
field.reset(mapper.mapSrcToTgt(field));
evaluateConstraintTypes(field);
field.reset(mapper.srcToTgt(field));
field.instance() = field.time().name();
}
}
@ -207,8 +125,7 @@ void MeshToMeshMapVolInternalFields
)
{
VolInternalField<Type>& field =
const_cast<VolInternalField<Type>&>
(*fieldIter());
const_cast<VolInternalField<Type>&>(*fieldIter());
if (fvMeshToFvMesh::debug)
{
@ -216,7 +133,8 @@ void MeshToMeshMapVolInternalFields
<< endl;
}
field.reset(mapper.mapSrcToTgt<Type>(field));
field.reset(mapper.srcToTgt<Type>(field));
field.instance() = field.time().name();
}
}

View File

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

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -57,10 +57,6 @@ class meshToMesh
//- Mesh-to-mesh control dictionary
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
scalarList times_;

View File

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

View File

@ -25,7 +25,7 @@ License
#include "interRegionModel.H"
#include "fvModels.H"
#include "directMethod.H"
#include "matchingCellsToCells.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -55,8 +55,10 @@ void Foam::fv::interRegionModel::readCoeffs()
}
void Foam::fv::interRegionModel::setMapper() const
const Foam::cellsToCells& Foam::fv::interRegionModel::interpolation() const
{
if (!interpolationPtr_.valid())
{
Info<< incrIndent;
if (master_)
@ -75,16 +77,8 @@ void Foam::fv::interRegionModel::setMapper() const
if (mesh().bounds().overlaps(nbrMesh().bounds()))
{
meshInterpPtr_.reset
(
new meshToMesh
(
mesh(),
nbrMesh(),
interpolationMethod_,
false // not interpolating patches
)
);
interpolationPtr_ = cellsToCells::New(interpolationMethod_);
interpolationPtr_->update(mesh(), nbrMesh());
}
else
{
@ -96,6 +90,9 @@ void Foam::fv::interRegionModel::setMapper() const
}
Info<< decrIndent;
}
return interpolationPtr_();
}
@ -140,8 +137,8 @@ Foam::fv::interRegionModel::interRegionModel
fvModel(name, modelType, mesh, dict),
master_(false),
nbrRegionName_(word::null),
interpolationMethod_(directMethod::typeName),
meshInterpPtr_()
interpolationMethod_(cellsToCellss::matching::typeName),
interpolationPtr_()
{
readCoeffs();
}
@ -160,7 +157,7 @@ bool Foam::fv::interRegionModel::read(const dictionary& dict)
if (fvModel::read(dict))
{
readCoeffs();
setMapper();
interpolationPtr_.clear();
return true;
}
else

View File

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

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2021 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,6 +23,8 @@ License
\*---------------------------------------------------------------------------*/
#include "interRegionModel.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
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
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -36,11 +36,11 @@ Foam::fv::interRegionModel::interpolate
{
if (master())
{
return meshInterp().mapTgtToSrc(field);
return interpolation().tgtToSrc(field);
}
else
{
return nbrModel().meshInterp().mapSrcToTgt(field);
return nbrModel().interpolation().srcToTgt(field);
}
}
@ -54,11 +54,11 @@ void Foam::fv::interRegionModel::interpolate
{
if (master())
{
meshInterp().mapTgtToSrc(field, result);
result = interpolation().tgtToSrc(field, result);
}
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/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/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/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 "OFstream.H"
#include "Time.H"
#include "globalIndex.H"
#include "cellsToCells.H"
#include "processorPolyPatch.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 * * * * * * * * * * * //
Foam::labelListList Foam::meshToMesh::tgtMeshSendCells
Foam::labelListList Foam::cellsToCells::tgtMeshSendCells
(
const polyMesh& srcMesh,
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 polyMesh& mesh,
@ -414,10 +434,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
internalFaceOffset[proci]
);
slice = SubList<face>(fcs, allNInternalFaces[proci]);
forAll(slice, i)
{
add(slice[i], pointOffset[proci]);
}
offset(slice, pointOffset[proci]);
SubField<label> ownSlice
(
@ -426,7 +443,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
internalFaceOffset[proci]
);
ownSlice = SubField<label>(faceOs, allNInternalFaces[proci]);
add(ownSlice, cellOffset[proci]);
offset(ownSlice, cellOffset[proci]);
SubField<label> nbrSlice
(
@ -435,7 +452,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
internalFaceOffset[proci]
);
nbrSlice = SubField<label>(faceNs, allNInternalFaces[proci]);
add(nbrSlice, cellOffset[proci]);
offset(nbrSlice, cellOffset[proci]);
internalFaceOffset[proci] += allNInternalFaces[proci];
}
@ -499,7 +516,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
localFaceNeighbours[localFacei] = newOwn;
}
add(localFaces[localFacei], pointOffset[proci]);
offset(localFaces[localFacei], pointOffset[proci]);
// mark with unique value
fnd() = -2;
@ -549,7 +566,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
}
localFaces[localFacei] = fcs[i];
add(localFaces[localFacei], pointOffset[proci]);
offset(localFaces[localFacei], pointOffset[proci]);
localFaceOwners[localFacei] = newOwn;
localFaceNeighbours[localFacei] = -1;
@ -568,7 +585,7 @@ Foam::List<Foam::remote> Foam::meshToMesh::distributeMesh
const label localFacei = nIntFaces++;
localFaces[localFacei] = fcs[i];
add(localFaces[localFacei], pointOffset[proci]);
offset(localFaces[localFacei], pointOffset[proci]);
localFaceOwners[localFacei] = newOwn;
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
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
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,8 +23,7 @@ License
\*---------------------------------------------------------------------------*/
#include "cellVolumeWeightMethod.H"
#include "intersectionPatchToPatch.H"
#include "intersectionCellsToCells.H"
#include "indexedOctree.H"
#include "treeDataCell.H"
#include "tetOverlapVolume.H"
@ -34,70 +33,64 @@ License
namespace Foam
{
defineTypeNameAndDebug(cellVolumeWeightMethod, 0);
addToRunTimeSelectionTable
(
meshToMeshMethod,
cellVolumeWeightMethod,
components
);
namespace cellsToCellss
{
defineTypeNameAndDebug(intersection, 0);
addToRunTimeSelectionTable(cellsToCells, intersection, word);
}
}
const Foam::scalar Foam::cellVolumeWeightMethod::tolerance_ = 1e-6;
const Foam::scalar Foam::cellsToCellss::intersection::tolerance_ = 1e-6;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::cellVolumeWeightMethod::intersect
bool Foam::cellsToCellss::intersection::intersect
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label srcCelli,
const label tgtCelli
) const
{
scalar threshold = tolerance_*src_.cellVolumes()[srcCelli];
tetOverlapVolume overlapEngine;
treeBoundBox bbTgtCell(tgt_.points(), tgt_.cellPoints()[tgtCelli]);
return overlapEngine.cellCellOverlapMinDecomp
return
tetOverlapVolume().cellCellOverlapMinDecomp
(
src_,
srcMesh,
srcCelli,
tgt_,
tgtMesh,
tgtCelli,
bbTgtCell,
threshold
treeBoundBox(tgtMesh.points(), tgtMesh.cellPoints()[tgtCelli]),
tolerance_*srcMesh.cellVolumes()[srcCelli]
);
}
Foam::scalar Foam::cellVolumeWeightMethod::interVol
Foam::scalar Foam::cellsToCellss::intersection::interVol
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label srcCelli,
const label tgtCelli
) const
{
tetOverlapVolume overlapEngine;
treeBoundBox bbTgtCell(tgt_.points(), tgt_.cellPoints()[tgtCelli]);
scalar vol = overlapEngine.cellCellOverlapVolumeMinDecomp
return
tetOverlapVolume().cellCellOverlapVolumeMinDecomp
(
src_,
srcMesh,
srcCelli,
tgt_,
tgtMesh,
tgtCelli,
bbTgtCell
treeBoundBox(tgtMesh.points(), tgtMesh.cellPoints()[tgtCelli])
);
return vol;
}
bool Foam::cellVolumeWeightMethod::findInitialSeeds
bool Foam::cellsToCellss::intersection::findInitialSeeds
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const labelList& srcCellIDs,
const boolList& mapFlag,
const label startSeedI,
@ -105,9 +98,9 @@ bool Foam::cellVolumeWeightMethod::findInitialSeeds
label& tgtSeedI
) const
{
const cellList& srcCells = src_.cells();
const faceList& srcFaces = src_.faces();
const pointField& srcPts = src_.points();
const cellList& srcCells = srcMesh.cells();
const faceList& srcFaces = srcMesh.faces();
const pointField& srcPts = srcMesh.points();
for (label i = startSeedI; i < srcCellIDs.size(); i++)
{
@ -117,7 +110,7 @@ bool Foam::cellVolumeWeightMethod::findInitialSeeds
{
const labelList tgtIDs
(
tgt_.cellTree().findBox
tgtMesh.cellTree().findBox
(
treeBoundBox(srcCells[srcI].bb(srcPts, srcFaces))
)
@ -127,7 +120,7 @@ bool Foam::cellVolumeWeightMethod::findInitialSeeds
{
const label tgtI = tgtIDs[j];
if (intersect(srcI, tgtI))
if (intersect(srcMesh, tgtMesh, srcI, tgtI))
{
srcSeedI = srcI;
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,
scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr,
@ -165,11 +160,11 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculateAddressing
label srcCelli = srcSeedI;
label tgtCelli = tgtSeedI;
List<DynamicList<label>> srcToTgtAddr(src_.nCells());
List<DynamicList<scalar>> srcToTgtWght(src_.nCells());
List<DynamicList<label>> srcToTgtAddr(srcMesh.nCells());
List<DynamicList<scalar>> srcToTgtWght(srcMesh.nCells());
List<DynamicList<label>> tgtToSrcAddr(tgt_.nCells());
List<DynamicList<scalar>> tgtToSrcWght(tgt_.nCells());
List<DynamicList<label>> tgtToSrcAddr(tgtMesh.nCells());
List<DynamicList<scalar>> tgtToSrcWght(tgtMesh.nCells());
// list of tgt cell neighbour cells
DynamicList<label> nbrTgtCells(10);
@ -178,10 +173,10 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculateAddressing
DynamicList<label> visitedTgtCells(10);
// 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;
const scalarField& srcVol = src_.cellVolumes();
const scalarField& srcVol = srcMesh.cellVolumes();
do
{
@ -190,14 +185,14 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculateAddressing
// append initial target cell and neighbours
nbrTgtCells.append(tgtCelli);
appendNbrCells(tgtCelli, tgt_, visitedTgtCells, nbrTgtCells);
appendNbrCells(tgtCelli, tgtMesh, visitedTgtCells, nbrTgtCells);
do
{
tgtCelli = nbrTgtCells.remove();
visitedTgtCells.append(tgtCelli);
scalar vol = interVol(srcCelli, tgtCelli);
scalar vol = interVol(srcMesh, tgtMesh, srcCelli, tgtCelli);
// accumulate addressing and weights for valid intersection
if (vol/srcVol[srcCelli] > tolerance_)
@ -209,7 +204,7 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculateAddressing
tgtToSrcAddr[tgtCelli].append(srcCelli);
tgtToSrcWght[tgtCelli].append(vol);
appendNbrCells(tgtCelli, tgt_, visitedTgtCells, nbrTgtCells);
appendNbrCells(tgtCelli, tgtMesh, visitedTgtCells, nbrTgtCells);
// accumulate intersection volume
V += vol;
@ -222,6 +217,8 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculateAddressing
// find new source seed cell
setNextCells
(
srcMesh,
tgtMesh,
startSeedI,
srcCelli,
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& srcCelli,
label& tgtCelli,
@ -261,7 +260,7 @@ void Foam::cellVolumeWeightMethod::setNextCells
labelList& seedCells
) 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
// with all visited target cells
@ -276,7 +275,7 @@ void Foam::cellVolumeWeightMethod::setNextCells
{
label cellT = visitedCells[j];
if (intersect(cellS, cellT))
if (intersect(srcMesh, tgtMesh, cellS, cellT))
{
seedCells[cellS] = cellT;
@ -332,6 +331,8 @@ void Foam::cellVolumeWeightMethod::setNextCells
bool restart =
findInitialSeeds
(
srcMesh,
tgtMesh,
srcCellIDs,
mapFlag,
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& tgt
)
:
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
const polyMesh& srcMesh,
const polyMesh& tgtMesh
)
{
bool ok = initialise
(
srcToTgtAddr,
srcToTgtWght,
tgtToSrcAddr,
tgtToSrcWght
);
initialise(srcMesh, tgtMesh);
if (!ok)
{
return 0;
}
// Determine (potentially) participating source mesh cells
const labelList srcCellIDs(maskCells(srcMesh, tgtMesh));
// (potentially) participating source mesh cells
const labelList srcCellIDs(maskCells());
// list to keep track of whether src cell can be mapped
boolList mapFlag(src_.nCells(), false);
// Initialise list to keep track of whether src cell can be mapped
boolList mapFlag(srcMesh.nCells(), false);
UIndirectList<bool>(mapFlag, srcCellIDs) = true;
// find initial point in tgt mesh
// Find initial point in tgt mesh
label srcSeedI = -1;
label tgtSeedI = -1;
label startSeedI = 0;
bool startWalk =
findInitialSeeds
(
srcMesh,
tgtMesh,
srcCellIDs,
mapFlag,
startSeedI,
@ -423,26 +388,21 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculate
if (startWalk)
{
const scalar V =
return
calculateAddressing
(
srcToTgtAddr,
srcToTgtWght,
tgtToSrcAddr,
tgtToSrcWght,
srcMesh,
tgtMesh,
srcLocalTgtCells_,
srcWeights_,
tgtLocalSrcCells_,
tgtWeights_,
srcSeedI,
tgtSeedI,
srcCellIDs,
mapFlag,
startSeedI
);
if (debug > 1)
{
writeConnectivity(src_, tgt_, srcToTgtAddr);
}
return V;
}
else
{
@ -451,7 +411,7 @@ Foam::scalar Foam::cellVolumeWeightMethod::calculate
}
void Foam::cellVolumeWeightMethod::normalise
void Foam::cellsToCellss::intersection::normalise
(
const polyMesh& srcMesh,
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
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -22,39 +22,39 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cellVolumeWeightMethod
Foam::cellsToCellss::intersection
Description
Cell-volume-weighted mesh-to-mesh interpolation class
Volume conservative.
Intersection-based cells-to-cells interpolation class. Volume conservative.
SourceFiles
cellVolumeWeightMethod.C
intersectionCellsToCells.C
\*---------------------------------------------------------------------------*/
#ifndef cellVolumeWeightMethod_H
#define cellVolumeWeightMethod_H
#ifndef intersectionCellsToCells_H
#define intersectionCellsToCells_H
#include "meshToMeshMethod.H"
#include "cellsToCells.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace cellsToCellss
{
/*---------------------------------------------------------------------------*\
Class cellVolumeWeightMethod Declaration
Class intersection Declaration
\*---------------------------------------------------------------------------*/
class cellVolumeWeightMethod
class intersection
:
public meshToMeshMethod
public cellsToCells
{
private:
// Private static data
// Private Static Data
//- Tolerance used in volume overlap calculations
static const scalar tolerance_;
@ -63,15 +63,29 @@ private:
// Private Member Functions
//- 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
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
// true if found a matching pair
bool findInitialSeeds
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const labelList& srcCellIDs,
const boolList& mapFlag,
const label startSeedI,
@ -82,6 +96,8 @@ private:
//- Calculate the mesh-to-mesh addressing and weights
scalar calculateAddressing
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
labelListList& srcToTgtCellAddr,
scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr,
@ -96,6 +112,8 @@ private:
//- Set the next cells in the advancing front algorithm
void setNextCells
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
label& startSeedI,
label& srcCelli,
label& tgtCelli,
@ -106,48 +124,48 @@ private:
) const;
public:
protected:
//- Run-time type information
TypeName("cellVolumeWeight");
// Protected Member Functions
// Intersection
// Constructors
//- Construct from source and target meshes
cellVolumeWeightMethod(const polyMesh& src, const polyMesh& tgt);
//- Destructor
virtual ~cellVolumeWeightMethod();
// Member Functions
//- Get the corresponding patchToPatch method
virtual const word& patchToPatchMethod() const;
//- Calculate addressing and weights
//- Calculate the addressing and weights
virtual scalar calculate
(
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght,
labelListList& tgtToTgtAddr,
scalarListList& tgtToTgtWght
const polyMesh& srcMesh,
const polyMesh& tgtMesh
);
//- Normalise the weights for a given mesh
virtual void normalise
(
const polyMesh& srcMesh,
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght
const polyMesh& mesh,
labelListList& localOtherCells,
scalarListList& weights
) const;
public:
//- Run-time type information
TypeName("intersection");
// Constructors
//- Construct null
intersection();
//- Destructor
virtual ~intersection();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace cellsToCellss
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,8 +23,7 @@ License
\*---------------------------------------------------------------------------*/
#include "directMethod.H"
#include "matchingPatchToPatch.H"
#include "matchingCellsToCells.H"
#include "indexedOctree.H"
#include "treeDataCell.H"
#include "addToRunTimeSelectionTable.H"
@ -33,30 +32,37 @@ License
namespace Foam
{
defineTypeNameAndDebug(directMethod, 0);
addToRunTimeSelectionTable(meshToMeshMethod, directMethod, components);
namespace cellsToCellss
{
defineTypeNameAndDebug(matching, 0);
addToRunTimeSelectionTable(cellsToCells, matching, word);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::directMethod::intersect
bool Foam::cellsToCellss::matching::intersect
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label srcCelli,
const label tgtCelli
) const
{
return tgt_.pointInCell
return tgtMesh.pointInCell
(
src_.cellCentres()[srcCelli],
srcMesh.cellCentres()[srcCelli],
tgtCelli,
polyMesh::FACE_PLANES
);
}
bool Foam::directMethod::findInitialSeeds
bool Foam::cellsToCellss::matching::findInitialSeeds
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const labelList& srcCellIDs,
const boolList& mapFlag,
const label startSeedI,
@ -64,9 +70,9 @@ bool Foam::directMethod::findInitialSeeds
label& tgtSeedI
) const
{
const cellList& srcCells = src_.cells();
const faceList& srcFaces = src_.faces();
const pointField& srcPts = src_.points();
const cellList& srcCells = srcMesh.cells();
const faceList& srcFaces = srcMesh.faces();
const pointField& srcPts = srcMesh.points();
for (label i = startSeedI; i < srcCellIDs.size(); i++)
{
@ -75,9 +81,9 @@ bool Foam::directMethod::findInitialSeeds
if (mapFlag[srcI])
{
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;
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,
scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr,
@ -112,15 +120,15 @@ Foam::scalar Foam::directMethod::calculateAddressing
scalar V = 0;
// 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>> tgtToSrc(tgt_.nCells());
List<DynamicList<label>> srcToTgt(srcMesh.nCells());
List<DynamicList<label>> tgtToSrc(tgtMesh.nCells());
DynamicList<label> srcSeeds(10);
const scalarField& srcVc = src_.cellVolumes();
const scalarField& tgtVc = tgt_.cellVolumes();
const scalarField& srcVc = srcMesh.cellVolumes();
const scalarField& tgtVc = tgtMesh.cellVolumes();
label srcCelli = srcSeedI;
label tgtCelli = tgtSeedI;
@ -140,6 +148,8 @@ Foam::scalar Foam::directMethod::calculateAddressing
// find new source seed cell
appendToDirectSeeds
(
srcMesh,
tgtMesh,
mapFlag,
srcTgtSeed,
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,
labelList& srcTgtSeed,
DynamicList<label>& srcSeeds,
@ -175,8 +187,8 @@ void Foam::directMethod::appendToDirectSeeds
label& tgtSeedI
) const
{
const labelList& srcNbr = src_.cellCells()[srcSeedI];
const labelList& tgtNbr = tgt_.cellCells()[tgtSeedI];
const labelList& srcNbr = srcMesh.cellCells()[srcSeedI];
const labelList& tgtNbr = tgtMesh.cellCells()[tgtSeedI];
forAll(srcNbr, i)
{
@ -192,7 +204,7 @@ void Foam::directMethod::appendToDirectSeeds
{
label tgtI = tgtNbr[j];
if (intersect(srcI, tgtI))
if (intersect(srcMesh, tgtMesh, srcI, tgtI))
{
// new match - append to lists
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& tgt
)
:
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
const polyMesh& srcMesh,
const polyMesh& tgtMesh
)
{
bool ok = initialise
(
srcToTgtAddr,
srcToTgtWght,
tgtToSrcAddr,
tgtToSrcWght
);
initialise(srcMesh, tgtMesh);
if (!ok)
{
return 0;
}
// Determine (potentially) participating source mesh cells
const labelList srcCellIDs(maskCells(srcMesh, tgtMesh));
// (potentially) participating source mesh cells
const labelList srcCellIDs(maskCells());
// list to keep track of whether src cell can be mapped
boolList mapFlag(src_.nCells(), false);
// Initialise list to keep track of whether src cell can be mapped
boolList mapFlag(srcMesh.nCells(), false);
UIndirectList<bool>(mapFlag, srcCellIDs) = true;
// find initial point in tgt mesh
// Find initial point in tgt mesh
label srcSeedI = -1;
label tgtSeedI = -1;
label startSeedI = 0;
bool startWalk =
findInitialSeeds
(
srcMesh,
tgtMesh,
srcCellIDs,
mapFlag,
startSeedI,
@ -294,26 +271,21 @@ Foam::scalar Foam::directMethod::calculate
if (startWalk)
{
const scalar V =
return
calculateAddressing
(
srcToTgtAddr,
srcToTgtWght,
tgtToSrcAddr,
tgtToSrcWght,
srcMesh,
tgtMesh,
srcLocalTgtCells_,
srcWeights_,
tgtLocalSrcCells_,
tgtWeights_,
srcSeedI,
tgtSeedI,
srcCellIDs,
mapFlag,
startSeedI
);
if (debug > 1)
{
writeConnectivity(src_, tgt_, srcToTgtAddr);
}
return V;
}
else
{
@ -322,7 +294,7 @@ Foam::scalar Foam::directMethod::calculate
}
void Foam::directMethod::normalise
void Foam::cellsToCellss::matching::normalise
(
const polyMesh& srcMesh,
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
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -22,35 +22,35 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::directMethod
Foam::cellsToCellss::matching
Description
Direct (one-to-one cell correspondence) mesh-to-mesh interpolation class
Volume conservative.
Matching, one-to-one, cells-to-cells interpolation class.
SourceFiles
directMethod.C
matchingCellsToCells.C
\*---------------------------------------------------------------------------*/
#ifndef directMethod_H
#define directMethod_H
#ifndef matchingCellsToCells_H
#define matchingCellsToCells_H
#include "meshToMeshMethod.H"
#include "cellsToCells.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace cellsToCellss
{
/*---------------------------------------------------------------------------*\
Class directMethod Declaration
Class matching Declaration
\*---------------------------------------------------------------------------*/
class directMethod
class matching
:
public meshToMeshMethod
public cellsToCells
{
private:
@ -59,6 +59,8 @@ private:
//- Return the true if cells intersect
bool intersect
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label srcCelli,
const label tgtCelli
) const;
@ -67,6 +69,8 @@ private:
// true if found a matching pair
bool findInitialSeeds
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const labelList& srcCellIDs,
const boolList& mapFlag,
const label startSeedI,
@ -77,6 +81,8 @@ private:
//- Calculate the mesh-to-mesh addressing and weights
scalar calculateAddressing
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
labelListList& srcToTgtCellAddr,
scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr,
@ -91,6 +97,8 @@ private:
//- Append to list of src mesh seed indices
void appendToDirectSeeds
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
boolList& mapFlag,
labelList& srcTgtSeed,
DynamicList<label>& srcSeeds,
@ -99,48 +107,48 @@ private:
) const;
public:
protected:
//- Run-time type information
TypeName("direct");
// Protected Member Functions
// Intersection
// Constructors
//- Construct from source and target meshes
directMethod(const polyMesh& src, const polyMesh& tgt);
//- Destructor
virtual ~directMethod();
// Member Functions
//- Get the corresponding patchToPatch method
virtual const word& patchToPatchMethod() const;
//- Calculate addressing and weights
//- Calculate the addressing and weights
virtual scalar calculate
(
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght,
labelListList& tgtToTgtAddr,
scalarListList& tgtToTgtWght
const polyMesh& srcMesh,
const polyMesh& tgtMesh
);
//- Normalise the weights for a given mesh
virtual void normalise
(
const polyMesh& srcMesh,
labelListList& srcToTgtAddr,
scalarListList& srcToTgtWght
const polyMesh& mesh,
labelListList& localOtherCells,
scalarListList& weights
) const;
public:
//- Run-time type information
TypeName("matching");
// Constructors
//- Construct null
matching();
//- Destructor
virtual ~matching();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace cellsToCellss
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,8 +23,7 @@ License
\*---------------------------------------------------------------------------*/
#include "mapNearestMethod.H"
#include "nearestPatchToPatch.H"
#include "nearestCellsToCells.H"
#include "pointIndexHit.H"
#include "indexedOctree.H"
#include "treeDataCell.H"
@ -34,15 +33,20 @@ License
namespace Foam
{
defineTypeNameAndDebug(mapNearestMethod, 0);
addToRunTimeSelectionTable(meshToMeshMethod, mapNearestMethod, components);
namespace cellsToCellss
{
defineTypeNameAndDebug(nearest, 0);
addToRunTimeSelectionTable(cellsToCells, nearest, word);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::mapNearestMethod::findInitialSeeds
bool Foam::cellsToCellss::nearest::findInitialSeeds
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const labelList& srcCellIDs,
const boolList& mapFlag,
const label startSeedI,
@ -50,7 +54,7 @@ bool Foam::mapNearestMethod::findInitialSeeds
label& tgtSeedI
) const
{
const vectorField& srcCcs = src_.cellCentres();
const vectorField& srcCcs = srcMesh.cellCentres();
for (label i = startSeedI; i < srcCellIDs.size(); i++)
{
@ -60,7 +64,7 @@ bool Foam::mapNearestMethod::findInitialSeeds
{
const point& srcCc = srcCcs[srcI];
pointIndexHit hit =
tgt_.cellTree().findNearest(srcCc, great);
tgtMesh.cellTree().findNearest(srcCc, great);
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,
scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr,
@ -106,11 +112,11 @@ Foam::scalar Foam::mapNearestMethod::calculateAddressing
{
scalar V = 0;
List<DynamicList<label>> srcToTgt(src_.nCells());
List<DynamicList<label>> tgtToSrc(tgt_.nCells());
List<DynamicList<label>> srcToTgt(srcMesh.nCells());
List<DynamicList<label>> tgtToSrc(tgtMesh.nCells());
const scalarField& srcVc = src_.cellVolumes();
const scalarField& tgtVc = tgt_.cellVolumes();
const scalarField& srcVc = srcMesh.cellVolumes();
const scalarField& tgtVc = tgtMesh.cellVolumes();
{
label srcCelli = srcSeedI;
@ -119,7 +125,7 @@ Foam::scalar Foam::mapNearestMethod::calculateAddressing
do
{
// find nearest tgt cell
findNearestCell(src_, tgt_, srcCelli, tgtCelli);
findNearestCell(srcMesh, tgtMesh, srcCelli, tgtCelli);
// store src/tgt cell pair
srcToTgt[srcCelli].append(tgtCelli);
@ -134,6 +140,8 @@ Foam::scalar Foam::mapNearestMethod::calculateAddressing
// find new source cell
setNextNearestCells
(
srcMesh,
tgtMesh,
startSeedI,
srcCelli,
tgtCelli,
@ -146,8 +154,8 @@ Foam::scalar Foam::mapNearestMethod::calculateAddressing
// for the case of multiple source cells per target cell, select the
// nearest source cell only and discard the others
const vectorField& srcCc = src_.cellCentres();
const vectorField& tgtCc = tgt_.cellCentres();
const vectorField& srcCc = srcMesh.cellCentres();
const vectorField& tgtCc = tgtMesh.cellCentres();
forAll(tgtToSrc, targetCelli)
{
@ -182,9 +190,10 @@ Foam::scalar Foam::mapNearestMethod::calculateAddressing
{
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);
}
@ -207,7 +216,7 @@ Foam::scalar Foam::mapNearestMethod::calculateAddressing
}
void Foam::mapNearestMethod::findNearestCell
void Foam::cellsToCellss::nearest::findNearestCell
(
const polyMesh& mesh1,
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& srcCelli,
label& tgtCelli,
@ -253,7 +264,7 @@ void Foam::mapNearestMethod::setNextNearestCells
const labelList& srcCellIDs
) const
{
const labelList& srcNbr = src_.cellCells()[srcCelli];
const labelList& srcNbr = srcMesh.cellCells()[srcCelli];
srcCelli = -1;
forAll(srcNbr, i)
@ -276,8 +287,10 @@ void Foam::mapNearestMethod::setNextNearestCells
}
}
(void)findInitialSeeds
findInitialSeeds
(
srcMesh,
tgtMesh,
srcCellIDs,
mapFlag,
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 List<DynamicList<label>>& tgtToSrc
) const
@ -313,7 +328,7 @@ Foam::label Foam::mapNearestMethod::findMappedSrcCell
}
else
{
const labelList& nbrCells = tgt_.cellCells()[tgtI];
const labelList& nbrCells = tgtMesh.cellCells()[tgtI];
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& tgt
)
:
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
const polyMesh& srcMesh,
const polyMesh& tgtMesh
)
{
bool ok = initialise
(
srcToTgtAddr,
srcToTgtWght,
tgtToSrcAddr,
tgtToSrcWght
);
initialise(srcMesh, tgtMesh);
if (!ok)
{
return 0;
}
// Determine (potentially) participating source mesh cells
const labelList srcCellIDs(maskCells(srcMesh, tgtMesh));
// (potentially) participating source mesh cells
const labelList srcCellIDs(maskCells());
// list to keep track of whether src cell can be mapped
boolList mapFlag(src_.nCells(), false);
// Initialise list to keep track of whether src cell can be mapped
boolList mapFlag(srcMesh.nCells(), false);
UIndirectList<bool>(mapFlag, srcCellIDs) = true;
// find initial point in tgt mesh
// Find initial point in tgt mesh
label srcSeedI = -1;
label tgtSeedI = -1;
label startSeedI = 0;
bool startWalk =
findInitialSeeds
(
srcMesh,
tgtMesh,
srcCellIDs,
mapFlag,
startSeedI,
@ -402,26 +381,21 @@ Foam::scalar Foam::mapNearestMethod::calculate
if (startWalk)
{
const scalar V =
return
calculateAddressing
(
srcToTgtAddr,
srcToTgtWght,
tgtToSrcAddr,
tgtToSrcWght,
srcMesh,
tgtMesh,
srcLocalTgtCells_,
srcWeights_,
tgtLocalSrcCells_,
tgtWeights_,
srcSeedI,
tgtSeedI,
srcCellIDs,
mapFlag,
startSeedI
);
if (debug > 1)
{
writeConnectivity(src_, tgt_, srcToTgtAddr);
}
return V;
}
else
{
@ -430,7 +404,7 @@ Foam::scalar Foam::mapNearestMethod::calculate
}
void Foam::mapNearestMethod::normalise
void Foam::cellsToCellss::nearest::normalise
(
const polyMesh& srcMesh,
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
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -22,39 +22,35 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::mapNearestMethod
Foam::cellsToCellss::nearest
Description
Map nearest mesh-to-mesh 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!
Nearest cells-to-cells interpolation class.
SourceFiles
mapNearestMethod.C
nearestCellsToCells.C
\*---------------------------------------------------------------------------*/
#ifndef mapNearestMethod_H
#define mapNearestMethod_H
#ifndef nearestCellsToCells_H
#define nearestCellsToCells_H
#include "meshToMeshMethod.H"
#include "cellsToCells.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace cellsToCellss
{
/*---------------------------------------------------------------------------*\
Class mapNearestMethod Declaration
Class nearest Declaration
\*---------------------------------------------------------------------------*/
class mapNearestMethod
class nearest
:
public meshToMeshMethod
public cellsToCells
{
private:
@ -64,6 +60,8 @@ private:
// true if found a matching pair
bool findInitialSeeds
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const labelList& srcCellIDs,
const boolList& mapFlag,
const label startSeedI,
@ -74,6 +72,8 @@ private:
//- Calculate the mesh-to-mesh addressing and weights
scalar calculateAddressing
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
labelListList& srcToTgtCellAddr,
scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr,
@ -97,6 +97,8 @@ private:
//- Set the next cells for the marching front algorithm
void setNextNearestCells
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
label& startSeedI,
label& srcCelli,
label& tgtCelli,
@ -107,53 +109,55 @@ private:
//- Find a source cell mapped to target cell tgtCelli
label findMappedSrcCell
(
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const label tgtCelli,
const List<DynamicList<label>>& tgtToSrc
) 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:
//- Run-time type information
TypeName("mapNearest");
TypeName("nearest");
// Constructors
//- Construct from source and target meshes
mapNearestMethod(const polyMesh& src, const polyMesh& tgt);
//- Construct null
nearest();
//- Destructor
virtual ~mapNearestMethod();
// 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;
virtual ~nearest();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace cellsToCellss
} // 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
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -24,12 +24,10 @@ License
\*---------------------------------------------------------------------------*/
#include "meshToMesh.H"
#include "globalIndex.H"
#include "meshToMeshMethod.H"
#include "PatchTools.H"
#include "patchToPatchTools.H"
#include "emptyPolyPatch.H"
#include "wedgePolyPatch.H"
#include "processorPolyPatch.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -39,200 +37,25 @@ namespace Foam
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::scalar Foam::meshToMesh::calculateCellToCells(const word& methodName)
{
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
Foam::meshToMesh::meshToMesh
(
const word& methodName,
const bool interpAllPatches
const polyMesh& srcMesh,
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;
@ -240,10 +63,18 @@ void Foam::meshToMesh::constructNoCuttingPatches
{
const polyPatch& srcPp = srcMesh_.boundaryMesh()[srcPatchi];
// We want to map all the global patches, including constraint
// patches (since they might have mappable properties, e.g.
// jumpCyclic). We'll fix the value afterwards.
if (!isA<processorPolyPatch>(srcPp))
// We don't want to map empty or wedge patches, as by definition
// these do not hold relevant values. We also don't want to map
// processor patches as these are likely to differ between cases.
// 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 =
tgtMesh_.boundaryMesh().findPatchID(srcPp.name());
@ -265,21 +96,9 @@ void Foam::meshToMesh::constructNoCuttingPatches
srcToTgtPatchIDs_.transfer(srcToTgtPatchIDs);
}
// calculate patch addressing and weights
calculatePatchToPatches(methodName);
// calculate cell addressing and weights
calculateCellToCells(methodName);
}
void Foam::meshToMesh::constructFromCuttingPatches
(
const word& methodName,
const HashTable<word>& patchMap,
const wordList& tgtCuttingPatches
)
{
// If a patch mas was supplied then convert it to pairs of patch indices
else
{
srcToTgtPatchIDs_.setSize(patchMap.size());
label i = 0;
forAllConstIter(HashTable<word>, patchMap, iter)
@ -287,93 +106,73 @@ void Foam::meshToMesh::constructFromCuttingPatches
const word& tgtPatchName = iter.key();
const word& srcPatchName = iter();
srcToTgtPatchIDs_[i++] =
labelPair
(
srcMesh_.boundaryMesh().findPatchID(srcPatchName),
tgtMesh_.boundaryMesh().findPatchID(tgtPatchName)
);
}
const label srcPatchi =
srcMesh_.boundaryMesh().findPatchID(srcPatchName);
const label tgtPatchi =
tgtMesh_.boundaryMesh().findPatchID(tgtPatchName);
// calculate patch addressing and weights
calculatePatchToPatches(methodName);
// calculate cell addressing and weights
calculateCellToCells(methodName);
// set IDs of cutting patches on target mesh
tgtCuttingPatchIDs_.setSize(tgtCuttingPatches.size());
forAll(tgtCuttingPatchIDs_, i)
if (srcPatchi == -1)
{
const word& patchName = tgtCuttingPatches[i];
tgtCuttingPatchIDs_[i] = tgtMesh_.boundaryMesh().findPatchID(patchName);
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);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Calculate cell addressing and weights
Info<< "Creating cellsToCells between source mesh "
<< srcMesh_.name() << " and target mesh " << tgtMesh_.name()
<< " using " << engineType << endl << incrIndent;
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
srcToTgtCellsToCells_ = cellsToCells::New(engineType);
srcToTgtCellsToCells_->update(srcMesh_, tgtMesh_);
Info<< decrIndent;
// Calculate patch addressing and weights
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 " << engineType << endl << incrIndent;
srcToTgtPatchToPatches_.set
(
methodName,
interpAllPatches
i,
patchToPatch::New(engineType, true)
);
}
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
srcToTgtPatchToPatches_[i].update
(
methodName,
patchMap,
tgtCuttingPatches
srcPP,
PatchTools::pointNormals(srcMesh_, srcPP),
tgtPP
);
Info<< decrIndent;
}
}
@ -385,29 +184,65 @@ Foam::meshToMesh::~meshToMesh()
// * * * * * * * * * * * * * * * 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
(
const label srcCelli,
const point& p
) const
{
forAll(srcLocalTgtCells_[srcCelli], i)
{
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();
return srcToTgtCellsToCells_().srcToTgtPoint(tgtMesh_, srcCelli, p);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -25,17 +25,11 @@ Class
Foam::meshToMesh
Description
Class to calculate the cell-addressing between two overlapping meshes
Mapping is performed using a run-time selectable interpolation mothod
See also
meshToMeshMethod
Class to calculate interpolative addressing and weights between the cells
and patches of two overlapping meshes
SourceFiles
meshToMesh.C
meshToMeshParallelOps.C
meshToMeshTemplates.C
\*---------------------------------------------------------------------------*/
@ -43,10 +37,8 @@ SourceFiles
#define meshToMesh_H
#include "polyMesh.H"
#include "boundBox.H"
#include "distributionMap.H"
#include "NamedEnum.H"
#include "patchToPatch.H"
#include "cellsToCells.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -67,6 +59,9 @@ class meshToMesh
//- Reference to the target mesh
const polyMesh& tgtMesh_;
//- Interpolation engine between source and target cells
autoPtr<cellsToCells> srcToTgtCellsToCells_;
//- List of corresponding source and target patches that are to be
// mapped to each other
List<labelPair> srcToTgtPatchIDs_;
@ -75,93 +70,6 @@ class meshToMesh
// target patches
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:
@ -169,6 +77,9 @@ protected:
// Access
//- Return the interpolation engine between source and target cells
inline const cellsToCells& srcToTgtCellsToCells() const;
//- Return the source patch indices
inline const List<labelPair>& srcToTgtPatchIDs() const;
@ -176,9 +87,6 @@ protected:
// source and target patches
inline const PtrList<patchToPatch>& srcToTgtPatchToPatches() const;
//- Return the cutting patch indices
inline const labelList& tgtCuttingPatchIDs() const;
public:
@ -188,23 +96,15 @@ public:
// 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
(
const polyMesh& src,
const polyMesh& tgt,
const word& methodName,
const bool interpAllPatches = true
);
//- 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
const polyMesh& srcMesh,
const polyMesh& tgtMesh,
const word& engineType,
const HashTable<word>& patchMap = NullObjectRef<HashTable<word>>()
);
//- Disallow default bitwise copy construction
@ -225,63 +125,16 @@ public:
//- Return const access to the target mesh
inline const polyMesh& tgtMesh() const;
//- Index of the processor holding all cells of the meshToMesh,
// or -1 if spread across multiple processors
inline label singleProcess() const;
//- Is this intersection on a single process?
inline bool isSingleProcess() const;
// Evaluation
// Source-to-target field mapping
//- Map field from src to tgt mesh. Values passed in via
// '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;
//- Is the map between consistent meshes? I.e., are all
// (non-processor) patches mapped one-to-one?
bool consistent() 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;
//- Find the target processor and cell associated with a point in a
// source cell. See cellsToCells::srcToTgtPoint.
remote srcToTgtPoint(const label srcCelli, const point& p) const;
// Member Operators
@ -301,12 +154,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "meshToMeshTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -27,6 +27,12 @@ License
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
inline const Foam::cellsToCells& Foam::meshToMesh::srcToTgtCellsToCells() const
{
return srcToTgtCellsToCells_();
}
inline const Foam::List<Foam::labelPair>&
Foam::meshToMesh::srcToTgtPatchIDs() const
{
@ -41,12 +47,6 @@ Foam::meshToMesh::srcToTgtPatchToPatches() const
}
inline const Foam::labelList& Foam::meshToMesh::tgtCuttingPatchIDs() const
{
return tgtCuttingPatchIDs_;
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
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
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2021-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -75,7 +75,7 @@ public:
part()
:
area(Zero),
centre(NaN<point>())
centre(patchToPatchTools::NaN<point>())
{}
//- Default construct

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -30,16 +30,17 @@ Description
SourceFiles
patchToPatch.C
patchToPatchParallelOps.C
patchToPatchTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef patchToPatch_H
#define patchToPatch_H
#include "remote.H"
#include "distributionMap.H"
#include "primitivePatch.H"
#include "primitiveOldTimePatch.H"
#include "remote.H"
#include "runTimeSelectionTables.H"
#include "treeBoundBox.H"
@ -254,31 +255,6 @@ protected:
//- For each target face, the coupled source weights
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:

View File

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

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -24,111 +24,7 @@ License
\*---------------------------------------------------------------------------*/
#include "patchToPatch.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;
}
#include "patchToPatchTools.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -137,10 +33,10 @@ Foam::tmp<Foam::Field<Type>>
Foam::patchToPatch::srcToTgt(const Field<Type>& srcFld) const
{
return
interpolate
patchToPatchTools::interpolate
(
tgtLocalSrcFaces_,
tgtWeights(),
tgtWeights()(),
srcMapPtr_,
srcFld
);
@ -155,10 +51,10 @@ Foam::tmp<Foam::Field<Type>> Foam::patchToPatch::srcToTgt
) const
{
return
interpolate
patchToPatchTools::interpolate
(
tgtLocalSrcFaces_,
tgtWeights(),
tgtWeights()(),
srcMapPtr_,
srcFld,
leftOverTgtFld
@ -171,10 +67,10 @@ Foam::tmp<Foam::Field<Type>>
Foam::patchToPatch::tgtToSrc(const Field<Type>& tgtFld) const
{
return
interpolate
patchToPatchTools::interpolate
(
srcLocalTgtFaces_,
srcWeights(),
srcWeights()(),
tgtMapPtr_,
tgtFld
);
@ -189,10 +85,10 @@ Foam::tmp<Foam::Field<Type>> Foam::patchToPatch::tgtToSrc
) const
{
return
interpolate
patchToPatchTools::interpolate
(
srcLocalTgtFaces_,
srcWeights(),
srcWeights()(),
tgtMapPtr_,
tgtFld,
leftOverSrcFld

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -137,6 +137,31 @@ void rDistributeTgtAddressing
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 Foam

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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;
master false;
interpolationMethod cellVolumeWeight;
interpolationMethod intersection;
semiImplicit no;
}
@ -34,7 +34,7 @@ porosityBlockage
{
nbrRegion porous;
interpolationMethod cellVolumeWeight;
interpolationMethod intersection;
type DarcyForchheimer;

View File

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