Merge branch 'master' of github.com-OpenFOAM:OpenFOAM/OpenFOAM-dev

This commit is contained in:
Henry Weller
2022-09-02 21:57:07 +01:00
36 changed files with 953 additions and 469 deletions

View File

@ -5,8 +5,9 @@ cd ${0%/*} || exit 1 # Run from this directory
. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
wmake -all $targetType blockMesh
wmake -all $targetType extrude
wmake -all $targetType extrude2DMesh
wmake -all $targetType extrudeMesh
wmake -all $targetType extrudeToRegionMesh
wmake -all $targetType snappyHexMesh
if [ -n "$FOAMY_HEX_MESH" ]
@ -14,5 +15,4 @@ then
foamyMesh/Allwmake $targetType $*
fi
#------------------------------------------------------------------------------

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -26,7 +26,6 @@ License
#include "nearWallFields.H"
#include "wordReList.H"
#include "findCellParticle.H"
#include "mappedPatchBase.H"
#include "OBJstream.H"
#include "addToRunTimeSelectionTable.H"

View File

@ -242,16 +242,16 @@ $(AMICycPatches)/cyclicAMIPointPatchField/cyclicAMIPointPatchFields.C
patchToPatch/patchToPatch/patchToPatch.C
patchToPatch/patchToPatch/patchToPatchParallelOps.C
patchToPatch/matching/matchingPatchToPatch.C
patchToPatch/nearest/nearestPatchToPatch.C
patchToPatch/inverseDistance/inverseDistancePatchToPatch.C
patchToPatch/intersection/intersectionPatchToPatch.C
patchToPatch/rays/raysPatchToPatch.C
mappedPatches/mappedPolyPatch/mappedPatchBase.C
mappedPatches/mappedPatchBase/mappedPatchBase.C
mappedPatches/mappedPolyPatch/mappedPolyPatch.C
mappedPatches/mappedPolyPatch/mappedWallPolyPatch.C
mappedPatches/mappedPolyPatch/mappedExtrudedWallPolyPatch.C
mappedPatches/mappedPointPatch/mappedPointPatch.C
mappedPatches/mappedPointPatch/mappedWallPointPatch.C
mappedPatches/mappedPointPatch/mappedExtrudedWallPointPatch.C

View File

@ -37,6 +37,7 @@ License
#include "distributionMap.H"
#include "triPointRef.H"
#include "RemoteData.H"
#include "intersectionPatchToPatch.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -49,12 +50,13 @@ namespace Foam
const char* Foam::NamedEnum
<
Foam::mappedPatchBase::sampleMode,
4
5
>::names[] =
{
"nearestCell",
"nearestPatchFace",
"nearestPatchFaceAMI",
"patchToPatch",
"nearestFace"
};
@ -72,7 +74,7 @@ namespace Foam
}
const Foam::NamedEnum<Foam::mappedPatchBase::sampleMode, 4>
const Foam::NamedEnum<Foam::mappedPatchBase::sampleMode, 5>
Foam::mappedPatchBase::sampleModeNames_;
const Foam::NamedEnum<Foam::mappedPatchBase::offsetMode, 3>
@ -272,6 +274,11 @@ void Foam::mappedPatchBase::findSamples
{
break;
}
case PATCHTOPATCH:
{
break;
}
}
// Find nearest. Combine on master.
@ -379,6 +386,10 @@ Foam::label Foam::mappedPatchBase::sampleSize() const
{
return samplePolyPatch().size();
}
case PATCHTOPATCH:
{
return samplePolyPatch().size();
}
case NEARESTFACE:
{
return sampleMesh().nFaces() - sampleMesh().nInternalFaces();
@ -539,6 +550,25 @@ void Foam::mappedPatchBase::calcAMI() const
}
void Foam::mappedPatchBase::calcPatchToPatch() const
{
if (patchToPatchIsValid_)
{
FatalErrorInFunction
<< "Patch-to-patch already calculated" << exit(FatalError);
}
patchToPatchPtr_->update
(
patch_,
patch_.pointNormals(),
samplePolyPatch()
);
patchToPatchIsValid_ = true;
}
// Hack to read old (List-based) format. See Field.C. The difference
// is only that in case of falling back to old format it expects a non-uniform
// list instead of a single vector.
@ -630,7 +660,9 @@ Foam::mappedPatchBase::mappedPatchBase
AMIPtr_(nullptr),
AMIReverse_(false),
surfPtr_(nullptr),
surfDict_(fileName("surface"))
surfDict_(fileName("surface")),
patchToPatchIsValid_(false),
patchToPatchPtr_(nullptr)
{}
@ -656,7 +688,14 @@ Foam::mappedPatchBase::mappedPatchBase
AMIPtr_(nullptr),
AMIReverse_(false),
surfPtr_(nullptr),
surfDict_(fileName("surface"))
surfDict_(fileName("surface")),
patchToPatchIsValid_(false),
patchToPatchPtr_
(
mode == PATCHTOPATCH
? new patchToPatches::intersection(false)
: nullptr
)
{}
@ -690,7 +729,14 @@ Foam::mappedPatchBase::mappedPatchBase
AMIPtr_(nullptr),
AMIReverse_(dict.lookupOrDefault<bool>("flipNormals", false)),
surfPtr_(nullptr),
surfDict_(dict.subOrEmptyDict("surface"))
surfDict_(dict.subOrEmptyDict("surface")),
patchToPatchIsValid_(false),
patchToPatchPtr_
(
mode_ == PATCHTOPATCH
? patchToPatch::New(dict.lookup("patchToPatchMode"), false)
: autoPtr<patchToPatch>(nullptr)
)
{
if (!coupleGroup_.valid() && sampleRegion_.empty())
{
@ -721,7 +767,14 @@ Foam::mappedPatchBase::mappedPatchBase
AMIPtr_(nullptr),
AMIReverse_(mpb.AMIReverse_),
surfPtr_(nullptr),
surfDict_(mpb.surfDict_)
surfDict_(mpb.surfDict_),
patchToPatchIsValid_(false),
patchToPatchPtr_
(
mode_ == PATCHTOPATCH
? patchToPatch::New(mpb.patchToPatchPtr_->type(), false)
: autoPtr<patchToPatch>(nullptr)
)
{}
@ -843,6 +896,7 @@ void Foam::mappedPatchBase::clearOut()
mapIndices_.clear();
AMIPtr_.clear();
surfPtr_.clear();
patchToPatchIsValid_ = false;
}
@ -886,6 +940,11 @@ void Foam::mappedPatchBase::write(Ostream& os) const
os << surfDict_;
}
}
if (mode_ == PATCHTOPATCH)
{
writeEntry(os, "patchToPatchMode", patchToPatchPtr_->type());
}
}

View File

@ -77,6 +77,7 @@ SourceFiles
#include "pointField.H"
#include "AMIInterpolation.H"
#include "patchToPatch.H"
#include "coupleGroupIdentifier.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -105,6 +106,7 @@ public:
NEARESTCELL, // nearest cell containing sample
NEARESTPATCHFACE, // nearest face on selected patch
NEARESTPATCHFACEAMI, // nearest patch face + AMI interpolation
PATCHTOPATCH, // ...
NEARESTFACE // nearest face
};
@ -116,7 +118,7 @@ public:
DIRECTION // offset with a specified vector
};
static const NamedEnum<sampleMode, 4> sampleModeNames_;
static const NamedEnum<sampleMode, 5> sampleModeNames_;
static const NamedEnum<offsetMode, 3> offsetModeNames_;
@ -177,6 +179,15 @@ protected:
dictionary surfDict_;
//- Patch-to-patch intersection engine (only for PATCHTOPATCH)
//- Is the patch-to-patch intersection engine up to date?
mutable bool patchToPatchIsValid_;
//- Patch-to-patch intersection engine
mutable autoPtr<patchToPatch> patchToPatchPtr_;
// Protected Member Functions
//- Read the offset mode from a dictionary
@ -199,6 +210,9 @@ protected:
//- Calculate AMI interpolator
void calcAMI() const;
//- Calculate the patch-to-patch intersection engine
void calcPatchToPatch() const;
//- Helper to read field or non-uniform list from dictionary
static tmp<pointField> readListOrField
(
@ -207,6 +221,12 @@ protected:
const label size
);
//- Return whether or not the sample patch (if any) is of mapped type
inline bool sampleIsMappedPatch() const;
//- Get the mapped sample patch
inline const mappedPatchBase& sampleMappedPatch() const;
public:
@ -300,22 +320,6 @@ public:
const tmp<Field<Type>>& fld
) const;
//- Wrapper around map/interpolate data distribution with operation
template<class Type, class CombineOp>
tmp<Field<Type>> reverseDistribute
(
const Field<Type>& fld,
const CombineOp& cop
) const;
//- Wrapper around map/interpolate data distribution with operation
template<class Type, class CombineOp>
tmp<Field<Type>> reverseDistribute
(
const tmp<Field<Type>>& fld,
const CombineOp& cop
) const;
// I/O

View File

@ -25,6 +25,31 @@ License
#include "mappedPatchBase.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
inline bool Foam::mappedPatchBase::sampleIsMappedPatch() const
{
switch (mode_)
{
case NEARESTCELL:
case NEARESTFACE:
return false;
case NEARESTPATCHFACE:
case NEARESTPATCHFACEAMI:
case PATCHTOPATCH:
return isA<mappedPatchBase>(samplePolyPatch());
}
return false;
}
inline const Foam::mappedPatchBase&
Foam::mappedPatchBase::sampleMappedPatch() const
{
return refCast<const mappedPatchBase>(samplePolyPatch());
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::mappedPatchBase::sampleMode&

View File

@ -41,6 +41,25 @@ Foam::mappedPatchBase::distribute(const Field<Type>& fld) const
}
return AMIPtr_->interpolateToSource(fld);
}
case PATCHTOPATCH:
{
if
(
!patchToPatchIsValid_
&& !(
sampleIsMappedPatch()
&& sampleMappedPatch().patchToPatchIsValid_
)
)
{
calcPatchToPatch();
}
return
patchToPatchIsValid_
? patchToPatchPtr_->tgtToSrc(fld)
: sampleMappedPatch().patchToPatchPtr_->srcToTgt(fld);
}
default:
{
if (mapPtr_.empty())
@ -91,12 +110,33 @@ Foam::mappedPatchBase::reverseDistribute(const Field<Type>& fld) const
}
return AMIPtr_->interpolateToTarget(fld);
}
case PATCHTOPATCH:
{
if
(
!patchToPatchIsValid_
&& !(
sampleIsMappedPatch()
&& sampleMappedPatch().patchToPatchIsValid_
)
)
{
calcPatchToPatch();
}
return
patchToPatchIsValid_
? patchToPatchPtr_->srcToTgt(fld)
: sampleMappedPatch().patchToPatchPtr_->tgtToSrc(fld);
}
default:
{
FatalErrorInFunction
<< "Reverse distribute can only be used in "
<< sampleModeNames_[NEARESTPATCHFACE] << " or "
<< sampleModeNames_[NEARESTPATCHFACEAMI] << "mode"
<< sampleModeNames_[NEARESTPATCHFACE] << ", "
<< sampleModeNames_[NEARESTPATCHFACEAMI] << " or "
<< sampleModeNames_[PATCHTOPATCH] << " mode"
<< exit(FatalError);
return tmp<Field<Type>>(nullptr);

View File

@ -68,10 +68,10 @@ protected:
//- Patch-to-patch intersection engine
mutable patchToPatches::intersection intersection_;
//- Is the intersection engine up to date?
//- Is the rays engine up to date?
mutable bool raysIsValid_;
//- Patch-to-patch intersection engine
//- Patch-to-patch rays engine
mutable patchToPatches::rays rays_;

View File

@ -544,13 +544,12 @@ void Foam::patchToPatches::intersection::initialise
void Foam::patchToPatches::intersection::rDistributeTgt
(
const primitiveOldTimePatch& tgtPatch,
const distributionMap& tgtMap
const primitiveOldTimePatch& tgtPatch
)
{
patchToPatch::rDistributeTgt(tgtPatch, tgtMap);
patchToPatch::rDistributeTgt(tgtPatch);
rDistributeListList(tgtPatch.size(), tgtMap, tgtCouples_);
rDistributeListList(tgtPatch.size(), tgtMapPtr_(), tgtCouples_);
}
@ -655,6 +654,44 @@ Foam::label Foam::patchToPatches::intersection::finalise
}
}
// Calculate coverage and total areas on both sides
auto coverage = []
(
const primitivePatch& patch,
const List<DynamicList<couple>>& couples,
scalar& area,
scalar& coupleArea,
List<scalar>& coverage
)
{
area = 0;
coupleArea = 0;
coverage.resize(patch.size());
forAll(patch, facei)
{
const scalar magA = mag(patch.faceAreas()[facei]);
vector aCouple = Zero;
forAll(couples[facei], i)
{
aCouple += couples[facei][i].area;
}
const scalar magACouple = mag(aCouple);
area += magA;
coupleArea += magACouple;
coverage[facei] = magACouple/magA;
}
reduce(area, sumOp<scalar>());
reduce(coupleArea, sumOp<scalar>());
};
scalar srcArea = 0, srcCoupleArea = 0;
scalar tgtArea = 0, tgtCoupleArea = 0;
coverage(srcPatch, srcCouples_, srcArea, srcCoupleArea, srcCoverage_);
coverage(tgtPatch, tgtCouples_, tgtArea, tgtCoupleArea, tgtCoverage_);
// Clear the triangulation workspace
srcTriPoints_.clear();
srcTriFaceEdges_.clear();
@ -669,8 +706,6 @@ Foam::label Foam::patchToPatches::intersection::finalise
// Checking and reporting
if (nCouples != 0)
{
scalar srcArea = 0, srcCoupleArea = 0;
scalarField srcCoverage(srcPatch.size());
scalarField srcOpenness(srcPatch.size());
scalarField srcError(srcPatch.size());
scalarField srcDepth(srcPatch.size());
@ -689,11 +724,6 @@ Foam::label Foam::patchToPatches::intersection::finalise
Cpl += cpl;
Cpl.nbr += cpl.nbr;
}
const scalar magCA = mag(Cpl.area);
srcArea += magA;
srcCoupleArea += magCA;
srcCoverage[srcFacei] = magCA/magA;
vector projectionA = Zero;
scalar projectionV = 0;
@ -736,36 +766,15 @@ Foam::label Foam::patchToPatches::intersection::finalise
srcDepth[srcFacei] = mag(projectionV)/pow3(sqrt(magA));
}
reduce(srcArea, sumOp<scalar>());
reduce(srcCoupleArea, sumOp<scalar>());
scalar tgtArea = 0, tgtCoupleArea = 0;
scalarField tgtCoverage(tgtPatch.size());
forAll(tgtPatch, tgtFacei)
{
const scalar magA = mag(tgtPatch.faceAreas()[tgtFacei]);
vector aCouple = Zero;
forAll(tgtCouples_[tgtFacei], tgtSrcFacei)
{
aCouple += tgtCouples_[tgtFacei][tgtSrcFacei].area;
}
const scalar magACouple = mag(aCouple);
tgtArea += magA;
tgtCoupleArea += magACouple;
tgtCoverage[tgtFacei] = magACouple/magA;
}
reduce(tgtArea, sumOp<scalar>());
reduce(tgtCoupleArea, sumOp<scalar>());
Info<< indent << "Source min/average/max coverage = "
<< gMin(srcCoverage) << '/' << srcCoupleArea/srcArea << '/'
<< gMax(srcCoverage) << endl
<< gMin(srcCoverage_) << '/' << srcCoupleArea/srcArea << '/'
<< gMax(srcCoverage_) << endl
<< indent << "Target min/average/max coverage = "
<< gMin(tgtCoverage) << '/' << tgtCoupleArea/tgtArea << '/'
<< gMax(tgtCoverage) << endl
<< gMin(tgtCoverage_) << '/' << tgtCoupleArea/tgtArea << '/'
<< gMax(tgtCoverage_) << endl
<< indent << "Source average openness/error/depth/angle = "
<< gAverage(srcOpenness) << '/' << gAverage(srcError) << '/'
<< gAverage(srcDepth) << '/' << gAverage(srcAngle) << endl
@ -815,7 +824,7 @@ Foam::label Foam::patchToPatches::intersection::finalise
labelList(),
labelListList(),
srcPatch.localFaces(),
"coverage", false, srcCoverage,
"coverage", false, scalarField(srcCoverage_),
"openness", false, srcOpenness,
"error", false, srcError,
"depth", false, srcDepth,
@ -833,7 +842,7 @@ Foam::label Foam::patchToPatches::intersection::finalise
labelList(),
labelListList(),
tgtPatch.localFaces(),
"coverage", false, tgtCoverage
"coverage", false, scalarField(tgtCoverage_)
);
}
}
@ -842,6 +851,68 @@ Foam::label Foam::patchToPatches::intersection::finalise
}
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::intersection::srcWeights() const
{
List<DynamicList<scalar>>* resultPtr
(
new List<DynamicList<scalar>>(srcCouples_.size())
);
List<DynamicList<scalar>>& result = *resultPtr;
forAll(srcCouples_, srcFacei)
{
result[srcFacei].resize(srcCouples_[srcFacei].size());
scalar aSum = 0;
forAll(srcCouples_[srcFacei], i)
{
const scalar a = mag(srcCouples_[srcFacei][i].area);
result[srcFacei][i] = a;
aSum += a;
}
forAll(srcCouples_[srcFacei], i)
{
result[srcFacei][i] *= srcCoverage_[srcFacei]/aSum;
}
}
return tmpNrc<List<DynamicList<scalar>>>(resultPtr);
}
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::intersection::tgtWeights() const
{
List<DynamicList<scalar>>* resultPtr
(
new List<DynamicList<scalar>>(tgtCouples_.size())
);
List<DynamicList<scalar>>& result = *resultPtr;
forAll(tgtCouples_, tgtFacei)
{
result[tgtFacei].resize(tgtCouples_[tgtFacei].size());
scalar aSum = 0;
forAll(tgtCouples_[tgtFacei], i)
{
const scalar a = mag(tgtCouples_[tgtFacei][i].area);
result[tgtFacei][i] = a;
aSum += a;
}
forAll(tgtCouples_[tgtFacei], i)
{
result[tgtFacei][i] *= tgtCoverage_[tgtFacei]/aSum;
}
}
return tmpNrc<List<DynamicList<scalar>>>(resultPtr);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::patchToPatches::intersection::intersection(const bool reverse)
@ -849,9 +920,11 @@ Foam::patchToPatches::intersection::intersection(const bool reverse)
patchToPatch(reverse),
srcCouples_(),
srcCoverage_(),
srcEdgeParts_(),
srcErrorParts_(),
tgtCouples_(),
tgtCoverage_(),
triEngine_(),
@ -884,62 +957,4 @@ Foam::patchToPatches::intersection::~intersection()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::intersection::srcWeights
(
const primitivePatch& srcPatch
) const
{
List<DynamicList<scalar>>* resultPtr
(
new List<DynamicList<scalar>>(srcCouples_.size())
);
List<DynamicList<scalar>>& result = *resultPtr;
forAll(srcCouples_, srcFacei)
{
result[srcFacei].resize(srcCouples_[srcFacei].size());
const scalar magA = mag(srcPatch.faceAreas()[srcFacei]);
forAll(srcCouples_[srcFacei], i)
{
result[srcFacei][i] = mag(srcCouples_[srcFacei][i].area)/magA;
}
}
return tmpNrc<List<DynamicList<scalar>>>(resultPtr);
}
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::intersection::tgtWeights
(
const primitivePatch& tgtPatch
) const
{
List<DynamicList<scalar>>* resultPtr
(
new List<DynamicList<scalar>>(tgtCouples_.size())
);
List<DynamicList<scalar>>& result = *resultPtr;
forAll(tgtCouples_, tgtFacei)
{
result[tgtFacei].resize(tgtCouples_[tgtFacei].size());
const scalar magA = mag(tgtPatch.faceAreas()[tgtFacei]);
forAll(tgtCouples_[tgtFacei], i)
{
result[tgtFacei][i] = mag(tgtCouples_[tgtFacei][i].area)/magA;
}
}
return tmpNrc<List<DynamicList<scalar>>>(resultPtr);
}
// ************************************************************************* //

View File

@ -75,7 +75,7 @@ public:
part()
:
area(Zero),
centre(point::uniform(NaN))
centre(NaN<point>())
{}
//- Default construct
@ -210,6 +210,9 @@ private:
//- The coupling geometry for for each source face
List<DynamicList<couple>> srcCouples_;
//- The proportion of the source faces that are coupled
List<scalar> srcCoverage_;
//- The non-coupled geometry associated with each source edge
List<part> srcEdgeParts_;
@ -220,6 +223,9 @@ private:
//- The coupling geometry for for each target face
List<DynamicList<couple>> tgtCouples_;
//- The proportion of the target faces that are coupled
List<scalar> tgtCoverage_;
//- Triangulation engine
mutable polygonTriangulate triEngine_;
@ -325,11 +331,7 @@ private:
//- Send data that resulted from an intersection between the source
// patch and a distributed source-local-target patch back to the
// original target processes.
virtual void rDistributeTgt
(
const primitiveOldTimePatch& tgtPatch,
const distributionMap& tgtMap
);
virtual void rDistributeTgt(const primitiveOldTimePatch& tgtPatch);
//- Finalise the intersection
virtual label finalise
@ -341,6 +343,12 @@ private:
const transformer& tgtToSrc
);
//- For each source face, the coupled target weights
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights() const;
//- For each target face, the coupled source weights
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights() const;
public:
@ -393,18 +401,6 @@ public:
//- For each target face, the target and source areas for each
// source coupling
inline const List<DynamicList<couple>>& tgtCouples() const;
//- For each source face, the coupled target weights
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights
(
const primitivePatch& srcPatch
) const;
//- For each target face, the coupled source weights
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights
(
const primitivePatch& tgtPatch
) const;
};

View File

@ -190,13 +190,12 @@ void Foam::patchToPatches::inverseDistance::initialise
void Foam::patchToPatches::inverseDistance::rDistributeTgt
(
const primitiveOldTimePatch& tgtPatch,
const distributionMap& tgtMap
const primitiveOldTimePatch& tgtPatch
)
{
patchToPatch::rDistributeTgt(tgtPatch, tgtMap);
patchToPatch::rDistributeTgt(tgtPatch);
rDistributeListList(tgtPatch.size(), tgtMap, tgtWeights_);
rDistributeListList(tgtPatch.size(), tgtMapPtr_(), tgtWeights_);
}
@ -243,6 +242,20 @@ Foam::label Foam::patchToPatches::inverseDistance::finalise
}
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::inverseDistance::srcWeights() const
{
return srcWeights_;
}
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::inverseDistance::tgtWeights() const
{
return tgtWeights_;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::patchToPatches::inverseDistance::inverseDistance(const bool reverse)
@ -259,26 +272,4 @@ Foam::patchToPatches::inverseDistance::~inverseDistance()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::inverseDistance::srcWeights
(
const primitivePatch& srcPatch
) const
{
return srcWeights_;
}
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::inverseDistance::tgtWeights
(
const primitivePatch& tgtPatch
) const
{
return tgtWeights_;
}
// ************************************************************************* //

View File

@ -117,11 +117,7 @@ class inverseDistance
//- Send data that resulted from an intersection between the source
// patch and a distributed source-local-target patch back to the
// original target processes.
virtual void rDistributeTgt
(
const primitiveOldTimePatch& tgtPatch,
const distributionMap& tgtMap
);
virtual void rDistributeTgt(const primitiveOldTimePatch& tgtPatch);
//- Finalise the intersection
virtual label finalise
@ -133,6 +129,12 @@ class inverseDistance
const transformer& tgtToSrc
);
//- For each source face, the coupled target weights
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights() const;
//- For each target face, the coupled source weights
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights() const;
public:
@ -148,21 +150,6 @@ public:
//- Destructor
~inverseDistance();
// Member Functions
//- For each source face, the coupled target weights
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights
(
const primitivePatch& srcPatch
) const;
//- For each target face, the coupled source weights
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights
(
const primitivePatch& tgtPatch
) const;
};

View File

@ -0,0 +1,163 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "matchingPatchToPatch.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace patchToPatches
{
defineTypeNameAndDebug(matching, 0);
addToRunTimeSelectionTable(patchToPatch, matching, bool);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::patchToPatches::matching::finalise
(
const primitiveOldTimePatch& srcPatch,
const vectorField& srcPointNormals,
const vectorField& srcPointNormals0,
const primitiveOldTimePatch& tgtPatch,
const transformer& tgtToSrc
)
{
const label nCouples =
nearest::finalise
(
srcPatch,
srcPointNormals,
srcPointNormals0,
tgtPatch,
tgtToSrc
);
// Make sure every face references exactly one face
auto forwardCheck = []
(
const primitiveOldTimePatch& patch,
const List<DynamicList<label>>& localOtherFaces,
const bool isSrc
)
{
forAll(localOtherFaces, facei)
{
if (localOtherFaces[facei].size() != 1)
{
FatalErrorInFunction
<< (isSrc ? "Source" : "Target")
<< " face #" << facei << " at "
<< patch.faceCentres()[facei]
<< " did not match a face on the "
<< (isSrc ? "target" : "source")
<< " side" << exit(FatalError);
}
}
};
forwardCheck(srcPatch, srcLocalTgtFaces_, true);
forwardCheck(tgtPatch, tgtLocalSrcFaces_, false);
// Make sure every face is referenced by exactly one face
auto reverseCheck = []
(
const primitiveOldTimePatch& patch,
const List<DynamicList<label>>& otherLocalFaces,
const autoPtr<distributionMap>& mapPtr,
const bool isSrc
)
{
labelList count
(
mapPtr.valid() ? mapPtr->constructSize() : patch.size(),
0
);
forAll(otherLocalFaces, otherFacei)
{
forAll(otherLocalFaces[otherFacei], i)
{
count[otherLocalFaces[otherFacei][i]] ++;
}
}
if (mapPtr.valid())
{
distributionMapBase::distribute
(
Pstream::commsTypes::nonBlocking,
List<labelPair>(),
patch.size(),
mapPtr->constructMap(),
false,
mapPtr->subMap(),
false,
count,
plusEqOp<label>(),
flipOp(),
label(0)
);
}
forAll(count, facei)
{
if (count[facei] != 1)
{
FatalErrorInFunction
<< (isSrc ? "Source" : "Target")
<< " face #" << facei << " at "
<< patch.faceCentres()[facei]
<< " did not match a face on the "
<< (isSrc ? "target" : "source")
<< " side" << exit(FatalError);
}
}
};
reverseCheck(srcPatch, tgtLocalSrcFaces_, srcMapPtr_, true);
reverseCheck(tgtPatch, srcLocalTgtFaces_, tgtMapPtr_, false);
return nCouples;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::patchToPatches::matching::matching(const bool reverse)
:
nearest(reverse)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::patchToPatches::matching::~matching()
{}
// ************************************************************************* //

View File

@ -0,0 +1,97 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::patchToPatches::matching
Description
Class to generate patchToPatch coupling geometry. Couples a face to the
single matching opposite face only. This is functionally identical to the
nearest algorithm. It just adds some checking to ensure that the coupling
is perfectly one-to-one.
SourceFiles
matching.C
\*---------------------------------------------------------------------------*/
#ifndef matchingPatchToPatch_H
#define matchingPatchToPatch_H
#include "nearestPatchToPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace patchToPatches
{
/*---------------------------------------------------------------------------*\
Class matching Declaration
\*---------------------------------------------------------------------------*/
class matching
:
public nearest
{
// Private Member Functions
//- Finalise the intersection
virtual label finalise
(
const primitiveOldTimePatch& srcPatch,
const vectorField& srcPointNormals,
const vectorField& srcPointNormals0,
const primitiveOldTimePatch& tgtPatch,
const transformer& tgtToSrc
);
public:
//- Runtime type information
TypeName("matching");
// Constructors
//- Construct from components
matching(const bool reverse);
//- Destructor
~matching();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace patchToPatches
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -202,8 +202,7 @@ void Foam::patchToPatches::nearest::initialise
void Foam::patchToPatches::nearest::rDistributeTgt
(
const primitiveOldTimePatch& tgtPatch,
const distributionMap& tgtMap
const primitiveOldTimePatch& tgtPatch
)
{
// Create a list-list of distances to match the addressing
@ -217,10 +216,10 @@ void Foam::patchToPatches::nearest::rDistributeTgt
}
// Let the base class reverse distribute the addressing
patchToPatch::rDistributeTgt(tgtPatch, tgtMap);
patchToPatch::rDistributeTgt(tgtPatch);
// Reverse distribute the distances
rDistributeListList(tgtPatch.size(), tgtMap, tgtDistances);
rDistributeListList(tgtPatch.size(), tgtMapPtr_(), tgtDistances);
// If there is more than one address, remove all but the closest
forAll(tgtLocalSrcFaces_, tgtFacei)
@ -240,24 +239,8 @@ void Foam::patchToPatches::nearest::rDistributeTgt
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::patchToPatches::nearest::nearest(const bool reverse)
:
patchToPatch(reverse)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::patchToPatches::nearest::~nearest()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::nearest::srcWeights(const primitivePatch& srcPatch) const
Foam::patchToPatches::nearest::srcWeights() const
{
tmpNrc<List<DynamicList<scalar>>> tResult
(
@ -279,7 +262,7 @@ Foam::patchToPatches::nearest::srcWeights(const primitivePatch& srcPatch) const
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::nearest::tgtWeights(const primitivePatch& tgtPatch) const
Foam::patchToPatches::nearest::tgtWeights() const
{
tmpNrc<List<DynamicList<scalar>>> tResult
(
@ -300,4 +283,18 @@ Foam::patchToPatches::nearest::tgtWeights(const primitivePatch& tgtPatch) const
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::patchToPatches::nearest::nearest(const bool reverse)
:
patchToPatch(reverse)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::patchToPatches::nearest::~nearest()
{}
// ************************************************************************* //

View File

@ -53,6 +53,8 @@ class nearest
:
public patchToPatch
{
protected:
// Private Member Data
//- For each source face, the distance to its coupled target face
@ -106,11 +108,13 @@ class nearest
//- Send data that resulted from an intersection between the source
// patch and a distributed source-local-target patch back to the
// original target processes.
virtual void rDistributeTgt
(
const primitiveOldTimePatch& tgtPatch,
const distributionMap& tgtMap
);
virtual void rDistributeTgt(const primitiveOldTimePatch& tgtPatch);
//- For each source face, the coupled target weights
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights() const;
//- For each target face, the coupled source weights
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights() const;
public:
@ -127,21 +131,6 @@ public:
//- Destructor
~nearest();
// Member Functions
//- For each source face, the coupled target weights
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights
(
const primitivePatch& srcPatch
) const;
//- For each target face, the coupled source weights
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights
(
const primitivePatch& tgtPatch
) const;
};

View File

@ -714,11 +714,10 @@ Foam::patchToPatch::distributeTgt
const primitiveOldTimePatch& srcPatch,
const vectorField& srcPointNormals,
const vectorField& srcPointNormals0,
const primitiveOldTimePatch& tgtPatch,
distributionMap& tgtMap
const primitiveOldTimePatch& tgtPatch
)
{
tgtMap =
tgtMapPtr_ =
patchDistributionMap
(
tgtPatchSendFaces
@ -740,7 +739,7 @@ Foam::patchToPatch::distributeTgt
(
new PrimitiveOldTimePatch<faceList, pointField>
(
distributePatch(tgtMap, tgtPatch, localTgtProcFacesPtr_())
distributePatch(tgtMapPtr_(), tgtPatch, localTgtProcFacesPtr_())
)
);
}
@ -749,11 +748,10 @@ Foam::patchToPatch::distributeTgt
Foam::tmpNrc<Foam::PrimitiveOldTimePatch<Foam::faceList, Foam::pointField>>
Foam::patchToPatch::distributeSrc
(
const primitiveOldTimePatch& srcPatch,
distributionMap& srcMap
const primitiveOldTimePatch& srcPatch
)
{
srcMap = patchDistributionMap(srcPatchSendFaces());
srcMapPtr_ = patchDistributionMap(srcPatchSendFaces());
if (localSrcProcFacesPtr_.empty())
{
@ -765,7 +763,7 @@ Foam::patchToPatch::distributeSrc
(
new PrimitiveOldTimePatch<faceList, pointField>
(
distributePatch(srcMap, srcPatch, localSrcProcFacesPtr_())
distributePatch(srcMapPtr_(), srcPatch, localSrcProcFacesPtr_())
)
);
}
@ -773,8 +771,7 @@ Foam::patchToPatch::distributeSrc
void Foam::patchToPatch::rDistributeTgt
(
const primitiveOldTimePatch& tgtPatch,
const distributionMap& tgtMap
const primitiveOldTimePatch& tgtPatch
)
{
// Create a map from source procFace to local source face
@ -793,7 +790,7 @@ void Foam::patchToPatch::rDistributeTgt
List<List<procFace>> tgtSrcProcFaces =
localFacesToProcFaces(tgtLocalSrcFaces_);
rDistributeListList(tgtPatch.size(), tgtMap, tgtSrcProcFaces);
rDistributeListList(tgtPatch.size(), tgtMapPtr_(), tgtSrcProcFaces);
tgtLocalSrcFaces_ =
procFacesToLocalFaces(tgtSrcProcFaces, srcProcFaceToLocal);
@ -832,10 +829,12 @@ Foam::patchToPatch::patchToPatch(const bool reverse)
:
reverse_(reverse),
singleProcess_(-labelMax),
localSrcProcFacesPtr_(nullptr),
localTgtProcFacesPtr_(nullptr),
srcLocalTgtFaces_(),
tgtLocalSrcFaces_()
tgtLocalSrcFaces_(),
srcMapPtr_(nullptr),
tgtMapPtr_(nullptr),
localSrcProcFacesPtr_(nullptr),
localTgtProcFacesPtr_(nullptr)
{}
@ -965,15 +964,13 @@ void Foam::patchToPatch::update
else
{
// Distribute the target
distributionMap tgtMap;
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>> localTTgtPatchPtr =
distributeTgt
(
srcPatch,
srcPointNormals,
srcPointNormals0,
tTgtPatch,
tgtMap
tTgtPatch
);
// Massage target patch into form that can be used by the serial
@ -1008,12 +1005,11 @@ void Foam::patchToPatch::update
}
// Distribute the source
distributionMap srcMap;
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>> localSrcPatchPtr =
distributeSrc(srcPatch, srcMap);
distributeSrc(srcPatch);
// Reverse distribute coupling data back to the target
rDistributeTgt(tgtPatch, tgtMap);
rDistributeTgt(tgtPatch);
}
// Finalise the intersection

View File

@ -104,6 +104,18 @@ protected:
// if spread across multiple processors
label singleProcess_;
//- For each source face, the coupled local target faces
List<DynamicList<label>> srcLocalTgtFaces_;
//- For each target face, the coupled local source faces
List<DynamicList<label>> tgtLocalSrcFaces_;
//- Map from source patch faces to target-local source patch faces
autoPtr<distributionMap> srcMapPtr_;
//- Map from target patch faces to source-local target patch faces
autoPtr<distributionMap> tgtMapPtr_;
//- When running in parallel, a map from local source face index to
// source processor and face index
autoPtr<List<procFace>> localSrcProcFacesPtr_;
@ -112,12 +124,6 @@ protected:
// target processor and face index
autoPtr<List<procFace>> localTgtProcFacesPtr_;
//- For each source face, the coupled local target faces
List<DynamicList<label>> srcLocalTgtFaces_;
//- For each target face, the coupled local source faces
List<DynamicList<label>> tgtLocalSrcFaces_;
// Private Member Functions
@ -285,19 +291,11 @@ protected:
//- Create a distribution map from a list-list of faces to be sent
// (i.e., the result of calling one of the above methods).
distributionMap patchDistributionMap
autoPtr<distributionMap> patchDistributionMap
(
labelListList&& sendFaces
) const;
//- Distribute a patch given its distribution map. Just generate
// local-proc-face addressing; not the distributed patch itself.
void distributePatch
(
const distributionMap& map,
List<procFace>& localProcFaces
) const;
//- Distribute a patch given its distribution map
PrimitiveOldTimePatch<faceList, pointField> distributePatch
(
@ -321,8 +319,8 @@ protected:
//- Distribute the target patch so that enough is locally available
// for its intersection with the source patch can be computed.
// Happens before intersection. Bound boxes are used to determine
// what is needed where. Return the resulting local patch and the
// map from which it was calculated.
// what is needed where. Return the resulting local patch and
// internally set the target map.
virtual
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>>
distributeTgt
@ -330,31 +328,22 @@ protected:
const primitiveOldTimePatch& srcPatch,
const vectorField& srcPointNormals,
const vectorField& srcPointNormals0,
const primitiveOldTimePatch& tgtPatch,
distributionMap& tgtMap
const primitiveOldTimePatch& tgtPatch
);
//- Distribute the source patch so that everything the target
// intersects is locally available. Happens after intersection.
// The intersection addressing is used to determine what is needed
// where. Return the resulting local patch and the map from which
// it was calculated.
// where. Return the resulting local patch and internally set the
// source map.
virtual
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>>
distributeSrc
(
const primitiveOldTimePatch& srcPatch,
distributionMap& srcMap
);
distributeSrc(const primitiveOldTimePatch& srcPatch);
//- Send data that resulted from an intersection between the source
// patch and a distributed source-local-target patch back to the
// original target processes.
virtual void rDistributeTgt
(
const primitiveOldTimePatch& tgtPatch,
const distributionMap& tgtMap
);
virtual void rDistributeTgt(const primitiveOldTimePatch& tgtPatch);
//- Finalising
virtual label finalise
@ -367,6 +356,40 @@ protected:
);
// Interpolation
//- For each source face, the coupled target weights
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights() const = 0;
//- For each target face, the coupled source weights
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights() const = 0;
//- Return a primitive with all components set to NaN
template<class Type>
static Type NaN();
//- Interpolate with normalisation
template<class Type>
static tmp<Field<Type>> interpolate
(
const List<DynamicList<label>>& localOtherFaces,
const List<DynamicList<scalar>>& weights,
const autoPtr<distributionMap>& otherMapPtr,
const Field<Type>& otherFld
);
//- Interpolate without normalisation
template<class Type>
static tmp<Field<Type>> interpolate
(
const List<DynamicList<label>>& localOtherFaces,
const List<DynamicList<scalar>>& weights,
const autoPtr<distributionMap>& otherMapPtr,
const Field<Type>& otherFld,
const Field<Type>& leftOverFld
);
public:
//- Runtime type information
@ -428,17 +451,32 @@ public:
//- For each target face, the coupled source procs and faces
inline List<List<procFace>> tgtSrcProcFaces() const;
//- For each source face, the coupled target weights
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights
(
const primitivePatch& srcPatch
) const = 0;
//- For each target face, the coupled source weights
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights
// Interpolation
//- ...
template<class Type>
tmp<Field<Type>> srcToTgt(const Field<Type>& srcFld) const;
//- ...
template<class Type>
tmp<Field<Type>> srcToTgt
(
const primitivePatch& tgtPatch
) const = 0;
const Field<Type>& srcFld,
const Field<Type>& leftOverTgtFld
) const;
//- ...
template<class Type>
tmp<Field<Type>> tgtToSrc(const Field<Type>& tgtFld) const;
//- ...
template<class Type>
tmp<Field<Type>> tgtToSrc
(
const Field<Type>& tgtFld,
const Field<Type>& leftOverSrcFld
) const;
// Manipulation
@ -480,6 +518,12 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "patchToPatchTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -23,6 +23,7 @@ License
\*---------------------------------------------------------------------------*/
#include "autoPtr.H"
#include "patchToPatch.H"
#include "treeBoundBoxList.H"
#include "uindirectPrimitivePatch.H"
@ -153,7 +154,7 @@ Foam::labelListList Foam::patchToPatch::srcPatchSendFaces() const
}
Foam::distributionMap Foam::patchToPatch::patchDistributionMap
Foam::autoPtr<Foam::distributionMap> Foam::patchToPatch::patchDistributionMap
(
labelListList&& sendFaces
) const
@ -204,99 +205,18 @@ Foam::distributionMap Foam::patchToPatch::patchDistributionMap
// Construct and return the map
return
distributionMap
autoPtr<distributionMap>
(
localFacei,
move(sendFaces),
move(receiveFaces)
new distributionMap
(
localFacei,
move(sendFaces),
move(receiveFaces)
)
);
}
void Foam::patchToPatch::distributePatch
(
const distributionMap& map,
List<procFace>& localProcFaces
) const
{
static const label thisProci = Pstream::myProcNo();
// Exchange per-processor data
List<labelList> procLocalFaceis(Pstream::nProcs());
{
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
// Send
for (label proci = 0; proci < Pstream::nProcs(); proci++)
{
const labelList& sendFaces = map.subMap()[proci];
if (proci != thisProci && sendFaces.size())
{
UOPstream(proci, pBufs)() << sendFaces;
}
}
pBufs.finishedSends();
// Map local data
{
const labelList& sendFaces = map.subMap()[thisProci];
procLocalFaceis[thisProci] = sendFaces;
}
// Receive remote data
for (label proci = 0; proci < Pstream::nProcs(); proci++)
{
const labelList& receiveNewFaces = map.constructMap()[proci];
if (proci != thisProci && receiveNewFaces.size())
{
UIPstream(proci, pBufs)() >> procLocalFaceis[proci];
}
}
}
// Allocate
{
label nLocalFaces = 0;
forAll(procLocalFaceis, proci)
{
nLocalFaces += procLocalFaceis[proci].size();
}
localProcFaces.setSize(nLocalFaces);
}
// Renumber and flatten
label localTgtFacei = 0;
// Local data first
{
const labelList& fis = procLocalFaceis[thisProci];
forAll(fis, i)
{
localProcFaces[localTgtFacei] = {thisProci, fis[i]};
localTgtFacei ++;
}
}
// Remote data after
forAll(procLocalFaceis, proci)
{
if (proci != thisProci)
{
const labelList& fis = procLocalFaceis[proci];
forAll(fis, i)
{
localProcFaces[localTgtFacei] = {proci, fis[i]};
localTgtFacei ++;
}
}
}
}
Foam::PrimitiveOldTimePatch<Foam::faceList, Foam::pointField>
Foam::patchToPatch::distributePatch
(

View File

@ -0,0 +1,201 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "patchToPatch.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Type Foam::patchToPatch::NaN()
{
Type result;
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
setComponent(result, cmpt) = Foam::NaN;
}
return result;
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::patchToPatch::interpolate
(
const List<DynamicList<label>>& localOtherFaces,
const List<DynamicList<scalar>>& weights,
const autoPtr<distributionMap>& otherMapPtr,
const Field<Type>& otherFld
)
{
// Distribute the other field if necessary
tmp<Field<Type>> tLocalOtherFld;
if (otherMapPtr.valid())
{
tLocalOtherFld = tmp<Field<Type>>(new Field<Type>(otherFld));
otherMapPtr->distribute(tLocalOtherFld.ref());
}
const Field<Type>& localOtherFld =
otherMapPtr.valid() ? tLocalOtherFld() : otherFld;
// Allocate the result
tmp<Field<Type>> tFld(new Field<Type>(localOtherFaces.size(), NaN<Type>()));
Field<Type>& fld = tFld.ref();
// Compute the result as a weighted sum
forAll(localOtherFaces, tgtFacei)
{
scalar sumW = 0;
Type sumWF = Zero;
forAll(localOtherFaces[tgtFacei], i)
{
const scalar w = weights[tgtFacei][i];
sumW += w;
sumWF += w*localOtherFld[localOtherFaces[tgtFacei][i]];
}
if (localOtherFaces[tgtFacei].size())
{
fld[tgtFacei] = sumWF/sumW;
}
}
return tFld;
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::patchToPatch::interpolate
(
const List<DynamicList<label>>& localOtherFaces,
const List<DynamicList<scalar>>& weights,
const autoPtr<distributionMap>& otherMapPtr,
const Field<Type>& otherFld,
const Field<Type>& leftOverFld
)
{
// Distribute the other field if necessary
tmp<Field<Type>> tLocalOtherFld;
if (otherMapPtr.valid())
{
tLocalOtherFld = tmp<Field<Type>>(new Field<Type>(otherFld));
otherMapPtr->distribute(tLocalOtherFld.ref());
}
const Field<Type>& localOtherFld =
otherMapPtr.valid() ? tLocalOtherFld() : otherFld;
// Allocate the result
tmp<Field<Type>> tFld(new Field<Type>(localOtherFaces.size(), NaN<Type>()));
Field<Type>& fld = tFld.ref();
// Compute the result as a weighted sum
forAll(localOtherFaces, tgtFacei)
{
scalar sumW = 0;
Type sumWF = Zero;
forAll(localOtherFaces[tgtFacei], i)
{
const scalar w = weights[tgtFacei][i];
sumW += w;
sumWF += w*localOtherFld[localOtherFaces[tgtFacei][i]];
}
fld[tgtFacei] = sumWF + (1 - sumW)*leftOverFld[tgtFacei];
}
return tFld;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::patchToPatch::srcToTgt(const Field<Type>& srcFld) const
{
return
interpolate
(
tgtLocalSrcFaces_,
tgtWeights(),
srcMapPtr_,
srcFld
);
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::patchToPatch::srcToTgt
(
const Field<Type>& srcFld,
const Field<Type>& leftOverTgtFld
) const
{
return
interpolate
(
tgtLocalSrcFaces_,
tgtWeights(),
srcMapPtr_,
srcFld,
leftOverTgtFld
);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::patchToPatch::tgtToSrc(const Field<Type>& tgtFld) const
{
return
interpolate
(
srcLocalTgtFaces_,
srcWeights(),
tgtMapPtr_,
tgtFld
);
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::patchToPatch::tgtToSrc
(
const Field<Type>& tgtFld,
const Field<Type>& leftOverSrcFld
) const
{
return
interpolate
(
srcLocalTgtFaces_,
srcWeights(),
tgtMapPtr_,
tgtFld,
leftOverSrcFld
);
}
// ************************************************************************* //

View File

@ -34,7 +34,6 @@ namespace Foam
namespace patchToPatches
{
defineTypeNameAndDebug(rays, 0);
addToRunTimeSelectionTable(patchToPatch, rays, bool);
}
}
@ -93,8 +92,7 @@ Foam::patchToPatches::rays::distributeTgt
const primitiveOldTimePatch& srcPatch,
const vectorField& srcPointNormals,
const vectorField& srcPointNormals0,
const primitiveOldTimePatch& tgtPatch,
distributionMap& tgtMap
const primitiveOldTimePatch& tgtPatch
)
{
// Intercept generation of the local patch. Store it. Return a const
@ -106,8 +104,7 @@ Foam::patchToPatches::rays::distributeTgt
srcPatch,
srcPointNormals,
srcPointNormals0,
tgtPatch,
tgtMap
tgtPatch
);
localTgtPatchPtr_.reset(localTgtPatchPtr.ptr());
@ -123,15 +120,14 @@ Foam::patchToPatches::rays::distributeTgt
Foam::tmpNrc<Foam::PrimitiveOldTimePatch<Foam::faceList, Foam::pointField>>
Foam::patchToPatches::rays::distributeSrc
(
const primitiveOldTimePatch& srcPatch,
distributionMap& srcMap
const primitiveOldTimePatch& srcPatch
)
{
// Intercept generation of the local patch. Store it. Return a const
// reference tmp instead of a pointer.
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>> localSrcPatchPtr =
patchToPatch::distributeSrc(srcPatch, srcMap);
patchToPatch::distributeSrc(srcPatch);
localSrcPatchPtr_.reset(localSrcPatchPtr.ptr());
@ -242,6 +238,22 @@ Foam::patchToPatch::procFace Foam::patchToPatches::rays::ray
}
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::rays::srcWeights() const
{
NotImplemented;
return tmpNrc<List<DynamicList<scalar>>>(nullptr);
}
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::rays::tgtWeights() const
{
NotImplemented;
return tmpNrc<List<DynamicList<scalar>>>(nullptr);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::patchToPatches::rays::rays
@ -261,22 +273,6 @@ Foam::patchToPatches::rays::~rays()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::rays::srcWeights(const primitivePatch& srcPatch) const
{
NotImplemented;
return tmpNrc<List<DynamicList<scalar>>>(nullptr);
}
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
Foam::patchToPatches::rays::tgtWeights(const primitivePatch& tgtPatch) const
{
NotImplemented;
return tmpNrc<List<DynamicList<scalar>>>(nullptr);
}
Foam::patchToPatch::procFace Foam::patchToPatches::rays::srcToTgtRay
(
const primitiveOldTimePatch& tgtPatch,

View File

@ -30,6 +30,9 @@ Description
This generates an outer "envelope" of possible intersections that can be
used for ray shooting and Lagrangian transfer.
Note that this method is not added to the run-time selection table, as it
is not a method which facilitates patch coupling or mapping.
SourceFiles
rays.C
@ -98,19 +101,14 @@ class rays
const primitiveOldTimePatch& srcPatch,
const vectorField& srcPointNormals,
const vectorField& srcPointNormals0,
const primitiveOldTimePatch& tgtPatch,
distributionMap& tgtMap
const primitiveOldTimePatch& tgtPatch
);
//- Distribute the source patch so that everything the target
// intersects is locally available. Happens after intersection.
virtual
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>>
distributeSrc
(
const primitiveOldTimePatch& srcPatch,
distributionMap& srcMap
);
distributeSrc(const primitiveOldTimePatch& srcPatch);
//- Finalising
virtual label finalise
@ -137,6 +135,12 @@ class rays
point& outP
) const;
//- For each source face, the coupled target weights
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights() const;
//- For each target face, the coupled source weights
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights() const;
public:
@ -156,18 +160,6 @@ public:
// Member Functions
//- For each source face, the coupled target weights
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights
(
const primitivePatch& srcPatch
) const;
//- For each target face, the coupled source weights
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights
(
const primitivePatch& tgtPatch
) const;
//- Compute a ray intersection from the source side to the target
procFace srcToTgtRay
(

View File

@ -228,15 +228,6 @@ public:
Field<Type>& regionField
) const;
//- Convert a local region field to the primary region with op
template<class Type, class CombineOp>
void toPrimary
(
const label regionPatchi,
Field<Type>& regionField,
const CombineOp& cop
) const;
//- Convert a primary region field to the local region
template<class Type>
void toRegion
@ -245,15 +236,6 @@ public:
Field<Type>& primaryFieldField
) const;
//- Return a primary patch field mapped the region internal field
template<class Type>
void toRegion
(
Field<Type>& regionField,
const label regionPatchi,
const fvPatchField<Type>& primaryPatchField
) const;
//- Return a primary patch field mapped the local region
template<class Type>
void toRegion

View File

@ -23,7 +23,8 @@ License
\*---------------------------------------------------------------------------*/
#include "mappedPatchFieldBase.H"
#include "regionModel.H"
#include "mappedPatchBase.H"
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
@ -81,24 +82,6 @@ void Foam::regionModels::regionModel::toRegion
}
template<class Type>
void Foam::regionModels::regionModel::toRegion
(
Field<Type>& regionField,
const label regionPatchi,
const fvPatchField<Type>& primaryPatchField
) const
{
const polyPatch& regionPatch = regionMesh().boundaryMesh()[regionPatchi];
const mappedPatchBase& mpb = refCast<const mappedPatchBase>(regionPatch);
mappedPatchFieldBase<Type> mpf(mpb, primaryPatchField);
UIndirectList<Type>(regionField, regionPatch.faceCells()) =
mpf.mappedField();
}
template<class Type>
void Foam::regionModels::regionModel::toRegion
(
@ -111,7 +94,14 @@ void Foam::regionModels::regionModel::toRegion
const label regionPatchi = intCoupledPatchIDs_[i];
const label primaryPatchi = primaryPatchIDs_[i];
toRegion(rf, regionPatchi, pBf[primaryPatchi]);
const polyPatch& regionPatch =
regionMesh().boundaryMesh()[regionPatchi];
const mappedPatchBase& mpb =
refCast<const mappedPatchBase>(regionPatch);
UIndirectList<Type>(rf, regionPatch.faceCells()) =
mpb.distribute(pBf[primaryPatchi]);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -36,6 +36,7 @@ SourceFiles
#define singleLayerRegion_H
#include "regionModel.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -75,7 +75,7 @@ void thermalBaffleFvPatchScalarField::checkPatches() const
checkPatchIsMapped(nbrPp);
const mappedPatchBase& mpp = refCast<const mappedPatchBase>(pp);
const mappedPatchBase nbrMpp = refCast<const mappedPatchBase>(nbrPp);
const mappedPatchBase& nbrMpp = refCast<const mappedPatchBase>(nbrPp);
// The patches should sample a different region
auto checkPatchMapsDifferentRegion = [&](const mappedPatchBase& mpp)