ENH: AMI: refactored parallel handling to be local to the AMI method

This commit is contained in:
Andrew Heather
2020-04-07 20:38:39 +01:00
committed by Andrew Heather
parent a13e00b5c4
commit c357d7a760
14 changed files with 577 additions and 643 deletions

View File

@ -66,7 +66,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::patchMagSf
const faceAreaIntersect::triangulationMode triMode
)
{
tmp<scalarField> tResult(new scalarField(patch.size(), Zero));
auto tResult = tmp<scalarField>::New(patch.size(), Zero);
scalarField& result = tResult.ref();
const pointField& patchPoints = patch.localPoints();
@ -538,7 +538,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::constructFromSurface
if (surfPtr.valid())
{
// Create new patches for source and target
pointField srcPoints = srcPatch.points();
pointField srcPoints(srcPatch.points());
SourcePatch srcPatch0
(
SubList<face>
@ -559,7 +559,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::constructFromSurface
}
}
pointField tgtPoints = tgtPatch.points();
pointField tgtPoints(tgtPatch.points());
TargetPatch tgtPatch0
(
SubList<face>
@ -610,27 +610,18 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
const bool reverseTarget
)
:
methodName_(interpolationMethodNames_[method]),
reverseTarget_(reverseTarget),
requireMatch_(requireMatch),
singlePatchProc_(-999),
lowWeightCorrection_(lowWeightCorrection),
srcMagSf_(),
srcAddress_(),
srcWeights_(),
srcWeightsSum_(),
srcCentroids_(),
tgtMagSf_(),
tgtAddress_(),
tgtWeights_(),
tgtWeightsSum_(),
tgtCentroids_(),
triMode_(triMode),
srcMapPtr_(nullptr),
tgtMapPtr_(nullptr)
{
update(srcPatch, tgtPatch);
}
AMIInterpolation
(
srcPatch,
tgtPatch,
nullptr,
triMode,
requireMatch,
method,
lowWeightCorrection,
reverseTarget
)
{}
template<class SourcePatch, class TargetPatch>
@ -645,27 +636,18 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
const bool reverseTarget
)
:
methodName_(methodName),
reverseTarget_(reverseTarget),
requireMatch_(requireMatch),
singlePatchProc_(-999),
lowWeightCorrection_(lowWeightCorrection),
srcMagSf_(),
srcAddress_(),
srcWeights_(),
srcWeightsSum_(),
srcCentroids_(),
tgtMagSf_(),
tgtAddress_(),
tgtWeights_(),
tgtWeightsSum_(),
tgtCentroids_(),
triMode_(triMode),
srcMapPtr_(nullptr),
tgtMapPtr_(nullptr)
{
update(srcPatch, tgtPatch);
}
AMIInterpolation
(
srcPatch,
tgtPatch,
nullptr,
triMode,
requireMatch,
interpolationMethodNames_.get(methodName),
lowWeightCorrection,
reverseTarget
)
{}
template<class SourcePatch, class TargetPatch>
@ -717,27 +699,18 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
const bool reverseTarget
)
:
methodName_(methodName),
reverseTarget_(reverseTarget),
requireMatch_(requireMatch),
singlePatchProc_(-999),
lowWeightCorrection_(lowWeightCorrection),
srcMagSf_(),
srcAddress_(),
srcWeights_(),
srcWeightsSum_(),
srcCentroids_(),
tgtMagSf_(),
tgtAddress_(),
tgtWeights_(),
tgtWeightsSum_(),
tgtCentroids_(),
triMode_(triMode),
srcMapPtr_(nullptr),
tgtMapPtr_(nullptr)
{
constructFromSurface(srcPatch, tgtPatch, surfPtr);
}
AMIInterpolation
(
srcPatch,
tgtPatch,
surfPtr,
triMode,
requireMatch,
interpolationMethodNames_.get(methodName),
lowWeightCorrection,
reverseTarget
)
{}
template<class SourcePatch, class TargetPatch>
@ -873,188 +846,37 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
<< tgtTotalSize << " target faces"
<< endl;
// Calculate if patches present on multiple processors
singlePatchProc_ = calcDistribution(srcPatch, tgtPatch);
if (singlePatchProc_ == -1)
{
// Convert local addressing to global addressing
globalIndex globalSrcFaces(srcPatch.size());
globalIndex globalTgtFaces(tgtPatch.size());
// Create processor map of overlapping faces. This map gets
// (possibly remote) faces from the tgtPatch such that they (together)
// cover all of the srcPatch
autoPtr<mapDistribute> mapPtr = calcProcMap(srcPatch, tgtPatch);
const mapDistribute& map = mapPtr();
// 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)
labelList tgtFaceIDs;
distributeAndMergePatches
// Calculate AMI interpolation
autoPtr<AMIMethod<SourcePatch, TargetPatch>> AMIPtr
(
AMIMethod<SourcePatch, TargetPatch>::New
(
map,
methodName_,
srcPatch,
tgtPatch,
globalTgtFaces,
newTgtFaces,
newTgtPoints,
tgtFaceIDs
);
triMode_,
reverseTarget_,
requireMatch_ && (lowWeightCorrection_ < 0)
)
);
const TargetPatch
newTgtPatch
(
SubList<face>
(
newTgtFaces,
newTgtFaces.size()
),
newTgtPoints
);
AMIPtr->calculate
(
srcAddress_,
srcWeights_,
srcCentroids_,
tgtAddress_,
tgtWeights_,
srcMagSf_,
tgtMagSf_,
srcMapPtr_,
tgtMapPtr_
);
// Calculate AMI interpolation
autoPtr<AMIMethod<SourcePatch, TargetPatch>> AMIPtr
(
AMIMethod<SourcePatch, TargetPatch>::New
(
methodName_,
srcPatch,
newTgtPatch,
triMode_,
reverseTarget_,
requireMatch_ && (lowWeightCorrection_ < 0)
)
);
AMIPtr->normaliseWeights(true, *this);
AMIPtr->calculate
(
srcAddress_,
srcWeights_,
srcCentroids_,
tgtAddress_,
tgtWeights_
);
// Note: using patch face areas calculated by the AMI method
// - TODO: move into the calculate or normalise method?
AMIPtr->setMagSf(tgtPatch, map, srcMagSf_, tgtMagSf_);
// Now
// ~~~
// srcAddress_ : per srcPatch face a list of the newTgtPatch (not
// tgtPatch) faces it overlaps
// tgtAddress_ : per newTgtPatch (not tgtPatch) face a list of the
// srcPatch faces it overlaps
if (debug)
{
writeFaceConnectivity(srcPatch, newTgtPatch, srcAddress_);
}
// Rework newTgtPatch indices into globalIndices of tgtPatch
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for (labelList& addressing : srcAddress_)
{
for (label& addr : addressing)
{
addr = tgtFaceIDs[addr];
}
}
for (labelList& addressing : tgtAddress_)
{
globalSrcFaces.inplaceToGlobal(addressing);
}
// Send data back to originating procs. Note that contributions
// from different processors get added (ListOps::appendEqOp)
mapDistributeBase::distribute
(
Pstream::commsTypes::nonBlocking,
List<labelPair>(),
tgtPatch.size(),
map.constructMap(),
false, // has flip
map.subMap(),
false, // has flip
tgtAddress_,
ListOps::appendEqOp<label>(),
flipOp(), // flip operation
labelList()
);
mapDistributeBase::distribute
(
Pstream::commsTypes::nonBlocking,
List<labelPair>(),
tgtPatch.size(),
map.constructMap(),
false,
map.subMap(),
false,
tgtWeights_,
ListOps::appendEqOp<scalar>(),
flipOp(),
scalarList()
);
// weights normalisation
AMIPtr->normaliseWeights(true, *this);
// 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)
);
}
else
{
// Calculate AMI interpolation
autoPtr<AMIMethod<SourcePatch, TargetPatch>> AMIPtr
(
AMIMethod<SourcePatch, TargetPatch>::New
(
methodName_,
srcPatch,
tgtPatch,
triMode_,
reverseTarget_,
requireMatch_ && (lowWeightCorrection_ < 0)
)
);
AMIPtr->calculate
(
srcAddress_,
srcWeights_,
srcCentroids_,
tgtAddress_,
tgtWeights_
);
srcMagSf_.transfer(AMIPtr->srcMagSf());
tgtMagSf_.transfer(AMIPtr->tgtMagSf());
AMIPtr->normaliseWeights(true, *this);
}
singlePatchProc_ = AMIPtr->distributed() ? -1 : 0;
if (debug)
{
@ -1115,18 +937,15 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::append
addProfiling(ami, "AMIInterpolation::append");
// Create a new interpolation
autoPtr<AMIInterpolation<SourcePatch, TargetPatch>> newPtr
auto newPtr = autoPtr<AMIInterpolation<SourcePatch, TargetPatch>>::New
(
new AMIInterpolation<SourcePatch, TargetPatch>
(
srcPatch,
tgtPatch,
triMode_,
requireMatch_,
methodName_,
lowWeightCorrection_,
reverseTarget_
)
srcPatch,
tgtPatch,
triMode_,
requireMatch_,
methodName_,
lowWeightCorrection_,
reverseTarget_
);
// If parallel then combine the mapDistribution and re-index
@ -1514,14 +1333,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
const UList<Type>& defaultValues
) const
{
tmp<Field<Type>> tresult
(
new Field<Type>
(
srcAddress_.size(),
Zero
)
);
auto tresult = tmp<Field<Type>>::New(srcAddress_.size(), Zero);
interpolateToSource
(
@ -1559,14 +1371,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
const UList<Type>& defaultValues
) const
{
tmp<Field<Type>> tresult
(
new Field<Type>
(
tgtAddress_.size(),
Zero
)
);
auto tresult = tmp<Field<Type>>::New(tgtAddress_.size(), Zero);
interpolateToTarget
(

View File

@ -188,49 +188,6 @@ private:
void operator=(const AMIInterpolation&) = delete;
// Parallel functionality
//- 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;
// Initialisation
//- Project points to surface
@ -637,7 +594,6 @@ public:
#ifdef NoRepository
#include "AMIInterpolation.C"
#include "AMIInterpolationParallelOps.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2013-2016 OpenFOAM Foundation
Copyright (C) 2015-2018 OpenCFD Ltd.
Copyright (C) 2015-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -38,10 +38,13 @@ License
template<class SourcePatch, class TargetPatch>
void Foam::AMIMethod<SourcePatch, TargetPatch>::checkPatches() const
{
if (debug && (!srcPatch_.size() || !tgtPatch_.size()))
const auto& src = srcPatch();
const auto& tgt = tgtPatch();
if (debug && (!src.size() || !tgt.size()))
{
Pout<< "AMI: Patches not on processor: Source faces = "
<< srcPatch_.size() << ", target faces = " << tgtPatch_.size()
<< src.size() << ", target faces = " << tgt.size()
<< endl;
}
@ -50,9 +53,9 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::checkPatches() const
{
const scalar maxBoundsError = 0.05;
// check bounds of source and target
boundBox bbSrc(srcPatch_.points(), srcPatch_.meshPoints(), true);
boundBox bbTgt(tgtPatch_.points(), tgtPatch_.meshPoints(), true);
// Check bounds of source and target
boundBox bbSrc(src.points(), src.meshPoints(), true);
boundBox bbTgt(tgt.points(), tgt.meshPoints(), true);
boundBox bbTgtInf(bbTgt);
bbTgtInf.inflate(maxBoundsError);
@ -72,6 +75,56 @@ 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
{
// 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();
// 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)
distributeAndMergePatches
(
map,
tgtPatch,
globalTgtFaces,
newTgtFaces_,
newTgtPoints_,
extendedTgtFaceIDs
);
return autoPtr<TargetPatch>::New
(
SubList<face>
(
newTgtFaces_,
newTgtFaces_.size()
),
newTgtPoints_
);
}
template<class SourcePatch, class TargetPatch>
bool Foam::AMIMethod<SourcePatch, TargetPatch>::initialise
(
@ -83,38 +136,41 @@ bool Foam::AMIMethod<SourcePatch, TargetPatch>::initialise
label& tgtFacei
)
{
const auto& src = srcPatch();
const auto& tgt = tgtPatch();
checkPatches();
// set initial sizes for weights and addressing - must be done even if
// Set initial sizes for weights and addressing - must be done even if
// returns false below
srcAddress.setSize(srcPatch_.size());
srcWeights.setSize(srcPatch_.size());
tgtAddress.setSize(tgtPatch_.size());
tgtWeights.setSize(tgtPatch_.size());
srcAddress.setSize(src.size());
srcWeights.setSize(srcAddress.size());
tgtAddress.setSize(tgt.size());
tgtWeights.setSize(tgtAddress.size());
// check that patch sizes are valid
if (!srcPatch_.size())
// Check that patch sizes are valid
if (!src.size())
{
return false;
}
else if (!tgtPatch_.size())
else if (!tgt.size())
{
WarningInFunction
<< srcPatch_.size() << " source faces but no target faces" << endl;
<< src.size() << " source faces but no target faces" << endl;
return false;
}
// reset the octree
// Reset the octree
resetTree();
// find initial face match using brute force/octree search
// Find initial face match using brute force/octree search
if ((srcFacei == -1) || (tgtFacei == -1))
{
srcFacei = 0;
tgtFacei = 0;
bool foundFace = false;
forAll(srcPatch_, facei)
forAll(src, facei)
{
tgtFacei = findTargetFace(facei);
if (tgtFacei >= 0)
@ -202,10 +258,12 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::writeIntersectionOBJ
template<class SourcePatch, class TargetPatch>
void Foam::AMIMethod<SourcePatch, TargetPatch>::resetTree()
{
const auto& tgt = tgtPatch();
// Clear the old octree
treePtr_.clear();
treeBoundBox bb(tgtPatch_.points(), tgtPatch_.meshPoints());
treeBoundBox bb(tgt.points(), tgt.meshPoints());
bb.inflate(0.01);
if (!treePtr_.valid())
@ -217,7 +275,7 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::resetTree()
treeType
(
false,
tgtPatch_,
tgt,
indexedOctree<treeType>::perturbTol()
),
bb, // overall search domain
@ -238,10 +296,12 @@ Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::findTargetFace
const label srcFacePti
) const
{
const auto& src = srcPatch();
label targetFacei = -1;
const pointField& srcPts = srcPatch_.points();
const face& srcFace = srcPatch_[srcFacei];
const pointField& srcPts = src.points();
const face& srcFace = src[srcFacei];
findNearestMaskedOp<TargetPatch> fnOp(*treePtr_, excludeFaces);
@ -282,7 +342,7 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::appendNbrFaces
const labelList& nbrFaces = patch.faceFaces()[facei];
// filter out faces already visited from face neighbours
// Filter out faces already visited from face neighbours
for (const label nbrFacei : nbrFaces)
{
bool valid = true;
@ -307,7 +367,7 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::appendNbrFaces
}
}
// prevent addition of face if it is not on the same plane-ish
// Prevent addition of face if it is not on the same plane-ish
if (valid)
{
const vector& n1 = patch.faceNormals()[facei];
@ -382,14 +442,14 @@ Foam::AMIMethod<SourcePatch, TargetPatch>::AMIMethod
const bool requireMatch
)
:
srcPatch_(srcPatch),
tgtPatch_(tgtPatch),
srcPatch0_(srcPatch),
tgtPatch0_(tgtPatch),
extendedTgtPatchPtr_(nullptr),
reverseTarget_(reverseTarget),
requireMatch_(requireMatch),
srcMagSf_(srcPatch.size(), 1.0),
tgtMagSf_(tgtPatch.size(), 1.0),
srcNonOverlap_(),
triMode_(triMode)
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

View File

@ -72,6 +72,48 @@ private:
//- 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:
@ -82,10 +124,13 @@ protected:
// Protected data
//- Reference to source patch
const SourcePatch& srcPatch_;
const SourcePatch& srcPatch0_;
//- Reference to target patch
const TargetPatch& tgtPatch_;
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
@ -95,12 +140,6 @@ protected:
//- exists between them
const bool requireMatch_;
//- Source face areas
List<scalar> srcMagSf_;
//- Target face areas
List<scalar> tgtMagSf_;
//- Labels of faces that are not overlapped by any target faces
//- (should be empty for correct functioning for fully covered AMIs)
labelList srcNonOverlap_;
@ -111,11 +150,27 @@ protected:
//- 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;
@ -229,6 +284,15 @@ public:
// 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;
@ -236,42 +300,25 @@ public:
//- Flag to indicate that interpolation patches are conformal
virtual bool conformal() const;
//- Return const access to source patch face areas
inline const List<scalar>& srcMagSf() const;
//- Return access to source patch face areas
inline List<scalar>& srcMagSf();
//- Return const access to target patch face areas
inline const List<scalar>& tgtMagSf() const;
//- Return access to target patch face areas
inline List<scalar>& tgtMagSf();
// Manipulation
//- Update addressing and weights
virtual void calculate
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;
//- Set the face areas for parallel runs
virtual void setMagSf
(
const TargetPatch& tgtPatch,
const mapDistribute& map,
scalarList& srcMagSf,
scalarList& tgtMagSf
) const = 0;
//- Normalise the weight. Can optionally subset addressing
//- (e.g. for mapNearest)
virtual void normaliseWeights
@ -318,6 +365,7 @@ public:
#ifdef NoRepository
#include "AMIMethod.C"
#include "AMIMethodNew.C"
#include "AMIMethodParallelOps.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -26,34 +26,30 @@ License
\*---------------------------------------------------------------------------*/
template<class SourcePatch, class TargetPatch>
inline const Foam::List<Foam::scalar>&
Foam::AMIMethod<SourcePatch, TargetPatch>::srcMagSf() const
inline const SourcePatch&
Foam::AMIMethod<SourcePatch, TargetPatch>::srcPatch() const
{
return srcMagSf_;
return srcPatch0_;
}
template<class SourcePatch, class TargetPatch>
inline Foam::List<Foam::scalar>&
Foam::AMIMethod<SourcePatch, TargetPatch>::srcMagSf()
inline const TargetPatch&
Foam::AMIMethod<SourcePatch, TargetPatch>::tgtPatch() const
{
return srcMagSf_;
if (extendedTgtPatchPtr_)
{
return extendedTgtPatchPtr_();
}
return tgtPatch0_;
}
template<class SourcePatch, class TargetPatch>
inline const Foam::List<Foam::scalar>&
Foam::AMIMethod<SourcePatch, TargetPatch>::tgtMagSf() const
bool Foam::AMIMethod<SourcePatch, TargetPatch>::distributed() const
{
return tgtMagSf_;
}
template<class SourcePatch, class TargetPatch>
inline Foam::List<Foam::scalar>&
Foam::AMIMethod<SourcePatch, TargetPatch>::tgtMagSf()
{
return tgtMagSf_;
return singleMeshProc_ == -1;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,8 +25,6 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "AMIInterpolation.H"
#include "mergePoints.H"
#include "mapDistribute.H"
#include "AABBTree.H"
@ -34,7 +32,7 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
Foam::label Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcDistribution
Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::calcDistribution
(
const SourcePatch& srcPatch,
const TargetPatch& tgtPatch
@ -80,8 +78,7 @@ Foam::label Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcDistribution
template<class SourcePatch, class TargetPatch>
Foam::label
Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcOverlappingProcs
Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::calcOverlappingProcs
(
const List<treeBoundBoxList>& procBb,
const treeBoundBox& bb,
@ -102,7 +99,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcOverlappingProcs
if (tbb.overlaps(bb))
{
overlaps[proci] = true;
nOverlaps++;
++nOverlaps;
break;
}
}
@ -113,7 +110,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcOverlappingProcs
template<class SourcePatch, class TargetPatch>
void Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributePatches
void Foam::AMIMethod<SourcePatch, TargetPatch>::distributePatches
(
const mapDistribute& map,
const TargetPatch& pp,
@ -198,7 +195,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributePatches
template<class SourcePatch, class TargetPatch>
void Foam::AMIInterpolation<SourcePatch, TargetPatch>::
void Foam::AMIMethod<SourcePatch, TargetPatch>::
distributeAndMergePatches
(
const mapDistribute& map,
@ -313,7 +310,7 @@ distributeAndMergePatches
template<class SourcePatch, class TargetPatch>
Foam::autoPtr<Foam::mapDistribute>
Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcProcMap
Foam::AMIMethod<SourcePatch, TargetPatch>::calcProcMap
(
const SourcePatch& srcPatch,
const TargetPatch& tgtPatch

View File

@ -40,20 +40,20 @@ void Foam::directAMI<SourcePatch, TargetPatch>::appendToDirectSeeds
label& tgtFacei
) const
{
const labelList& srcNbr = this->srcPatch_.faceFaces()[srcFacei];
const labelList& tgtNbr = this->tgtPatch_.faceFaces()[tgtFacei];
const labelList& srcNbr = this->srcPatch().faceFaces()[srcFacei];
const labelList& tgtNbr = this->tgtPatch().faceFaces()[tgtFacei];
const pointField& srcPoints = this->srcPatch_.points();
const pointField& tgtPoints = this->tgtPatch_.points();
const pointField& srcPoints = this->srcPatch().points();
const pointField& tgtPoints = this->tgtPatch().points();
const vectorField& srcCf = this->srcPatch_.faceCentres();
const vectorField& srcCf = this->srcPatch().faceCentres();
for (const label srcI : srcNbr)
{
if ((mapFlag[srcI] == 0) && (srcTgtSeed[srcI] == -1))
{
// first attempt: match by comparing face centres
const face& srcF = this->srcPatch_[srcI];
const face& srcF = this->srcPatch()[srcI];
const point& srcC = srcCf[srcI];
scalar tol = GREAT;
@ -71,7 +71,7 @@ void Foam::directAMI<SourcePatch, TargetPatch>::appendToDirectSeeds
bool found = false;
for (const label tgtI : tgtNbr)
{
const face& tgtF = this->tgtPatch_[tgtI];
const face& tgtF = this->tgtPatch()[tgtI];
const point tgtC = tgtF.centre(tgtPoints);
if (mag(srcC - tgtC) < tol)
@ -93,7 +93,7 @@ void Foam::directAMI<SourcePatch, TargetPatch>::appendToDirectSeeds
for (const label tgtI : tgtNbr)
{
const face& tgtF = this->tgtPatch_[tgtI];
const face& tgtF = this->tgtPatch()[tgtI];
pointHit ray = tgtF.ray(srcCf[srcI], srcN, tgtPoints);
if (ray.hit())
@ -126,7 +126,7 @@ void Foam::directAMI<SourcePatch, TargetPatch>::appendToDirectSeeds
Pout<< "target neighbours:" << nl;
for (const label tgtI : tgtNbr)
{
const face& tgtF = this->tgtPatch_[tgtI];
const face& tgtF = this->tgtPatch()[tgtI];
Pout<< "face id: " << tgtI
<< " centre=" << tgtF.centre(tgtPoints)
@ -208,13 +208,17 @@ Foam::directAMI<SourcePatch, TargetPatch>::directAMI
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
void Foam::directAMI<SourcePatch, TargetPatch>::calculate
bool Foam::directAMI<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
)
@ -232,13 +236,13 @@ void Foam::directAMI<SourcePatch, TargetPatch>::calculate
if (!ok)
{
return;
return false;
}
NotImplemented;
// temporary storage for addressing and weights
List<DynamicList<label>> srcAddr(this->srcPatch_.size());
List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
List<DynamicList<label>> srcAddr(this->srcPatch0_.size());
List<DynamicList<label>> tgtAddr(this->tgtPatch0_.size());
// construct weights and addressing
@ -277,7 +281,7 @@ void Foam::directAMI<SourcePatch, TargetPatch>::calculate
tgtFacei
);
if (srcFacei < 0 && nTested < this->srcPatch_.size())
if (srcFacei < 0 && nTested < this->srcPatch().size())
{
restartAdvancingFront(mapFlag, nonOverlapFaces, srcFacei, tgtFacei);
}
@ -306,20 +310,8 @@ void Foam::directAMI<SourcePatch, TargetPatch>::calculate
tgtAddress[i].transfer(tgtAddr[i]);
tgtWeights[i] = scalarList(1, magSf);
}
}
template<class SourcePatch, class TargetPatch>
void Foam::directAMI<SourcePatch, TargetPatch>::setMagSf
(
const TargetPatch& tgtPatch,
const mapDistribute& map,
scalarList& srcMagSf,
scalarList& tgtMagSf
) const
{
srcMagSf = std::move(this->srcMagSf_);
tgtMagSf = scalarList(tgtPatch.size(), 1.0);
return true;
}

View File

@ -126,26 +126,21 @@ public:
// Manipulation
//- Update addressing and weights
virtual void calculate
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
);
//- Set the face areas for parallel runs
virtual void setMagSf
(
const TargetPatch& tgtPatch,
const mapDistribute& map,
scalarList& srcMagSf,
scalarList& tgtMagSf
) const;
//- Normalise the weight. Can optionally subset addressing
// (e.g. for mapNearest)
virtual void normaliseWeights

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2013-2016 OpenFOAM Foundation
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,6 +32,76 @@ License
// * * * * * * * * * * * * * 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;
// Write out triangulated surfaces as OBJ files
OBJstream srcTriObj("srcTris_" + Foam::name(nAMI) + ".obj");
const pointField& srcPts = src.points();
forAll(srcTris_, facei)
{
const DynamicList<face>& faces = srcTris_[facei];
for (const face& f : faces)
{
srcTriObj.write
(
triPointRef(srcPts[f[0]], srcPts[f[1]], srcPts[f[2]])
);
}
}
OBJstream tgtTriObj("tgtTris_" + Foam::name(nAMI) + ".obj");
const pointField& tgtPts = tgt.points();
forAll(tgtTris_, facei)
{
const DynamicList<face>& faces = tgtTris_[facei];
for (const face& f : faces)
{
tgtTriObj.write
(
triPointRef(tgtPts[f[0]], tgtPts[f[1]], tgtPts[f[2]])
);
}
}
++nAMI;
}
}
template<class SourcePatch, class TargetPatch>
void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing
(
@ -148,7 +218,7 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
this->appendNbrFaces
(
tgtStartFacei,
this->tgtPatch_,
this->tgtPatch(),
visitedFaces,
nbrFaces
);
@ -184,7 +254,7 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
this->appendNbrFaces
(
tgtFacei,
this->tgtPatch_,
this->tgtPatch(),
visitedFaces,
nbrFaces
);
@ -219,7 +289,7 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
{
addProfiling(ami, "faceAreaWeightAMI::setNextFaces");
const labelList& srcNbrFaces = this->srcPatch_.faceFaces()[srcFacei];
const labelList& srcNbrFaces = this->srcPatch().faceFaces()[srcFacei];
// initialise tgtFacei
tgtFacei = -1;
@ -327,12 +397,12 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcInterArea
{
addProfiling(ami, "faceAreaWeightAMI::interArea");
const pointField& srcPoints = this->srcPatch_.points();
const pointField& tgtPoints = this->tgtPatch_.points();
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];
const face& src = this->srcPatch()[srcFacei];
const face& tgt = this->tgtPatch()[tgtFacei];
// quick reject if either face has zero area
if
@ -356,14 +426,14 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcInterArea
);
// crude resultant norm
vector n(-this->srcPatch_.faceNormals()[srcFacei]);
vector n(-this->srcPatch().faceNormals()[srcFacei]);
if (this->reverseTarget_)
{
n -= this->tgtPatch_.faceNormals()[tgtFacei];
n -= this->tgtPatch().faceNormals()[tgtFacei];
}
else
{
n += this->tgtPatch_.faceNormals()[tgtFacei];
n += this->tgtPatch().faceNormals()[tgtFacei];
}
scalar magN = mag(n);
@ -410,12 +480,12 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::overlaps
const scalar threshold
) const
{
const pointField& srcPoints = this->srcPatch_.points();
const pointField& tgtPoints = this->tgtPatch_.points();
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];
const face& src = this->srcPatch()[srcFacei];
const face& tgt = this->tgtPatch()[tgtFacei];
// quick reject if either face has zero area
if
@ -438,14 +508,14 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::overlaps
);
// crude resultant norm
vector n(-this->srcPatch_.faceNormals()[srcFacei]);
vector n(-this->srcPatch().faceNormals()[srcFacei]);
if (this->reverseTarget_)
{
n -= this->tgtPatch_.faceNormals()[tgtFacei];
n -= this->tgtPatch().faceNormals()[tgtFacei];
}
else
{
n += this->tgtPatch_.faceNormals()[tgtFacei];
n += this->tgtPatch().faceNormals()[tgtFacei];
}
scalar magN = mag(n);
@ -500,7 +570,7 @@ restartUncoveredSourceFace
{
++nBelowMinWeight;
const face& f = this->srcPatch_[srcFacei];
const face& f = this->srcPatch()[srcFacei];
forAll(f, fpi)
{
@ -563,66 +633,42 @@ Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::faceAreaWeightAMI
requireMatch
),
restartUncoveredSourceFace_(restartUncoveredSourceFace),
srcMagSf_(),
tgtMagSf_(),
srcTris_(),
tgtTris_()
{
this->triangulatePatch(srcPatch, srcTris_, this->srcMagSf_);
this->triangulatePatch(tgtPatch, tgtTris_, this->tgtMagSf_);
if (debug)
{
static label nAMI = 0;
// Write out triangulated surfaces as OBJ files
OBJstream srcTriObj("srcTris_" + Foam::name(nAMI) + ".obj");
const pointField& srcPts = srcPatch.points();
forAll(srcTris_, facei)
{
const DynamicList<face>& faces = srcTris_[facei];
for (const face& f : faces)
{
srcTriObj.write
(
triPointRef(srcPts[f[0]], srcPts[f[1]], srcPts[f[2]])
);
}
}
OBJstream tgtTriObj("tgtTris_" + Foam::name(nAMI) + ".obj");
const pointField& tgtPts = tgtPatch.points();
forAll(tgtTris_, facei)
{
const DynamicList<face>& faces = tgtTris_[facei];
for (const face& f : faces)
{
tgtTriObj.write
(
triPointRef(tgtPts[f[0]], tgtPts[f[1]], tgtPts[f[2]])
);
}
}
++nAMI;
}
}
tgtTris_(),
extendedTgtMapPtr_(nullptr)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
bool Foam::faceAreaWeightAMI<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
)
{
addProfiling(ami, "faceAreaWeightAMI::calculate");
// Create global indexing for each patch
globalIndex globalSrcFaces(this->srcPatch0_.size());
globalIndex globalTgtFaces(this->tgtPatch0_.size());
// Initialise the geometry
labelList extendedTgtFaceIDs;
initGeom(globalTgtFaces, extendedTgtFaceIDs);
bool ok =
this->initialise
(
@ -636,51 +682,55 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
srcCentroids.setSize(srcAddress.size());
const auto& src = this->srcPatch();
const auto& tgt = this->tgtPatch();
if (!ok)
{
return;
}
// temporary storage for addressing and weights
List<DynamicList<label>> srcAddr(this->srcPatch_.size());
// Temporary storage for addressing and weights
List<DynamicList<label>> srcAddr(src.size());
List<DynamicList<scalar>> srcWght(srcAddr.size());
List<DynamicList<point>> srcCtr(srcAddr.size());
List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
List<DynamicList<label>> tgtAddr(tgt.size());
List<DynamicList<scalar>> tgtWght(tgtAddr.size());
calcAddressing
(
srcAddr,
srcWght,
srcCtr,
tgtAddr,
tgtWght,
srcFacei,
tgtFacei
);
if (debug && !this->srcNonOverlap_.empty())
if (ok)
{
Pout<< " AMI: " << this->srcNonOverlap_.size()
<< " non-overlap faces identified"
<< endl;
}
// Check for badly covered faces
if (restartUncoveredSourceFace_)
{
restartUncoveredSourceFace
calcAddressing
(
srcAddr,
srcWght,
srcCtr,
tgtAddr,
tgtWght
tgtWght,
srcFacei,
tgtFacei
);
if (debug && !this->srcNonOverlap_.empty())
{
Pout<< " AMI: " << this->srcNonOverlap_.size()
<< " non-overlap faces identified"
<< endl;
}
// Check for badly covered faces
if (restartUncoveredSourceFace_)
{
restartUncoveredSourceFace
(
srcAddr,
srcWght,
srcCtr,
tgtAddr,
tgtWght
);
}
}
// Set the patch face areas
srcMagSf = std::move(srcMagSf_);
tgtMagSf = std::move(tgtMagSf_);
// Transfer data to persistent storage
forAll(srcAddr, i)
{
@ -688,26 +738,76 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
srcWeights[i].transfer(srcWght[i]);
srcCentroids[i].transfer(srcCtr[i]);
}
forAll(tgtAddr, i)
{
tgtAddress[i].transfer(tgtAddr[i]);
tgtWeights[i].transfer(tgtWght[i]);
}
}
if (this->distributed())
{
for (labelList& addressing : srcAddress)
{
for (label& addr : addressing)
{
addr = extendedTgtFaceIDs[addr];
}
}
template<class SourcePatch, class TargetPatch>
void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setMagSf
(
const TargetPatch& tgtPatch,
const mapDistribute& map,
scalarList& srcMagSf,
scalarList& tgtMagSf
) const
{
srcMagSf = std::move(this->srcMagSf_);
tgtMagSf = std::move(this->tgtMagSf_);
map.reverseDistribute(tgtPatch.size(), tgtMagSf);
for (labelList& addressing : tgtAddress)
{
globalSrcFaces.inplaceToGlobal(addressing);
}
// Send data back to originating procs. Note that contributions
// from different processors get added (ListOps::appendEqOp)
mapDistributeBase::distribute
(
Pstream::commsTypes::nonBlocking,
List<labelPair>(),
this->tgtPatch0_.size(),
extendedTgtMapPtr_->constructMap(),
false, // has flip
extendedTgtMapPtr_->subMap(),
false, // has flip
tgtAddress,
ListOps::appendEqOp<label>(),
flipOp(), // flip operation
labelList()
);
mapDistributeBase::distribute
(
Pstream::commsTypes::nonBlocking,
List<labelPair>(),
this->tgtPatch0_.size(),
extendedTgtMapPtr_->constructMap(),
false,
extendedTgtMapPtr_->subMap(),
false,
tgtWeights,
ListOps::appendEqOp<scalar>(),
flipOp(),
scalarList()
);
// Note: using patch face areas calculated by the AMI method
extendedTgtMapPtr_->reverseDistribute
(
this->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;
}

View File

@ -61,6 +61,12 @@ 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_;
@ -70,6 +76,9 @@ private:
protected:
autoPtr<mapDistribute> extendedTgtMapPtr_;
// Protected Member Functions
//- No copy construct
@ -78,6 +87,14 @@ protected:
//- No copy assignment
void operator=(const faceAreaWeightAMI&) = delete;
//- Initialise the geometry
void initGeom
(
const globalIndex& globalTgtFaces,
labelList& extendedTgtFaceIDs
);
// Marching front
//- Calculate addressing, weights and centroids using temporary
@ -179,26 +196,21 @@ public:
// Manipulation
//- Update addressing, weights and centroids
virtual void calculate
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
);
//- Set the face areas for parallel runs
virtual void setMagSf
(
const TargetPatch& tgtPatch,
const mapDistribute& map,
scalarList& srcMagSf,
scalarList& tgtMagSf
) const;
//- Normalise the weight. Can optionally subset addressing
//- (e.g. for mapNearest)
virtual void normaliseWeights

View File

@ -84,7 +84,7 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::setNextNearestFaces
label& tgtFacei
) const
{
const labelList& srcNbr = this->srcPatch_.faceFaces()[srcFacei];
const labelList& srcNbr = this->srcPatch().faceFaces()[srcFacei];
srcFacei = -1;
@ -108,7 +108,7 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::setNextNearestFaces
if (tgtFacei == -1)
{
const vectorField& srcCf = this->srcPatch_.faceCentres();
const vectorField& srcCf = this->srcPatch().faceCentres();
FatalErrorInFunction
<< "Unable to find target face for source face "
@ -149,7 +149,7 @@ Foam::label Foam::mapNearestAMI<SourcePatch, TargetPatch>::findMappedSrcFace
}
else
{
const labelList& nbrFaces = this->tgtPatch_.faceFaces()[tgtI];
const labelList& nbrFaces = this->tgtPatch().faceFaces()[tgtI];
for (const label nbrFacei : nbrFaces)
{
@ -193,13 +193,17 @@ Foam::mapNearestAMI<SourcePatch, TargetPatch>::mapNearestAMI
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
bool Foam::mapNearestAMI<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
)
@ -217,13 +221,13 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
if (!ok)
{
return;
return false;
}
// temporary storage for addressing and weights
List<DynamicList<label>> srcAddr(this->srcPatch_.size());
List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
List<DynamicList<label>> srcAddr(this->srcPatch().size());
List<DynamicList<label>> tgtAddr(this->tgtPatch().size());
// construct weights and addressing
@ -238,7 +242,7 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
DynamicList<label> nonOverlapFaces;
do
{
findNearestFace(this->srcPatch_, this->tgtPatch_, srcFacei, tgtFacei);
findNearestFace(this->srcPatch(), this->tgtPatch(), srcFacei, tgtFacei);
srcAddr[srcFacei].append(tgtFacei);
tgtAddr[tgtFacei].append(srcFacei);
@ -258,8 +262,8 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
// for the case of multiple source faces per target face, select the
// nearest source face only and discard the others
const vectorField& srcCf = this->srcPatch_.faceCentres();
const vectorField& tgtCf = this->tgtPatch_.faceCentres();
const vectorField& srcCf = this->srcPatch().faceCentres();
const vectorField& tgtCf = this->tgtPatch().faceCentres();
forAll(tgtAddr, targetFacei)
{
@ -301,8 +305,8 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
// note - reversed search from src->tgt to tgt->src
findNearestFace
(
this->tgtPatch_,
this->srcPatch_,
this->tgtPatch(),
this->srcPatch(),
tgtFacei,
srcFacei
);
@ -314,8 +318,8 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
// transfer data to persistent storage
const pointField& srcFc = this->srcPatch_.faceCentres();
const pointField& tgtFc = this->tgtPatch_.faceCentres();
const pointField& srcFc = this->srcPatch().faceCentres();
const pointField& tgtFc = this->tgtPatch().faceCentres();
forAll(srcAddr, srcI)
{
@ -341,6 +345,8 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
tgtWeights[tgtI][i] = magSqr(tgtPt-srcFc[addr[i]]);
}
}
return true;
}

View File

@ -131,13 +131,17 @@ public:
// Manipulation
//- Update addressing and weights
virtual void calculate
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
);

View File

@ -73,7 +73,8 @@ partialFaceAreaWeightAMI
tgtPatch,
triMode,
reverseTarget,
requireMatch
requireMatch,
true // false // Not performing restart on low weights - valid for partial match
)
{}
@ -88,93 +89,60 @@ bool Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::conformal() const
template<class SourcePatch, class TargetPatch>
void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
bool Foam::partialFaceAreaWeightAMI<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 ok =
this->initialise
bool ok =
faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
(
srcAddress,
srcWeights,
srcCentroids,
tgtAddress,
tgtWeights,
srcMagSf,
tgtMagSf,
srcMapPtr,
tgtMapPtr,
srcFacei,
tgtFacei
);
if (!ok)
if (ok)
{
return;
if (this->distributed())
{
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();
for (const labelList& smap : this->extendedTgtMapPtr_->subMap())
{
UIndirectList<scalar>(tgtMagSf, smap) =
UIndirectList<scalar>(newTgtMagSf, smap);
}
}
return true;
}
srcCentroids.setSize(srcAddress.size());
// temporary storage for addressing and weights
List<DynamicList<label>> srcAddr(this->srcPatch_.size());
List<DynamicList<scalar>> srcWght(srcAddr.size());
List<DynamicList<point>> srcCtr(srcAddr.size());
List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
List<DynamicList<scalar>> tgtWght(tgtAddr.size());
faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing
(
srcAddr,
srcWght,
srcCtr,
tgtAddr,
tgtWght,
srcFacei,
tgtFacei
);
// transfer data to persistent storage
forAll(srcAddr, 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]);
}
}
template<class SourcePatch, class TargetPatch>
void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::setMagSf
(
const TargetPatch& tgtPatch,
const mapDistribute& map,
scalarList& srcMagSf,
scalarList& tgtMagSf
) const
{
srcMagSf = std::move(this->srcMagSf_);
scalarList newTgtMagSf(std::move(this->tgtMagSf_));
map.reverseDistribute(tgtPatch.size(), newTgtMagSf);
// 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 = tgtPatch.magFaceAreas();
for (const labelList& smap : map.subMap())
{
UIndirectList<scalar>(tgtMagSf, smap) =
UIndirectList<scalar>(newTgtMagSf, smap);
}
return false;
}

View File

@ -117,25 +117,20 @@ public:
// Manipulation
//- Update addressing and weights
virtual void calculate
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
);
//- Set the face areas for parallel runs
virtual void setMagSf
(
const TargetPatch& tgtPatch,
const mapDistribute& map,
scalarList& srcMagSf,
scalarList& tgtMagSf
) const;
};