mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: AMI code refactoring
This commit is contained in:
committed by
Andrew Heather
parent
2a955ad949
commit
c6e18e7593
@ -226,10 +226,9 @@ void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
|
||||
{
|
||||
const cyclicACMIPolyPatch& cpp = cyclicACMIPatch_.cyclicACMIPatch();
|
||||
|
||||
// note: only applying coupled contribution
|
||||
// Note: only applying coupled contribution
|
||||
|
||||
const labelUList& nbrFaceCellsCoupled =
|
||||
cpp.neighbPatch().faceCells();
|
||||
const labelUList& nbrFaceCellsCoupled = cpp.neighbPatch().faceCells();
|
||||
|
||||
solveScalarField pnf(psiInternal, nbrFaceCellsCoupled);
|
||||
|
||||
@ -254,7 +253,7 @@ void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
|
||||
{
|
||||
const cyclicACMIPolyPatch& cpp = cyclicACMIPatch_.cyclicACMIPatch();
|
||||
|
||||
// note: only applying coupled contribution
|
||||
// Note: only applying coupled contribution
|
||||
|
||||
const labelUList& nbrFaceCellsCoupled = cpp.neighbPatch().faceCells();
|
||||
|
||||
@ -277,7 +276,7 @@ void Foam::cyclicACMIFvPatchField<Type>::manipulateMatrix
|
||||
{
|
||||
const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
|
||||
|
||||
// nothing to be done by the AMI, but re-direct to non-overlap patch
|
||||
// Nothing to be done by the AMI, but re-direct to non-overlap patch
|
||||
// with non-overlap patch weights
|
||||
const fvPatchField<Type>& npf = nonOverlapPatchField();
|
||||
|
||||
|
||||
@ -46,6 +46,7 @@ namespace Foam
|
||||
void Foam::cyclicACMIFvPatch::resetPatchAreas(const fvPatch& fvp) const
|
||||
{
|
||||
const_cast<vectorField&>(fvp.Sf()) = fvp.patch().faceAreas();
|
||||
const_cast<vectorField&>(fvp.Cf()) = fvp.patch().faceCentres();
|
||||
const_cast<scalarField&>(fvp.magSf()) = mag(fvp.patch().faceAreas());
|
||||
|
||||
DebugPout
|
||||
@ -117,7 +118,7 @@ Foam::tmp<Foam::vectorField> Foam::cyclicACMIFvPatch::delta() const
|
||||
|
||||
vectorField nbrPatchD(interpolate(nbrPatch.coupledFvPatch::delta()));
|
||||
|
||||
tmp<vectorField> tpdv(new vectorField(patchD.size()));
|
||||
auto tpdv = tmp<vectorField>::New(patchD.size());
|
||||
vectorField& pdv = tpdv.ref();
|
||||
|
||||
// do the transformation if necessary
|
||||
@ -204,6 +205,9 @@ void Foam::cyclicACMIFvPatch::movePoints()
|
||||
scalarField& phiNonOverlapp =
|
||||
meshPhiBf[nonOverlapPatch.patch().index()];
|
||||
|
||||
const auto& localFaces = cyclicACMIPolyPatch_.localFaces();
|
||||
const auto& localPoints = cyclicACMIPolyPatch_.localPoints();
|
||||
|
||||
forAll(phip, facei)
|
||||
{
|
||||
if (newSrcAddr[facei].empty())
|
||||
@ -214,12 +218,12 @@ void Foam::cyclicACMIFvPatch::movePoints()
|
||||
else
|
||||
{
|
||||
// Scale the mesh flux according to the area fraction
|
||||
const face& fAMI = cyclicACMIPolyPatch_.localFaces()[facei];
|
||||
const face& fAMI = localFaces[facei];
|
||||
|
||||
// Note: using raw point locations to calculate the geometric
|
||||
// area - faces areas are currently scaled (decoupled from
|
||||
// mesh points)
|
||||
const scalar geomArea = fAMI.mag(cyclicACMIPolyPatch_.localPoints());
|
||||
const scalar geomArea = fAMI.mag(localPoints);
|
||||
phip[facei] *= magSf()[facei]/geomArea;
|
||||
}
|
||||
}
|
||||
@ -234,6 +238,9 @@ void Foam::cyclicACMIFvPatch::movePoints()
|
||||
scalarField& nbrPhiNonOverlapp =
|
||||
meshPhiBf[nbrNonOverlapPatch.patch().index()];
|
||||
|
||||
const auto& nbrLocalFaces = nbrACMI.patch().localFaces();
|
||||
const auto& nbrLocalPoints = nbrACMI.patch().localPoints();
|
||||
|
||||
forAll(nbrPhip, facei)
|
||||
{
|
||||
if (newTgtAddr[facei].empty())
|
||||
@ -242,12 +249,12 @@ void Foam::cyclicACMIFvPatch::movePoints()
|
||||
}
|
||||
else
|
||||
{
|
||||
const face& fAMI = nbrACMI.patch().localFaces()[facei];
|
||||
const face& fAMI = nbrLocalFaces[facei];
|
||||
|
||||
// Note: using raw point locations to calculate the geometric
|
||||
// area - faces areas are currently scaled (decoupled from
|
||||
// mesh points)
|
||||
const scalar geomArea = fAMI.mag(nbrACMI.patch().localPoints());
|
||||
const scalar geomArea = fAMI.mag(nbrLocalPoints);
|
||||
nbrPhip[facei] *= nbrACMI.magSf()[facei]/geomArea;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -123,7 +124,7 @@ Foam::tmp<Foam::vectorField> Foam::cyclicAMIFvPatch::delta() const
|
||||
|
||||
const vectorField& nbrPatchD = tnbrPatchD();
|
||||
|
||||
tmp<vectorField> tpdv(new vectorField(patchD.size()));
|
||||
auto tpdv = tmp<vectorField>::New(patchD.size());
|
||||
vectorField& pdv = tpdv.ref();
|
||||
|
||||
// do the transformation if necessary
|
||||
|
||||
@ -159,8 +159,8 @@ public:
|
||||
}
|
||||
|
||||
//- Return true if this patch is coupled. This is equivalent
|
||||
// to the coupledPolyPatch::coupled() if parallel running or
|
||||
// both sides present, false otherwise
|
||||
//- to the coupledPolyPatch::coupled() if parallel running or
|
||||
//- both sides present, false otherwise
|
||||
virtual bool coupled() const;
|
||||
|
||||
//- Return delta (P to N) vectors across coupled patch
|
||||
@ -190,7 +190,7 @@ public:
|
||||
// Interface transfer functions
|
||||
|
||||
//- Return the values of the given internal data adjacent to
|
||||
// the interface as a field
|
||||
//- the interface as a field
|
||||
virtual tmp<labelField> interfaceInternalField
|
||||
(
|
||||
const labelUList& internalData
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -62,75 +62,52 @@ SourceFiles
|
||||
#include "ops.H"
|
||||
#include "Enum.H"
|
||||
#include "pointList.H"
|
||||
#include "indexedOctree.H"
|
||||
#include "treeDataPrimitivePatch.H"
|
||||
|
||||
#include "runTimeSelectionTables.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class AMIInterpolationName Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
TemplateName(AMIInterpolation);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class AMIInterpolation Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
class AMIInterpolation
|
||||
:
|
||||
public AMIInterpolationName
|
||||
{
|
||||
public:
|
||||
|
||||
// Public data types
|
||||
|
||||
//- Enumeration specifying interpolation method
|
||||
enum interpolationMethod
|
||||
{
|
||||
imNearestFace,
|
||||
imFaceAreaWeight,
|
||||
imPartialFaceAreaWeight
|
||||
};
|
||||
|
||||
static const Enum<interpolationMethod> interpolationMethodNames_;
|
||||
|
||||
static bool cacheIntersections_;
|
||||
|
||||
//- Calculate the patch face magnitudes for the given tri-mode
|
||||
template<class Patch>
|
||||
static tmp<scalarField> patchMagSf
|
||||
(
|
||||
const Patch& patch,
|
||||
const faceAreaIntersect::triangulationMode triMode
|
||||
);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
//- Local typedef to octree tree-type
|
||||
typedef treeDataPrimitivePatch<primitivePatch> treeType;
|
||||
|
||||
// Private data
|
||||
// Protected data
|
||||
|
||||
//- Interpolation method
|
||||
const word methodName_;
|
||||
//- Flag to indicate that the two patches must be matched/an overlap
|
||||
//- exists between them
|
||||
bool requireMatch_;
|
||||
|
||||
//- Flag to indicate that the two patches are co-directional and
|
||||
//- that the orientation of the target patch should be reversed
|
||||
const bool reverseTarget_;
|
||||
|
||||
//- Flag to indicate that the two patches must be matched/an overlap
|
||||
//- exists between them
|
||||
const bool requireMatch_;
|
||||
//- Threshold weight below which interpolation is deactivated
|
||||
scalar lowWeightCorrection_;
|
||||
|
||||
//- Index of processor that holds all of both sides. -1 in all other
|
||||
//- cases
|
||||
label singlePatchProc_;
|
||||
|
||||
//- Threshold weight below which interpolation is deactivated
|
||||
scalar lowWeightCorrection_;
|
||||
|
||||
|
||||
// Source patch
|
||||
|
||||
@ -149,6 +126,16 @@ private:
|
||||
//- Centroid of target faces per source face
|
||||
pointListList srcCentroids_;
|
||||
|
||||
//- Source patch points if input points are manipulated, e.g.
|
||||
//- projected
|
||||
pointField srcPatchPts_;
|
||||
|
||||
//- Source patch using manipulated input points
|
||||
tmpNrc<primitivePatch> tsrcPatch0_;
|
||||
|
||||
//- Source map pointer - parallel running only
|
||||
autoPtr<mapDistribute> srcMapPtr_;
|
||||
|
||||
|
||||
// Target patch
|
||||
|
||||
@ -167,21 +154,21 @@ private:
|
||||
//- Centroid of source faces per target face
|
||||
pointListList tgtCentroids_;
|
||||
|
||||
//- Target patch points if input points are manipulated, e.g.
|
||||
//- projected
|
||||
pointField tgtPatchPts_;
|
||||
|
||||
//- Face triangulation mode
|
||||
const faceAreaIntersect::triangulationMode triMode_;
|
||||
|
||||
//- Source map pointer - parallel running only
|
||||
autoPtr<mapDistribute> srcMapPtr_;
|
||||
//- Target patch using manipulated input points
|
||||
tmpNrc<primitivePatch> ttgtPatch0_;
|
||||
|
||||
//- Target map pointer - parallel running only
|
||||
autoPtr<mapDistribute> tgtMapPtr_;
|
||||
|
||||
//- Up-to-date flag
|
||||
bool upToDate_;
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- No copy construct
|
||||
AMIInterpolation(const AMIInterpolation&) = delete;
|
||||
// Protected Member Functions
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const AMIInterpolation&) = delete;
|
||||
@ -189,6 +176,19 @@ private:
|
||||
|
||||
// Initialisation
|
||||
|
||||
//- Reset the octree for the patch face search
|
||||
autoPtr<indexedOctree<treeType>> createTree
|
||||
(
|
||||
const primitivePatch& patch
|
||||
) const;
|
||||
|
||||
//- Calculate if patches are on multiple processors
|
||||
label calcDistribution
|
||||
(
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch
|
||||
) const;
|
||||
|
||||
//- Project points to surface
|
||||
void projectPointsToSurface
|
||||
(
|
||||
@ -197,6 +197,15 @@ private:
|
||||
) const;
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//- Return the orginal src patch with optionally updated points
|
||||
inline const primitivePatch& srcPatch0() const;
|
||||
|
||||
//- Return the orginal tgt patch with optionally updated points
|
||||
inline const primitivePatch& tgtPatch0() const;
|
||||
|
||||
|
||||
// Evaluation
|
||||
|
||||
//- Normalise the (area) weights - suppresses numerical error in
|
||||
@ -236,96 +245,127 @@ private:
|
||||
autoPtr<mapDistribute>& tgtMap
|
||||
);
|
||||
|
||||
void constructFromSurface
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr
|
||||
);
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("AMIInterpolation");
|
||||
|
||||
// Selection tables
|
||||
|
||||
//- Selection table for dictionary construction
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
AMIInterpolation,
|
||||
dict,
|
||||
(
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget
|
||||
),
|
||||
(
|
||||
dict,
|
||||
reverseTarget
|
||||
)
|
||||
);
|
||||
|
||||
//- Selection table for component-wise construction
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
AMIInterpolation,
|
||||
component,
|
||||
(
|
||||
const bool requireMatch,
|
||||
const bool reverseTarget,
|
||||
const scalar lowWeightCorrection
|
||||
),
|
||||
(
|
||||
requireMatch,
|
||||
reverseTarget,
|
||||
lowWeightCorrection
|
||||
)
|
||||
);
|
||||
|
||||
//- Selector for dictionary
|
||||
static autoPtr<AMIInterpolation> New
|
||||
(
|
||||
const word& modelName,
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget = false
|
||||
);
|
||||
|
||||
//- Selector for components
|
||||
static autoPtr<AMIInterpolation> New
|
||||
(
|
||||
const word& modelName,
|
||||
const bool requireMatch = true,
|
||||
const bool reverseTarget = false,
|
||||
const scalar lowWeightCorrection = -1
|
||||
);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
//- Construct from dictionary
|
||||
AMIInterpolation
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool requireMatch = true,
|
||||
const interpolationMethod& method = imFaceAreaWeight,
|
||||
const scalar lowWeightCorrection = -1,
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget = false
|
||||
);
|
||||
|
||||
//- Construct from components
|
||||
AMIInterpolation
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool requireMatch = true,
|
||||
const word& methodName =
|
||||
interpolationMethodNames_[imFaceAreaWeight],
|
||||
const scalar lowWeightCorrection = -1,
|
||||
const bool reverseTarget = false
|
||||
);
|
||||
|
||||
//- Construct from components, with projection surface
|
||||
AMIInterpolation
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surf,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool requireMatch = true,
|
||||
const interpolationMethod& method = imFaceAreaWeight,
|
||||
const scalar lowWeightCorrection = -1,
|
||||
const bool reverseTarget = false
|
||||
);
|
||||
|
||||
//- Construct from components, with projection surface
|
||||
AMIInterpolation
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surf,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool requireMatch = true,
|
||||
const word& methodName =
|
||||
interpolationMethodNames_[imFaceAreaWeight],
|
||||
const scalar lowWeightCorrection = -1,
|
||||
const bool reverseTarget = false
|
||||
const bool reverseTarget = false,
|
||||
const scalar lowWeightCorrection = -1
|
||||
);
|
||||
|
||||
//- Construct from agglomeration of AMIInterpolation. Agglomeration
|
||||
// passed in as new coarse size and addressing from fine from coarse
|
||||
//- passed in as new coarse size and addressing from fine from coarse
|
||||
AMIInterpolation
|
||||
(
|
||||
const AMIInterpolation<SourcePatch, TargetPatch>& fineAMI,
|
||||
const AMIInterpolation& fineAMI,
|
||||
const labelList& sourceRestrictAddressing,
|
||||
const labelList& neighbourRestrictAddressing
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
AMIInterpolation(const AMIInterpolation& ami);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual autoPtr<AMIInterpolation> clone() const
|
||||
{
|
||||
return autoPtr<AMIInterpolation>::New(*this);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
~AMIInterpolation() = default;
|
||||
|
||||
// Typedef to SourcePatch type this AMIInterpolation is instantiated on
|
||||
typedef SourcePatch sourcePatchType;
|
||||
|
||||
// Typedef to TargetPatch type this AMIInterpolation is instantiated on
|
||||
typedef TargetPatch targetPatchType;
|
||||
virtual ~AMIInterpolation() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Set to -1, or the processor holding all faces (both sides) of
|
||||
//- the AMI
|
||||
inline label singlePatchProc() const;
|
||||
//- Access to the up-to-date flag
|
||||
inline bool upToDate() const;
|
||||
|
||||
//- Access to the up-to-date flag
|
||||
inline bool& upToDate();
|
||||
|
||||
//- Access to the distributed flag
|
||||
inline bool distributed() const;
|
||||
|
||||
//- Access to the requireMatch flag
|
||||
inline bool requireMatch() const;
|
||||
|
||||
//- Access to the requireMatch flag
|
||||
inline bool setRequireMatch(const bool flag);
|
||||
|
||||
//- Access to the reverseTarget flag
|
||||
inline bool reverseTarget() const;
|
||||
|
||||
//- Threshold weight below which interpolation is deactivated
|
||||
inline scalar lowWeightCorrection() const;
|
||||
@ -333,6 +373,10 @@ public:
|
||||
//- Return true if employing a 'lowWeightCorrection'
|
||||
inline bool applyLowWeightCorrection() const;
|
||||
|
||||
//- Set to -1, or the processor holding all faces (both sides) of
|
||||
//- the AMI
|
||||
inline label singlePatchProc() const;
|
||||
|
||||
|
||||
// Source patch
|
||||
|
||||
@ -410,14 +454,16 @@ public:
|
||||
|
||||
// Manipulation
|
||||
|
||||
//- Update addressing and weights
|
||||
void update
|
||||
//- Update addressing, weights and (optional) centroids
|
||||
virtual bool calculate
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr = nullptr
|
||||
);
|
||||
|
||||
void update
|
||||
//- Set the maps, addresses and weights from an external source
|
||||
void reset
|
||||
(
|
||||
autoPtr<mapDistribute>&& srcToTgtMap,
|
||||
autoPtr<mapDistribute>&& tgtToSrcMap,
|
||||
@ -427,17 +473,11 @@ public:
|
||||
scalarListList&& tgtWeights
|
||||
);
|
||||
|
||||
void setAreas(const scalarList& srcMagSf, const scalarList& tgtMagSf)
|
||||
{
|
||||
srcMagSf_ = srcMagSf;
|
||||
tgtMagSf_ = tgtMagSf;
|
||||
}
|
||||
|
||||
//- Append additional addressing and weights
|
||||
void append
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch
|
||||
);
|
||||
|
||||
//- Normalise the weights
|
||||
@ -545,8 +585,8 @@ public:
|
||||
//- Return source patch face index of point on target patch face
|
||||
label srcPointFace
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const vector& n,
|
||||
const label tgtFacei,
|
||||
point& tgtPoint
|
||||
@ -556,8 +596,8 @@ public:
|
||||
//- Return target patch face index of point on source patch face
|
||||
label tgtPointFace
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const vector& n,
|
||||
const label srcFacei,
|
||||
point& srcPoint
|
||||
@ -574,10 +614,16 @@ public:
|
||||
//- Write face connectivity as OBJ file
|
||||
void writeFaceConnectivity
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const labelListList& srcAddress
|
||||
) const;
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Write
|
||||
virtual void write(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
@ -592,7 +638,7 @@ public:
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "AMIInterpolation.C"
|
||||
#include "AMIInterpolationTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -26,186 +26,203 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline Foam::label
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::singlePatchProc() const
|
||||
inline const Foam::primitivePatch& Foam::AMIInterpolation::srcPatch0() const
|
||||
{
|
||||
return singlePatchProc_;
|
||||
if (!tsrcPatch0_.valid())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "tsrcPatch0Ptr_ not set"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return tsrcPatch0_();
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline Foam::scalar
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::lowWeightCorrection() const
|
||||
inline const Foam::primitivePatch& Foam::AMIInterpolation::tgtPatch0() const
|
||||
{
|
||||
|
||||
if (!ttgtPatch0_.valid())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "ttgtPatch0Ptr_ not set"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return ttgtPatch0_();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::AMIInterpolation::upToDate() const
|
||||
{
|
||||
return upToDate_;
|
||||
}
|
||||
|
||||
|
||||
inline bool& Foam::AMIInterpolation::upToDate()
|
||||
{
|
||||
return upToDate_;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::AMIInterpolation::distributed() const
|
||||
{
|
||||
return singlePatchProc_ == -1;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::AMIInterpolation::requireMatch() const
|
||||
{
|
||||
return requireMatch_ && lowWeightCorrection_ < 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::AMIInterpolation::setRequireMatch(const bool flag)
|
||||
{
|
||||
requireMatch_ = flag;
|
||||
return requireMatch_;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::AMIInterpolation::reverseTarget() const
|
||||
{
|
||||
return reverseTarget_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::scalar Foam::AMIInterpolation::lowWeightCorrection() const
|
||||
{
|
||||
return lowWeightCorrection_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline bool
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::
|
||||
applyLowWeightCorrection() const
|
||||
inline bool Foam::AMIInterpolation::applyLowWeightCorrection() const
|
||||
{
|
||||
return lowWeightCorrection_ > 0;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::List<Foam::scalar>&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcMagSf() const
|
||||
inline Foam::label Foam::AMIInterpolation::singlePatchProc() const
|
||||
{
|
||||
return singlePatchProc_;
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::List<Foam::scalar>& Foam::AMIInterpolation::srcMagSf() const
|
||||
{
|
||||
return srcMagSf_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline Foam::List<Foam::scalar>&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcMagSf()
|
||||
inline Foam::List<Foam::scalar>& Foam::AMIInterpolation::srcMagSf()
|
||||
{
|
||||
return srcMagSf_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::labelListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcAddress() const
|
||||
inline const Foam::labelListList& Foam::AMIInterpolation::srcAddress() const
|
||||
{
|
||||
return srcAddress_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline Foam::labelListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcAddress()
|
||||
inline Foam::labelListList& Foam::AMIInterpolation::srcAddress()
|
||||
{
|
||||
return srcAddress_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::scalarListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeights() const
|
||||
inline const Foam::scalarListList& Foam::AMIInterpolation::srcWeights() const
|
||||
{
|
||||
return srcWeights_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline Foam::scalarListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeights()
|
||||
inline Foam::scalarListList& Foam::AMIInterpolation::srcWeights()
|
||||
{
|
||||
return srcWeights_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::scalarField&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeightsSum() const
|
||||
inline const Foam::scalarField& Foam::AMIInterpolation::srcWeightsSum() const
|
||||
{
|
||||
return srcWeightsSum_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline Foam::scalarField&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeightsSum()
|
||||
inline Foam::scalarField& Foam::AMIInterpolation::srcWeightsSum()
|
||||
{
|
||||
return srcWeightsSum_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::pointListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcCentroids() const
|
||||
inline const Foam::pointListList& Foam::AMIInterpolation::srcCentroids() const
|
||||
{
|
||||
return srcCentroids_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline Foam::pointListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcCentroids()
|
||||
inline Foam::pointListList& Foam::AMIInterpolation::srcCentroids()
|
||||
{
|
||||
return srcCentroids_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::mapDistribute&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcMap() const
|
||||
inline const Foam::mapDistribute& Foam::AMIInterpolation::srcMap() const
|
||||
{
|
||||
return *srcMapPtr_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::List<Foam::scalar>&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtMagSf() const
|
||||
inline const Foam::List<Foam::scalar>& Foam::AMIInterpolation::tgtMagSf() const
|
||||
{
|
||||
return tgtMagSf_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline Foam::List<Foam::scalar>&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtMagSf()
|
||||
inline Foam::List<Foam::scalar>& Foam::AMIInterpolation::tgtMagSf()
|
||||
{
|
||||
return tgtMagSf_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::labelListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtAddress() const
|
||||
inline const Foam::labelListList& Foam::AMIInterpolation::tgtAddress() const
|
||||
{
|
||||
return tgtAddress_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline Foam::labelListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtAddress()
|
||||
inline Foam::labelListList& Foam::AMIInterpolation::tgtAddress()
|
||||
{
|
||||
return tgtAddress_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::scalarListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeights() const
|
||||
inline const Foam::scalarListList& Foam::AMIInterpolation::tgtWeights() const
|
||||
{
|
||||
return tgtWeights_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline Foam::scalarListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeights()
|
||||
inline Foam::scalarListList& Foam::AMIInterpolation::tgtWeights()
|
||||
{
|
||||
return tgtWeights_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::scalarField&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeightsSum() const
|
||||
inline const Foam::scalarField& Foam::AMIInterpolation::tgtWeightsSum() const
|
||||
{
|
||||
return tgtWeightsSum_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline Foam::scalarField&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeightsSum()
|
||||
inline Foam::scalarField& Foam::AMIInterpolation::tgtWeightsSum()
|
||||
{
|
||||
return tgtWeightsSum_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::mapDistribute&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtMap() const
|
||||
inline const Foam::mapDistribute& Foam::AMIInterpolation::tgtMap() const
|
||||
{
|
||||
return *tgtMapPtr_;
|
||||
}
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "AMIInterpolation.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(AMIInterpolationName, 0);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -5,8 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -26,46 +25,66 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "AMIInterpolation.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::autoPtr<Foam::AMIMethod<SourcePatch, TargetPatch>>
|
||||
Foam::AMIMethod<SourcePatch, TargetPatch>::New
|
||||
Foam::autoPtr<Foam::AMIInterpolation> Foam::AMIInterpolation::New
|
||||
(
|
||||
const word& methodName,
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool reverseTarget,
|
||||
const bool requireMatch
|
||||
const word& modelName,
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget
|
||||
)
|
||||
{
|
||||
DebugInfo << "Selecting AMIMethod " << methodName << endl;
|
||||
DebugInfo << "Selecting model " << modelName << endl;
|
||||
|
||||
auto cstrIter = componentsConstructorTablePtr_->cfind(methodName);
|
||||
auto cstrIter = dictConstructorTablePtr_->cfind(modelName);
|
||||
|
||||
if (!cstrIter.found())
|
||||
{
|
||||
FatalErrorInLookup
|
||||
(
|
||||
"AMIMethod",
|
||||
methodName,
|
||||
*componentsConstructorTablePtr_
|
||||
typeName,
|
||||
modelName,
|
||||
*dictConstructorTablePtr_
|
||||
) << exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<AMIMethod<SourcePatch, TargetPatch>>
|
||||
return autoPtr<AMIInterpolation>(cstrIter()(dict, reverseTarget));
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::AMIInterpolation> Foam::AMIInterpolation::New
|
||||
(
|
||||
const word& modelName,
|
||||
const bool requireMatch,
|
||||
const bool reverseTarget,
|
||||
const scalar lowWeightCorrection
|
||||
)
|
||||
{
|
||||
DebugInfo << "Selecting model " << modelName << endl;
|
||||
|
||||
auto cstrIter = componentConstructorTablePtr_->cfind(modelName);
|
||||
|
||||
if (!cstrIter.found())
|
||||
{
|
||||
FatalErrorInLookup
|
||||
(
|
||||
typeName,
|
||||
modelName,
|
||||
*componentConstructorTablePtr_
|
||||
) << exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<AMIInterpolation>
|
||||
(
|
||||
cstrIter()
|
||||
(
|
||||
srcPatch,
|
||||
tgtPatch,
|
||||
triMode,
|
||||
requireMatch,
|
||||
reverseTarget,
|
||||
requireMatch
|
||||
lowWeightCorrection
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,318 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "profiling.H"
|
||||
#include "mapDistribute.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type, class CombineOp>
|
||||
void Foam::AMIInterpolation::interpolateToTarget
|
||||
(
|
||||
const UList<Type>& fld,
|
||||
const CombineOp& cop,
|
||||
List<Type>& result,
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
addProfiling(ami, "AMIInterpolation::interpolateToTarget");
|
||||
|
||||
if (fld.size() != srcAddress_.size())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Supplied field size is not equal to source patch size" << nl
|
||||
<< " source patch = " << srcAddress_.size() << nl
|
||||
<< " target patch = " << tgtAddress_.size() << nl
|
||||
<< " supplied field = " << fld.size()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (lowWeightCorrection_ > 0)
|
||||
{
|
||||
if (defaultValues.size() != tgtAddress_.size())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Employing default values when sum of weights falls below "
|
||||
<< lowWeightCorrection_
|
||||
<< " but supplied default field size is not equal to target "
|
||||
<< "patch size" << nl
|
||||
<< " default values = " << defaultValues.size() << nl
|
||||
<< " target patch = " << tgtAddress_.size() << nl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
result.setSize(tgtAddress_.size());
|
||||
|
||||
if (distributed())
|
||||
{
|
||||
const mapDistribute& map = srcMapPtr_();
|
||||
|
||||
List<Type> work(fld);
|
||||
map.distribute(work);
|
||||
|
||||
forAll(result, facei)
|
||||
{
|
||||
if (tgtWeightsSum_[facei] < lowWeightCorrection_)
|
||||
{
|
||||
result[facei] = defaultValues[facei];
|
||||
}
|
||||
else
|
||||
{
|
||||
const labelList& faces = tgtAddress_[facei];
|
||||
const scalarList& weights = tgtWeights_[facei];
|
||||
|
||||
forAll(faces, i)
|
||||
{
|
||||
cop(result[facei], facei, work[faces[i]], weights[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(result, facei)
|
||||
{
|
||||
if (tgtWeightsSum_[facei] < lowWeightCorrection_)
|
||||
{
|
||||
result[facei] = defaultValues[facei];
|
||||
}
|
||||
else
|
||||
{
|
||||
const labelList& faces = tgtAddress_[facei];
|
||||
const scalarList& weights = tgtWeights_[facei];
|
||||
|
||||
forAll(faces, i)
|
||||
{
|
||||
cop(result[facei], facei, fld[faces[i]], weights[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class CombineOp>
|
||||
void Foam::AMIInterpolation::interpolateToSource
|
||||
(
|
||||
const UList<Type>& fld,
|
||||
const CombineOp& cop,
|
||||
List<Type>& result,
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
addProfiling(ami, "AMIInterpolation::interpolateToSource");
|
||||
|
||||
if (fld.size() != tgtAddress_.size())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Supplied field size is not equal to target patch size" << nl
|
||||
<< " source patch = " << srcAddress_.size() << nl
|
||||
<< " target patch = " << tgtAddress_.size() << nl
|
||||
<< " supplied field = " << fld.size()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (lowWeightCorrection_ > 0)
|
||||
{
|
||||
if (defaultValues.size() != srcAddress_.size())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Employing default values when sum of weights falls below "
|
||||
<< lowWeightCorrection_
|
||||
<< " but supplied default field size is not equal to source "
|
||||
<< "patch size" << nl
|
||||
<< " default values = " << defaultValues.size() << nl
|
||||
<< " source patch = " << srcAddress_.size() << nl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
result.setSize(srcAddress_.size());
|
||||
|
||||
if (distributed())
|
||||
{
|
||||
const mapDistribute& map = tgtMapPtr_();
|
||||
|
||||
List<Type> work(fld);
|
||||
map.distribute(work);
|
||||
|
||||
forAll(result, facei)
|
||||
{
|
||||
if (srcWeightsSum_[facei] < lowWeightCorrection_)
|
||||
{
|
||||
result[facei] = defaultValues[facei];
|
||||
}
|
||||
else
|
||||
{
|
||||
const labelList& faces = srcAddress_[facei];
|
||||
const scalarList& weights = srcWeights_[facei];
|
||||
|
||||
forAll(faces, i)
|
||||
{
|
||||
cop(result[facei], facei, work[faces[i]], weights[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(result, facei)
|
||||
{
|
||||
if (srcWeightsSum_[facei] < lowWeightCorrection_)
|
||||
{
|
||||
result[facei] = defaultValues[facei];
|
||||
}
|
||||
else
|
||||
{
|
||||
const labelList& faces = srcAddress_[facei];
|
||||
const scalarList& weights = srcWeights_[facei];
|
||||
|
||||
forAll(faces, i)
|
||||
{
|
||||
cop(result[facei], facei, fld[faces[i]], weights[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class CombineOp>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::AMIInterpolation::interpolateToSource
|
||||
(
|
||||
const Field<Type>& fld,
|
||||
const CombineOp& cop,
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
auto tresult = tmp<Field<Type>>::New(srcAddress_.size(), Zero);
|
||||
|
||||
interpolateToSource
|
||||
(
|
||||
fld,
|
||||
multiplyWeightedOp<Type, CombineOp>(cop),
|
||||
tresult.ref(),
|
||||
defaultValues
|
||||
);
|
||||
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class CombineOp>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::AMIInterpolation::interpolateToSource
|
||||
(
|
||||
const tmp<Field<Type>>& tFld,
|
||||
const CombineOp& cop,
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
return interpolateToSource(tFld(), cop, defaultValues);
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class CombineOp>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::AMIInterpolation::interpolateToTarget
|
||||
(
|
||||
const Field<Type>& fld,
|
||||
const CombineOp& cop,
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
auto tresult = tmp<Field<Type>>::New(tgtAddress_.size(), Zero);
|
||||
|
||||
interpolateToTarget
|
||||
(
|
||||
fld,
|
||||
multiplyWeightedOp<Type, CombineOp>(cop),
|
||||
tresult.ref(),
|
||||
defaultValues
|
||||
);
|
||||
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class CombineOp>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::AMIInterpolation::interpolateToTarget
|
||||
(
|
||||
const tmp<Field<Type>>& tFld,
|
||||
const CombineOp& cop,
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
return interpolateToTarget(tFld(), cop, defaultValues);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::AMIInterpolation::interpolateToSource
|
||||
(
|
||||
const Field<Type>& fld,
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
return interpolateToSource(fld, plusEqOp<Type>(), defaultValues);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::AMIInterpolation::interpolateToSource
|
||||
(
|
||||
const tmp<Field<Type>>& tFld,
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
return interpolateToSource(tFld(), plusEqOp<Type>(), defaultValues);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::AMIInterpolation::interpolateToTarget
|
||||
(
|
||||
const Field<Type>& fld,
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
return interpolateToTarget(fld, plusEqOp<Type>(), defaultValues);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::AMIInterpolation::interpolateToTarget
|
||||
(
|
||||
const tmp<Field<Type>>& tFld,
|
||||
const UList<Type>& defaultValues
|
||||
) const
|
||||
{
|
||||
return interpolateToTarget(tFld(), plusEqOp<Type>(), defaultValues);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,380 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::AMIMethod
|
||||
|
||||
Description
|
||||
Base class for Arbitrary Mesh Interface (AMI) methods
|
||||
|
||||
SourceFiles
|
||||
AMIMethod.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef AMIMethod_H
|
||||
#define AMIMethod_H
|
||||
|
||||
#include "className.H"
|
||||
#include "DynamicList.H"
|
||||
#include "faceAreaIntersect.H"
|
||||
#include "indexedOctree.H"
|
||||
#include "treeDataPrimitivePatch.H"
|
||||
#include "treeBoundBoxList.H"
|
||||
#include "runTimeSelectionTables.H"
|
||||
#include "pointList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
template<class SourcePatch, class TargetPatch> class AMIInterpolation;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class AMIMethod Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
class AMIMethod
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- No copy construct
|
||||
AMIMethod(const AMIMethod&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const AMIMethod&) = delete;
|
||||
|
||||
// Parallel operations
|
||||
|
||||
//- Calculate if patches are on multiple processors
|
||||
label calcDistribution
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch
|
||||
) const;
|
||||
|
||||
label calcOverlappingProcs
|
||||
(
|
||||
const List<treeBoundBoxList>& procBb,
|
||||
const treeBoundBox& bb,
|
||||
boolList& overlaps
|
||||
) const;
|
||||
|
||||
void distributePatches
|
||||
(
|
||||
const mapDistribute& map,
|
||||
const TargetPatch& pp,
|
||||
const globalIndex& gi,
|
||||
List<faceList>& faces,
|
||||
List<pointField>& points,
|
||||
List<labelList>& tgtFaceIDs
|
||||
) const;
|
||||
|
||||
void distributeAndMergePatches
|
||||
(
|
||||
const mapDistribute& map,
|
||||
const TargetPatch& tgtPatch,
|
||||
const globalIndex& gi,
|
||||
faceList& tgtFaces,
|
||||
pointField& tgtPoints,
|
||||
labelList& tgtFaceIDs
|
||||
) const;
|
||||
|
||||
autoPtr<mapDistribute> calcProcMap
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch
|
||||
) const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
//- Local typedef to octree tree-type
|
||||
typedef treeDataPrimitivePatch<TargetPatch> treeType;
|
||||
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Reference to source patch
|
||||
const SourcePatch& srcPatch0_;
|
||||
|
||||
//- Reference to target patch
|
||||
const TargetPatch& tgtPatch0_;
|
||||
|
||||
//- Demand-driven extended target mesh (distributed parallel usage)
|
||||
autoPtr<TargetPatch> extendedTgtPatchPtr_;
|
||||
|
||||
//- Flag to indicate that the two patches are co-directional and
|
||||
//- that the orientation of the target patch should be reversed
|
||||
const bool reverseTarget_;
|
||||
|
||||
//- Flag to indicate that the two patches must be matched/an overlap
|
||||
//- exists between them
|
||||
const bool requireMatch_;
|
||||
|
||||
//- Labels of faces that are not overlapped by any target faces
|
||||
//- (should be empty for correct functioning for fully covered AMIs)
|
||||
labelList srcNonOverlap_;
|
||||
|
||||
//- Octree used to find face seeds
|
||||
autoPtr<indexedOctree<treeType>> treePtr_;
|
||||
|
||||
//- Face triangulation mode
|
||||
const faceAreaIntersect::triangulationMode triMode_;
|
||||
|
||||
//- Label of processor containing all meshes
|
||||
//- Note: set to -1 if distributed
|
||||
label singleMeshProc_;
|
||||
|
||||
mutable faceList newTgtFaces_;
|
||||
mutable pointField newTgtPoints_;
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
// Helper functions
|
||||
|
||||
//- Create a map that extends tgtPatch so that it covers srcPatch
|
||||
autoPtr<TargetPatch> createExtendedTgtPatch
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const globalIndex& globalTgtFaces,
|
||||
autoPtr<mapDistribute>& mapPtr,
|
||||
labelList& extendedTgtFaceIDs
|
||||
) const;
|
||||
|
||||
//- Check AMI patch coupling
|
||||
void checkPatches() const;
|
||||
|
||||
//- Initialise and return true if all ok
|
||||
bool initialise
|
||||
(
|
||||
labelListList& srcAddress,
|
||||
scalarListList& srcWeights,
|
||||
labelListList& tgtAddress,
|
||||
scalarListList& tgtWeights,
|
||||
label& srcFacei,
|
||||
label& tgtFacei
|
||||
);
|
||||
|
||||
//- Write triangle intersection to OBJ file
|
||||
void writeIntersectionOBJ
|
||||
(
|
||||
const scalar area,
|
||||
const face& f1,
|
||||
const face& f2,
|
||||
const pointField& f1Points,
|
||||
const pointField& f2Points
|
||||
) const;
|
||||
|
||||
|
||||
// Common AMI method functions
|
||||
|
||||
//- Reset the octree for the target patch face search
|
||||
template<class PatchType>
|
||||
autoPtr<indexedOctree<treeDataPrimitivePatch<PatchType>>>
|
||||
createTree
|
||||
(
|
||||
const PatchType& patch
|
||||
) const;
|
||||
|
||||
label findTargetFace
|
||||
(
|
||||
const label srcFacei,
|
||||
const UList<label>& excludeFaces = UList<label>::null(),
|
||||
const label srcFacePti = -1
|
||||
) const;
|
||||
|
||||
//- Add faces neighbouring facei to the ID list
|
||||
void appendNbrFaces
|
||||
(
|
||||
const label facei,
|
||||
const TargetPatch& patch,
|
||||
const DynamicList<label>& visitedFaces,
|
||||
DynamicList<label>& faceIDs
|
||||
) const;
|
||||
|
||||
//- Helper function to decompose a patch
|
||||
template<class PatchType>
|
||||
void triangulatePatch
|
||||
(
|
||||
const PatchType& patch,
|
||||
List<DynamicList<face>>& tris,
|
||||
List<scalar>& magSf
|
||||
) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("AMIMethod");
|
||||
|
||||
//- Declare runtime constructor selection table
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
AMIMethod,
|
||||
components,
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool reverseTarget,
|
||||
const bool requireMatch
|
||||
),
|
||||
(
|
||||
srcPatch,
|
||||
tgtPatch,
|
||||
triMode,
|
||||
reverseTarget,
|
||||
requireMatch
|
||||
)
|
||||
);
|
||||
|
||||
//- Construct from components
|
||||
AMIMethod
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool reverseTarget,
|
||||
const bool requireMatch
|
||||
);
|
||||
|
||||
//- Selector
|
||||
static autoPtr<AMIMethod> New
|
||||
(
|
||||
const word& methodName,
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool reverseTarget,
|
||||
const bool requireMatch
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~AMIMethod() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return const access to the source patch
|
||||
inline const SourcePatch& srcPatch() const;
|
||||
|
||||
//- Return const access to the target patch
|
||||
inline const TargetPatch& tgtPatch() const;
|
||||
|
||||
//- Return true if the patches are split across multiple processors
|
||||
inline bool distributed() const;
|
||||
|
||||
//- Labels of faces that are not overlapped by any target faces
|
||||
// Note: this should be empty for correct functioning
|
||||
inline const labelList& srcNonOverlap() const;
|
||||
|
||||
//- Flag to indicate that interpolation patches are conformal
|
||||
virtual bool conformal() const;
|
||||
|
||||
|
||||
// Manipulation
|
||||
|
||||
//- Update addressing and weights
|
||||
virtual bool calculate
|
||||
(
|
||||
labelListList& srcAddress,
|
||||
scalarListList& srcWeights,
|
||||
pointListList& srcCentroids,
|
||||
labelListList& tgtAddress,
|
||||
scalarListList& tgtWeights,
|
||||
scalarList& srcMagSf,
|
||||
scalarList& tgtMagSf,
|
||||
autoPtr<mapDistribute>& srcMapPtr,
|
||||
autoPtr<mapDistribute>& tgtMapPtr,
|
||||
label srcFacei = -1,
|
||||
label tgtFacei = -1
|
||||
) = 0;
|
||||
|
||||
//- Normalise the weight. Can optionally subset addressing
|
||||
//- (e.g. for mapNearest)
|
||||
virtual void normaliseWeights
|
||||
(
|
||||
const bool verbose,
|
||||
AMIInterpolation<SourcePatch, TargetPatch>& inter
|
||||
) = 0;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#define makeAMIMethod(AMIType) \
|
||||
\
|
||||
typedef AMIMethod<AMIType::sourcePatchType,AMIType::targetPatchType> \
|
||||
AMIMethod##AMIType; \
|
||||
\
|
||||
defineNamedTemplateTypeNameAndDebug(AMIMethod##AMIType, 0); \
|
||||
defineTemplateRunTimeSelectionTable(AMIMethod##AMIType, components);
|
||||
|
||||
|
||||
#define makeAMIMethodType(AMIType, Method) \
|
||||
\
|
||||
typedef Method<AMIType::sourcePatchType,AMIType::targetPatchType> \
|
||||
Method##AMIType; \
|
||||
\
|
||||
defineNamedTemplateTypeNameAndDebug(Method##AMIType, 0); \
|
||||
\
|
||||
AMIMethod<AMIType::sourcePatchType,AMIType::targetPatchType>:: \
|
||||
addcomponentsConstructorToTable<Method##AMIType> \
|
||||
add##Method##AMIType##ConstructorToTable_;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "AMIMethodI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "AMIMethod.C"
|
||||
#include "AMIMethodNew.C"
|
||||
#include "AMIMethodParallelOps.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,361 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "nearestFaceAMI.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::autoPtr<Foam::mapDistribute>
|
||||
Foam::nearestFaceAMI<SourcePatch, TargetPatch>::calcFaceMap
|
||||
(
|
||||
const List<nearestAndDist>& localInfo,
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch
|
||||
) const
|
||||
{
|
||||
// Generate the list of processor bounding boxes
|
||||
List<boundBox> procBbs(Pstream::nProcs());
|
||||
procBbs[Pstream::myProcNo()] =
|
||||
boundBox(srcPatch.points(), srcPatch.meshPoints(), true);
|
||||
Pstream::gatherList(procBbs);
|
||||
Pstream::scatterList(procBbs);
|
||||
|
||||
// Identify which of my local tgt faces intersect with each processor bb
|
||||
// within the current match's search distance
|
||||
const pointField& tgtCcs = tgtPatch.faceCentres();
|
||||
List<DynamicList<label>> dynSendMap(Pstream::nProcs());
|
||||
|
||||
forAll(localInfo, tgtFacei)
|
||||
{
|
||||
const scalar r2 = localInfo[tgtFacei].second();
|
||||
|
||||
// Construct local bounding box to test against processor bb
|
||||
forAll(procBbs, proci)
|
||||
{
|
||||
if (proci != Pstream::myProcNo())
|
||||
{
|
||||
if (procBbs[proci].overlaps(tgtCcs[tgtFacei], r2))
|
||||
{
|
||||
dynSendMap[proci].append(tgtFacei);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert dynamicList to labelList
|
||||
labelListList sendMap(Pstream::nProcs());
|
||||
forAll(sendMap, proci)
|
||||
{
|
||||
dynSendMap[proci].shrink();
|
||||
sendMap[proci].transfer(dynSendMap[proci]);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "send map - to proc " << proci << " sending "
|
||||
<< sendMap[proci].size() << " elements" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return autoPtr<mapDistribute>::New(std::move(sendMap));
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::autoPtr<Foam::mapDistribute>
|
||||
Foam::nearestFaceAMI<SourcePatch, TargetPatch>::calcDistributed
|
||||
(
|
||||
const SourcePatch& src,
|
||||
const TargetPatch& tgt,
|
||||
labelListList& srcToTgtAddr,
|
||||
scalarListList& srcToTgtWght
|
||||
) const
|
||||
{
|
||||
const auto tgtTreePtr = this->createTree(tgt);
|
||||
const auto& tgtTree = tgtTreePtr();
|
||||
|
||||
// Create global indexing for each patch
|
||||
globalIndex globalTgtCells(src.size());
|
||||
|
||||
// First pass: determine local matches
|
||||
|
||||
// Identify local nearest matches
|
||||
pointField srcCcs(src.faceCentres());
|
||||
|
||||
List<nearestAndDist> localInfo(src.size());
|
||||
forAll(srcCcs, srcCelli)
|
||||
{
|
||||
const point& srcCc = srcCcs[srcCelli];
|
||||
|
||||
pointIndexHit& test = localInfo[srcCelli].first();
|
||||
test = tgtTree.findNearest(srcCc, GREAT);
|
||||
|
||||
if (test.hit())
|
||||
{
|
||||
// With a search radius2 of GREAT all cells should receive a hit
|
||||
localInfo[srcCelli].second() = magSqr(srcCc - test.hitPoint());
|
||||
test.setIndex(globalTgtCells.toGlobal(test.index()));
|
||||
}
|
||||
}
|
||||
|
||||
// Second pass: determine remote matches
|
||||
|
||||
autoPtr<mapDistribute> mapPtr = calcFaceMap(localInfo, src, tgt);
|
||||
mapDistribute& map = mapPtr();
|
||||
|
||||
List<nearestAndDist> remoteInfo(localInfo);
|
||||
map.distribute(remoteInfo);
|
||||
|
||||
// Note: re-using srcCcs
|
||||
map.distribute(srcCcs);
|
||||
|
||||
// Test remote target cells against local source cells
|
||||
nearestAndDist testInfo;
|
||||
pointIndexHit& test = testInfo.first();
|
||||
forAll(remoteInfo, i)
|
||||
{
|
||||
test = tgtTree.findNearest(srcCcs[i], remoteInfo[i].second());
|
||||
if (test.hit())
|
||||
{
|
||||
testInfo.first().setIndex
|
||||
(
|
||||
globalTgtCells.toGlobal(test.index())
|
||||
);
|
||||
testInfo.second() = magSqr(test.hitPoint() - srcCcs[i]);
|
||||
nearestEqOp()(remoteInfo[i], testInfo);
|
||||
}
|
||||
}
|
||||
|
||||
// Send back to originating processor. Choose best if sent to multiple
|
||||
// processors. Note that afterwards all unused entries have the unique
|
||||
// value nearestZero (distance < 0). This is used later on to see if
|
||||
// the sample was sent to any processor.
|
||||
const nearestAndDist nearestZero(pointIndexHit(), -GREAT);
|
||||
mapDistributeBase::distribute
|
||||
(
|
||||
Pstream::commsTypes::nonBlocking,
|
||||
List<labelPair>(0),
|
||||
src.size(),
|
||||
map.constructMap(),
|
||||
map.constructHasFlip(),
|
||||
map.subMap(),
|
||||
map.subHasFlip(),
|
||||
remoteInfo,
|
||||
nearestEqOp(),
|
||||
noOp(), // no flipping
|
||||
nearestZero
|
||||
);
|
||||
|
||||
// Third pass: combine local and remote info and filter out any
|
||||
// connections that are further away than threshold distance squared
|
||||
srcToTgtAddr.setSize(src.size());
|
||||
srcToTgtWght.setSize(src.size());
|
||||
forAll(srcToTgtAddr, srcCelli)
|
||||
{
|
||||
nearestEqOp()(localInfo[srcCelli], remoteInfo[srcCelli]);
|
||||
if (localInfo[srcCelli].second() < maxDistance2_)
|
||||
{
|
||||
const label tgtCelli = localInfo[srcCelli].first().index();
|
||||
srcToTgtAddr[srcCelli] = labelList(1, tgtCelli);
|
||||
srcToTgtWght[srcCelli] = scalarList(1, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
List<Map<label>> cMap;
|
||||
return autoPtr<mapDistribute>::New(globalTgtCells, srcToTgtAddr, cMap);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::nearestFaceAMI<SourcePatch, TargetPatch>::nearestFaceAMI
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool reverseTarget,
|
||||
const bool requireMatch
|
||||
)
|
||||
:
|
||||
AMIMethod<SourcePatch, TargetPatch>
|
||||
(
|
||||
srcPatch,
|
||||
tgtPatch,
|
||||
triMode,
|
||||
reverseTarget,
|
||||
requireMatch
|
||||
),
|
||||
maxDistance2_(GREAT)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
bool Foam::nearestFaceAMI<SourcePatch, TargetPatch>::calculate
|
||||
(
|
||||
labelListList& srcAddress,
|
||||
scalarListList& srcWeights,
|
||||
pointListList& srcCentroids,
|
||||
labelListList& tgtAddress,
|
||||
scalarListList& tgtWeights,
|
||||
scalarList& srcMagSf,
|
||||
scalarList& tgtMagSf,
|
||||
autoPtr<mapDistribute>& srcMapPtr,
|
||||
autoPtr<mapDistribute>& tgtMapPtr,
|
||||
label srcFacei,
|
||||
label tgtFacei
|
||||
)
|
||||
{
|
||||
bool symmetric_ = true;
|
||||
|
||||
if (this->distributed())
|
||||
{
|
||||
tgtMapPtr =
|
||||
calcDistributed
|
||||
(
|
||||
this->srcPatch0_,
|
||||
this->tgtPatch0_,
|
||||
srcAddress,
|
||||
srcWeights
|
||||
);
|
||||
|
||||
if (symmetric_)
|
||||
{
|
||||
srcMapPtr =
|
||||
calcDistributed
|
||||
(
|
||||
this->tgtPatch0_,
|
||||
this->srcPatch0_,
|
||||
tgtAddress,
|
||||
tgtWeights
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
srcAddress.setSize(this->srcPatch0_.size());
|
||||
srcWeights.setSize(this->srcPatch0_.size());
|
||||
|
||||
if (symmetric_)
|
||||
{
|
||||
tgtAddress.setSize(this->tgtPatch0_.size());
|
||||
tgtWeights.setSize(this->tgtPatch0_.size());
|
||||
}
|
||||
|
||||
const pointField& srcCcs = this->srcPatch0_.faceCentres();
|
||||
const pointField& tgtCcs = this->tgtPatch0_.faceCentres();
|
||||
|
||||
const auto tgtTreePtr = this->createTree(this->tgtPatch0_);
|
||||
const auto& tgtTree = tgtTreePtr();
|
||||
|
||||
forAll(srcCcs, srcFacei)
|
||||
{
|
||||
const point& srcCc = srcCcs[srcFacei];
|
||||
const pointIndexHit hit = tgtTree.findNearest(srcCc, GREAT);
|
||||
|
||||
if
|
||||
(
|
||||
hit.hit()
|
||||
&& (magSqr(srcCc - tgtCcs[hit.index()]) < maxDistance2_)
|
||||
)
|
||||
{
|
||||
label tgtFacei = hit.index();
|
||||
srcAddress[srcFacei] = labelList(1, tgtFacei);
|
||||
srcWeights[srcFacei] = scalarList(1, 1.0);
|
||||
|
||||
if (symmetric_)
|
||||
{
|
||||
tgtAddress[tgtFacei] = labelList(1, srcFacei);
|
||||
tgtWeights[tgtFacei] = scalarList(1, 1.0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Unable to find target face for source face "
|
||||
<< srcFacei << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (symmetric_)
|
||||
{
|
||||
const auto srcTreePtr = this->createTree(this->srcPatch0_);
|
||||
const auto& srcTree = srcTreePtr();
|
||||
|
||||
// Check that all source cells have connections and populate any
|
||||
// missing entries
|
||||
forAll(tgtWeights, tgtCelli)
|
||||
{
|
||||
if (tgtAddress[tgtCelli].empty())
|
||||
{
|
||||
const point& tgtCc = tgtCcs[tgtCelli];
|
||||
pointIndexHit hit = srcTree.findNearest(tgtCc, GREAT);
|
||||
|
||||
if
|
||||
(
|
||||
hit.hit()
|
||||
&& (magSqr(tgtCc - srcCcs[hit.index()]) < maxDistance2_)
|
||||
)
|
||||
{
|
||||
tgtAddress[tgtCelli] = labelList(1, hit.index());
|
||||
tgtWeights[tgtCelli] = scalarList(1, 1.0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Unable to find source face for target face "
|
||||
<< tgtCelli << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::nearestFaceAMI<SourcePatch, TargetPatch>::normaliseWeights
|
||||
(
|
||||
const bool verbose,
|
||||
AMIInterpolation<SourcePatch, TargetPatch>& inter
|
||||
)
|
||||
{
|
||||
// Do nothing - weights already 1-to-1 and normalised
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,46 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013 OpenFOAM Foundation
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "AMIPatchToPatchInterpolation.H"
|
||||
#include "AMIMethod.H"
|
||||
#include "nearestFaceAMI.H"
|
||||
#include "faceAreaWeightAMI.H"
|
||||
#include "partialFaceAreaWeightAMI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
makeAMIMethod(AMIPatchToPatchInterpolation);
|
||||
|
||||
makeAMIMethodType(AMIPatchToPatchInterpolation, nearestFaceAMI);
|
||||
makeAMIMethodType(AMIPatchToPatchInterpolation, faceAreaWeightAMI);
|
||||
makeAMIMethodType(AMIPatchToPatchInterpolation, partialFaceAreaWeightAMI);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -30,14 +30,12 @@ License
|
||||
#define AMIPatchToPatchInterpolation_H
|
||||
|
||||
#include "AMIInterpolation.H"
|
||||
#include "primitivePatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
typedef AMIInterpolation<primitivePatch, primitivePatch>
|
||||
AMIPatchToPatchInterpolation;
|
||||
typedef AMIInterpolation AMIPatchToPatchInterpolation;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -26,17 +26,23 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "AMIMethod.H"
|
||||
#include "advancingFrontAMI.H"
|
||||
#include "meshTools.H"
|
||||
#include "mapDistribute.H"
|
||||
#include "unitConversion.H"
|
||||
|
||||
#include "findNearestMaskedOp.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(advancingFrontAMI, 0);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::AMIMethod<SourcePatch, TargetPatch>::checkPatches() const
|
||||
void Foam::advancingFrontAMI::checkPatches() const
|
||||
{
|
||||
const auto& src = srcPatch();
|
||||
const auto& tgt = tgtPatch();
|
||||
@ -75,101 +81,68 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::checkPatches() const
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::autoPtr<TargetPatch>
|
||||
Foam::AMIMethod<SourcePatch, TargetPatch>::createExtendedTgtPatch
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const globalIndex& globalTgtFaces,
|
||||
autoPtr<mapDistribute>& mapPtr,
|
||||
labelList& extendedTgtFaceIDs
|
||||
) const
|
||||
void Foam::advancingFrontAMI::createExtendedTgtPatch()
|
||||
{
|
||||
// Create a representation of the src mesh that is extended to overlap the
|
||||
// tgt mesh
|
||||
|
||||
// Create processor map of extended cells. This map gets (possibly
|
||||
// remote) cells from the src mesh such that they (together) cover
|
||||
// all of tgt
|
||||
mapPtr = calcProcMap(srcPatch, tgtPatch);
|
||||
const mapDistribute& map = mapPtr();
|
||||
extendedTgtMapPtr_.reset(calcProcMap(srcPatch0(), tgtPatch0()));
|
||||
const mapDistribute& map = extendedTgtMapPtr_();
|
||||
|
||||
// Create new target patch that fully encompasses source patch
|
||||
|
||||
// Faces and points
|
||||
// faceList newTgtFaces_;
|
||||
// pointField newTgtPoints_;
|
||||
|
||||
// Original faces from tgtPatch (in globalIndexing since might be
|
||||
// remote)
|
||||
// Original faces from tgtPatch
|
||||
// Note: in globalIndexing since might be remote
|
||||
globalIndex globalTgtFaces(tgtPatch0().size());
|
||||
distributeAndMergePatches
|
||||
(
|
||||
map,
|
||||
tgtPatch,
|
||||
tgtPatch0(),
|
||||
globalTgtFaces,
|
||||
newTgtFaces_,
|
||||
newTgtPoints_,
|
||||
extendedTgtFaceIDs
|
||||
extendedTgtFaces_,
|
||||
extendedTgtPoints_,
|
||||
extendedTgtFaceIDs_
|
||||
);
|
||||
|
||||
return autoPtr<TargetPatch>::New
|
||||
// Create a representation of the tgt patch that is extended to overlap
|
||||
// the src patch
|
||||
extendedTgtPatchPtr_.reset
|
||||
(
|
||||
SubList<face>
|
||||
autoPtr<primitivePatch>::New
|
||||
(
|
||||
newTgtFaces_,
|
||||
newTgtFaces_.size()
|
||||
),
|
||||
newTgtPoints_
|
||||
SubList<face>(extendedTgtFaces_),
|
||||
extendedTgtPoints_
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
bool Foam::AMIMethod<SourcePatch, TargetPatch>::initialise
|
||||
(
|
||||
labelListList& srcAddress,
|
||||
scalarListList& srcWeights,
|
||||
labelListList& tgtAddress,
|
||||
scalarListList& tgtWeights,
|
||||
label& srcFacei,
|
||||
label& tgtFacei
|
||||
)
|
||||
bool Foam::advancingFrontAMI::initialiseWalk(label& srcFacei, label& tgtFacei)
|
||||
{
|
||||
const auto& src = srcPatch();
|
||||
const auto& tgt = tgtPatch();
|
||||
const auto& src = this->srcPatch();
|
||||
const auto& tgt = this->tgtPatch();
|
||||
|
||||
checkPatches();
|
||||
|
||||
// Set initial sizes for weights and addressing - must be done even if
|
||||
// returns false below
|
||||
srcAddress.setSize(src.size());
|
||||
srcWeights.setSize(srcAddress.size());
|
||||
tgtAddress.setSize(tgt.size());
|
||||
tgtWeights.setSize(tgtAddress.size());
|
||||
bool foundFace = false;
|
||||
|
||||
// Check that patch sizes are valid
|
||||
if (!src.size())
|
||||
{
|
||||
return false;
|
||||
return foundFace;
|
||||
}
|
||||
else if (!tgt.size())
|
||||
{
|
||||
WarningInFunction
|
||||
<< src.size() << " source faces but no target faces" << endl;
|
||||
|
||||
return false;
|
||||
return foundFace;
|
||||
}
|
||||
|
||||
// Reset the octree
|
||||
treePtr_.reset(createTree<TargetPatch>(tgtPatch()));
|
||||
treePtr_.reset(createTree(tgt));
|
||||
|
||||
// Find initial face match using brute force/octree search
|
||||
if ((srcFacei == -1) || (tgtFacei == -1))
|
||||
{
|
||||
srcFacei = 0;
|
||||
tgtFacei = 0;
|
||||
bool foundFace = false;
|
||||
forAll(src, facei)
|
||||
{
|
||||
tgtFacei = findTargetFace(facei);
|
||||
@ -190,7 +163,7 @@ bool Foam::AMIMethod<SourcePatch, TargetPatch>::initialise
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return false;
|
||||
return foundFace;
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,8 +176,7 @@ bool Foam::AMIMethod<SourcePatch, TargetPatch>::initialise
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::AMIMethod<SourcePatch, TargetPatch>::writeIntersectionOBJ
|
||||
void Foam::advancingFrontAMI::writeIntersectionOBJ
|
||||
(
|
||||
const scalar area,
|
||||
const face& f1,
|
||||
@ -255,37 +227,7 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::writeIntersectionOBJ
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
template<class PatchType>
|
||||
Foam::autoPtr<Foam::indexedOctree<Foam::treeDataPrimitivePatch<PatchType>>>
|
||||
Foam::AMIMethod<SourcePatch, TargetPatch>::createTree
|
||||
(
|
||||
const PatchType& patch
|
||||
) const
|
||||
{
|
||||
typedef treeDataPrimitivePatch<PatchType> PatchTreeType;
|
||||
|
||||
treeBoundBox bb(patch.points(), patch.meshPoints());
|
||||
bb.inflate(0.01);
|
||||
|
||||
return autoPtr<indexedOctree<PatchTreeType>>::New
|
||||
(
|
||||
PatchTreeType
|
||||
(
|
||||
false,
|
||||
patch,
|
||||
indexedOctree<PatchTreeType>::perturbTol()
|
||||
),
|
||||
bb, // overall search domain
|
||||
8, // maxLevel
|
||||
10, // leaf size
|
||||
3.0 // duplicity
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::findTargetFace
|
||||
Foam::label Foam::advancingFrontAMI::findTargetFace
|
||||
(
|
||||
const label srcFacei,
|
||||
const UList<label>& excludeFaces,
|
||||
@ -299,9 +241,9 @@ Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::findTargetFace
|
||||
const pointField& srcPts = src.points();
|
||||
const face& srcFace = src[srcFacei];
|
||||
|
||||
findNearestMaskedOp<TargetPatch> fnOp(*treePtr_, excludeFaces);
|
||||
findNearestMaskedOp<primitivePatch> fnOp(*treePtr_, excludeFaces);
|
||||
|
||||
boundBox bb(srcPts, srcFace, false);
|
||||
const boundBox bb(srcPts, srcFace, false);
|
||||
|
||||
const point srcPt =
|
||||
srcFacePti == -1 ? bb.centre() : srcPts[srcFace[srcFacePti]];
|
||||
@ -325,11 +267,10 @@ Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::findTargetFace
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::AMIMethod<SourcePatch, TargetPatch>::appendNbrFaces
|
||||
void Foam::advancingFrontAMI::appendNbrFaces
|
||||
(
|
||||
const label facei,
|
||||
const TargetPatch& patch,
|
||||
const primitivePatch& patch,
|
||||
const DynamicList<label>& visitedFaces,
|
||||
DynamicList<label>& faceIDs
|
||||
) const
|
||||
@ -341,30 +282,8 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::appendNbrFaces
|
||||
// Filter out faces already visited from face neighbours
|
||||
for (const label nbrFacei : nbrFaces)
|
||||
{
|
||||
bool valid = true;
|
||||
for (const label visitedFacei : visitedFaces)
|
||||
{
|
||||
if (nbrFacei == visitedFacei)
|
||||
{
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid)
|
||||
{
|
||||
for (const label testFacei : faceIDs)
|
||||
{
|
||||
if (nbrFacei == testFacei)
|
||||
{
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent addition of face if it is not on the same plane-ish
|
||||
if (valid)
|
||||
if (!visitedFaces.found(nbrFacei) && !faceIDs.found(nbrFacei))
|
||||
{
|
||||
const vector& n1 = patch.faceNormals()[facei];
|
||||
const vector& n2 = patch.faceNormals()[nbrFacei];
|
||||
@ -380,11 +299,9 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::appendNbrFaces
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
template<class PatchType>
|
||||
void Foam::AMIMethod<SourcePatch, TargetPatch>::triangulatePatch
|
||||
void Foam::advancingFrontAMI::triangulatePatch
|
||||
(
|
||||
const PatchType& patch,
|
||||
const primitivePatch& patch,
|
||||
List<DynamicList<face>>& tris,
|
||||
List<scalar>& magSf
|
||||
) const
|
||||
@ -396,6 +313,8 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::triangulatePatch
|
||||
// Using methods that index into existing points
|
||||
forAll(patch, facei)
|
||||
{
|
||||
tris[facei].clear();
|
||||
|
||||
switch (triMode_)
|
||||
{
|
||||
case faceAreaIntersect::tmFan:
|
||||
@ -428,34 +347,114 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::triangulatePatch
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::AMIMethod<SourcePatch, TargetPatch>::AMIMethod
|
||||
Foam::advancingFrontAMI::advancingFrontAMI
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool reverseTarget,
|
||||
const bool requireMatch
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget
|
||||
)
|
||||
:
|
||||
srcPatch0_(srcPatch),
|
||||
tgtPatch0_(tgtPatch),
|
||||
AMIInterpolation(dict, reverseTarget),
|
||||
srcTris_(),
|
||||
tgtTris_(),
|
||||
extendedTgtPatchPtr_(nullptr),
|
||||
reverseTarget_(reverseTarget),
|
||||
requireMatch_(requireMatch),
|
||||
extendedTgtFaces_(),
|
||||
extendedTgtPoints_(),
|
||||
extendedTgtFaceIDs_(),
|
||||
extendedTgtMapPtr_(nullptr),
|
||||
srcNonOverlap_(),
|
||||
triMode_(triMode),
|
||||
singleMeshProc_(calcDistribution(srcPatch, tgtPatch))
|
||||
{
|
||||
// Note: setting srcMagSf and tgtMagSf to 1 by default for 1-to-1 methods
|
||||
// - others will need to overwrite as necessary
|
||||
}
|
||||
triMode_
|
||||
(
|
||||
faceAreaIntersect::triangulationModeNames_.getOrDefault
|
||||
(
|
||||
"triMode",
|
||||
dict,
|
||||
faceAreaIntersect::tmMesh
|
||||
)
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
Foam::advancingFrontAMI::advancingFrontAMI
|
||||
(
|
||||
const bool requireMatch,
|
||||
const bool reverseTarget,
|
||||
const scalar lowWeightCorrection,
|
||||
const faceAreaIntersect::triangulationMode triMode
|
||||
)
|
||||
:
|
||||
AMIInterpolation(requireMatch, reverseTarget, lowWeightCorrection),
|
||||
srcTris_(),
|
||||
tgtTris_(),
|
||||
extendedTgtPatchPtr_(nullptr),
|
||||
extendedTgtFaces_(),
|
||||
extendedTgtPoints_(),
|
||||
extendedTgtFaceIDs_(),
|
||||
extendedTgtMapPtr_(nullptr),
|
||||
srcNonOverlap_(),
|
||||
triMode_(triMode)
|
||||
{}
|
||||
|
||||
|
||||
Foam::advancingFrontAMI::advancingFrontAMI(const advancingFrontAMI& ami)
|
||||
:
|
||||
AMIInterpolation(ami),
|
||||
srcTris_(),
|
||||
tgtTris_(),
|
||||
extendedTgtPatchPtr_(nullptr),
|
||||
extendedTgtFaces_(),
|
||||
extendedTgtPoints_(),
|
||||
extendedTgtFaceIDs_(),
|
||||
extendedTgtMapPtr_(nullptr),
|
||||
srcNonOverlap_(),
|
||||
triMode_(ami.triMode_)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
bool Foam::AMIMethod<SourcePatch, TargetPatch>::conformal() const
|
||||
bool Foam::advancingFrontAMI::calculate
|
||||
(
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr
|
||||
)
|
||||
{
|
||||
if (AMIInterpolation::calculate(srcPatch, tgtPatch, surfPtr))
|
||||
{
|
||||
// Create a representation of the target patch that covers the source patch
|
||||
if (distributed())
|
||||
{
|
||||
createExtendedTgtPatch();
|
||||
}
|
||||
|
||||
const auto& src = this->srcPatch();
|
||||
const auto& tgt = this->tgtPatch();
|
||||
|
||||
// Initialise area magnitudes
|
||||
srcMagSf_.setSize(src.size(), 1.0);
|
||||
tgtMagSf_.setSize(tgt.size(), 1.0);
|
||||
|
||||
// Source and target patch triangulations
|
||||
triangulatePatch(src, srcTris_, srcMagSf_);
|
||||
triangulatePatch(tgt, tgtTris_, tgtMagSf_);
|
||||
|
||||
checkPatches();
|
||||
|
||||
// Set initial sizes for weights and addressing - must be done even if
|
||||
// returns false below
|
||||
srcAddress_.setSize(src.size());
|
||||
srcWeights_.setSize(src.size());
|
||||
tgtAddress_.setSize(tgt.size());
|
||||
tgtWeights_.setSize(tgt.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::advancingFrontAMI::conformal() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -0,0 +1,271 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::advancingFrontAMI
|
||||
|
||||
Description
|
||||
Base class for Arbitrary Mesh Interface (AMI) methods
|
||||
|
||||
SourceFiles
|
||||
advancingFrontAMI.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef advancingFrontAMI_H
|
||||
#define advancingFrontAMI_H
|
||||
|
||||
#include "className.H"
|
||||
#include "DynamicList.H"
|
||||
#include "faceAreaIntersect.H"
|
||||
#include "pointList.H"
|
||||
#include "AMIInterpolation.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class advancingFrontAMI Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class advancingFrontAMI
|
||||
:
|
||||
public AMIInterpolation
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const advancingFrontAMI&) = delete;
|
||||
|
||||
|
||||
// Parallel operations
|
||||
|
||||
label calcOverlappingProcs
|
||||
(
|
||||
const List<treeBoundBoxList>& procBb,
|
||||
const treeBoundBox& bb,
|
||||
boolList& overlaps
|
||||
) const;
|
||||
|
||||
void distributePatches
|
||||
(
|
||||
const mapDistribute& map,
|
||||
const primitivePatch& pp,
|
||||
const globalIndex& gi,
|
||||
List<faceList>& faces,
|
||||
List<pointField>& points,
|
||||
List<labelList>& tgtFaceIDs
|
||||
) const;
|
||||
|
||||
void distributeAndMergePatches
|
||||
(
|
||||
const mapDistribute& map,
|
||||
const primitivePatch& tgtPatch,
|
||||
const globalIndex& gi,
|
||||
faceList& tgtFaces,
|
||||
pointField& tgtPoints,
|
||||
labelList& tgtFaceIDs
|
||||
) const;
|
||||
|
||||
autoPtr<mapDistribute> calcProcMap
|
||||
(
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch
|
||||
) const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Storage for src-side triangle decomposition
|
||||
List<DynamicList<face>> srcTris_;
|
||||
|
||||
//- Storage for tgt-side triangle decomposition
|
||||
List<DynamicList<face>> tgtTris_;
|
||||
|
||||
//- Demand-driven extended target mesh (distributed parallel usage)
|
||||
autoPtr<primitivePatch> extendedTgtPatchPtr_;
|
||||
|
||||
//- Extended patch faces
|
||||
faceList extendedTgtFaces_;
|
||||
|
||||
//- Extended patch points
|
||||
pointField extendedTgtPoints_;
|
||||
|
||||
//- Extended patch face IDs
|
||||
labelList extendedTgtFaceIDs_;
|
||||
|
||||
//- Extended patch map
|
||||
autoPtr<mapDistribute> extendedTgtMapPtr_;
|
||||
|
||||
//- Labels of faces that are not overlapped by any target faces
|
||||
//- (should be empty for correct functioning for fully covered AMIs)
|
||||
labelList srcNonOverlap_;
|
||||
|
||||
//- Octree used to find face seeds
|
||||
autoPtr<indexedOctree<treeType>> treePtr_;
|
||||
|
||||
//- Face triangulation mode
|
||||
const faceAreaIntersect::triangulationMode triMode_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
// Helper functions
|
||||
|
||||
//- Create a map that extends tgtPatch so that it covers srcPatch
|
||||
void createExtendedTgtPatch();
|
||||
|
||||
//- Check AMI patch coupling
|
||||
void checkPatches() const;
|
||||
|
||||
virtual bool calculate
|
||||
(
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr = nullptr
|
||||
);
|
||||
|
||||
//- Initialise walk and return true if all ok
|
||||
bool initialiseWalk
|
||||
(
|
||||
label& srcFacei,
|
||||
label& tgtFacei
|
||||
);
|
||||
|
||||
//- Write triangle intersection to OBJ file
|
||||
void writeIntersectionOBJ
|
||||
(
|
||||
const scalar area,
|
||||
const face& f1,
|
||||
const face& f2,
|
||||
const pointField& f1Points,
|
||||
const pointField& f2Points
|
||||
) const;
|
||||
|
||||
|
||||
// Common AMI method functions
|
||||
|
||||
label findTargetFace
|
||||
(
|
||||
const label srcFacei,
|
||||
const UList<label>& excludeFaces = UList<label>::null(),
|
||||
const label srcFacePti = -1
|
||||
) const;
|
||||
|
||||
//- Add faces neighbouring facei to the ID list
|
||||
void appendNbrFaces
|
||||
(
|
||||
const label facei,
|
||||
const primitivePatch& patch,
|
||||
const DynamicList<label>& visitedFaces,
|
||||
DynamicList<label>& faceIDs
|
||||
) const;
|
||||
|
||||
//- Helper function to decompose a patch
|
||||
void triangulatePatch
|
||||
(
|
||||
const primitivePatch& patch,
|
||||
List<DynamicList<face>>& tris,
|
||||
List<scalar>& magSf
|
||||
) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("advancingFrontAMI");
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
advancingFrontAMI
|
||||
(
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget
|
||||
);
|
||||
|
||||
//- Construct from components
|
||||
advancingFrontAMI
|
||||
(
|
||||
const bool requireMatch = true,
|
||||
const bool reverseTarget = false,
|
||||
const scalar lowWeightCorrection = -1,
|
||||
const faceAreaIntersect::triangulationMode triMode =
|
||||
faceAreaIntersect::tmMesh
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
advancingFrontAMI(const advancingFrontAMI& ami);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual autoPtr<AMIInterpolation> clone() const
|
||||
{
|
||||
return autoPtr<AMIInterpolation>(new advancingFrontAMI(*this));
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~advancingFrontAMI() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return const access to the source patch
|
||||
inline const primitivePatch& srcPatch() const;
|
||||
|
||||
//- Return const access to the target patch
|
||||
inline const primitivePatch& tgtPatch() const;
|
||||
|
||||
//- Labels of faces that are not overlapped by any target faces
|
||||
// Note: this should be empty for correct functioning
|
||||
inline const labelList& srcNonOverlap() const;
|
||||
|
||||
//- Flag to indicate that interpolation patches are conformal, i.e.
|
||||
//- should fully cover each other
|
||||
virtual bool conformal() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "advancingFrontAMII.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013 OpenFOAM Foundation
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -25,37 +25,38 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const SourcePatch&
|
||||
Foam::AMIMethod<SourcePatch, TargetPatch>::srcPatch() const
|
||||
inline const Foam::primitivePatch& Foam::advancingFrontAMI::srcPatch() const
|
||||
{
|
||||
return srcPatch0_;
|
||||
if (!tsrcPatch0_.valid())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "tsrcPatch0_ not allocated"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return tsrcPatch0_();
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const TargetPatch&
|
||||
Foam::AMIMethod<SourcePatch, TargetPatch>::tgtPatch() const
|
||||
inline const Foam::primitivePatch& Foam::advancingFrontAMI::tgtPatch() const
|
||||
{
|
||||
if (extendedTgtPatchPtr_)
|
||||
{
|
||||
return extendedTgtPatchPtr_();
|
||||
}
|
||||
|
||||
return tgtPatch0_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
bool Foam::AMIMethod<SourcePatch, TargetPatch>::distributed() const
|
||||
if (!ttgtPatch0_.valid())
|
||||
{
|
||||
return singleMeshProc_ == -1;
|
||||
FatalErrorInFunction
|
||||
<< "srcPatch0Ptr not allocated"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return ttgtPatch0_();
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::labelList&
|
||||
Foam::AMIMethod<SourcePatch, TargetPatch>::srcNonOverlap() const
|
||||
inline const Foam::labelList& Foam::advancingFrontAMI::srcNonOverlap() const
|
||||
{
|
||||
return srcNonOverlap_;
|
||||
}
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2018-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -25,60 +25,15 @@ License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "advancingFrontAMI.H"
|
||||
#include "mergePoints.H"
|
||||
#include "mapDistribute.H"
|
||||
#include "AABBTree.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::calcDistribution
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch
|
||||
) const
|
||||
{
|
||||
label proci = 0;
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
labelList facesPresentOnProc(Pstream::nProcs(), Zero);
|
||||
if ((srcPatch.size() > 0) || (tgtPatch.size() > 0))
|
||||
{
|
||||
facesPresentOnProc[Pstream::myProcNo()] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
facesPresentOnProc[Pstream::myProcNo()] = 0;
|
||||
}
|
||||
|
||||
Pstream::gatherList(facesPresentOnProc);
|
||||
Pstream::scatterList(facesPresentOnProc);
|
||||
|
||||
label nHaveFaces = sum(facesPresentOnProc);
|
||||
|
||||
if (nHaveFaces > 1)
|
||||
{
|
||||
proci = -1;
|
||||
DebugInFunction
|
||||
<< "AMI split across multiple processors" << endl;
|
||||
}
|
||||
else if (nHaveFaces == 1)
|
||||
{
|
||||
proci = facesPresentOnProc.find(1);
|
||||
DebugInFunction
|
||||
<< "AMI local to processor" << proci << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Either not parallel or no faces on any processor
|
||||
return proci;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::calcOverlappingProcs
|
||||
Foam::label Foam::advancingFrontAMI::calcOverlappingProcs
|
||||
(
|
||||
const List<treeBoundBoxList>& procBb,
|
||||
const treeBoundBox& bb,
|
||||
@ -109,11 +64,10 @@ Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::calcOverlappingProcs
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::AMIMethod<SourcePatch, TargetPatch>::distributePatches
|
||||
void Foam::advancingFrontAMI::distributePatches
|
||||
(
|
||||
const mapDistribute& map,
|
||||
const TargetPatch& pp,
|
||||
const primitivePatch& pp,
|
||||
const globalIndex& gi,
|
||||
List<faceList>& faces,
|
||||
List<pointField>& points,
|
||||
@ -194,12 +148,10 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::distributePatches
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::AMIMethod<SourcePatch, TargetPatch>::
|
||||
distributeAndMergePatches
|
||||
void Foam::advancingFrontAMI::distributeAndMergePatches
|
||||
(
|
||||
const mapDistribute& map,
|
||||
const TargetPatch& tgtPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const globalIndex& gi,
|
||||
faceList& tgtFaces,
|
||||
pointField& tgtPoints,
|
||||
@ -308,12 +260,10 @@ distributeAndMergePatches
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::autoPtr<Foam::mapDistribute>
|
||||
Foam::AMIMethod<SourcePatch, TargetPatch>::calcProcMap
|
||||
Foam::autoPtr<Foam::mapDistribute> Foam::advancingFrontAMI::calcProcMap
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch
|
||||
) const
|
||||
{
|
||||
// Get decomposition of patch
|
||||
@ -29,41 +29,20 @@ License
|
||||
#include "faceAreaWeightAMI.H"
|
||||
#include "profiling.H"
|
||||
#include "OBJstream.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(faceAreaWeightAMI, 0);
|
||||
addToRunTimeSelectionTable(AMIInterpolation, faceAreaWeightAMI, dict);
|
||||
addToRunTimeSelectionTable(AMIInterpolation, faceAreaWeightAMI, component);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::initGeom
|
||||
(
|
||||
const globalIndex& globalTgtFaces,
|
||||
labelList& extendedTgtFaceIDs
|
||||
)
|
||||
{
|
||||
// Create a representation of the target patch that covers the source patch
|
||||
if (this->distributed())
|
||||
{
|
||||
this->extendedTgtPatchPtr_ =
|
||||
this->createExtendedTgtPatch
|
||||
(
|
||||
this->srcPatch0_,
|
||||
this->tgtPatch0_,
|
||||
globalTgtFaces,
|
||||
extendedTgtMapPtr_,
|
||||
extendedTgtFaceIDs
|
||||
);
|
||||
}
|
||||
|
||||
const auto& src = this->srcPatch();
|
||||
const auto& tgt = this->tgtPatch();
|
||||
|
||||
// Initialise area magnitudes
|
||||
srcMagSf_.setSize(src.size(), 1.0);
|
||||
tgtMagSf_.setSize(tgt.size(), 1.0);
|
||||
|
||||
// Source and target patch triangulations
|
||||
this->triangulatePatch(src, srcTris_, srcMagSf_);
|
||||
this->triangulatePatch(tgt, tgtTris_, tgtMagSf_);
|
||||
|
||||
/*
|
||||
if (debug)
|
||||
{
|
||||
static label nAMI = 0;
|
||||
@ -99,11 +78,10 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::initGeom
|
||||
|
||||
++nAMI;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing
|
||||
void Foam::faceAreaWeightAMI::calcAddressing
|
||||
(
|
||||
List<DynamicList<label>>& srcAddr,
|
||||
List<DynamicList<scalar>>& srcWght,
|
||||
@ -116,27 +94,28 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing
|
||||
{
|
||||
addProfiling(ami, "faceAreaWeightAMI::calcAddressing");
|
||||
|
||||
// construct weights and addressing
|
||||
// Construct weights and addressing
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
label nFacesRemaining = srcAddr.size();
|
||||
|
||||
// list of tgt face neighbour faces
|
||||
// List of tgt face neighbour faces
|
||||
DynamicList<label> nbrFaces(10);
|
||||
|
||||
// list of faces currently visited for srcFacei to avoid multiple hits
|
||||
// List of faces currently visited for srcFacei to avoid multiple hits
|
||||
DynamicList<label> visitedFaces(10);
|
||||
|
||||
// list to keep track of tgt faces used to seed src faces
|
||||
// List to keep track of tgt faces used to seed src faces
|
||||
labelList seedFaces(nFacesRemaining, -1);
|
||||
seedFaces[srcFacei] = tgtFacei;
|
||||
|
||||
// list to keep track of whether src face can be mapped
|
||||
// List to keep track of whether src face can be mapped
|
||||
bitSet mapFlag(nFacesRemaining, true);
|
||||
|
||||
// reset starting seed
|
||||
// Reset starting seed
|
||||
label startSeedi = 0;
|
||||
|
||||
bool continueWalk = true;
|
||||
DynamicList<label> nonOverlapFaces;
|
||||
do
|
||||
{
|
||||
@ -161,34 +140,30 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing
|
||||
|
||||
mapFlag.unset(srcFacei);
|
||||
|
||||
nFacesRemaining--;
|
||||
|
||||
if (!faceProcessed)
|
||||
{
|
||||
nonOverlapFaces.append(srcFacei);
|
||||
}
|
||||
|
||||
// choose new src face from current src face neighbour
|
||||
if (nFacesRemaining > 0)
|
||||
{
|
||||
setNextFaces
|
||||
// Choose new src face from current src face neighbour
|
||||
continueWalk = setNextFaces
|
||||
(
|
||||
startSeedi,
|
||||
srcFacei,
|
||||
tgtFacei,
|
||||
mapFlag,
|
||||
seedFaces,
|
||||
visitedFaces
|
||||
visitedFaces,
|
||||
requireMatch_ && (lowWeightCorrection_ < 0)
|
||||
// pass in nonOverlapFaces for failed tree search?
|
||||
);
|
||||
}
|
||||
} while (nFacesRemaining > 0);
|
||||
} while (continueWalk);
|
||||
|
||||
this->srcNonOverlap_.transfer(nonOverlapFaces);
|
||||
srcNonOverlap_.transfer(nonOverlapFaces);
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
|
||||
bool Foam::faceAreaWeightAMI::processSourceFace
|
||||
(
|
||||
const label srcFacei,
|
||||
const label tgtStartFacei,
|
||||
@ -213,15 +188,11 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& tgtPatch = this->tgtPatch();
|
||||
|
||||
// append initial target face and neighbours
|
||||
nbrFaces.append(tgtStartFacei);
|
||||
this->appendNbrFaces
|
||||
(
|
||||
tgtStartFacei,
|
||||
this->tgtPatch(),
|
||||
visitedFaces,
|
||||
nbrFaces
|
||||
);
|
||||
appendNbrFaces(tgtStartFacei, tgtPatch, visitedFaces, nbrFaces);
|
||||
|
||||
bool faceProcessed = false;
|
||||
|
||||
@ -238,11 +209,7 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
|
||||
calcInterArea(srcFacei, tgtFacei, interArea, interCentroid);
|
||||
|
||||
// store when intersection fractional area > tolerance
|
||||
if
|
||||
(
|
||||
interArea/this->srcMagSf_[srcFacei]
|
||||
> faceAreaIntersect::tolerance()
|
||||
)
|
||||
if (interArea/srcMagSf_[srcFacei] > faceAreaIntersect::tolerance())
|
||||
{
|
||||
srcAddr[srcFacei].append(tgtFacei);
|
||||
srcWght[srcFacei].append(interArea);
|
||||
@ -251,13 +218,7 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
|
||||
tgtAddr[tgtFacei].append(srcFacei);
|
||||
tgtWght[tgtFacei].append(interArea);
|
||||
|
||||
this->appendNbrFaces
|
||||
(
|
||||
tgtFacei,
|
||||
this->tgtPatch(),
|
||||
visitedFaces,
|
||||
nbrFaces
|
||||
);
|
||||
appendNbrFaces(tgtFacei, tgtPatch, visitedFaces, nbrFaces);
|
||||
|
||||
faceProcessed = true;
|
||||
|
||||
@ -275,8 +236,7 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
|
||||
bool Foam::faceAreaWeightAMI::setNextFaces
|
||||
(
|
||||
label& startSeedi,
|
||||
label& srcFacei,
|
||||
@ -289,12 +249,18 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
|
||||
{
|
||||
addProfiling(ami, "faceAreaWeightAMI::setNextFaces");
|
||||
|
||||
if (mapFlag.count() == 0)
|
||||
{
|
||||
// No more faces to map
|
||||
return false;
|
||||
}
|
||||
|
||||
const labelList& srcNbrFaces = this->srcPatch().faceFaces()[srcFacei];
|
||||
|
||||
// initialise tgtFacei
|
||||
// Initialise tgtFacei
|
||||
tgtFacei = -1;
|
||||
|
||||
// set possible seeds for later use
|
||||
// Set possible seeds for later use
|
||||
bool valuesSet = false;
|
||||
for (label faceS: srcNbrFaces)
|
||||
{
|
||||
@ -303,7 +269,7 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
|
||||
for (label faceT : visitedFaces)
|
||||
{
|
||||
const scalar threshold =
|
||||
this->srcMagSf_[faceS]*faceAreaIntersect::tolerance();
|
||||
srcMagSf_[faceS]*faceAreaIntersect::tolerance();
|
||||
|
||||
// Store when intersection fractional area > threshold
|
||||
if (overlaps(faceS, faceT, threshold))
|
||||
@ -321,14 +287,13 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
|
||||
}
|
||||
}
|
||||
|
||||
// set next src and tgt faces if not set above
|
||||
if (valuesSet)
|
||||
{
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// try to use existing seed
|
||||
|
||||
// Set next src and tgt faces if not set above
|
||||
// - try to use existing seed
|
||||
label facei = startSeedi;
|
||||
if (!mapFlag.test(startSeedi))
|
||||
{
|
||||
@ -350,13 +315,13 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
|
||||
srcFacei = facei;
|
||||
tgtFacei = seedFaces[facei];
|
||||
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
facei = mapFlag.find_next(facei);
|
||||
}
|
||||
|
||||
// perform new search to find match
|
||||
// Perform new search to find match
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "Advancing front stalled: searching for new "
|
||||
@ -367,11 +332,11 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
|
||||
while (facei != -1)
|
||||
{
|
||||
srcFacei = facei;
|
||||
tgtFacei = this->findTargetFace(srcFacei, visitedFaces);
|
||||
tgtFacei = findTargetFace(srcFacei, visitedFaces);
|
||||
|
||||
if (tgtFacei >= 0)
|
||||
{
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
facei = mapFlag.find_next(facei);
|
||||
@ -380,14 +345,15 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
|
||||
if (errorOnNotFound)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unable to set source and target faces" << abort(FatalError);
|
||||
}
|
||||
<< "Unable to set target face for source face " << srcFacei
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcInterArea
|
||||
void Foam::faceAreaWeightAMI::calcInterArea
|
||||
(
|
||||
const label srcFacei,
|
||||
const label tgtFacei,
|
||||
@ -397,46 +363,48 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcInterArea
|
||||
{
|
||||
addProfiling(ami, "faceAreaWeightAMI::interArea");
|
||||
|
||||
const pointField& srcPoints = this->srcPatch().points();
|
||||
const pointField& tgtPoints = this->tgtPatch().points();
|
||||
|
||||
// references to candidate faces
|
||||
const face& src = this->srcPatch()[srcFacei];
|
||||
const face& tgt = this->tgtPatch()[tgtFacei];
|
||||
|
||||
// quick reject if either face has zero area
|
||||
// Quick reject if either face has zero area
|
||||
if
|
||||
(
|
||||
(this->srcMagSf_[srcFacei] < ROOTVSMALL)
|
||||
|| (this->tgtMagSf_[tgtFacei] < ROOTVSMALL)
|
||||
(srcMagSf_[srcFacei] < ROOTVSMALL)
|
||||
|| (tgtMagSf_[tgtFacei] < ROOTVSMALL)
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// create intersection object
|
||||
const auto& srcPatch = this->srcPatch();
|
||||
const auto& tgtPatch = this->tgtPatch();
|
||||
|
||||
const pointField& srcPoints = srcPatch.points();
|
||||
const pointField& tgtPoints = tgtPatch.points();
|
||||
|
||||
// Create intersection object
|
||||
faceAreaIntersect inter
|
||||
(
|
||||
srcPoints,
|
||||
tgtPoints,
|
||||
this->srcTris_[srcFacei],
|
||||
this->tgtTris_[tgtFacei],
|
||||
this->reverseTarget_,
|
||||
AMIInterpolation<SourcePatch, TargetPatch>::cacheIntersections_
|
||||
srcTris_[srcFacei],
|
||||
tgtTris_[tgtFacei],
|
||||
reverseTarget_,
|
||||
AMIInterpolation::cacheIntersections_
|
||||
);
|
||||
|
||||
// crude resultant norm
|
||||
vector n(-this->srcPatch().faceNormals()[srcFacei]);
|
||||
if (this->reverseTarget_)
|
||||
// Crude resultant norm
|
||||
vector n(-srcPatch.faceNormals()[srcFacei]);
|
||||
if (reverseTarget_)
|
||||
{
|
||||
n -= this->tgtPatch().faceNormals()[tgtFacei];
|
||||
n -= tgtPatch.faceNormals()[tgtFacei];
|
||||
}
|
||||
else
|
||||
{
|
||||
n += this->tgtPatch().faceNormals()[tgtFacei];
|
||||
n += tgtPatch.faceNormals()[tgtFacei];
|
||||
}
|
||||
scalar magN = mag(n);
|
||||
|
||||
const face& src = srcPatch[srcFacei];
|
||||
const face& tgt = tgtPatch[tgtFacei];
|
||||
|
||||
if (magN > ROOTVSMALL)
|
||||
{
|
||||
inter.calc(src, tgt, n/magN, area, centroid);
|
||||
@ -451,11 +419,7 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcInterArea
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
AMIInterpolation<SourcePatch, TargetPatch>::cacheIntersections_
|
||||
&& debug
|
||||
)
|
||||
if (AMIInterpolation::cacheIntersections_ && debug)
|
||||
{
|
||||
static OBJstream tris("intersectionTris.obj");
|
||||
const auto& triPts = inter.triangles();
|
||||
@ -467,58 +431,59 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcInterArea
|
||||
|
||||
if ((debug > 1) && (area > 0))
|
||||
{
|
||||
this->writeIntersectionOBJ(area, src, tgt, srcPoints, tgtPoints);
|
||||
writeIntersectionOBJ(area, src, tgt, srcPoints, tgtPoints);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::overlaps
|
||||
bool Foam::faceAreaWeightAMI::overlaps
|
||||
(
|
||||
const label srcFacei,
|
||||
const label tgtFacei,
|
||||
const scalar threshold
|
||||
) const
|
||||
{
|
||||
const pointField& srcPoints = this->srcPatch().points();
|
||||
const pointField& tgtPoints = this->tgtPatch().points();
|
||||
|
||||
// references to candidate faces
|
||||
const face& src = this->srcPatch()[srcFacei];
|
||||
const face& tgt = this->tgtPatch()[tgtFacei];
|
||||
|
||||
// quick reject if either face has zero area
|
||||
// Quick reject if either face has zero area
|
||||
if
|
||||
(
|
||||
(this->srcMagSf_[srcFacei] < ROOTVSMALL)
|
||||
|| (this->tgtMagSf_[tgtFacei] < ROOTVSMALL)
|
||||
(srcMagSf_[srcFacei] < ROOTVSMALL)
|
||||
|| (tgtMagSf_[tgtFacei] < ROOTVSMALL)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& srcPatch = this->srcPatch();
|
||||
const auto& tgtPatch = this->tgtPatch();
|
||||
|
||||
const pointField& srcPoints = srcPatch.points();
|
||||
const pointField& tgtPoints = tgtPatch.points();
|
||||
|
||||
faceAreaIntersect inter
|
||||
(
|
||||
srcPoints,
|
||||
tgtPoints,
|
||||
this->srcTris_[srcFacei],
|
||||
this->tgtTris_[tgtFacei],
|
||||
this->reverseTarget_,
|
||||
AMIInterpolation<SourcePatch, TargetPatch>::cacheIntersections_
|
||||
srcTris_[srcFacei],
|
||||
tgtTris_[tgtFacei],
|
||||
reverseTarget_,
|
||||
AMIInterpolation::cacheIntersections_
|
||||
);
|
||||
|
||||
// crude resultant norm
|
||||
vector n(-this->srcPatch().faceNormals()[srcFacei]);
|
||||
if (this->reverseTarget_)
|
||||
// Crude resultant norm
|
||||
vector n(-srcPatch.faceNormals()[srcFacei]);
|
||||
if (reverseTarget_)
|
||||
{
|
||||
n -= this->tgtPatch().faceNormals()[tgtFacei];
|
||||
n -= tgtPatch.faceNormals()[tgtFacei];
|
||||
}
|
||||
else
|
||||
{
|
||||
n += this->tgtPatch().faceNormals()[tgtFacei];
|
||||
n += tgtPatch.faceNormals()[tgtFacei];
|
||||
}
|
||||
scalar magN = mag(n);
|
||||
|
||||
const face& src = srcPatch[srcFacei];
|
||||
const face& tgt = tgtPatch[tgtFacei];
|
||||
|
||||
if (magN > ROOTVSMALL)
|
||||
{
|
||||
return inter.overlaps(src, tgt, n/magN, threshold);
|
||||
@ -537,9 +502,7 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::overlaps
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::
|
||||
restartUncoveredSourceFace
|
||||
void Foam::faceAreaWeightAMI::restartUncoveredSourceFace
|
||||
(
|
||||
List<DynamicList<label>>& srcAddr,
|
||||
List<DynamicList<scalar>>& srcWght,
|
||||
@ -555,27 +518,29 @@ restartUncoveredSourceFace
|
||||
label nBelowMinWeight = 0;
|
||||
const scalar minWeight = 0.95;
|
||||
|
||||
// list of tgt face neighbour faces
|
||||
// List of tgt face neighbour faces
|
||||
DynamicList<label> nbrFaces(10);
|
||||
|
||||
// list of faces currently visited for srcFacei to avoid multiple hits
|
||||
// List of faces currently visited for srcFacei to avoid multiple hits
|
||||
DynamicList<label> visitedFaces(10);
|
||||
|
||||
const auto& srcPatch = this->srcPatch();
|
||||
|
||||
forAll(srcWght, srcFacei)
|
||||
{
|
||||
const scalar s = sum(srcWght[srcFacei]);
|
||||
const scalar t = s/this->srcMagSf_[srcFacei];
|
||||
const scalar t = s/srcMagSf_[srcFacei];
|
||||
|
||||
if (t < minWeight)
|
||||
{
|
||||
++nBelowMinWeight;
|
||||
|
||||
const face& f = this->srcPatch()[srcFacei];
|
||||
const face& f = srcPatch[srcFacei];
|
||||
|
||||
forAll(f, fpi)
|
||||
{
|
||||
const label tgtFacei =
|
||||
this->findTargetFace(srcFacei, srcAddr[srcFacei], fpi);
|
||||
findTargetFace(srcFacei, srcAddr[srcFacei], fpi);
|
||||
|
||||
if (tgtFacei != -1)
|
||||
{
|
||||
@ -613,77 +578,74 @@ restartUncoveredSourceFace
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::faceAreaWeightAMI
|
||||
Foam::faceAreaWeightAMI::faceAreaWeightAMI
|
||||
(
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget
|
||||
)
|
||||
:
|
||||
advancingFrontAMI(dict, reverseTarget),
|
||||
restartUncoveredSourceFace_
|
||||
(
|
||||
dict.getOrDefault("restartUncoveredSourceFace", true)
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
Foam::faceAreaWeightAMI::faceAreaWeightAMI
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool reverseTarget,
|
||||
const bool requireMatch,
|
||||
const bool reverseTarget,
|
||||
const scalar lowWeightCorrection,
|
||||
const faceAreaIntersect::triangulationMode triMode,
|
||||
const bool restartUncoveredSourceFace
|
||||
)
|
||||
:
|
||||
AMIMethod<SourcePatch, TargetPatch>
|
||||
advancingFrontAMI
|
||||
(
|
||||
srcPatch,
|
||||
tgtPatch,
|
||||
triMode,
|
||||
requireMatch,
|
||||
reverseTarget,
|
||||
requireMatch
|
||||
lowWeightCorrection,
|
||||
triMode
|
||||
),
|
||||
restartUncoveredSourceFace_(restartUncoveredSourceFace),
|
||||
srcMagSf_(),
|
||||
tgtMagSf_(),
|
||||
srcTris_(),
|
||||
tgtTris_(),
|
||||
extendedTgtMapPtr_(nullptr)
|
||||
restartUncoveredSourceFace_(restartUncoveredSourceFace)
|
||||
{}
|
||||
|
||||
|
||||
Foam::faceAreaWeightAMI::faceAreaWeightAMI(const faceAreaWeightAMI& ami)
|
||||
:
|
||||
advancingFrontAMI(ami),
|
||||
restartUncoveredSourceFace_(ami.restartUncoveredSourceFace_)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
|
||||
bool Foam::faceAreaWeightAMI::calculate
|
||||
(
|
||||
labelListList& srcAddress,
|
||||
scalarListList& srcWeights,
|
||||
pointListList& srcCentroids,
|
||||
labelListList& tgtAddress,
|
||||
scalarListList& tgtWeights,
|
||||
scalarList& srcMagSf,
|
||||
scalarList& tgtMagSf,
|
||||
autoPtr<mapDistribute>& srcMapPtr,
|
||||
autoPtr<mapDistribute>& tgtMapPtr,
|
||||
label srcFacei,
|
||||
label tgtFacei
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr
|
||||
)
|
||||
{
|
||||
if (upToDate_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
addProfiling(ami, "faceAreaWeightAMI::calculate");
|
||||
|
||||
// Create global indexing for each patch
|
||||
globalIndex globalSrcFaces(this->srcPatch0_.size());
|
||||
globalIndex globalTgtFaces(this->tgtPatch0_.size());
|
||||
advancingFrontAMI::calculate(srcPatch, tgtPatch, surfPtr);
|
||||
|
||||
// Initialise the geometry
|
||||
labelList extendedTgtFaceIDs;
|
||||
initGeom(globalTgtFaces, extendedTgtFaceIDs);
|
||||
label srcFacei = 0;
|
||||
label tgtFacei = 0;
|
||||
|
||||
bool ok =
|
||||
this->initialise
|
||||
(
|
||||
srcAddress,
|
||||
srcWeights,
|
||||
tgtAddress,
|
||||
tgtWeights,
|
||||
srcFacei,
|
||||
tgtFacei
|
||||
);
|
||||
bool ok = initialiseWalk(srcFacei, tgtFacei);
|
||||
|
||||
srcCentroids.setSize(srcAddress.size());
|
||||
srcCentroids_.setSize(srcAddress_.size());
|
||||
|
||||
const auto& src = this->srcPatch();
|
||||
const auto& tgt = this->tgtPatch();
|
||||
const auto& tgt = this->tgtPatch(); // might be the extended patch!
|
||||
|
||||
// Temporary storage for addressing and weights
|
||||
List<DynamicList<label>> srcAddr(src.size());
|
||||
@ -705,15 +667,15 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
|
||||
tgtFacei
|
||||
);
|
||||
|
||||
if (debug && !this->srcNonOverlap_.empty())
|
||||
if (debug && !srcNonOverlap_.empty())
|
||||
{
|
||||
Pout<< " AMI: " << this->srcNonOverlap_.size()
|
||||
Pout<< " AMI: " << srcNonOverlap_.size()
|
||||
<< " non-overlap faces identified"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Check for badly covered faces
|
||||
if (restartUncoveredSourceFace_)
|
||||
if (restartUncoveredSourceFace_) // && requireMatch_???
|
||||
{
|
||||
restartUncoveredSourceFace
|
||||
(
|
||||
@ -726,36 +688,38 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set the patch face areas
|
||||
srcMagSf = std::move(srcMagSf_);
|
||||
tgtMagSf = std::move(tgtMagSf_);
|
||||
|
||||
// Transfer data to persistent storage
|
||||
forAll(srcAddr, i)
|
||||
{
|
||||
srcAddress[i].transfer(srcAddr[i]);
|
||||
srcWeights[i].transfer(srcWght[i]);
|
||||
srcCentroids[i].transfer(srcCtr[i]);
|
||||
srcAddress_[i].transfer(srcAddr[i]);
|
||||
srcWeights_[i].transfer(srcWght[i]);
|
||||
srcCentroids_[i].transfer(srcCtr[i]);
|
||||
}
|
||||
|
||||
forAll(tgtAddr, i)
|
||||
{
|
||||
tgtAddress[i].transfer(tgtAddr[i]);
|
||||
tgtWeights[i].transfer(tgtWght[i]);
|
||||
tgtAddress_[i].transfer(tgtAddr[i]);
|
||||
tgtWeights_[i].transfer(tgtWght[i]);
|
||||
}
|
||||
|
||||
if (this->distributed())
|
||||
if (distributed())
|
||||
{
|
||||
for (labelList& addressing : srcAddress)
|
||||
const primitivePatch& srcPatch0 = this->srcPatch0();
|
||||
const primitivePatch& tgtPatch0 = this->tgtPatch0();
|
||||
|
||||
// Create global indexing for each original patch
|
||||
globalIndex globalSrcFaces(srcPatch0.size());
|
||||
globalIndex globalTgtFaces(tgtPatch0.size());
|
||||
|
||||
for (labelList& addressing : srcAddress_)
|
||||
{
|
||||
for (label& addr : addressing)
|
||||
{
|
||||
addr = extendedTgtFaceIDs[addr];
|
||||
addr = extendedTgtFaceIDs_[addr];
|
||||
}
|
||||
}
|
||||
|
||||
for (labelList& addressing : tgtAddress)
|
||||
for (labelList& addressing : tgtAddress_)
|
||||
{
|
||||
globalSrcFaces.inplaceToGlobal(addressing);
|
||||
}
|
||||
@ -767,12 +731,12 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
|
||||
(
|
||||
Pstream::commsTypes::nonBlocking,
|
||||
List<labelPair>(),
|
||||
this->tgtPatch0_.size(),
|
||||
tgtPatch0.size(),
|
||||
extendedTgtMapPtr_->constructMap(),
|
||||
false, // has flip
|
||||
extendedTgtMapPtr_->subMap(),
|
||||
false, // has flip
|
||||
tgtAddress,
|
||||
tgtAddress_,
|
||||
ListOps::appendEqOp<label>(),
|
||||
flipOp(), // flip operation
|
||||
labelList()
|
||||
@ -782,43 +746,55 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
|
||||
(
|
||||
Pstream::commsTypes::nonBlocking,
|
||||
List<labelPair>(),
|
||||
this->tgtPatch0_.size(),
|
||||
tgtPatch0.size(),
|
||||
extendedTgtMapPtr_->constructMap(),
|
||||
false,
|
||||
extendedTgtMapPtr_->subMap(),
|
||||
false,
|
||||
tgtWeights,
|
||||
tgtWeights_,
|
||||
ListOps::appendEqOp<scalar>(),
|
||||
flipOp(),
|
||||
scalarList()
|
||||
);
|
||||
|
||||
// Note: using patch face areas calculated by the AMI method
|
||||
extendedTgtMapPtr_->reverseDistribute
|
||||
(
|
||||
this->tgtPatch0_.size(),
|
||||
tgtMagSf
|
||||
);
|
||||
extendedTgtMapPtr_->reverseDistribute(tgtPatch0.size(), tgtMagSf_);
|
||||
|
||||
// Cache maps and reset addresses
|
||||
List<Map<label>> cMapSrc;
|
||||
srcMapPtr.reset(new mapDistribute(globalSrcFaces, tgtAddress, cMapSrc));
|
||||
List<Map<label>> cMapTgt;
|
||||
tgtMapPtr.reset(new mapDistribute(globalTgtFaces, srcAddress, cMapTgt));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::normaliseWeights
|
||||
srcMapPtr_.reset
|
||||
(
|
||||
const bool verbose,
|
||||
AMIInterpolation<SourcePatch, TargetPatch>& inter
|
||||
)
|
||||
new mapDistribute(globalSrcFaces, tgtAddress_, cMapSrc)
|
||||
);
|
||||
|
||||
List<Map<label>> cMapTgt;
|
||||
tgtMapPtr_.reset
|
||||
(
|
||||
new mapDistribute(globalTgtFaces, srcAddress_, cMapTgt)
|
||||
);
|
||||
}
|
||||
|
||||
// Convert the weights from areas to normalised values
|
||||
normaliseWeights(conformal(), true);
|
||||
|
||||
upToDate_ = true;
|
||||
|
||||
return upToDate_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::faceAreaWeightAMI::write(Ostream& os) const
|
||||
{
|
||||
inter.normaliseWeights(this->conformal(), verbose);
|
||||
advancingFrontAMI::write(os);
|
||||
|
||||
if (restartUncoveredSourceFace_)
|
||||
{
|
||||
os.writeEntry
|
||||
(
|
||||
"restartUncoveredSourceFace",
|
||||
restartUncoveredSourceFace_
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ SourceFiles
|
||||
#ifndef faceAreaWeightAMI_H
|
||||
#define faceAreaWeightAMI_H
|
||||
|
||||
#include "AMIMethod.H"
|
||||
#include "advancingFrontAMI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -49,10 +49,9 @@ namespace Foam
|
||||
Class faceAreaWeightAMI Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
class faceAreaWeightAMI
|
||||
:
|
||||
public AMIMethod<SourcePatch, TargetPatch>
|
||||
public advancingFrontAMI
|
||||
{
|
||||
private:
|
||||
|
||||
@ -61,35 +60,20 @@ private:
|
||||
//- Flag to restart uncovered source faces
|
||||
const bool restartUncoveredSourceFace_;
|
||||
|
||||
//- Source face areas
|
||||
List<scalar> srcMagSf_;
|
||||
|
||||
//- Target face areas
|
||||
List<scalar> tgtMagSf_;
|
||||
|
||||
//- Storage for src-side triangle decomposition
|
||||
List<DynamicList<face>> srcTris_;
|
||||
|
||||
//- Storage for tgt-side triangle decomposition
|
||||
List<DynamicList<face>> tgtTris_;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
autoPtr<mapDistribute> extendedTgtMapPtr_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- No copy construct
|
||||
faceAreaWeightAMI(const faceAreaWeightAMI&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const faceAreaWeightAMI&) = delete;
|
||||
|
||||
//- Initialise the geometry
|
||||
void initGeom
|
||||
(
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const globalIndex& globalTgtFaces,
|
||||
labelList& extendedTgtFaceIDs
|
||||
);
|
||||
@ -135,7 +119,7 @@ protected:
|
||||
);
|
||||
|
||||
//- Set the source and target seed faces
|
||||
virtual void setNextFaces
|
||||
virtual bool setNextFaces
|
||||
(
|
||||
label& startSeedi,
|
||||
label& srcFacei,
|
||||
@ -175,17 +159,33 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from dictionary
|
||||
faceAreaWeightAMI
|
||||
(
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget = false
|
||||
);
|
||||
|
||||
//- Construct from components
|
||||
faceAreaWeightAMI
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool requireMatch,
|
||||
const bool reverseTarget = false,
|
||||
const bool requireMatch = true,
|
||||
const scalar lowWeightCorrection = -1,
|
||||
const faceAreaIntersect::triangulationMode triMode =
|
||||
faceAreaIntersect::tmMesh,
|
||||
const bool restartUncoveredSourceFace = true
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
faceAreaWeightAMI(const faceAreaWeightAMI& ami);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual autoPtr<AMIInterpolation> clone() const
|
||||
{
|
||||
return autoPtr<AMIInterpolation>(new faceAreaWeightAMI(*this));
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~faceAreaWeightAMI() = default;
|
||||
@ -193,31 +193,16 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Manipulation
|
||||
|
||||
//- Update addressing, weights and centroids
|
||||
//- Update addressing, weights and (optional) centroids
|
||||
virtual bool calculate
|
||||
(
|
||||
labelListList& srcAddress,
|
||||
scalarListList& srcWeights,
|
||||
pointListList& srcCentroids,
|
||||
labelListList& tgtAddress,
|
||||
scalarListList& tgtWeights,
|
||||
scalarList& srcMagSf,
|
||||
scalarList& tgtMagSf,
|
||||
autoPtr<mapDistribute>& srcMapPtr,
|
||||
autoPtr<mapDistribute>& tgtMapPtr,
|
||||
label srcFacei = -1,
|
||||
label tgtFacei = -1
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr = nullptr
|
||||
);
|
||||
|
||||
//- Normalise the weight. Can optionally subset addressing
|
||||
//- (e.g. for mapNearest)
|
||||
virtual void normaliseWeights
|
||||
(
|
||||
const bool verbose,
|
||||
AMIInterpolation<SourcePatch, TargetPatch>& inter
|
||||
);
|
||||
//- Write
|
||||
virtual void write(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
@ -227,12 +212,6 @@ public:
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "faceAreaWeightAMI.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,408 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "nearestFaceAMI.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(nearestFaceAMI, 0);
|
||||
addToRunTimeSelectionTable(AMIInterpolation, nearestFaceAMI, dict);
|
||||
addToRunTimeSelectionTable(AMIInterpolation, nearestFaceAMI, component);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::autoPtr<Foam::mapDistribute> Foam::nearestFaceAMI::calcFaceMap
|
||||
(
|
||||
const List<nearestAndDist>& localInfo,
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch
|
||||
) const
|
||||
{
|
||||
// Generate the list of processor bounding boxes for tgtPatch
|
||||
List<boundBox> procBbs(Pstream::nProcs());
|
||||
procBbs[Pstream::myProcNo()] =
|
||||
boundBox(tgtPatch.points(), tgtPatch.meshPoints(), true);
|
||||
Pstream::gatherList(procBbs);
|
||||
Pstream::scatterList(procBbs);
|
||||
|
||||
// Identify which of my local src faces intersect with each processor
|
||||
// tgtPatch bb within the current match's search distance
|
||||
const pointField& srcCcs = srcPatch.faceCentres();
|
||||
List<DynamicList<label>> dynSendMap(Pstream::nProcs());
|
||||
|
||||
forAll(localInfo, srcFacei)
|
||||
{
|
||||
// Test local srcPatch face centres against remote processor tgtPatch bb
|
||||
// using distance from initial pass
|
||||
|
||||
const scalar r2 = localInfo[srcFacei].second();
|
||||
|
||||
forAll(procBbs, proci)
|
||||
{
|
||||
if (proci != Pstream::myProcNo())
|
||||
{
|
||||
if (procBbs[proci].overlaps(srcCcs[srcFacei], r2))
|
||||
{
|
||||
dynSendMap[proci].append(srcFacei);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert dynamicList to labelList
|
||||
labelListList sendMap(Pstream::nProcs());
|
||||
forAll(sendMap, proci)
|
||||
{
|
||||
dynSendMap[proci].shrink();
|
||||
sendMap[proci].transfer(dynSendMap[proci]);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "send map - to proc " << proci << " sending "
|
||||
<< sendMap[proci].size() << " elements" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return autoPtr<mapDistribute>::New(std::move(sendMap));
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::mapDistribute> Foam::nearestFaceAMI::calcDistributed
|
||||
(
|
||||
const primitivePatch& src,
|
||||
const primitivePatch& tgt,
|
||||
labelListList& srcToTgtAddr,
|
||||
scalarListList& srcToTgtWght
|
||||
) const
|
||||
{
|
||||
autoPtr<indexedOctree<treeType>> tgtTreePtr;
|
||||
if (tgt.size())
|
||||
{
|
||||
tgtTreePtr = this->createTree(tgt);
|
||||
}
|
||||
|
||||
// Create global indexing for tgtPatch
|
||||
globalIndex globalTgtCells(tgt.size());
|
||||
|
||||
|
||||
// First pass
|
||||
// ==========
|
||||
// For each srcPatch face, determine local match on tgtPatch
|
||||
|
||||
// Identify local nearest matches
|
||||
pointField srcCcs(src.faceCentres());
|
||||
|
||||
List<nearestAndDist> localInfo(src.size());
|
||||
if (tgt.size())
|
||||
{
|
||||
const auto& tgtTree = tgtTreePtr();
|
||||
|
||||
forAll(srcCcs, srcCelli)
|
||||
{
|
||||
const point& srcCc = srcCcs[srcCelli];
|
||||
|
||||
pointIndexHit& test = localInfo[srcCelli].first();
|
||||
test = tgtTree.findNearest(srcCc, GREAT);
|
||||
|
||||
if (test.hit())
|
||||
{
|
||||
// With a search radius2 of GREAT all cells should receive a hit
|
||||
localInfo[srcCelli].second() = magSqr(srcCc - test.hitPoint());
|
||||
test.setIndex(globalTgtCells.toGlobal(test.index()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No local tgtPatch faces - initialise nearest distance for all
|
||||
// srcPatch faces to GREAT so that they [should be] set by remote
|
||||
// tgtPatch faces
|
||||
for (auto& info : localInfo)
|
||||
{
|
||||
info.second() = GREAT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Second pass
|
||||
// ===========
|
||||
// Determine remote matches
|
||||
|
||||
// Map returns labels of src patch faces to send to each proc
|
||||
autoPtr<mapDistribute> mapPtr = calcFaceMap(localInfo, src, tgt);
|
||||
mapDistribute& map = mapPtr();
|
||||
|
||||
List<nearestAndDist> remoteInfo(localInfo);
|
||||
map.distribute(remoteInfo);
|
||||
|
||||
// Note: re-using srcCcs
|
||||
map.distribute(srcCcs);
|
||||
|
||||
if (tgt.size())
|
||||
{
|
||||
const auto& tgtTree = tgtTreePtr();
|
||||
|
||||
// Test remote srcPatch faces against local tgtPatch faces
|
||||
nearestAndDist testInfo;
|
||||
pointIndexHit& test = testInfo.first();
|
||||
forAll(remoteInfo, i)
|
||||
{
|
||||
test = tgtTree.findNearest(srcCcs[i], remoteInfo[i].second());
|
||||
if (test.hit())
|
||||
{
|
||||
test.setIndex(globalTgtCells.toGlobal(test.index()));
|
||||
testInfo.second() = magSqr(test.hitPoint() - srcCcs[i]);
|
||||
nearestEqOp()(remoteInfo[i], testInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send back to originating processor. Choose best if sent to multiple
|
||||
// processors. Note that afterwards all unused entries have the unique
|
||||
// value nearestZero (distance < 0). This is used later on to see if
|
||||
// the sample was sent to any processor.
|
||||
const nearestAndDist nearestZero(pointIndexHit(), -GREAT);
|
||||
mapDistributeBase::distribute
|
||||
(
|
||||
Pstream::commsTypes::nonBlocking,
|
||||
List<labelPair>(0),
|
||||
src.size(),
|
||||
map.constructMap(),
|
||||
map.constructHasFlip(),
|
||||
map.subMap(),
|
||||
map.subHasFlip(),
|
||||
remoteInfo,
|
||||
nearestEqOp(),
|
||||
noOp(), // no flipping
|
||||
nearestZero
|
||||
);
|
||||
|
||||
|
||||
// Third pass
|
||||
// ==========
|
||||
// Combine local and remote info and filter out any connections that are
|
||||
// further away than threshold distance squared
|
||||
|
||||
srcToTgtAddr.setSize(src.size());
|
||||
srcToTgtWght.setSize(src.size());
|
||||
forAll(srcToTgtAddr, srcFacei)
|
||||
{
|
||||
nearestEqOp()(localInfo[srcFacei], remoteInfo[srcFacei]);
|
||||
if (localInfo[srcFacei].second() < maxDistance2_)
|
||||
{
|
||||
const label tgtFacei = localInfo[srcFacei].first().index();
|
||||
srcToTgtAddr[srcFacei] = labelList(1, tgtFacei);
|
||||
srcToTgtWght[srcFacei] = scalarList(1, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
List<Map<label>> cMap;
|
||||
return autoPtr<mapDistribute>::New(globalTgtCells, srcToTgtAddr, cMap);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::nearestFaceAMI::nearestFaceAMI
|
||||
(
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget
|
||||
)
|
||||
:
|
||||
AMIInterpolation(dict, reverseTarget),
|
||||
maxDistance2_(dict.getOrDefault<scalar>("maxDistance2", GREAT))
|
||||
{}
|
||||
|
||||
|
||||
Foam::nearestFaceAMI::nearestFaceAMI
|
||||
(
|
||||
const bool requireMatch,
|
||||
const bool reverseTarget,
|
||||
const scalar lowWeightCorrection
|
||||
)
|
||||
:
|
||||
AMIInterpolation(requireMatch, reverseTarget, lowWeightCorrection),
|
||||
maxDistance2_(GREAT)
|
||||
{}
|
||||
|
||||
|
||||
Foam::nearestFaceAMI::nearestFaceAMI(const nearestFaceAMI& ami)
|
||||
:
|
||||
AMIInterpolation(ami),
|
||||
maxDistance2_(ami.maxDistance2_)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::nearestFaceAMI::calculate
|
||||
(
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr
|
||||
)
|
||||
{
|
||||
if (upToDate_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AMIInterpolation::calculate(srcPatch, tgtPatch, surfPtr);
|
||||
|
||||
const auto& src = this->srcPatch0();
|
||||
const auto& tgt = this->tgtPatch0();
|
||||
|
||||
// Set face area magnitudes
|
||||
srcMagSf_ = mag(src.faceAreas());
|
||||
tgtMagSf_ = mag(tgt.faceAreas());
|
||||
|
||||
// TODO: implement symmetric calculation controls; assume yes for now
|
||||
bool symmetric_ = true;
|
||||
|
||||
if (this->distributed())
|
||||
{
|
||||
tgtMapPtr_ =
|
||||
calcDistributed
|
||||
(
|
||||
src,
|
||||
tgt,
|
||||
srcAddress_,
|
||||
srcWeights_
|
||||
);
|
||||
|
||||
if (symmetric_)
|
||||
{
|
||||
srcMapPtr_ =
|
||||
calcDistributed
|
||||
(
|
||||
tgt,
|
||||
src,
|
||||
tgtAddress_,
|
||||
tgtWeights_
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
srcAddress_.setSize(src.size());
|
||||
srcWeights_.setSize(src.size());
|
||||
|
||||
if (symmetric_)
|
||||
{
|
||||
tgtAddress_.setSize(tgt.size());
|
||||
tgtWeights_.setSize(tgt.size());
|
||||
}
|
||||
|
||||
const pointField& srcCcs = src.faceCentres();
|
||||
const pointField& tgtCcs = tgt.faceCentres();
|
||||
|
||||
const auto tgtTreePtr = this->createTree(tgtPatch);
|
||||
const auto& tgtTree = tgtTreePtr();
|
||||
|
||||
forAll(srcCcs, srcFacei)
|
||||
{
|
||||
const point& srcCc = srcCcs[srcFacei];
|
||||
const pointIndexHit hit = tgtTree.findNearest(srcCc, GREAT);
|
||||
|
||||
if
|
||||
(
|
||||
hit.hit()
|
||||
&& (magSqr(srcCc - tgtCcs[hit.index()]) < maxDistance2_)
|
||||
)
|
||||
{
|
||||
label tgtFacei = hit.index();
|
||||
srcAddress_[srcFacei] = labelList(1, tgtFacei);
|
||||
srcWeights_[srcFacei] = scalarList(1, 1.0);
|
||||
|
||||
if (symmetric_)
|
||||
{
|
||||
tgtAddress_[tgtFacei] = labelList(1, srcFacei);
|
||||
tgtWeights_[tgtFacei] = scalarList(1, 1.0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Unable to find target face for source face "
|
||||
<< srcFacei << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (symmetric_)
|
||||
{
|
||||
const auto srcTreePtr = this->createTree(srcPatch);
|
||||
const auto& srcTree = srcTreePtr();
|
||||
|
||||
// Check that all source cells have connections and populate any
|
||||
// missing entries
|
||||
forAll(tgtWeights_, tgtCelli)
|
||||
{
|
||||
if (tgtAddress_[tgtCelli].empty())
|
||||
{
|
||||
const point& tgtCc = tgtCcs[tgtCelli];
|
||||
pointIndexHit hit = srcTree.findNearest(tgtCc, GREAT);
|
||||
|
||||
if
|
||||
(
|
||||
hit.hit()
|
||||
&& (magSqr(tgtCc - srcCcs[hit.index()]) < maxDistance2_)
|
||||
)
|
||||
{
|
||||
tgtAddress_[tgtCelli] = labelList(1, hit.index());
|
||||
tgtWeights_[tgtCelli] = scalarList(1, 1.0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Unable to find source face for target face "
|
||||
<< tgtCelli << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
srcWeightsSum_.setSize(srcWeights_.size(), 1);
|
||||
tgtWeightsSum_.setSize(tgtWeights_.size(), 1);
|
||||
|
||||
upToDate_ = true;
|
||||
|
||||
return upToDate_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -37,7 +37,7 @@ SourceFiles
|
||||
#ifndef nearestFaceAMI_H
|
||||
#define nearestFaceAMI_H
|
||||
|
||||
#include "AMIMethod.H"
|
||||
#include "AMIInterpolation.H"
|
||||
#include "pointIndexHit.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -49,10 +49,9 @@ namespace Foam
|
||||
Class nearestFaceAMI Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
class nearestFaceAMI
|
||||
:
|
||||
public AMIMethod<SourcePatch, TargetPatch>
|
||||
public AMIInterpolation
|
||||
{
|
||||
public:
|
||||
|
||||
@ -91,23 +90,20 @@ private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- No copy construct
|
||||
nearestFaceAMI(const nearestFaceAMI&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const nearestFaceAMI&) = delete;
|
||||
|
||||
autoPtr<mapDistribute> calcFaceMap
|
||||
(
|
||||
const List<nearestAndDist>& localInfo,
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch
|
||||
) const;
|
||||
|
||||
autoPtr<mapDistribute> calcDistributed
|
||||
(
|
||||
const SourcePatch& src,
|
||||
const TargetPatch& tgt,
|
||||
const primitivePatch& src,
|
||||
const primitivePatch& tgt,
|
||||
labelListList& srcToTgtAddr,
|
||||
scalarListList& srcToTgtWght
|
||||
) const;
|
||||
@ -121,16 +117,30 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from dictionary
|
||||
nearestFaceAMI
|
||||
(
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget = false
|
||||
);
|
||||
|
||||
//- Construct from components
|
||||
nearestFaceAMI
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool requireMatch = true,
|
||||
const bool reverseTarget = false,
|
||||
const bool requireMatch = true
|
||||
const scalar lowWeightCorrection = -1
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
nearestFaceAMI(const nearestFaceAMI& ami);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual autoPtr<AMIInterpolation> clone() const
|
||||
{
|
||||
return autoPtr<AMIInterpolation>(new nearestFaceAMI(*this));
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~nearestFaceAMI() = default;
|
||||
@ -138,30 +148,12 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Manipulation
|
||||
|
||||
//- Update addressing and weights
|
||||
virtual bool calculate
|
||||
(
|
||||
labelListList& srcAddress,
|
||||
scalarListList& srcWeights,
|
||||
pointListList& srcCentroids,
|
||||
labelListList& tgtAddress,
|
||||
scalarListList& tgtWeights,
|
||||
scalarList& srcMagSf,
|
||||
scalarList& tgtMagSf,
|
||||
autoPtr<mapDistribute>& srcMapPtr,
|
||||
autoPtr<mapDistribute>& tgtMapPtr,
|
||||
label srcFacei = -1,
|
||||
label tgtFacei = -1
|
||||
);
|
||||
|
||||
//- Normalise the weight. Can optionally subset addressing
|
||||
//- (e.g. for mapNearest)
|
||||
virtual void normaliseWeights
|
||||
(
|
||||
const bool verbose,
|
||||
AMIInterpolation<SourcePatch, TargetPatch>& inter
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr = nullptr
|
||||
);
|
||||
};
|
||||
|
||||
@ -172,12 +164,6 @@ public:
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "nearestFaceAMI.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -6,6 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -26,11 +27,30 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "partialFaceAreaWeightAMI.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(partialFaceAreaWeightAMI, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
AMIInterpolation,
|
||||
partialFaceAreaWeightAMI,
|
||||
dict
|
||||
);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
AMIInterpolation,
|
||||
partialFaceAreaWeightAMI,
|
||||
component
|
||||
);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
|
||||
bool Foam::partialFaceAreaWeightAMI::setNextFaces
|
||||
(
|
||||
label& startSeedi,
|
||||
label& srcFacei,
|
||||
@ -41,7 +61,7 @@ void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
|
||||
const bool errorOnNotFound
|
||||
) const
|
||||
{
|
||||
faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
|
||||
return faceAreaWeightAMI::setNextFaces
|
||||
(
|
||||
startSeedi,
|
||||
srcFacei,
|
||||
@ -56,85 +76,75 @@ void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::
|
||||
partialFaceAreaWeightAMI
|
||||
Foam::partialFaceAreaWeightAMI::partialFaceAreaWeightAMI
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool reverseTarget,
|
||||
const bool requireMatch
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget
|
||||
)
|
||||
:
|
||||
faceAreaWeightAMI<SourcePatch, TargetPatch>
|
||||
faceAreaWeightAMI(dict, reverseTarget)
|
||||
{}
|
||||
|
||||
|
||||
Foam::partialFaceAreaWeightAMI::partialFaceAreaWeightAMI
|
||||
(
|
||||
srcPatch,
|
||||
tgtPatch,
|
||||
triMode,
|
||||
reverseTarget,
|
||||
requireMatch,
|
||||
true // false // Not performing restart on low weights - valid for partial match
|
||||
const bool requireMatch,
|
||||
const bool reverseTarget,
|
||||
const scalar lowWeightCorrection,
|
||||
const faceAreaIntersect::triangulationMode triMode,
|
||||
const bool restartUncoveredSourceFace
|
||||
)
|
||||
:
|
||||
faceAreaWeightAMI
|
||||
(
|
||||
requireMatch,
|
||||
reverseTarget,
|
||||
lowWeightCorrection,
|
||||
triMode,
|
||||
restartUncoveredSourceFace
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
Foam::partialFaceAreaWeightAMI::partialFaceAreaWeightAMI
|
||||
(
|
||||
const partialFaceAreaWeightAMI& ami
|
||||
)
|
||||
:
|
||||
faceAreaWeightAMI(ami)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
bool Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::conformal() const
|
||||
bool Foam::partialFaceAreaWeightAMI::conformal() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
bool Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
|
||||
bool Foam::partialFaceAreaWeightAMI::calculate
|
||||
(
|
||||
labelListList& srcAddress,
|
||||
scalarListList& srcWeights,
|
||||
pointListList& srcCentroids,
|
||||
labelListList& tgtAddress,
|
||||
scalarListList& tgtWeights,
|
||||
scalarList& srcMagSf,
|
||||
scalarList& tgtMagSf,
|
||||
autoPtr<mapDistribute>& srcMapPtr,
|
||||
autoPtr<mapDistribute>& tgtMapPtr,
|
||||
label srcFacei,
|
||||
label tgtFacei
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr
|
||||
)
|
||||
{
|
||||
bool ok =
|
||||
faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
|
||||
(
|
||||
srcAddress,
|
||||
srcWeights,
|
||||
srcCentroids,
|
||||
tgtAddress,
|
||||
tgtWeights,
|
||||
srcMagSf,
|
||||
tgtMagSf,
|
||||
srcMapPtr,
|
||||
tgtMapPtr,
|
||||
srcFacei,
|
||||
tgtFacei
|
||||
);
|
||||
|
||||
if (ok)
|
||||
if (faceAreaWeightAMI::calculate(srcPatch, tgtPatch, surfPtr))
|
||||
{
|
||||
if (this->distributed())
|
||||
if (distributed())
|
||||
{
|
||||
scalarList newTgtMagSf(std::move(tgtMagSf));
|
||||
scalarList newTgtMagSf(std::move(tgtMagSf_));
|
||||
|
||||
// Assign default sizes. Override selected values with
|
||||
// calculated values. This is to support ACMI
|
||||
// where some of the target faces are never used (so never get sent
|
||||
// over and hence never assigned to)
|
||||
tgtMagSf = this->tgtPatch0_.magFaceAreas();
|
||||
// Assign default sizes. Override selected values with calculated
|
||||
// values. This is to support ACMI where some of the target faces
|
||||
// are never used (so never get sent over and hence never assigned
|
||||
// to)
|
||||
tgtMagSf_ = tgtPatch0().magFaceAreas();
|
||||
|
||||
for (const labelList& smap : this->extendedTgtMapPtr_->subMap())
|
||||
{
|
||||
UIndirectList<scalar>(tgtMagSf, smap) =
|
||||
UIndirectList<scalar>(tgtMagSf_, smap) =
|
||||
UIndirectList<scalar>(newTgtMagSf, smap);
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -49,19 +49,15 @@ namespace Foam
|
||||
Class partialFaceAreaWeightAMI Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
class partialFaceAreaWeightAMI
|
||||
:
|
||||
public faceAreaWeightAMI<SourcePatch, TargetPatch>
|
||||
public faceAreaWeightAMI
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- No copy construct
|
||||
partialFaceAreaWeightAMI(const partialFaceAreaWeightAMI&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const partialFaceAreaWeightAMI&) = delete;
|
||||
|
||||
@ -71,7 +67,7 @@ protected:
|
||||
// Protected Member Functions
|
||||
|
||||
//- Set the source and target seed faces
|
||||
virtual void setNextFaces
|
||||
virtual bool setNextFaces
|
||||
(
|
||||
label& startSeedi,
|
||||
label& srcFacei,
|
||||
@ -91,16 +87,34 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from dictionary
|
||||
partialFaceAreaWeightAMI
|
||||
(
|
||||
const dictionary& dict,
|
||||
const bool reverseTarget = false
|
||||
);
|
||||
|
||||
//- Construct from components
|
||||
partialFaceAreaWeightAMI
|
||||
(
|
||||
const SourcePatch& srcPatch,
|
||||
const TargetPatch& tgtPatch,
|
||||
const faceAreaIntersect::triangulationMode& triMode,
|
||||
const bool requireMatch = false,
|
||||
const bool reverseTarget = false,
|
||||
const bool requireMatch = true
|
||||
const scalar lowWeightCorrection = -1,
|
||||
const faceAreaIntersect::triangulationMode triMode =
|
||||
faceAreaIntersect::tmMesh,
|
||||
const bool restartUncoveredSourceFace = true
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
partialFaceAreaWeightAMI(const partialFaceAreaWeightAMI& ami);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual autoPtr<AMIInterpolation> clone() const
|
||||
{
|
||||
return
|
||||
autoPtr<AMIInterpolation>(new partialFaceAreaWeightAMI(*this));
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~partialFaceAreaWeightAMI() = default;
|
||||
@ -108,28 +122,15 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Flag to indicate that interpolation patches are conformal
|
||||
virtual bool conformal() const;
|
||||
|
||||
|
||||
// Manipulation
|
||||
|
||||
//- Update addressing and weights
|
||||
//- Update addressing, weights and (optional) centroids
|
||||
virtual bool calculate
|
||||
(
|
||||
labelListList& srcAddress,
|
||||
scalarListList& srcWeights,
|
||||
pointListList& srcCentroids,
|
||||
labelListList& tgtAddress,
|
||||
scalarListList& tgtWeights,
|
||||
scalarList& srcMagSf,
|
||||
scalarList& tgtMagSf,
|
||||
autoPtr<mapDistribute>& srcMapPtr,
|
||||
autoPtr<mapDistribute>& tgtMapPtr,
|
||||
label srcFacei = -1,
|
||||
label tgtFacei = -1
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch,
|
||||
const autoPtr<searchableSurface>& surfPtr = nullptr
|
||||
);
|
||||
};
|
||||
|
||||
@ -140,12 +141,6 @@ public:
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "partialFaceAreaWeightAMI.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -46,6 +46,7 @@ SourceFiles
|
||||
#include "face.H"
|
||||
#include "triPoints.H"
|
||||
#include "Enum.H"
|
||||
#include "searchableSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2019 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -72,20 +72,13 @@ void Foam::cyclicACMIPolyPatch::reportCoverage
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicACMIPolyPatch::resetAMI
|
||||
(
|
||||
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod
|
||||
) const
|
||||
void Foam::cyclicACMIPolyPatch::resetAMI() const
|
||||
{
|
||||
resetAMI(boundaryMesh().mesh().points(), AMIMethod);
|
||||
resetAMI(boundaryMesh().mesh().points());
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicACMIPolyPatch::resetAMI
|
||||
(
|
||||
const UList<point>& points,
|
||||
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod
|
||||
) const
|
||||
void Foam::cyclicACMIPolyPatch::resetAMI(const UList<point>& points) const
|
||||
{
|
||||
if (!owner())
|
||||
{
|
||||
@ -94,52 +87,40 @@ void Foam::cyclicACMIPolyPatch::resetAMI
|
||||
|
||||
const polyPatch& nonOverlapPatch = this->nonOverlapPatch();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicACMIPolyPatch::resetAMI : recalculating weights"
|
||||
DebugPout
|
||||
<< "cyclicACMIPolyPatch::resetAMI : recalculating weights"
|
||||
<< " for " << name() << " and " << nonOverlapPatch.name()
|
||||
<< endl;
|
||||
}
|
||||
|
||||
const polyMesh& mesh = boundaryMesh().mesh();
|
||||
|
||||
WarningInFunction<< "DEACTIVATED clearGeom()" << endl;
|
||||
// if (boundaryMesh().mesh().hasCellCentres())
|
||||
if (0 && boundaryMesh().mesh().hasCellCentres())
|
||||
if (!createAMIFaces_ && mesh.hasCellCentres())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicACMIPolyPatch::resetAMI : clearing cellCentres"
|
||||
DebugPout
|
||||
<< "cyclicACMIPolyPatch::resetAMI : clearing cellCentres"
|
||||
<< " for " << name() << " and " << nonOverlapPatch.name()
|
||||
<< endl;
|
||||
}
|
||||
|
||||
//WarningInFunction
|
||||
// << "The mesh already has cellCentres calculated when"
|
||||
// << " resetting ACMI " << name() << "." << endl
|
||||
// << "This is a problem since ACMI adapts the face areas"
|
||||
// << " (to close cells) so this has" << endl
|
||||
// << "to be done before cell centre calculation." << endl
|
||||
// << "This can happen if e.g. the cyclicACMI is after"
|
||||
// << " any processor patches in the boundary." << endl;
|
||||
const_cast<polyMesh&>
|
||||
(
|
||||
boundaryMesh().mesh()
|
||||
).primitiveMesh::clearGeom();
|
||||
WarningInFunction
|
||||
<< "The mesh already has cellCentres calculated when"
|
||||
<< " resetting ACMI " << name() << "." << nl
|
||||
<< "This is a problem since ACMI adapts the face areas"
|
||||
<< " (to close cells) so this has" << nl
|
||||
<< "to be done before cell centre calculation." << nl
|
||||
<< "This can happen if e.g. the cyclicACMI is after"
|
||||
<< " any processor patches in the boundary." << endl;
|
||||
const_cast<polyMesh&>(mesh).primitiveMesh::clearGeom();
|
||||
}
|
||||
|
||||
|
||||
// Trigger re-building of faceAreas
|
||||
(void)boundaryMesh().mesh().faceAreas();
|
||||
(void)mesh.faceAreas();
|
||||
|
||||
|
||||
// Calculate the AMI using partial face-area-weighted. This leaves
|
||||
// the weights as fractions of local areas (sum(weights) = 1 means
|
||||
// face is fully covered)
|
||||
cyclicAMIPolyPatch::resetAMI
|
||||
(
|
||||
points,
|
||||
AMIPatchToPatchInterpolation::imPartialFaceAreaWeight
|
||||
);
|
||||
cyclicAMIPolyPatch::resetAMI(points);
|
||||
|
||||
const AMIPatchToPatchInterpolation& AMI = this->AMI();
|
||||
|
||||
@ -196,15 +177,17 @@ void Foam::cyclicACMIPolyPatch::scalePatchFaceAreas
|
||||
// Primitive patch face areas have been cleared/reset based on the raw
|
||||
// points - need to reset to avoid double-accounting of face areas
|
||||
|
||||
DebugPout
|
||||
<< "rescaling non-overlap patch areas" << endl;
|
||||
|
||||
const scalar maxTol = scalar(1) - tolerance_;
|
||||
const scalarField& mask = acmipp.mask();
|
||||
|
||||
const polyPatch& nonOverlapPatch = acmipp.nonOverlapPatch();
|
||||
vectorField::subField noSf = nonOverlapPatch.faceAreas();
|
||||
|
||||
DebugPout
|
||||
<< "rescaling non-overlap patch areas for: " << nonOverlapPatch.name()
|
||||
<< endl;
|
||||
|
||||
|
||||
if (mask.size() != noSf.size())
|
||||
{
|
||||
WarningInFunction
|
||||
@ -232,7 +215,7 @@ void Foam::cyclicACMIPolyPatch::scalePatchFaceAreas
|
||||
// updates, e.g. by the calls to cyclicAMIPolyPatch's setTopology and
|
||||
// initMovePoints
|
||||
DebugPout
|
||||
<< "scaling coupled patch areas" << endl;
|
||||
<< "scaling coupled patch areas for: " << acmipp.name() << endl;
|
||||
|
||||
// Scale the coupled patch face areas
|
||||
vectorField::subField Sf = acmipp.faceAreas();
|
||||
@ -266,26 +249,26 @@ void Foam::cyclicACMIPolyPatch::scalePatchFaceAreas
|
||||
|
||||
void Foam::cyclicACMIPolyPatch::initGeometry(PstreamBuffers& pBufs)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicACMIPolyPatch::initGeometry : " << name() << endl;
|
||||
}
|
||||
DebugPout << "cyclicACMIPolyPatch::initGeometry : " << name() << endl;
|
||||
|
||||
// Note: calculates transformation and triggers face centre calculation
|
||||
cyclicAMIPolyPatch::initGeometry(pBufs);
|
||||
|
||||
// On start-up there are no topological updates so scale the face areas
|
||||
// - Note: resetAMI called by cyclicAMIPolyPatch::initGeometry
|
||||
// Initialise the AMI early to make sure we adapt the face areas before the
|
||||
// cell centre calculation gets triggered.
|
||||
if (!createAMIFaces_ && canResetAMI())
|
||||
{
|
||||
resetAMI();
|
||||
}
|
||||
|
||||
scalePatchFaceAreas();
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicACMIPolyPatch::calcGeometry(PstreamBuffers& pBufs)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicACMIPolyPatch::calcGeometry : " << name() << endl;
|
||||
}
|
||||
DebugPout << "cyclicACMIPolyPatch::calcGeometry : " << name() << endl;
|
||||
|
||||
cyclicAMIPolyPatch::calcGeometry(pBufs);
|
||||
}
|
||||
|
||||
@ -296,10 +279,7 @@ void Foam::cyclicACMIPolyPatch::initMovePoints
|
||||
const pointField& p
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicACMIPolyPatch::initMovePoints : " << name() << endl;
|
||||
}
|
||||
DebugPout<< "cyclicACMIPolyPatch::initMovePoints : " << name() << endl;
|
||||
|
||||
// Note: calculates transformation and triggers face centre calculation
|
||||
// - Note: resetAMI called by cyclicAMIPolyPatch::initMovePoints
|
||||
@ -315,10 +295,7 @@ void Foam::cyclicACMIPolyPatch::movePoints
|
||||
const pointField& p
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicACMIPolyPatch::movePoints : " << name() << endl;
|
||||
}
|
||||
DebugPout << "cyclicACMIPolyPatch::movePoints : " << name() << endl;
|
||||
|
||||
// When topology is changing, this will scale the duplicate AMI faces
|
||||
cyclicAMIPolyPatch::movePoints(pBufs, p);
|
||||
@ -327,30 +304,24 @@ void Foam::cyclicACMIPolyPatch::movePoints
|
||||
|
||||
void Foam::cyclicACMIPolyPatch::initUpdateMesh(PstreamBuffers& pBufs)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicACMIPolyPatch::initUpdateMesh : " << name() << endl;
|
||||
}
|
||||
DebugPout << "cyclicACMIPolyPatch::initUpdateMesh : " << name() << endl;
|
||||
|
||||
cyclicAMIPolyPatch::initUpdateMesh(pBufs);
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicACMIPolyPatch::updateMesh(PstreamBuffers& pBufs)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicACMIPolyPatch::updateMesh : " << name() << endl;
|
||||
}
|
||||
DebugPout << "cyclicACMIPolyPatch::updateMesh : " << name() << endl;
|
||||
|
||||
cyclicAMIPolyPatch::updateMesh(pBufs);
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicACMIPolyPatch::clearGeom()
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicACMIPolyPatch::clearGeom : " << name() << endl;
|
||||
}
|
||||
DebugPout << "cyclicACMIPolyPatch::clearGeom : " << name() << endl;
|
||||
|
||||
cyclicAMIPolyPatch::clearGeom();
|
||||
}
|
||||
|
||||
@ -377,16 +348,27 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
|
||||
const label index,
|
||||
const polyBoundaryMesh& bm,
|
||||
const word& patchType,
|
||||
const transformType transform
|
||||
const transformType transform,
|
||||
const word& defaultAMIMethod
|
||||
)
|
||||
:
|
||||
cyclicAMIPolyPatch(name, size, start, index, bm, patchType, transform),
|
||||
cyclicAMIPolyPatch
|
||||
(
|
||||
name,
|
||||
size,
|
||||
start,
|
||||
index,
|
||||
bm,
|
||||
patchType,
|
||||
transform,
|
||||
defaultAMIMethod
|
||||
),
|
||||
nonOverlapPatchName_(word::null),
|
||||
nonOverlapPatchID_(-1),
|
||||
srcMask_(),
|
||||
tgtMask_()
|
||||
{
|
||||
AMIRequireMatch_ = false;
|
||||
AMIPtr_->setRequireMatch(false);
|
||||
|
||||
// Non-overlapping patch might not be valid yet so cannot determine
|
||||
// associated patchID
|
||||
@ -399,16 +381,17 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
|
||||
const dictionary& dict,
|
||||
const label index,
|
||||
const polyBoundaryMesh& bm,
|
||||
const word& patchType
|
||||
const word& patchType,
|
||||
const word& defaultAMIMethod
|
||||
)
|
||||
:
|
||||
cyclicAMIPolyPatch(name, dict, index, bm, patchType),
|
||||
nonOverlapPatchName_(dict.lookup("nonOverlapPatch")),
|
||||
cyclicAMIPolyPatch(name, dict, index, bm, patchType, defaultAMIMethod),
|
||||
nonOverlapPatchName_(dict.get<word>("nonOverlapPatch")),
|
||||
nonOverlapPatchID_(-1),
|
||||
srcMask_(),
|
||||
tgtMask_()
|
||||
{
|
||||
AMIRequireMatch_ = false;
|
||||
AMIPtr_->setRequireMatch(false);
|
||||
|
||||
if (nonOverlapPatchName_ == name)
|
||||
{
|
||||
@ -435,7 +418,7 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
|
||||
srcMask_(),
|
||||
tgtMask_()
|
||||
{
|
||||
AMIRequireMatch_ = false;
|
||||
AMIPtr_->setRequireMatch(false);
|
||||
|
||||
// Non-overlapping patch might not be valid yet so cannot determine
|
||||
// associated patchID
|
||||
@ -459,7 +442,7 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
|
||||
srcMask_(),
|
||||
tgtMask_()
|
||||
{
|
||||
AMIRequireMatch_ = false;
|
||||
AMIPtr_->setRequireMatch(false);
|
||||
|
||||
if (nonOverlapPatchName_ == name())
|
||||
{
|
||||
@ -489,7 +472,7 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
|
||||
srcMask_(),
|
||||
tgtMask_()
|
||||
{
|
||||
AMIRequireMatch_ = false;
|
||||
AMIPtr_->setRequireMatch(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2018-2019 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -41,6 +41,7 @@ SourceFiles
|
||||
#include "cyclicAMIPolyPatch.H"
|
||||
#include "AMIPatchToPatchInterpolation.H"
|
||||
#include "polyBoundaryMesh.H"
|
||||
#include "partialFaceAreaWeightAMI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -86,19 +87,10 @@ protected:
|
||||
) const;
|
||||
|
||||
//- Reset the AMI interpolator, supply patch points
|
||||
virtual void resetAMI
|
||||
(
|
||||
const UList<point>& points,
|
||||
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod =
|
||||
AMIPatchToPatchInterpolation::imFaceAreaWeight
|
||||
) const;
|
||||
virtual void resetAMI(const UList<point>& points) const;
|
||||
|
||||
//- Reset the AMI interpolator, use current patch points
|
||||
virtual void resetAMI
|
||||
(
|
||||
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod =
|
||||
AMIPatchToPatchInterpolation::imFaceAreaWeight
|
||||
) const;
|
||||
virtual void resetAMI() const;
|
||||
|
||||
//- Scale patch face areas to maintain physical area
|
||||
virtual void scalePatchFaceAreas();
|
||||
@ -145,7 +137,8 @@ public:
|
||||
const label index,
|
||||
const polyBoundaryMesh& bm,
|
||||
const word& patchType,
|
||||
const transformType transform = UNKNOWN
|
||||
const transformType transform = UNKNOWN,
|
||||
const word& defaultAMIMethod = partialFaceAreaWeightAMI::typeName
|
||||
);
|
||||
|
||||
//- Construct from dictionary
|
||||
@ -155,7 +148,8 @@ public:
|
||||
const dictionary& dict,
|
||||
const label index,
|
||||
const polyBoundaryMesh& bm,
|
||||
const word& patchType
|
||||
const word& patchType,
|
||||
const word& defaultAMIMethod = partialFaceAreaWeightAMI::typeName
|
||||
);
|
||||
|
||||
//- Construct as copy, resetting the boundary mesh
|
||||
|
||||
@ -29,7 +29,9 @@ License
|
||||
#include "cyclicAMIPolyPatch.H"
|
||||
#include "SubField.H"
|
||||
#include "Time.H"
|
||||
#include "faceAreaIntersect.H"
|
||||
#include "unitConversion.H"
|
||||
#include "OFstream.H"
|
||||
#include "meshTools.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -59,14 +61,12 @@ Foam::vector Foam::cyclicAMIPolyPatch::findFaceNormalMaxRadius
|
||||
|
||||
label facei = findMax(magRadSqr);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "findFaceMaxRadius(const pointField&) : patch: " << name() << nl
|
||||
DebugInFunction
|
||||
<< "Patch: " << name() << nl
|
||||
<< " rotFace = " << facei << nl
|
||||
<< " point = " << faceCentres[facei] << nl
|
||||
<< " distance = " << Foam::sqrt(magRadSqr[facei])
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return n[facei];
|
||||
}
|
||||
@ -288,20 +288,45 @@ void Foam::cyclicAMIPolyPatch::calcTransforms
|
||||
|
||||
// * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void Foam::cyclicAMIPolyPatch::resetAMI
|
||||
(
|
||||
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod
|
||||
) const
|
||||
const Foam::autoPtr<Foam::searchableSurface>&
|
||||
Foam::cyclicAMIPolyPatch::surfPtr() const
|
||||
{
|
||||
resetAMI(boundaryMesh().mesh().points(), AMIMethod);
|
||||
const word surfType(surfDict_.getOrDefault<word>("type", "none"));
|
||||
|
||||
if (!surfPtr_ && owner() && surfType != "none")
|
||||
{
|
||||
word surfName(surfDict_.getOrDefault("name", name()));
|
||||
|
||||
const polyMesh& mesh = boundaryMesh().mesh();
|
||||
|
||||
surfPtr_ =
|
||||
searchableSurface::New
|
||||
(
|
||||
surfType,
|
||||
IOobject
|
||||
(
|
||||
surfName,
|
||||
mesh.time().constant(),
|
||||
"triSurface",
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
surfDict_
|
||||
);
|
||||
}
|
||||
|
||||
return surfPtr_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicAMIPolyPatch::resetAMI
|
||||
(
|
||||
const UList<point>& points,
|
||||
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod
|
||||
) const
|
||||
void Foam::cyclicAMIPolyPatch::resetAMI() const
|
||||
{
|
||||
resetAMI(boundaryMesh().mesh().points());
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicAMIPolyPatch::resetAMI(const UList<point>& points) const
|
||||
{
|
||||
DebugInFunction << endl;
|
||||
|
||||
@ -310,11 +335,9 @@ void Foam::cyclicAMIPolyPatch::resetAMI
|
||||
return;
|
||||
}
|
||||
|
||||
AMIPtr_.clear();
|
||||
|
||||
const cyclicAMIPolyPatch& nbr = neighbPatch();
|
||||
pointField srcPoints(points, meshPoints());
|
||||
pointField nbrPoints(points, neighbPatch().meshPoints());
|
||||
pointField srcPoints(localPoints());
|
||||
pointField nbrPoints(nbr.localPoints());
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -343,20 +366,12 @@ void Foam::cyclicAMIPolyPatch::resetAMI
|
||||
transformPosition(nbrPoints);
|
||||
primitivePatch nbrPatch0
|
||||
(
|
||||
SubList<face>
|
||||
(
|
||||
nbr.localFaces(),
|
||||
nbrPatchSize0
|
||||
),
|
||||
SubList<face>(nbr.localFaces(), nbrPatchSize0),
|
||||
nbrPoints
|
||||
);
|
||||
primitivePatch patch0
|
||||
(
|
||||
SubList<face>
|
||||
(
|
||||
localFaces(),
|
||||
patchSize0
|
||||
),
|
||||
SubList<face>(localFaces(), patchSize0),
|
||||
srcPoints
|
||||
);
|
||||
|
||||
@ -372,23 +387,8 @@ void Foam::cyclicAMIPolyPatch::resetAMI
|
||||
}
|
||||
|
||||
// Construct/apply AMI interpolation to determine addressing and weights
|
||||
AMIPtr_.reset
|
||||
(
|
||||
new AMIPatchToPatchInterpolation
|
||||
(
|
||||
patch0, // *this,
|
||||
nbrPatch0,
|
||||
surfPtr(),
|
||||
faceAreaIntersect::tmMesh,
|
||||
AMIRequireMatch_,
|
||||
AMIMethod,
|
||||
AMILowWeightCorrection_,
|
||||
AMIReverse_
|
||||
)
|
||||
);
|
||||
|
||||
// Set the updated flag
|
||||
updated_ = true;
|
||||
AMIPtr_->upToDate() = false;
|
||||
AMIPtr_->calculate(patch0, nbrPatch0, surfPtr());
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -424,28 +424,21 @@ void Foam::cyclicAMIPolyPatch::calcTransforms()
|
||||
half1Areas
|
||||
);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "calcTransforms() : patch: " << name() << nl
|
||||
DebugPout
|
||||
<< "calcTransforms() : patch: " << name() << nl
|
||||
<< " forwardT = " << forwardT() << nl
|
||||
<< " reverseT = " << reverseT() << nl
|
||||
<< " separation = " << separation() << nl
|
||||
<< " collocated = " << collocated() << nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicAMIPolyPatch::initGeometry(PstreamBuffers& pBufs)
|
||||
{
|
||||
DebugInFunction << endl;
|
||||
|
||||
// Only resetting the AMI if not creating additional AMI faces
|
||||
// - When creating additional faces the AMI is updated externally by the
|
||||
// dynamic mesh via the setTopology function.
|
||||
if (!createAMIFaces_ && canResetAMI())
|
||||
{
|
||||
resetAMI(AMIMethod_);
|
||||
}
|
||||
// Flag AMI as needing update
|
||||
AMIPtr_->upToDate() = false;
|
||||
|
||||
polyPatch::initGeometry(pBufs);
|
||||
|
||||
@ -491,7 +484,7 @@ void Foam::cyclicAMIPolyPatch::initMovePoints
|
||||
}
|
||||
else
|
||||
{
|
||||
resetAMI(p, AMIMethod_);
|
||||
AMIPtr_->upToDate() = false;
|
||||
}
|
||||
|
||||
// Early calculation of transforms. See above.
|
||||
@ -551,9 +544,9 @@ void Foam::cyclicAMIPolyPatch::clearGeom()
|
||||
|
||||
if (!updatingAMI_)
|
||||
{
|
||||
//DEBUG("*** CLEARING AMI ***");
|
||||
AMIPtr_.clear();
|
||||
AMIPtr_->upToDate() = false;
|
||||
}
|
||||
|
||||
polyPatch::clearGeom();
|
||||
}
|
||||
|
||||
@ -568,11 +561,11 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
|
||||
const label index,
|
||||
const polyBoundaryMesh& bm,
|
||||
const word& patchType,
|
||||
const transformType transform
|
||||
const transformType transform,
|
||||
const word& defaultAMIMethod
|
||||
)
|
||||
:
|
||||
coupledPolyPatch(name, size, start, index, bm, patchType, transform),
|
||||
updated_(false),
|
||||
nbrPatchName_(word::null),
|
||||
nbrPatchID_(-1),
|
||||
rotationAxis_(Zero),
|
||||
@ -580,14 +573,11 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
|
||||
rotationAngleDefined_(false),
|
||||
rotationAngle_(0.0),
|
||||
separationVector_(Zero),
|
||||
AMIPtr_(nullptr),
|
||||
AMIMethod_(AMIPatchToPatchInterpolation::imFaceAreaWeight),
|
||||
AMIReverse_(false),
|
||||
AMIRequireMatch_(true),
|
||||
AMILowWeightCorrection_(-1.0),
|
||||
surfPtr_(nullptr),
|
||||
AMIPtr_(AMIInterpolation::New(defaultAMIMethod)),
|
||||
surfDict_(fileName("surface")),
|
||||
surfPtr_(nullptr),
|
||||
createAMIFaces_(false),
|
||||
moveFaceCentres_(false),
|
||||
updatingAMI_(true),
|
||||
srcFaceIDs_(),
|
||||
tgtFaceIDs_(),
|
||||
@ -605,12 +595,12 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
|
||||
const dictionary& dict,
|
||||
const label index,
|
||||
const polyBoundaryMesh& bm,
|
||||
const word& patchType
|
||||
const word& patchType,
|
||||
const word& defaultAMIMethod
|
||||
)
|
||||
:
|
||||
coupledPolyPatch(name, dict, index, bm, patchType),
|
||||
updated_(false),
|
||||
nbrPatchName_(dict.getOrDefault<word>("neighbourPatch", "")),
|
||||
nbrPatchName_(dict.getOrDefault<word>("neighbourPatch", word::null)),
|
||||
coupleGroup_(dict),
|
||||
nbrPatchID_(-1),
|
||||
rotationAxis_(Zero),
|
||||
@ -618,27 +608,19 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
|
||||
rotationAngleDefined_(false),
|
||||
rotationAngle_(0.0),
|
||||
separationVector_(Zero),
|
||||
AMIPtr_(nullptr),
|
||||
AMIMethod_
|
||||
AMIPtr_
|
||||
(
|
||||
AMIPatchToPatchInterpolation::interpolationMethodNames_
|
||||
[
|
||||
dict.getOrDefault
|
||||
AMIInterpolation::New
|
||||
(
|
||||
"method",
|
||||
AMIPatchToPatchInterpolation::interpolationMethodNames_
|
||||
[
|
||||
AMIPatchToPatchInterpolation::imFaceAreaWeight
|
||||
]
|
||||
dict.getOrDefault<word>("AMIMethod", defaultAMIMethod),
|
||||
dict,
|
||||
dict.getOrDefault("flipNormals", false)
|
||||
)
|
||||
]
|
||||
),
|
||||
AMIReverse_(dict.getOrDefault("flipNormals", false)),
|
||||
AMIRequireMatch_(true),
|
||||
AMILowWeightCorrection_(dict.getOrDefault("lowWeightCorrection", -1.0)),
|
||||
surfPtr_(nullptr),
|
||||
surfDict_(dict.subOrEmptyDict("surface")),
|
||||
createAMIFaces_(false),
|
||||
surfPtr_(nullptr),
|
||||
createAMIFaces_(dict.getOrDefault("createAMIFaces", false)),
|
||||
moveFaceCentres_(false),
|
||||
updatingAMI_(true),
|
||||
srcFaceIDs_(),
|
||||
tgtFaceIDs_(),
|
||||
@ -704,18 +686,13 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
|
||||
// Neighbour patch might not be valid yet so no transformation
|
||||
// calculation possible
|
||||
|
||||
// If topology change, recover the sizes of the original patches
|
||||
label srcSize0 = 0;
|
||||
if (dict.readIfPresent("srcSize", srcSize0))
|
||||
// If topology change, recover the sizes of the original patches and
|
||||
// read additional controls
|
||||
if (createAMIFaces_)
|
||||
{
|
||||
srcFaceIDs_.setSize(srcSize0);
|
||||
createAMIFaces_ = true;
|
||||
}
|
||||
label tgtSize0 = 0;
|
||||
if (dict.readIfPresent("tgtSize", tgtSize0))
|
||||
{
|
||||
tgtFaceIDs_.setSize(tgtSize0);
|
||||
createAMIFaces_ = true;
|
||||
srcFaceIDs_.setSize(dict.get<label>("srcSize"));
|
||||
tgtFaceIDs_.setSize(dict.get<label>("tgtSize"));
|
||||
moveFaceCentres_ = dict.getOrDefault("moveFaceCentres", true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -727,7 +704,6 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
|
||||
)
|
||||
:
|
||||
coupledPolyPatch(pp, bm),
|
||||
updated_(false),
|
||||
nbrPatchName_(pp.nbrPatchName_),
|
||||
coupleGroup_(pp.coupleGroup_),
|
||||
nbrPatchID_(-1),
|
||||
@ -736,14 +712,11 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
|
||||
rotationAngleDefined_(pp.rotationAngleDefined_),
|
||||
rotationAngle_(pp.rotationAngle_),
|
||||
separationVector_(pp.separationVector_),
|
||||
AMIPtr_(nullptr),
|
||||
AMIMethod_(pp.AMIMethod_),
|
||||
AMIReverse_(pp.AMIReverse_),
|
||||
AMIRequireMatch_(pp.AMIRequireMatch_),
|
||||
AMILowWeightCorrection_(pp.AMILowWeightCorrection_),
|
||||
surfPtr_(nullptr),
|
||||
AMIPtr_(pp.AMIPtr_->clone()),
|
||||
surfDict_(pp.surfDict_),
|
||||
createAMIFaces_(false),
|
||||
surfPtr_(nullptr),
|
||||
createAMIFaces_(pp.createAMIFaces_),
|
||||
moveFaceCentres_(pp.moveFaceCentres_),
|
||||
updatingAMI_(true),
|
||||
srcFaceIDs_(),
|
||||
tgtFaceIDs_(),
|
||||
@ -766,7 +739,6 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
|
||||
)
|
||||
:
|
||||
coupledPolyPatch(pp, bm, index, newSize, newStart),
|
||||
updated_(false),
|
||||
nbrPatchName_(nbrPatchName),
|
||||
coupleGroup_(pp.coupleGroup_),
|
||||
nbrPatchID_(-1),
|
||||
@ -775,14 +747,11 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
|
||||
rotationAngleDefined_(pp.rotationAngleDefined_),
|
||||
rotationAngle_(pp.rotationAngle_),
|
||||
separationVector_(pp.separationVector_),
|
||||
AMIPtr_(nullptr),
|
||||
AMIMethod_(pp.AMIMethod_),
|
||||
AMIReverse_(pp.AMIReverse_),
|
||||
AMIRequireMatch_(pp.AMIRequireMatch_),
|
||||
AMILowWeightCorrection_(pp.AMILowWeightCorrection_),
|
||||
surfPtr_(nullptr),
|
||||
AMIPtr_(pp.AMIPtr_->clone()),
|
||||
surfDict_(pp.surfDict_),
|
||||
createAMIFaces_(false),
|
||||
surfPtr_(nullptr),
|
||||
createAMIFaces_(pp.createAMIFaces_),
|
||||
moveFaceCentres_(pp.moveFaceCentres_),
|
||||
updatingAMI_(true),
|
||||
srcFaceIDs_(),
|
||||
tgtFaceIDs_(),
|
||||
@ -812,7 +781,6 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
|
||||
)
|
||||
:
|
||||
coupledPolyPatch(pp, bm, index, mapAddressing, newStart),
|
||||
updated_(false),
|
||||
nbrPatchName_(pp.nbrPatchName_),
|
||||
coupleGroup_(pp.coupleGroup_),
|
||||
nbrPatchID_(-1),
|
||||
@ -821,14 +789,11 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
|
||||
rotationAngleDefined_(pp.rotationAngleDefined_),
|
||||
rotationAngle_(pp.rotationAngle_),
|
||||
separationVector_(pp.separationVector_),
|
||||
AMIPtr_(nullptr),
|
||||
AMIMethod_(pp.AMIMethod_),
|
||||
AMIReverse_(pp.AMIReverse_),
|
||||
AMIRequireMatch_(pp.AMIRequireMatch_),
|
||||
AMILowWeightCorrection_(pp.AMILowWeightCorrection_),
|
||||
surfPtr_(nullptr),
|
||||
AMIPtr_(pp.AMIPtr_->clone()),
|
||||
surfDict_(pp.surfDict_),
|
||||
createAMIFaces_(false),
|
||||
surfPtr_(nullptr),
|
||||
createAMIFaces_(pp.createAMIFaces_),
|
||||
moveFaceCentres_(pp.moveFaceCentres_),
|
||||
updatingAMI_(true),
|
||||
srcFaceIDs_(),
|
||||
tgtFaceIDs_(),
|
||||
@ -888,38 +853,6 @@ const Foam::cyclicAMIPolyPatch& Foam::cyclicAMIPolyPatch::neighbPatch() const
|
||||
}
|
||||
|
||||
|
||||
const Foam::autoPtr<Foam::searchableSurface>&
|
||||
Foam::cyclicAMIPolyPatch::surfPtr() const
|
||||
{
|
||||
const word surfType(surfDict_.getOrDefault<word>("type", "none"));
|
||||
|
||||
if (!surfPtr_.valid() && owner() && surfType != "none")
|
||||
{
|
||||
word surfName(surfDict_.getOrDefault("name", name()));
|
||||
|
||||
const polyMesh& mesh = boundaryMesh().mesh();
|
||||
|
||||
surfPtr_ =
|
||||
searchableSurface::New
|
||||
(
|
||||
surfType,
|
||||
IOobject
|
||||
(
|
||||
surfName,
|
||||
mesh.time().constant(),
|
||||
"triSurface",
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
surfDict_
|
||||
);
|
||||
}
|
||||
|
||||
return surfPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::AMIPatchToPatchInterpolation& Foam::cyclicAMIPolyPatch::AMI() const
|
||||
{
|
||||
if (!owner())
|
||||
@ -929,9 +862,9 @@ const Foam::AMIPatchToPatchInterpolation& Foam::cyclicAMIPolyPatch::AMI() const
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (!AMIPtr_.valid())
|
||||
if (!AMIPtr_->upToDate())
|
||||
{
|
||||
resetAMI(AMIMethod_);
|
||||
resetAMI();
|
||||
}
|
||||
|
||||
return *AMIPtr_;
|
||||
@ -1206,27 +1139,7 @@ void Foam::cyclicAMIPolyPatch::write(Ostream& os) const
|
||||
}
|
||||
}
|
||||
|
||||
if (AMIMethod_ != AMIPatchToPatchInterpolation::imFaceAreaWeight)
|
||||
{
|
||||
os.writeEntry
|
||||
(
|
||||
"method",
|
||||
AMIPatchToPatchInterpolation::interpolationMethodNames_
|
||||
[
|
||||
AMIMethod_
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
if (AMIReverse_)
|
||||
{
|
||||
os.writeEntry("flipNormals", AMIReverse_);
|
||||
}
|
||||
|
||||
if (AMILowWeightCorrection_ > 0)
|
||||
{
|
||||
os.writeEntry("lowWeightCorrection", AMILowWeightCorrection_);
|
||||
}
|
||||
AMIPtr_->write(os);
|
||||
|
||||
if (!surfDict_.empty())
|
||||
{
|
||||
@ -1235,8 +1148,10 @@ void Foam::cyclicAMIPolyPatch::write(Ostream& os) const
|
||||
|
||||
if (createAMIFaces_)
|
||||
{
|
||||
os.writeEntry("createAMIFaces", createAMIFaces_);
|
||||
os.writeEntry("srcSize", srcFaceIDs_.size());
|
||||
os.writeEntry("tgtSize", tgtFaceIDs_.size());
|
||||
os.writeEntry("moveFaceCentres", moveFaceCentres_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2018-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -41,6 +42,7 @@ SourceFiles
|
||||
#include "AMIPatchToPatchInterpolation.H"
|
||||
#include "polyBoundaryMesh.H"
|
||||
#include "coupleGroupIdentifier.H"
|
||||
#include "faceAreaWeightAMI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -74,9 +76,6 @@ protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Flag to indicate that AMI has been updated
|
||||
mutable bool updated_;
|
||||
|
||||
//- Name of other half
|
||||
mutable word nbrPatchName_;
|
||||
|
||||
@ -113,24 +112,12 @@ protected:
|
||||
//- AMI interpolation class
|
||||
mutable autoPtr<AMIPatchToPatchInterpolation> AMIPtr_;
|
||||
|
||||
//- AMI method
|
||||
const AMIPatchToPatchInterpolation::interpolationMethod AMIMethod_;
|
||||
|
||||
//- Flag to indicate that slave patch should be reversed for AMI
|
||||
const bool AMIReverse_;
|
||||
|
||||
//- Flag to indicate that patches should match/overlap
|
||||
bool AMIRequireMatch_;
|
||||
|
||||
//- Low weight correction threshold for AMI
|
||||
const scalar AMILowWeightCorrection_;
|
||||
//- Dictionary used during projection surface construction
|
||||
const dictionary surfDict_;
|
||||
|
||||
//- Projection surface
|
||||
mutable autoPtr<searchableSurface> surfPtr_;
|
||||
|
||||
//- Dictionary used during projection surface construction
|
||||
const dictionary surfDict_;
|
||||
|
||||
|
||||
// Change of topology as AMI is updated
|
||||
|
||||
@ -138,6 +125,9 @@ protected:
|
||||
// Set by the call to changeTopology
|
||||
mutable bool createAMIFaces_;
|
||||
|
||||
//- Move face centres (default = no)
|
||||
bool moveFaceCentres_;
|
||||
|
||||
mutable bool updatingAMI_;
|
||||
|
||||
labelListList srcFaceIDs_;
|
||||
@ -163,21 +153,14 @@ protected:
|
||||
|
||||
virtual void restoreScaledGeometry();
|
||||
|
||||
//- Create and return pointer to the projection surface
|
||||
const autoPtr<searchableSurface>& surfPtr() const;
|
||||
|
||||
//- Reset the AMI interpolator, supply patch points
|
||||
virtual void resetAMI
|
||||
(
|
||||
const UList<point>& points,
|
||||
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod =
|
||||
AMIPatchToPatchInterpolation::imFaceAreaWeight
|
||||
) const;
|
||||
virtual void resetAMI(const UList<point>& points) const;
|
||||
|
||||
//- Reset the AMI interpolator, use current patch points
|
||||
virtual void resetAMI
|
||||
(
|
||||
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod =
|
||||
AMIPatchToPatchInterpolation::imFaceAreaWeight
|
||||
) const;
|
||||
virtual void resetAMI() const;
|
||||
|
||||
//- Recalculate the transformation tensors
|
||||
virtual void calcTransforms();
|
||||
@ -221,7 +204,8 @@ public:
|
||||
const label index,
|
||||
const polyBoundaryMesh& bm,
|
||||
const word& patchType,
|
||||
const transformType transform = UNKNOWN
|
||||
const transformType transform = UNKNOWN,
|
||||
const word& defaultAMIMethod = faceAreaWeightAMI::typeName
|
||||
);
|
||||
|
||||
//- Construct from dictionary
|
||||
@ -231,7 +215,8 @@ public:
|
||||
const dictionary& dict,
|
||||
const label index,
|
||||
const polyBoundaryMesh& bm,
|
||||
const word& patchType
|
||||
const word& patchType,
|
||||
const word& defaultAMIMethod = faceAreaWeightAMI::typeName
|
||||
);
|
||||
|
||||
//- Construct as copy, resetting the boundary mesh
|
||||
@ -328,23 +313,12 @@ public:
|
||||
//- Flag to indicate whether the AMI can be reset
|
||||
inline bool canResetAMI() const;
|
||||
|
||||
//- Reset the updated flag
|
||||
inline void setUpdated(bool flag) const;
|
||||
|
||||
//- Return access to the updated flag
|
||||
inline bool updated() const;
|
||||
|
||||
//- Return access to the createAMIFaces flag
|
||||
inline bool createAMIFaces() const;
|
||||
|
||||
//- Return access to the updated flag
|
||||
inline bool updatingAMI() const;
|
||||
|
||||
void clearAMI() const
|
||||
{
|
||||
AMIPtr_.clear();
|
||||
}
|
||||
|
||||
//- Return true if this patch changes the mesh topology
|
||||
// True when createAMIFaces is true
|
||||
virtual bool changeTopology() const;
|
||||
@ -371,9 +345,6 @@ void clearAMI() const
|
||||
//- Return a reference to the neighbour patch
|
||||
virtual const cyclicAMIPolyPatch& neighbPatch() const;
|
||||
|
||||
//- Return a reference to the projection surface
|
||||
const autoPtr<searchableSurface>& surfPtr() const;
|
||||
|
||||
//- Return a reference to the AMI interpolator
|
||||
const AMIPatchToPatchInterpolation& AMI() const;
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -34,18 +34,6 @@ inline bool Foam::cyclicAMIPolyPatch::canResetAMI() const
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::cyclicAMIPolyPatch::setUpdated(const bool flag) const
|
||||
{
|
||||
updated_ = flag;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::cyclicAMIPolyPatch::updated() const
|
||||
{
|
||||
return updated_;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::cyclicAMIPolyPatch::createAMIFaces() const
|
||||
{
|
||||
return createAMIFaces_;
|
||||
|
||||
@ -2,8 +2,10 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -53,30 +55,28 @@ void Foam::cyclicAMIPolyPatch::restoreScaledGeometry()
|
||||
vectorField::subField faceAreas = this->faceAreas();
|
||||
vectorField::subField faceCentres = this->faceCentres();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Patch:" << name() << " before: sum(mag(faceAreas)):"
|
||||
<< gSum(mag(faceAreas)) << endl;
|
||||
Info<< "Patch:" << name() << " before: sum(mag(faceAreas0)):"
|
||||
DebugInfo
|
||||
<< "Patch:" << name() << " before: sum(mag(faceAreas)):"
|
||||
<< gSum(mag(faceAreas)) << nl
|
||||
<< "Patch:" << name() << " before: sum(mag(faceAreas0)):"
|
||||
<< gSum(mag(faceAreas0_)) << endl;
|
||||
}
|
||||
|
||||
faceAreas = faceAreas0_;
|
||||
Info<< "WARNING: ==============================" << endl;
|
||||
Info<< "WARNING: Not updating face cell centres" << endl;
|
||||
Info<< "WARNING: ==============================" << endl;
|
||||
//faceCentres = faceCentres0_;
|
||||
if (moveFaceCentres_)
|
||||
{
|
||||
DebugInfo << "Moving face centres" << endl;
|
||||
faceCentres = faceCentres0_;
|
||||
}
|
||||
|
||||
faceAreas0_.clear();
|
||||
faceCentres0_.clear();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Patch:" << name() << " after: sum(mag(faceAreas)):"
|
||||
<< gSum(mag(faceAreas)) << endl;
|
||||
Info<< "Patch:" << name() << " after: sum(mag(faceAreas0)):"
|
||||
DebugInfo
|
||||
<< "Patch:" << name() << " after: sum(mag(faceAreas)):"
|
||||
<< gSum(mag(faceAreas)) << nl
|
||||
<< "Patch:" << name() << " after: sum(mag(faceAreas0)):"
|
||||
<< gSum(mag(faceAreas0_)) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Foam::cyclicAMIPolyPatch::removeAMIFaces(polyTopoChange& topoChange)
|
||||
@ -614,9 +614,9 @@ void Foam::cyclicAMIPolyPatch::setAMIFaces()
|
||||
}
|
||||
}
|
||||
|
||||
// Update the AMI addressing and weights to reflect the new 1-to-1
|
||||
// Reset the AMI addressing and weights to reflect the new 1-to-1
|
||||
// correspondence
|
||||
AMIPtr_->update
|
||||
AMIPtr_->reset
|
||||
(
|
||||
std::move(srcToTgtMap1),
|
||||
std::move(tgtToSrcMap1),
|
||||
@ -626,7 +626,9 @@ void Foam::cyclicAMIPolyPatch::setAMIFaces()
|
||||
std::move(newTgtToSrcWeights)
|
||||
);
|
||||
|
||||
AMIPtr_->setAreas(mag(faceAreas0_), mag(nbrFaceAreas0));
|
||||
// Need to set areas, e.g. for agglomeration to (re-)normalisation weights
|
||||
AMIPtr_->srcMagSf() = mag(faceAreas0_);
|
||||
AMIPtr_->tgtMagSf() = mag(nbrFaceAreas0);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -660,7 +662,7 @@ bool Foam::cyclicAMIPolyPatch::setTopology(polyTopoChange& topoChange)
|
||||
{
|
||||
// Calculate the AMI using the new points
|
||||
// Note: mesh still has old points
|
||||
resetAMI(topoChange.points(), AMIMethod_);
|
||||
resetAMI(topoChange.points());
|
||||
|
||||
removeAMIFaces(topoChange);
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "cyclicPeriodicAMIPolyPatch.H"
|
||||
#include "partialFaceAreaWeightAMI.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// For debugging
|
||||
@ -228,10 +229,7 @@ void Foam::cyclicPeriodicAMIPolyPatch::writeOBJ
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicPeriodicAMIPolyPatch::resetAMI
|
||||
(
|
||||
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod
|
||||
) const
|
||||
void Foam::cyclicPeriodicAMIPolyPatch::resetAMI() const
|
||||
{
|
||||
if (owner())
|
||||
{
|
||||
@ -326,20 +324,8 @@ void Foam::cyclicPeriodicAMIPolyPatch::resetAMI
|
||||
);
|
||||
|
||||
// Construct a new AMI interpolation between the initial patch locations
|
||||
AMIPtr_.reset
|
||||
(
|
||||
new AMIPatchToPatchInterpolation
|
||||
(
|
||||
thisPatch0,
|
||||
nbrPatch0,
|
||||
surfPtr(),
|
||||
faceAreaIntersect::tmMesh,
|
||||
false,
|
||||
AMIPatchToPatchInterpolation::imPartialFaceAreaWeight,
|
||||
AMILowWeightCorrection_,
|
||||
AMIReverse_
|
||||
)
|
||||
);
|
||||
AMIPtr_->setRequireMatch(false);
|
||||
AMIPtr_->calculate(thisPatch0, nbrPatch0, surfPtr());
|
||||
|
||||
// Number of geometry replications
|
||||
label iter(0);
|
||||
@ -358,7 +344,6 @@ void Foam::cyclicPeriodicAMIPolyPatch::resetAMI
|
||||
// Weight sum averages
|
||||
scalar srcSum(gAverage(AMIPtr_->srcWeightsSum()));
|
||||
scalar tgtSum(gAverage(AMIPtr_->tgtWeightsSum()));
|
||||
|
||||
// Direction (or rather side of AMI : this or nbr patch) of
|
||||
// geometry replication
|
||||
bool direction = nTransforms_ >= 0;
|
||||
@ -527,10 +512,6 @@ void Foam::cyclicPeriodicAMIPolyPatch::resetAMI
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Normalise the weights. Disable printing since weights are
|
||||
// still areas.
|
||||
AMIPtr_->normaliseWeights(true, false);
|
||||
|
||||
// Print some statistics
|
||||
const label nFace = returnReduce(size(), sumOp<label>());
|
||||
|
||||
@ -577,7 +558,17 @@ Foam::cyclicPeriodicAMIPolyPatch::cyclicPeriodicAMIPolyPatch
|
||||
const transformType transform
|
||||
)
|
||||
:
|
||||
cyclicAMIPolyPatch(name, size, start, index, bm, patchType, transform),
|
||||
cyclicAMIPolyPatch
|
||||
(
|
||||
name,
|
||||
size,
|
||||
start,
|
||||
index,
|
||||
bm,
|
||||
patchType,
|
||||
transform,
|
||||
partialFaceAreaWeightAMI::typeName
|
||||
),
|
||||
periodicPatchName_(word::null),
|
||||
periodicPatchID_(-1),
|
||||
nTransforms_(0),
|
||||
@ -595,7 +586,15 @@ Foam::cyclicPeriodicAMIPolyPatch::cyclicPeriodicAMIPolyPatch
|
||||
const word& patchType
|
||||
)
|
||||
:
|
||||
cyclicAMIPolyPatch(name, dict, index, bm, patchType),
|
||||
cyclicAMIPolyPatch
|
||||
(
|
||||
name,
|
||||
dict,
|
||||
index,
|
||||
bm,
|
||||
patchType,
|
||||
partialFaceAreaWeightAMI::typeName
|
||||
),
|
||||
periodicPatchName_(dict.lookup("periodicPatch")),
|
||||
periodicPatchID_(-1),
|
||||
nTransforms_(dict.getOrDefault<label>("nTransforms", 0)),
|
||||
|
||||
@ -83,11 +83,7 @@ private:
|
||||
void writeOBJ(const primitivePatch& p, OBJstream& str) const;
|
||||
|
||||
//- Reset the AMI interpolator
|
||||
virtual void resetAMI
|
||||
(
|
||||
const AMIPatchToPatchInterpolation::interpolationMethod& AMIMethod =
|
||||
AMIPatchToPatchInterpolation::imFaceAreaWeight
|
||||
) const;
|
||||
virtual void resetAMI() const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@ -259,8 +259,13 @@ processorLOD/cellBox/cellBox.C
|
||||
processorLOD/faceBox/faceBox.C
|
||||
|
||||
AMI=AMIInterpolation
|
||||
$(AMI)/AMIInterpolation/AMIInterpolationName.C
|
||||
$(AMI)/AMIInterpolation/AMIPatchToPatchInterpolation.C
|
||||
$(AMI)/AMIInterpolation/AMIInterpolation.C
|
||||
$(AMI)/AMIInterpolation/AMIInterpolationNew.C
|
||||
$(AMI)/AMIInterpolation/advancingFrontAMI/advancingFrontAMI.C
|
||||
$(AMI)/AMIInterpolation/advancingFrontAMI/advancingFrontAMIParallelOps.C
|
||||
$(AMI)/AMIInterpolation/faceAreaWeightAMI/faceAreaWeightAMI.C
|
||||
$(AMI)/AMIInterpolation/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.C
|
||||
$(AMI)/AMIInterpolation/nearestFaceAMI/nearestFaceAMI.C
|
||||
$(AMI)/faceAreaIntersect/faceAreaIntersect.C
|
||||
$(AMI)/GAMG/interfaces/cyclicAMIGAMGInterface/cyclicAMIGAMGInterface.C
|
||||
$(AMI)/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C
|
||||
|
||||
@ -45,6 +45,7 @@ License
|
||||
#include "syncTools.H"
|
||||
#include "treeDataCell.H"
|
||||
#include "DynamicField.H"
|
||||
#include "faceAreaWeightAMI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -791,15 +792,13 @@ const
|
||||
|
||||
void Foam::mappedPatchBase::calcAMI() const
|
||||
{
|
||||
if (AMIPtr_.valid())
|
||||
if (AMIPtr_->upToDate())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "AMI already calculated" << exit(FatalError);
|
||||
WarningInFunction
|
||||
<< "AMI already up-to-date"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
AMIPtr_.clear();
|
||||
|
||||
|
||||
const polyPatch& nbr = samplePolyPatch();
|
||||
|
||||
// Transform neighbour patch to local system
|
||||
@ -829,29 +828,13 @@ void Foam::mappedPatchBase::calcAMI() const
|
||||
}
|
||||
|
||||
// Construct/apply AMI interpolation to determine addressing and weights
|
||||
AMIPtr_.reset
|
||||
(
|
||||
new AMIPatchToPatchInterpolation
|
||||
(
|
||||
patch_,
|
||||
nbrPatch0,
|
||||
surfPtr(),
|
||||
faceAreaIntersect::tmMesh,
|
||||
true,
|
||||
AMIPatchToPatchInterpolation::imFaceAreaWeight,
|
||||
-1,
|
||||
AMIReverse_
|
||||
)
|
||||
);
|
||||
AMIPtr_->calculate(patch_, nbrPatch0, surfPtr());
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::mappedPatchBase::mappedPatchBase
|
||||
(
|
||||
const polyPatch& pp
|
||||
)
|
||||
Foam::mappedPatchBase::mappedPatchBase(const polyPatch& pp)
|
||||
:
|
||||
patch_(pp),
|
||||
sampleRegion_(patch_.boundaryMesh().mesh().name()),
|
||||
@ -864,8 +847,8 @@ Foam::mappedPatchBase::mappedPatchBase
|
||||
distance_(0),
|
||||
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
||||
mapPtr_(nullptr),
|
||||
AMIPtr_(nullptr),
|
||||
AMIReverse_(false),
|
||||
AMIPtr_(new faceAreaWeightAMI(true, AMIReverse_)),
|
||||
surfPtr_(nullptr),
|
||||
surfDict_(fileName("surface"))
|
||||
{}
|
||||
@ -891,8 +874,8 @@ Foam::mappedPatchBase::mappedPatchBase
|
||||
distance_(0),
|
||||
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
||||
mapPtr_(nullptr),
|
||||
AMIPtr_(nullptr),
|
||||
AMIReverse_(false),
|
||||
AMIPtr_(new faceAreaWeightAMI(true, AMIReverse_)),
|
||||
surfPtr_(nullptr),
|
||||
surfDict_(fileName("surface"))
|
||||
{}
|
||||
@ -918,8 +901,8 @@ Foam::mappedPatchBase::mappedPatchBase
|
||||
distance_(0),
|
||||
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
||||
mapPtr_(nullptr),
|
||||
AMIPtr_(nullptr),
|
||||
AMIReverse_(false),
|
||||
AMIPtr_(new faceAreaWeightAMI(true, AMIReverse_)),
|
||||
surfPtr_(nullptr),
|
||||
surfDict_(fileName("surface"))
|
||||
{}
|
||||
@ -945,8 +928,8 @@ Foam::mappedPatchBase::mappedPatchBase
|
||||
distance_(distance),
|
||||
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
||||
mapPtr_(nullptr),
|
||||
AMIPtr_(nullptr),
|
||||
AMIReverse_(false),
|
||||
AMIPtr_(new faceAreaWeightAMI(true, AMIReverse_)),
|
||||
surfPtr_(nullptr),
|
||||
surfDict_(fileName("surface"))
|
||||
{}
|
||||
@ -969,8 +952,16 @@ Foam::mappedPatchBase::mappedPatchBase
|
||||
distance_(0),
|
||||
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
||||
mapPtr_(nullptr),
|
||||
AMIPtr_(nullptr),
|
||||
AMIReverse_(dict.getOrDefault("flipNormals", false)),
|
||||
AMIPtr_
|
||||
(
|
||||
AMIInterpolation::New
|
||||
(
|
||||
dict.getOrDefault("AMIMethod", faceAreaWeightAMI::typeName),
|
||||
dict,
|
||||
AMIReverse_
|
||||
)
|
||||
),
|
||||
surfPtr_(nullptr),
|
||||
surfDict_(dict.subOrEmptyDict("surface"))
|
||||
{
|
||||
@ -1044,8 +1035,16 @@ Foam::mappedPatchBase::mappedPatchBase
|
||||
distance_(0),
|
||||
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
|
||||
mapPtr_(nullptr),
|
||||
AMIPtr_(nullptr),
|
||||
AMIReverse_(dict.getOrDefault("flipNormals", false)),
|
||||
AMIPtr_
|
||||
(
|
||||
AMIInterpolation::New
|
||||
(
|
||||
dict.lookupOrDefault("AMIMethod", faceAreaWeightAMI::typeName),
|
||||
dict,
|
||||
AMIReverse_
|
||||
)
|
||||
),
|
||||
surfPtr_(nullptr),
|
||||
surfDict_(dict.subOrEmptyDict("surface"))
|
||||
{
|
||||
@ -1089,8 +1088,8 @@ Foam::mappedPatchBase::mappedPatchBase
|
||||
distance_(mpb.distance_),
|
||||
sameRegion_(mpb.sameRegion_),
|
||||
mapPtr_(nullptr),
|
||||
AMIPtr_(nullptr),
|
||||
AMIReverse_(mpb.AMIReverse_),
|
||||
AMIPtr_(mpb.AMIPtr_->clone()),
|
||||
surfPtr_(nullptr),
|
||||
surfDict_(mpb.surfDict_)
|
||||
{}
|
||||
@ -1119,8 +1118,8 @@ Foam::mappedPatchBase::mappedPatchBase
|
||||
distance_(mpb.distance_),
|
||||
sameRegion_(mpb.sameRegion_),
|
||||
mapPtr_(nullptr),
|
||||
AMIPtr_(nullptr),
|
||||
AMIReverse_(mpb.AMIReverse_),
|
||||
AMIPtr_(mpb.AMIPtr_->clone()),
|
||||
surfPtr_(nullptr),
|
||||
surfDict_(mpb.surfDict_)
|
||||
{}
|
||||
@ -1137,8 +1136,8 @@ Foam::mappedPatchBase::~mappedPatchBase()
|
||||
void Foam::mappedPatchBase::clearOut()
|
||||
{
|
||||
mapPtr_.clear();
|
||||
AMIPtr_.clear();
|
||||
surfPtr_.clear();
|
||||
AMIPtr_->upToDate() = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -231,12 +231,12 @@ protected:
|
||||
|
||||
// AMI interpolator (only for NEARESTPATCHFACEAMI)
|
||||
|
||||
//- Pointer to AMI interpolator
|
||||
mutable autoPtr<AMIPatchToPatchInterpolation> AMIPtr_;
|
||||
|
||||
//- Flag to indicate that slave patch should be reversed for AMI
|
||||
const bool AMIReverse_;
|
||||
|
||||
//- Pointer to AMI interpolator
|
||||
mutable autoPtr<AMIPatchToPatchInterpolation> AMIPtr_;
|
||||
|
||||
//- Pointer to projection surface employed by AMI interpolator
|
||||
mutable autoPtr<searchableSurface> surfPtr_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user