mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: cyclicAMI: GAMG support
This commit is contained in:
@ -143,7 +143,7 @@ Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField() const
|
||||
{
|
||||
const Field<Type>& iField = this->internalField();
|
||||
const labelUList& nbrFaceCells =
|
||||
cyclicAMIPatch_.cyclicAMIPatch().nbrPatch().faceCells();
|
||||
cyclicAMIPatch_.cyclicAMIPatch().neighbPatch().faceCells();
|
||||
|
||||
Field<Type> pnf(iField, nbrFaceCells);
|
||||
|
||||
@ -187,7 +187,7 @@ void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
|
||||
) const
|
||||
{
|
||||
const labelUList& nbrFaceCells =
|
||||
cyclicAMIPatch_.cyclicAMIPatch().nbrPatch().faceCells();
|
||||
cyclicAMIPatch_.cyclicAMIPatch().neighbPatch().faceCells();
|
||||
|
||||
scalarField pnf(psiInternal, nbrFaceCells);
|
||||
|
||||
|
||||
@ -97,7 +97,7 @@ public:
|
||||
//- Return neighbour
|
||||
virtual label neighbPatchID() const
|
||||
{
|
||||
return cyclicAMIPolyPatch_.nbrPatchID();
|
||||
return cyclicAMIPolyPatch_.neighbPatchID();
|
||||
}
|
||||
|
||||
virtual bool owner() const
|
||||
@ -110,10 +110,16 @@ public:
|
||||
{
|
||||
return refCast<const cyclicAMIFvPatch>
|
||||
(
|
||||
this->boundaryMesh()[cyclicAMIPolyPatch_.nbrPatchID()]
|
||||
this->boundaryMesh()[cyclicAMIPolyPatch_.neighbPatchID()]
|
||||
);
|
||||
}
|
||||
|
||||
//- Return a reference to the AMI interpolator
|
||||
virtual const AMIPatchToPatchInterpolation& AMI() const
|
||||
{
|
||||
return cyclicAMIPolyPatch_.AMI();
|
||||
}
|
||||
|
||||
//- Are the cyclic planes parallel
|
||||
virtual bool parallel() const
|
||||
{
|
||||
@ -136,7 +142,7 @@ public:
|
||||
{
|
||||
return refCast<const cyclicAMIFvPatch>
|
||||
(
|
||||
this->boundaryMesh()[cyclicAMIPolyPatch_.nbrPatchID()]
|
||||
this->boundaryMesh()[cyclicAMIPolyPatch_.neighbPatchID()]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -120,7 +120,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::checkPatches
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
bool Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributed
|
||||
Foam::label Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcDistribution
|
||||
(
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch
|
||||
@ -140,13 +140,21 @@ bool Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributed
|
||||
|
||||
Pstream::gatherList(facesPresentOnProc);
|
||||
Pstream::scatterList(facesPresentOnProc);
|
||||
if (sum(facesPresentOnProc) > 1)
|
||||
|
||||
label nHaveFaces = sum(facesPresentOnProc);
|
||||
|
||||
if (nHaveFaces > 1)
|
||||
{
|
||||
return true;
|
||||
return -1;
|
||||
}
|
||||
else if (nHaveFaces == 1)
|
||||
{
|
||||
return findIndex(facesPresentOnProc, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
// Either not parallel or no faces on any processor
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1005,7 +1013,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcAddressing
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
|
||||
(
|
||||
const primitivePatch& patch,
|
||||
const scalarField& patchAreas,
|
||||
const word& patchName,
|
||||
const labelListList& addr,
|
||||
scalarListList& wght,
|
||||
@ -1023,7 +1031,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
|
||||
scalar s = sum(wght[faceI]);
|
||||
wghtSum[faceI] = s;
|
||||
|
||||
scalar t = s/patch[faceI].mag(patch.points());
|
||||
scalar t = s/patchAreas[faceI];
|
||||
if (t < minBound)
|
||||
{
|
||||
minBound = t;
|
||||
@ -1049,6 +1057,266 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
void Foam::AMIInterpolation<SourcePatch, TargetPatch>::agglomerate
|
||||
(
|
||||
const autoPtr<mapDistribute>& targetMapPtr,
|
||||
const scalarField& fineSrcMagSf,
|
||||
const labelListList& fineSrcAddress,
|
||||
const scalarListList& fineSrcWeights,
|
||||
|
||||
const labelList& sourceRestrictAddressing,
|
||||
const labelList& targetRestrictAddressing,
|
||||
|
||||
scalarField& srcMagSf,
|
||||
labelListList& srcAddress,
|
||||
scalarListList& srcWeights,
|
||||
autoPtr<mapDistribute>& tgtMap
|
||||
)
|
||||
{
|
||||
label sourceCoarseSize =
|
||||
(
|
||||
sourceRestrictAddressing.size()
|
||||
? max(sourceRestrictAddressing)+1
|
||||
: 0
|
||||
);
|
||||
|
||||
label targetCoarseSize =
|
||||
(
|
||||
targetRestrictAddressing.size()
|
||||
? max(targetRestrictAddressing)+1
|
||||
: 0
|
||||
);
|
||||
|
||||
// Agglomerate face areas
|
||||
{
|
||||
srcMagSf.setSize(sourceRestrictAddressing.size(), 0.0);
|
||||
forAll(sourceRestrictAddressing, faceI)
|
||||
{
|
||||
label coarseFaceI = sourceRestrictAddressing[faceI];
|
||||
srcMagSf[coarseFaceI] += fineSrcMagSf[faceI];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Agglomerate weights and indices
|
||||
if (targetMapPtr.valid())
|
||||
{
|
||||
const mapDistribute& map = targetMapPtr();
|
||||
|
||||
// Get all restriction addressing.
|
||||
labelList allRestrict(targetRestrictAddressing);
|
||||
map.distribute(allRestrict);
|
||||
|
||||
// So now we have agglomeration of the target side in
|
||||
// allRestrict:
|
||||
// 0..size-1 : local agglomeration (= targetRestrictAddressing)
|
||||
// size.. : agglomeration data from other processors
|
||||
|
||||
labelListList tgtSubMap(Pstream::nProcs());
|
||||
|
||||
// Local subMap is just identity
|
||||
{
|
||||
tgtSubMap[Pstream::myProcNo()] = identity(targetCoarseSize);
|
||||
}
|
||||
|
||||
forAll(map.subMap(), procI)
|
||||
{
|
||||
if (procI != Pstream::myProcNo())
|
||||
{
|
||||
// Combine entries that point to the same coarse element. All
|
||||
// the elements refer to local data so index into
|
||||
// targetRestrictAddressing or allRestrict (since the same
|
||||
// for local data).
|
||||
const labelList& elems = map.subMap()[procI];
|
||||
labelList& newSubMap = tgtSubMap[procI];
|
||||
newSubMap.setSize(elems.size());
|
||||
|
||||
labelList oldToNew(targetCoarseSize, -1);
|
||||
label newI = 0;
|
||||
|
||||
forAll(elems, i)
|
||||
{
|
||||
label fineElem = elems[i];
|
||||
label coarseElem = allRestrict[fineElem];
|
||||
if (oldToNew[coarseElem] == -1)
|
||||
{
|
||||
oldToNew[coarseElem] = newI;
|
||||
newSubMap[newI] = coarseElem;
|
||||
newI++;
|
||||
}
|
||||
}
|
||||
newSubMap.setSize(newI);
|
||||
}
|
||||
}
|
||||
|
||||
// Reconstruct constructMap by combining entries. Note that order
|
||||
// of handing out indices should be the same as loop above to compact
|
||||
// the sending map
|
||||
|
||||
labelListList tgtConstructMap(Pstream::nProcs());
|
||||
labelList tgtCompactMap;
|
||||
|
||||
// Local constructMap is just identity
|
||||
{
|
||||
tgtConstructMap[Pstream::myProcNo()] =
|
||||
identity(targetCoarseSize);
|
||||
|
||||
tgtCompactMap = targetRestrictAddressing;
|
||||
}
|
||||
tgtCompactMap.setSize(map.constructSize());
|
||||
label compactI = targetCoarseSize;
|
||||
|
||||
// Compact data from other processors
|
||||
forAll(map.constructMap(), procI)
|
||||
{
|
||||
if (procI != Pstream::myProcNo())
|
||||
{
|
||||
// Combine entries that point to the same coarse element. All
|
||||
// elements now are remote data so we cannot use any local
|
||||
// data here - use allRestrict instead.
|
||||
const labelList& elems = map.constructMap()[procI];
|
||||
|
||||
labelList& newConstructMap = tgtConstructMap[procI];
|
||||
newConstructMap.setSize(elems.size());
|
||||
|
||||
if (elems.size())
|
||||
{
|
||||
// Get the maximum target coarse size for this set of
|
||||
// received data.
|
||||
label remoteTargetCoarseSize = labelMin;
|
||||
forAll(elems, i)
|
||||
{
|
||||
remoteTargetCoarseSize = max
|
||||
(
|
||||
remoteTargetCoarseSize,
|
||||
allRestrict[elems[i]]
|
||||
);
|
||||
}
|
||||
remoteTargetCoarseSize += 1;
|
||||
|
||||
// Combine locally data coming from procI
|
||||
labelList oldToNew(remoteTargetCoarseSize, -1);
|
||||
label newI = 0;
|
||||
|
||||
forAll(elems, i)
|
||||
{
|
||||
label fineElem = elems[i];
|
||||
// fineElem now points to section from procI
|
||||
label coarseElem = allRestrict[fineElem];
|
||||
if (oldToNew[coarseElem] == -1)
|
||||
{
|
||||
oldToNew[coarseElem] = newI;
|
||||
tgtCompactMap[fineElem] = compactI;
|
||||
newConstructMap[newI] = compactI++;
|
||||
newI++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get compact index
|
||||
label compactI = oldToNew[coarseElem];
|
||||
tgtCompactMap[fineElem] = newConstructMap[compactI];
|
||||
}
|
||||
}
|
||||
newConstructMap.setSize(newI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
srcAddress.setSize(sourceCoarseSize);
|
||||
srcWeights.setSize(sourceCoarseSize);
|
||||
|
||||
forAll(fineSrcAddress, faceI)
|
||||
{
|
||||
// All the elements contributing to faceI. Are slots in
|
||||
// mapDistribute'd data.
|
||||
const labelList& elems = fineSrcAddress[faceI];
|
||||
const scalarList& weights = fineSrcWeights[faceI];
|
||||
const scalar fineArea = fineSrcMagSf[faceI];
|
||||
|
||||
label coarseFaceI = sourceRestrictAddressing[faceI];
|
||||
|
||||
labelList& newElems = srcAddress[coarseFaceI];
|
||||
scalarList& newWeights = srcWeights[coarseFaceI];
|
||||
|
||||
forAll(elems, i)
|
||||
{
|
||||
label elemI = elems[i];
|
||||
label coarseElemI = tgtCompactMap[elemI];
|
||||
|
||||
label index = findIndex(newElems, coarseElemI);
|
||||
if (index == -1)
|
||||
{
|
||||
newElems.append(coarseElemI);
|
||||
newWeights.append(fineArea*weights[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
newWeights[index] += fineArea*weights[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tgtMap.reset
|
||||
(
|
||||
new mapDistribute
|
||||
(
|
||||
compactI,
|
||||
tgtSubMap.xfer(),
|
||||
tgtConstructMap.xfer()
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
srcAddress.setSize(sourceCoarseSize);
|
||||
srcWeights.setSize(sourceCoarseSize);
|
||||
|
||||
forAll(fineSrcAddress, faceI)
|
||||
{
|
||||
// All the elements contributing to faceI. Are slots in
|
||||
// mapDistribute'd data.
|
||||
const labelList& elems = fineSrcAddress[faceI];
|
||||
const scalarList& weights = fineSrcWeights[faceI];
|
||||
const scalar fineArea = fineSrcMagSf[faceI];
|
||||
|
||||
label coarseFaceI = sourceRestrictAddressing[faceI];
|
||||
|
||||
labelList& newElems = srcAddress[coarseFaceI];
|
||||
scalarList& newWeights = srcWeights[coarseFaceI];
|
||||
|
||||
forAll(elems, i)
|
||||
{
|
||||
label elemI = elems[i];
|
||||
label coarseElemI = targetRestrictAddressing[elemI];
|
||||
|
||||
label index = findIndex(newElems, coarseElemI);
|
||||
if (index == -1)
|
||||
{
|
||||
newElems.append(coarseElemI);
|
||||
newWeights.append(fineArea*weights[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
newWeights[index] += fineArea*weights[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// weights normalisation
|
||||
normaliseWeights
|
||||
(
|
||||
srcMagSf,
|
||||
"source",
|
||||
srcAddress,
|
||||
srcWeights,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
@ -1059,6 +1327,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
|
||||
const faceAreaIntersect::triangulationMode& triMode
|
||||
)
|
||||
:
|
||||
singlePatchProc_(-999),
|
||||
srcAddress_(),
|
||||
srcWeights_(),
|
||||
tgtAddress_(),
|
||||
@ -1088,6 +1357,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
|
||||
const faceAreaIntersect::triangulationMode& triMode
|
||||
)
|
||||
:
|
||||
singlePatchProc_(-999),
|
||||
srcAddress_(),
|
||||
srcWeights_(),
|
||||
tgtAddress_(),
|
||||
@ -1165,6 +1435,127 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
|
||||
(
|
||||
const AMIInterpolation<SourcePatch, TargetPatch>& fineAMI,
|
||||
const labelList& sourceRestrictAddressing,
|
||||
const labelList& targetRestrictAddressing
|
||||
)
|
||||
:
|
||||
singlePatchProc_(fineAMI.singlePatchProc_),
|
||||
srcAddress_(),
|
||||
srcWeights_(),
|
||||
tgtAddress_(),
|
||||
tgtWeights_(),
|
||||
startSeedI_(0),
|
||||
triMode_(fineAMI.triMode_),
|
||||
srcMapPtr_(NULL),
|
||||
tgtMapPtr_(NULL)
|
||||
{
|
||||
label sourceCoarseSize =
|
||||
(
|
||||
sourceRestrictAddressing.size()
|
||||
? max(sourceRestrictAddressing)+1
|
||||
: 0
|
||||
);
|
||||
|
||||
label neighbourCoarseSize =
|
||||
(
|
||||
targetRestrictAddressing.size()
|
||||
? max(targetRestrictAddressing)+1
|
||||
: 0
|
||||
);
|
||||
|
||||
if (debug & 2)
|
||||
{
|
||||
Pout<< "AMI: Creating addressing and weights as agglomeration of AMI :"
|
||||
<< " source:" << fineAMI.srcAddress().size()
|
||||
<< " target:" << fineAMI.tgtAddress().size()
|
||||
<< " coarse source size:" << sourceCoarseSize
|
||||
<< " neighbour source size:" << neighbourCoarseSize
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
fineAMI.srcAddress().size() != sourceRestrictAddressing.size()
|
||||
|| fineAMI.tgtAddress().size() != targetRestrictAddressing.size()
|
||||
)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation\n"
|
||||
"(\n"
|
||||
" const AMIInterpolation<SourcePatch, TargetPatch>&,\n"
|
||||
" const label,\n"
|
||||
" const labelList&\n"
|
||||
")"
|
||||
) << "Size mismatch." << nl
|
||||
<< "Source patch size:" << fineAMI.srcAddress().size() << nl
|
||||
<< "Source agglomeration size:"
|
||||
<< sourceRestrictAddressing.size() << nl
|
||||
<< "Target patch size:" << fineAMI.tgtAddress().size() << nl
|
||||
<< "Target agglomeration size:"
|
||||
<< targetRestrictAddressing.size()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
// Agglomerate addresses and weights
|
||||
|
||||
agglomerate
|
||||
(
|
||||
fineAMI.tgtMapPtr_,
|
||||
fineAMI.srcMagSf(),
|
||||
fineAMI.srcAddress(),
|
||||
fineAMI.srcWeights(),
|
||||
|
||||
sourceRestrictAddressing,
|
||||
targetRestrictAddressing,
|
||||
|
||||
srcMagSf_,
|
||||
srcAddress_,
|
||||
srcWeights_,
|
||||
tgtMapPtr_
|
||||
);
|
||||
|
||||
//if (tgtMapPtr_.valid())
|
||||
//{
|
||||
// Pout<< "tgtMap:" << endl;
|
||||
// string oldPrefix = Pout.prefix();
|
||||
// Pout.prefix() = oldPrefix + " ";
|
||||
// tgtMapPtr_().printLayout(Pout);
|
||||
// Pout.prefix() = oldPrefix;
|
||||
//}
|
||||
|
||||
agglomerate
|
||||
(
|
||||
fineAMI.srcMapPtr_,
|
||||
fineAMI.tgtMagSf(),
|
||||
fineAMI.tgtAddress(),
|
||||
fineAMI.tgtWeights(),
|
||||
|
||||
targetRestrictAddressing,
|
||||
sourceRestrictAddressing,
|
||||
|
||||
tgtMagSf_,
|
||||
tgtAddress_,
|
||||
tgtWeights_,
|
||||
srcMapPtr_
|
||||
);
|
||||
|
||||
//if (srcMapPtr_.valid())
|
||||
//{
|
||||
// Pout<< "srcMap:" << endl;
|
||||
// string oldPrefix = Pout.prefix();
|
||||
// Pout.prefix() = oldPrefix + " ";
|
||||
// srcMapPtr_().printLayout(Pout);
|
||||
// Pout.prefix() = oldPrefix;
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
@ -1181,9 +1572,23 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
|
||||
const primitivePatch& tgtPatch
|
||||
)
|
||||
{
|
||||
static label patchI = 0;
|
||||
// Calculate face areas
|
||||
srcMagSf_.setSize(srcPatch.size());
|
||||
forAll(srcMagSf_, faceI)
|
||||
{
|
||||
srcMagSf_[faceI] = srcPatch[faceI].mag(srcPatch.points());
|
||||
}
|
||||
tgtMagSf_.setSize(tgtPatch.size());
|
||||
forAll(tgtMagSf_, faceI)
|
||||
{
|
||||
tgtMagSf_[faceI] = tgtPatch[faceI].mag(tgtPatch.points());
|
||||
}
|
||||
|
||||
if (Pstream::parRun() && distributed(srcPatch, tgtPatch))
|
||||
|
||||
// Calculate if patches present on multiple processors
|
||||
singlePatchProc_ = calcDistribution(srcPatch, tgtPatch);
|
||||
|
||||
if (singlePatchProc_ == -1)
|
||||
{
|
||||
// convert local addressing to global addressing
|
||||
globalIndex globalSrcFaces(srcPatch.size());
|
||||
@ -1288,8 +1693,8 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
|
||||
);
|
||||
|
||||
// weights normalisation
|
||||
normaliseWeights(srcPatch, "source", srcAddress_, srcWeights_, true);
|
||||
normaliseWeights(tgtPatch, "target", tgtAddress_, tgtWeights_, true);
|
||||
normaliseWeights(srcMagSf_, "source", srcAddress_, srcWeights_, true);
|
||||
normaliseWeights(tgtMagSf_, "target", tgtAddress_, tgtWeights_, true);
|
||||
|
||||
// cache maps and reset addresses
|
||||
List<Map<label> > cMap;
|
||||
@ -1308,11 +1713,9 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
|
||||
|
||||
calcAddressing(srcPatch, tgtPatch);
|
||||
|
||||
normaliseWeights(srcPatch, "source", srcAddress_, srcWeights_, true);
|
||||
normaliseWeights(tgtPatch, "target", tgtAddress_, tgtWeights_, true);
|
||||
normaliseWeights(srcMagSf_, "source", srcAddress_, srcWeights_, true);
|
||||
normaliseWeights(tgtMagSf_, "target", tgtAddress_, tgtWeights_, true);
|
||||
}
|
||||
|
||||
patchI++;
|
||||
}
|
||||
|
||||
|
||||
@ -1348,7 +1751,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
|
||||
|
||||
Field<Type>& result = tresult();
|
||||
|
||||
if (Pstream::parRun())
|
||||
if (singlePatchProc_ == -1)
|
||||
{
|
||||
const mapDistribute& map = tgtMapPtr_();
|
||||
|
||||
@ -1430,7 +1833,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
|
||||
|
||||
Field<Type>& result = tresult();
|
||||
|
||||
if (Pstream::parRun())
|
||||
if (singlePatchProc_ == -1)
|
||||
{
|
||||
const mapDistribute& map = srcMapPtr_();
|
||||
|
||||
|
||||
@ -106,8 +106,16 @@ class AMIInterpolation
|
||||
|
||||
// Private data
|
||||
|
||||
|
||||
//- Index of processor that holds all of both sides. -1 in all other
|
||||
// cases
|
||||
label singlePatchProc_;
|
||||
|
||||
// Source patch
|
||||
|
||||
//- Source face areas
|
||||
scalarField srcMagSf_;
|
||||
|
||||
//- Addresses of target faces per source face
|
||||
labelListList srcAddress_;
|
||||
|
||||
@ -117,6 +125,9 @@ class AMIInterpolation
|
||||
|
||||
// Target patch
|
||||
|
||||
//- Target face areas
|
||||
scalarField tgtMagSf_;
|
||||
|
||||
//- Addresses of source faces per target face
|
||||
labelListList tgtAddress_;
|
||||
|
||||
@ -168,8 +179,8 @@ class AMIInterpolation
|
||||
|
||||
// Parallel functionality
|
||||
|
||||
//- Return true if faces are spread over multiple domains
|
||||
bool distributed
|
||||
//- Calculate if patches are on multiple processors
|
||||
label calcDistribution
|
||||
(
|
||||
const primitivePatch& srcPatch,
|
||||
const primitivePatch& tgtPatch
|
||||
@ -276,15 +287,32 @@ class AMIInterpolation
|
||||
// NOTE: if area weights are incorrect by 'a significant amount'
|
||||
// normalisation may stabilise the solution, but will introduce
|
||||
// numerical error!
|
||||
void normaliseWeights
|
||||
static void normaliseWeights
|
||||
(
|
||||
const primitivePatch& patch,
|
||||
const scalarField& patchAreas,
|
||||
const word& patchName,
|
||||
const labelListList& addr,
|
||||
scalarListList& wght,
|
||||
const bool output
|
||||
);
|
||||
|
||||
// Constructor helper
|
||||
|
||||
static void agglomerate
|
||||
(
|
||||
const autoPtr<mapDistribute>& targetMap,
|
||||
const scalarField& fineSrcMagSf,
|
||||
const labelListList& fineSrcAddress,
|
||||
const scalarListList& fineSrcWeights,
|
||||
|
||||
const labelList& sourceRestrictAddressing,
|
||||
const labelList& targetRestrictAddressing,
|
||||
|
||||
scalarField& srcMagSf,
|
||||
labelListList& srcAddress,
|
||||
scalarListList& srcWeights,
|
||||
autoPtr<mapDistribute>& tgtMap
|
||||
);
|
||||
|
||||
public:
|
||||
|
||||
@ -307,6 +335,15 @@ public:
|
||||
const faceAreaIntersect::triangulationMode& triMode
|
||||
);
|
||||
|
||||
//- Construct from agglomeration of AMIInterpolation. Agglomeration
|
||||
// passed in as new coarse size and addressing from fine from coarse.
|
||||
AMIInterpolation
|
||||
(
|
||||
const AMIInterpolation<SourcePatch, TargetPatch>& fineAMI,
|
||||
const labelList& sourceRestrictAddressing,
|
||||
const labelList& neighbourRestrictAddressing
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~AMIInterpolation();
|
||||
@ -316,22 +353,43 @@ public:
|
||||
|
||||
// Access
|
||||
|
||||
//- -1 or the processor holding all faces (both sides) of the AMI
|
||||
label singlePatchProc() const;
|
||||
|
||||
// Source patch
|
||||
|
||||
//- Return const access to source patch face areas
|
||||
inline const scalarField& srcMagSf() const;
|
||||
|
||||
//- Return const access to source patch addressing
|
||||
inline const labelListList& srcAddress();
|
||||
inline const labelListList& srcAddress() const;
|
||||
|
||||
//- Return const access to source patch weights
|
||||
inline const scalarListList& srcWeights();
|
||||
inline const scalarListList& srcWeights() const;
|
||||
|
||||
//- Source map pointer - valid only if singlePatchProc=-1.
|
||||
// This gets
|
||||
// source data into a form to be consumed by
|
||||
// tgtAddress, tgtWeights
|
||||
inline const mapDistribute& srcMap() const;
|
||||
|
||||
|
||||
// Target patch
|
||||
|
||||
//- Return const access to target patch face areas
|
||||
inline const scalarField& tgtMagSf() const;
|
||||
|
||||
//- Return const access to target patch addressing
|
||||
inline const labelListList& tgtAddress();
|
||||
inline const labelListList& tgtAddress() const;
|
||||
|
||||
//- Return const access to target patch weights
|
||||
inline const scalarListList& tgtWeights();
|
||||
inline const scalarListList& tgtWeights() const;
|
||||
|
||||
//- Target map pointer - valid only if singlePatchProc=-1.
|
||||
// This gets
|
||||
// target data into a form to be consumed by
|
||||
// srcAddress, srcWeights
|
||||
inline const mapDistribute& tgtMap() const;
|
||||
|
||||
|
||||
// Manipulation
|
||||
|
||||
@ -23,9 +23,25 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline Foam::label
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::singlePatchProc() const
|
||||
{
|
||||
return singlePatchProc_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::scalarField&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcMagSf() const
|
||||
{
|
||||
return srcMagSf_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::labelListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcAddress()
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcAddress() const
|
||||
{
|
||||
return srcAddress_;
|
||||
}
|
||||
@ -33,15 +49,31 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcAddress()
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::scalarListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeights()
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeights() const
|
||||
{
|
||||
return srcWeights_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::mapDistribute&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcMap() const
|
||||
{
|
||||
return srcMapPtr_();
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::scalarField&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtMagSf() const
|
||||
{
|
||||
return tgtMagSf_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::labelListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtAddress()
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtAddress() const
|
||||
{
|
||||
return tgtAddress_;
|
||||
}
|
||||
@ -49,10 +81,18 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtAddress()
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::scalarListList&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeights()
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeights() const
|
||||
{
|
||||
return tgtWeights_;
|
||||
}
|
||||
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
inline const Foam::mapDistribute&
|
||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtMap() const
|
||||
{
|
||||
return tgtMapPtr_();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -0,0 +1,107 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "cyclicAMIGAMGInterfaceField.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "lduMatrix.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(cyclicAMIGAMGInterfaceField, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
GAMGInterfaceField,
|
||||
cyclicAMIGAMGInterfaceField,
|
||||
lduInterface
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField
|
||||
(
|
||||
const GAMGInterface& GAMGCp,
|
||||
const lduInterfaceField& fineInterface
|
||||
)
|
||||
:
|
||||
GAMGInterfaceField(GAMGCp, fineInterface),
|
||||
cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)),
|
||||
doTransform_(false),
|
||||
rank_(0)
|
||||
{
|
||||
const cyclicAMILduInterfaceField& p =
|
||||
refCast<const cyclicAMILduInterfaceField>(fineInterface);
|
||||
|
||||
doTransform_ = p.doTransform();
|
||||
rank_ = p.rank();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::cyclicAMIGAMGInterfaceField::~cyclicAMIGAMGInterfaceField()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix
|
||||
(
|
||||
const scalarField& psiInternal,
|
||||
scalarField& result,
|
||||
const lduMatrix&,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes
|
||||
) const
|
||||
{
|
||||
// Get neighbouring field
|
||||
scalarField pnf
|
||||
(
|
||||
cyclicAMIInterface_.neighbPatch().interfaceInternalField(psiInternal)
|
||||
);
|
||||
|
||||
if (cyclicAMIInterface_.owner())
|
||||
{
|
||||
pnf = cyclicAMIInterface_.AMI().interpolateToSource(pnf);
|
||||
}
|
||||
else
|
||||
{
|
||||
pnf = cyclicAMIInterface_.neighbPatch().AMI().interpolateToTarget(pnf);
|
||||
}
|
||||
|
||||
const labelUList& faceCells = cyclicAMIInterface_.faceCells();
|
||||
|
||||
forAll(faceCells, elemI)
|
||||
{
|
||||
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,158 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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::cyclicAMIGAMGInterfaceField
|
||||
|
||||
Description
|
||||
GAMG agglomerated cyclic interface field.
|
||||
|
||||
SourceFiles
|
||||
cyclicAMIGAMGInterfaceField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef cyclicAMIGAMGInterfaceField_H
|
||||
#define cyclicAMIGAMGInterfaceField_H
|
||||
|
||||
#include "GAMGInterfaceField.H"
|
||||
#include "cyclicAMIGAMGInterface.H"
|
||||
#include "cyclicAMILduInterfaceField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class cyclicAMIGAMGInterfaceField Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class cyclicAMIGAMGInterfaceField
|
||||
:
|
||||
public GAMGInterfaceField,
|
||||
virtual public cyclicAMILduInterfaceField
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Local reference cast into the cyclic interface
|
||||
const cyclicAMIGAMGInterface& cyclicAMIInterface_;
|
||||
|
||||
//- Is the transform required
|
||||
bool doTransform_;
|
||||
|
||||
//- Rank of component for transformation
|
||||
int rank_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
cyclicAMIGAMGInterfaceField(const cyclicAMIGAMGInterfaceField&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const cyclicAMIGAMGInterfaceField&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("cyclicAMI");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from GAMG interface and fine level interface field
|
||||
cyclicAMIGAMGInterfaceField
|
||||
(
|
||||
const GAMGInterface& GAMGCp,
|
||||
const lduInterfaceField& fineInterfaceField
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~cyclicAMIGAMGInterfaceField();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return size
|
||||
label size() const
|
||||
{
|
||||
return cyclicAMIInterface_.size();
|
||||
}
|
||||
|
||||
|
||||
// Interface matrix update
|
||||
|
||||
//- Update result field based on interface functionality
|
||||
virtual void updateInterfaceMatrix
|
||||
(
|
||||
const scalarField& psiInternal,
|
||||
scalarField& result,
|
||||
const lduMatrix&,
|
||||
const scalarField& coeffs,
|
||||
const direction cmpt,
|
||||
const Pstream::commsTypes commsType
|
||||
) const;
|
||||
|
||||
|
||||
//- Cyclic interface functions
|
||||
|
||||
//- Does the interface field perform the transfromation
|
||||
virtual bool doTransform() const
|
||||
{
|
||||
return doTransform_;
|
||||
}
|
||||
|
||||
//- Return face transformation tensor
|
||||
virtual const tensorField& forwardT() const
|
||||
{
|
||||
return cyclicAMIInterface_.forwardT();
|
||||
}
|
||||
|
||||
//- Return neighbour-cell transformation tensor
|
||||
virtual const tensorField& reverseT() const
|
||||
{
|
||||
return cyclicAMIInterface_.reverseT();
|
||||
}
|
||||
|
||||
//- Return rank of component for transform
|
||||
virtual int rank() const
|
||||
{
|
||||
return rank_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,198 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "AMIInterpolation.H"
|
||||
#include "cyclicAMIGAMGInterface.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "Map.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(cyclicAMIGAMGInterface, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
GAMGInterface,
|
||||
cyclicAMIGAMGInterface,
|
||||
lduInterface
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::cyclicAMIGAMGInterface::cyclicAMIGAMGInterface
|
||||
(
|
||||
const label index,
|
||||
const lduInterfacePtrsList& coarseInterfaces,
|
||||
const lduInterface& fineInterface,
|
||||
const labelField& localRestrictAddressing,
|
||||
const labelField& neighbourRestrictAddressing
|
||||
)
|
||||
:
|
||||
GAMGInterface
|
||||
(
|
||||
index,
|
||||
coarseInterfaces,
|
||||
fineInterface,
|
||||
localRestrictAddressing,
|
||||
neighbourRestrictAddressing
|
||||
),
|
||||
fineCyclicAMIInterface_
|
||||
(
|
||||
refCast<const cyclicAMILduInterface>(fineInterface)
|
||||
)
|
||||
{
|
||||
// Construct face agglomeration from cell agglomeration
|
||||
{
|
||||
// From coarse face to cell
|
||||
DynamicList<label> dynFaceCells(localRestrictAddressing.size());
|
||||
|
||||
// From face to coarse face
|
||||
DynamicList<label> dynFaceRestrictAddressing
|
||||
(
|
||||
localRestrictAddressing.size()
|
||||
);
|
||||
|
||||
Map<label> masterToCoarseFace(localRestrictAddressing.size());
|
||||
|
||||
forAll(localRestrictAddressing, ffi)
|
||||
{
|
||||
label curMaster = localRestrictAddressing[ffi];
|
||||
|
||||
Map<label>::const_iterator fnd = masterToCoarseFace.find
|
||||
(
|
||||
curMaster
|
||||
);
|
||||
|
||||
if (fnd == masterToCoarseFace.end())
|
||||
{
|
||||
// New coarse face
|
||||
label coarseI = dynFaceCells.size();
|
||||
dynFaceRestrictAddressing.append(coarseI);
|
||||
dynFaceCells.append(curMaster);
|
||||
masterToCoarseFace.insert(curMaster, coarseI);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Already have coarse face
|
||||
dynFaceRestrictAddressing.append(fnd());
|
||||
}
|
||||
}
|
||||
|
||||
faceCells_.transfer(dynFaceCells);
|
||||
faceRestrictAddressing_.transfer(dynFaceRestrictAddressing);
|
||||
}
|
||||
|
||||
|
||||
// On the owner side construct the AMI
|
||||
|
||||
if (fineCyclicAMIInterface_.owner())
|
||||
{
|
||||
// Construct the neighbour side agglomeration (as the neighbour would
|
||||
// do it so it the exact loop above using neighbourRestrictAddressing
|
||||
// instead of localRestrictAddressing)
|
||||
|
||||
labelList nbrFaceRestrictAddressing;
|
||||
{
|
||||
// From face to coarse face
|
||||
DynamicList<label> dynNbrFaceRestrictAddressing
|
||||
(
|
||||
neighbourRestrictAddressing.size()
|
||||
);
|
||||
|
||||
Map<label> masterToCoarseFace(neighbourRestrictAddressing.size());
|
||||
|
||||
forAll(neighbourRestrictAddressing, ffi)
|
||||
{
|
||||
label curMaster = neighbourRestrictAddressing[ffi];
|
||||
|
||||
Map<label>::const_iterator fnd = masterToCoarseFace.find
|
||||
(
|
||||
curMaster
|
||||
);
|
||||
|
||||
if (fnd == masterToCoarseFace.end())
|
||||
{
|
||||
// New coarse face
|
||||
label coarseI = masterToCoarseFace.size();
|
||||
dynNbrFaceRestrictAddressing.append(coarseI);
|
||||
masterToCoarseFace.insert(curMaster, coarseI);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Already have coarse face
|
||||
dynNbrFaceRestrictAddressing.append(fnd());
|
||||
}
|
||||
}
|
||||
|
||||
nbrFaceRestrictAddressing.transfer(dynNbrFaceRestrictAddressing);
|
||||
}
|
||||
|
||||
amiPtr_.reset
|
||||
(
|
||||
new AMIPatchToPatchInterpolation
|
||||
(
|
||||
fineCyclicAMIInterface_.AMI(),
|
||||
faceRestrictAddressing_,
|
||||
nbrFaceRestrictAddressing
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::cyclicAMIGAMGInterface::~cyclicAMIGAMGInterface()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::labelField> Foam::cyclicAMIGAMGInterface::internalFieldTransfer
|
||||
(
|
||||
const Pstream::commsTypes,
|
||||
const labelUList& iF
|
||||
) const
|
||||
{
|
||||
const cyclicAMIGAMGInterface& nbr =
|
||||
dynamic_cast<const cyclicAMIGAMGInterface&>(neighbPatch());
|
||||
const labelUList& nbrFaceCells = nbr.faceCells();
|
||||
|
||||
tmp<labelField> tpnf(new labelField(nbrFaceCells.size()));
|
||||
labelField& pnf = tpnf();
|
||||
|
||||
forAll(pnf, facei)
|
||||
{
|
||||
pnf[facei] = iF[nbrFaceCells[facei]];
|
||||
}
|
||||
|
||||
return tpnf;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,158 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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::cyclicAMIGAMGInterface
|
||||
|
||||
Description
|
||||
GAMG agglomerated cyclic AMI interface.
|
||||
|
||||
SourceFiles
|
||||
cyclicAMIGAMGInterface.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef cyclicAMIGAMGInterface_H
|
||||
#define cyclicAMIGAMGInterface_H
|
||||
|
||||
#include "GAMGInterface.H"
|
||||
#include "cyclicAMILduInterface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class cyclicAMIGAMGInterface Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class cyclicAMIGAMGInterface
|
||||
:
|
||||
public GAMGInterface,
|
||||
virtual public cyclicAMILduInterface
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Reference for the cyclicLduInterface from which this is
|
||||
// agglomerated
|
||||
const cyclicAMILduInterface& fineCyclicAMIInterface_;
|
||||
|
||||
//- AMI interface
|
||||
autoPtr<AMIPatchToPatchInterpolation> amiPtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
cyclicAMIGAMGInterface(const cyclicAMIGAMGInterface&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const cyclicAMIGAMGInterface&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("cyclicAMI");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from fine level interface,
|
||||
// local and neighbour restrict addressing
|
||||
cyclicAMIGAMGInterface
|
||||
(
|
||||
const label index,
|
||||
const lduInterfacePtrsList& coarseInterfaces,
|
||||
const lduInterface& fineInterface,
|
||||
const labelField& restrictAddressing,
|
||||
const labelField& neighbourRestrictAddressing
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~cyclicAMIGAMGInterface();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Interface transfer functions
|
||||
|
||||
//- Transfer and return internal field adjacent to the interface
|
||||
virtual tmp<labelField> internalFieldTransfer
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const labelUList& iF
|
||||
) const;
|
||||
|
||||
|
||||
//- Cyclic interface functions
|
||||
|
||||
//- Return neigbour processor number
|
||||
virtual label neighbPatchID() const
|
||||
{
|
||||
return fineCyclicAMIInterface_.neighbPatchID();
|
||||
}
|
||||
|
||||
virtual bool owner() const
|
||||
{
|
||||
return fineCyclicAMIInterface_.owner();
|
||||
}
|
||||
|
||||
virtual const cyclicAMIGAMGInterface& neighbPatch() const
|
||||
{
|
||||
return dynamic_cast<const cyclicAMIGAMGInterface&>
|
||||
(
|
||||
coarseInterfaces_[neighbPatchID()]
|
||||
);
|
||||
}
|
||||
|
||||
virtual const AMIPatchToPatchInterpolation& AMI() const
|
||||
{
|
||||
return amiPtr_();
|
||||
}
|
||||
|
||||
//- Return face transformation tensor
|
||||
virtual const tensorField& forwardT() const
|
||||
{
|
||||
return fineCyclicAMIInterface_.forwardT();
|
||||
}
|
||||
|
||||
//- Return neighbour-cell transformation tensor
|
||||
virtual const tensorField& reverseT() const
|
||||
{
|
||||
return fineCyclicAMIInterface_.reverseT();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -36,6 +36,7 @@ SourceFiles
|
||||
#define cyclicAMILduInterface_H
|
||||
|
||||
#include "primitiveFieldsFwd.H"
|
||||
#include "AMIPatchToPatchInterpolation.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -78,6 +79,8 @@ public:
|
||||
//- Return processor number
|
||||
virtual const cyclicAMILduInterface& neighbPatch() const = 0;
|
||||
|
||||
virtual const AMIPatchToPatchInterpolation& AMI() const = 0;
|
||||
|
||||
//- Return face transformation tensor
|
||||
virtual const tensorField& forwardT() const = 0;
|
||||
|
||||
|
||||
@ -86,7 +86,7 @@ void Foam::cyclicAMIPolyPatch::calcTransforms()
|
||||
}
|
||||
|
||||
// Half1
|
||||
const cyclicAMIPolyPatch& half1 = nbrPatch();
|
||||
const cyclicAMIPolyPatch& half1 = neighbPatch();
|
||||
vectorField half1Areas(half1.size());
|
||||
forAll(half1, facei)
|
||||
{
|
||||
@ -114,14 +114,14 @@ void Foam::cyclicAMIPolyPatch::calcTransforms
|
||||
const vectorField& half1Areas
|
||||
)
|
||||
{
|
||||
if (transform_ != nbrPatch().transform_)
|
||||
if (transform_ != neighbPatch().transform_)
|
||||
{
|
||||
FatalErrorIn("cyclicAMIPolyPatch::calcTransforms()")
|
||||
<< "Patch " << name()
|
||||
<< " has transform type " << transformTypeNames[transform_]
|
||||
<< ", neighbour patch " << nbrPatchName_
|
||||
<< " has transform type "
|
||||
<< nbrPatch().transformTypeNames[nbrPatch().transform_]
|
||||
<< neighbPatch().transformTypeNames[neighbPatch().transform_]
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
@ -221,19 +221,19 @@ void Foam::cyclicAMIPolyPatch::calcTransforms
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicAMIPolyPatch::resetAMI()
|
||||
void Foam::cyclicAMIPolyPatch::resetAMI() const
|
||||
{
|
||||
if (owner())
|
||||
{
|
||||
AMIPtr_.clear();
|
||||
|
||||
const polyPatch& nbr = nbrPatch();
|
||||
pointField nbrPoints = nbrPatch().localPoints();
|
||||
const polyPatch& nbr = neighbPatch();
|
||||
pointField nbrPoints = neighbPatch().localPoints();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
OFstream os(name() + "_neighbourPatch-org.obj");
|
||||
meshTools::writeOBJ(os, nbrPatch().localFaces(), nbrPoints);
|
||||
meshTools::writeOBJ(os, neighbPatch().localFaces(), nbrPoints);
|
||||
}
|
||||
|
||||
// transform neighbour patch to local system
|
||||
@ -288,9 +288,9 @@ void Foam::cyclicAMIPolyPatch::calcGeometry(PstreamBuffers& pBufs)
|
||||
faceCentres(),
|
||||
faceAreas(),
|
||||
faceCellCentres(),
|
||||
nbrPatch().faceCentres(),
|
||||
nbrPatch().faceAreas(),
|
||||
nbrPatch().faceCellCentres()
|
||||
neighbPatch().faceCentres(),
|
||||
neighbPatch().faceAreas(),
|
||||
neighbPatch().faceCellCentres()
|
||||
);
|
||||
}
|
||||
|
||||
@ -535,7 +535,7 @@ Foam::cyclicAMIPolyPatch::~cyclicAMIPolyPatch()
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::label Foam::cyclicAMIPolyPatch::nbrPatchID() const
|
||||
Foam::label Foam::cyclicAMIPolyPatch::neighbPatchID() const
|
||||
{
|
||||
if (nbrPatchID_ == -1)
|
||||
{
|
||||
@ -543,7 +543,7 @@ Foam::label Foam::cyclicAMIPolyPatch::nbrPatchID() const
|
||||
|
||||
if (nbrPatchID_ == -1)
|
||||
{
|
||||
FatalErrorIn("cyclicPolyAMIPatch::nbrPatchID() const")
|
||||
FatalErrorIn("cyclicPolyAMIPatch::neighbPatchID() const")
|
||||
<< "Illegal neighbourPatch name " << nbrPatchName_
|
||||
<< nl << "Valid patch names are "
|
||||
<< this->boundaryMesh().names()
|
||||
@ -557,13 +557,13 @@ Foam::label Foam::cyclicAMIPolyPatch::nbrPatchID() const
|
||||
this->boundaryMesh()[nbrPatchID_]
|
||||
);
|
||||
|
||||
if (nbrPatch.nbrPatchName() != name())
|
||||
if (nbrPatch.neighbPatchName() != name())
|
||||
{
|
||||
WarningIn("cyclicAMIPolyPatch::nbrPatchID() const")
|
||||
WarningIn("cyclicAMIPolyPatch::neighbPatchID() const")
|
||||
<< "Patch " << name()
|
||||
<< " specifies neighbour patch " << nbrPatchName()
|
||||
<< " specifies neighbour patch " << neighbPatchName()
|
||||
<< nl << " but that in return specifies "
|
||||
<< nbrPatch.nbrPatchName() << endl;
|
||||
<< nbrPatch.neighbPatchName() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -573,12 +573,12 @@ Foam::label Foam::cyclicAMIPolyPatch::nbrPatchID() const
|
||||
|
||||
bool Foam::cyclicAMIPolyPatch::owner() const
|
||||
{
|
||||
return index() < nbrPatchID();
|
||||
return index() < neighbPatchID();
|
||||
}
|
||||
|
||||
|
||||
const Foam::autoPtr<Foam::searchableSurface>&
|
||||
Foam::cyclicAMIPolyPatch::surfPtr()
|
||||
Foam::cyclicAMIPolyPatch::surfPtr() const
|
||||
{
|
||||
const word surfType(surfDict_.lookupOrDefault<word>("type", "none"));
|
||||
|
||||
@ -609,7 +609,7 @@ Foam::cyclicAMIPolyPatch::surfPtr()
|
||||
}
|
||||
|
||||
|
||||
const Foam::AMIPatchToPatchInterpolation& Foam::cyclicAMIPolyPatch::AMI()
|
||||
const Foam::AMIPatchToPatchInterpolation& Foam::cyclicAMIPolyPatch::AMI() const
|
||||
{
|
||||
if (!owner())
|
||||
{
|
||||
@ -626,6 +626,16 @@ const Foam::AMIPatchToPatchInterpolation& Foam::cyclicAMIPolyPatch::AMI()
|
||||
resetAMI();
|
||||
}
|
||||
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicAMIPolyPatch : " << name()
|
||||
<< " constructed AMI with " << endl
|
||||
<< " " << ":srcAddress:" << AMIPtr_().srcAddress().size() << endl
|
||||
<< " " << " tgAddress :" << AMIPtr_().tgtAddress().size() << endl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return AMIPtr_();
|
||||
}
|
||||
|
||||
|
||||
@ -86,10 +86,10 @@ private:
|
||||
|
||||
|
||||
//- AMI interpolation class
|
||||
autoPtr<AMIPatchToPatchInterpolation> AMIPtr_;
|
||||
mutable autoPtr<AMIPatchToPatchInterpolation> AMIPtr_;
|
||||
|
||||
//- Projection surface
|
||||
autoPtr<searchableSurface> surfPtr_;
|
||||
mutable autoPtr<searchableSurface> surfPtr_;
|
||||
|
||||
//- Dictionary used during projection surface construction
|
||||
const dictionary surfDict_;
|
||||
@ -110,7 +110,7 @@ private:
|
||||
);
|
||||
|
||||
//- Reset the AMI interpolator
|
||||
void resetAMI();
|
||||
void resetAMI() const;
|
||||
|
||||
|
||||
protected:
|
||||
@ -255,22 +255,22 @@ public:
|
||||
// Access
|
||||
|
||||
//- Neighbour patch name
|
||||
inline const word& nbrPatchName() const;
|
||||
inline const word& neighbPatchName() const;
|
||||
|
||||
//- Neighbour patch ID
|
||||
virtual label nbrPatchID() const;
|
||||
virtual label neighbPatchID() const;
|
||||
|
||||
//- Does this side own the patch?
|
||||
virtual bool owner() const;
|
||||
|
||||
//- Return a reference to the neihgjbour patch
|
||||
inline const cyclicAMIPolyPatch& nbrPatch() const;
|
||||
//- Return a reference to the neighbour patch
|
||||
inline const cyclicAMIPolyPatch& neighbPatch() const;
|
||||
|
||||
//- Return a reference to the projection surface
|
||||
const autoPtr<searchableSurface>& surfPtr();
|
||||
const autoPtr<searchableSurface>& surfPtr() const;
|
||||
|
||||
//- Return a reference to the AMI interpolator
|
||||
const AMIPatchToPatchInterpolation& AMI();
|
||||
const AMIPatchToPatchInterpolation& AMI() const;
|
||||
|
||||
|
||||
// Transformations
|
||||
|
||||
@ -25,16 +25,16 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
inline const Foam::word& Foam::cyclicAMIPolyPatch::nbrPatchName() const
|
||||
inline const Foam::word& Foam::cyclicAMIPolyPatch::neighbPatchName() const
|
||||
{
|
||||
return nbrPatchName_;
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::cyclicAMIPolyPatch&
|
||||
Foam::cyclicAMIPolyPatch::nbrPatch() const
|
||||
Foam::cyclicAMIPolyPatch::neighbPatch() const
|
||||
{
|
||||
const polyPatch& pp = this->boundaryMesh()[nbrPatchID()];
|
||||
const polyPatch& pp = this->boundaryMesh()[neighbPatchID()];
|
||||
return refCast<const cyclicAMIPolyPatch>(pp);
|
||||
}
|
||||
|
||||
|
||||
@ -23,8 +23,6 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//#include "cyclicAMIPolyPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
@ -39,7 +37,7 @@ Foam::tmp<Foam::Field<Type> > Foam::cyclicAMIPolyPatch::interpolate
|
||||
}
|
||||
else
|
||||
{
|
||||
return nbrPatch().AMIPtr_->interpolateToTarget(fld);
|
||||
return neighbPatch().AMIPtr_->interpolateToTarget(fld);
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +54,7 @@ Foam::tmp<Foam::Field<Type> > Foam::cyclicAMIPolyPatch::interpolate
|
||||
}
|
||||
else
|
||||
{
|
||||
return nbrPatch().AMIPtr_->interpolateToTarget(tFld);
|
||||
return neighbPatch().AMIPtr_->interpolateToTarget(tFld);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -165,6 +165,8 @@ twoDPointCorrector/twoDPointCorrector.C
|
||||
AMI=AMIInterpolation
|
||||
$(AMI)/AMIInterpolation/AMIInterpolationName.C
|
||||
$(AMI)/faceAreaIntersect/faceAreaIntersect.C
|
||||
$(AMI)/GAMG/interfaces/cyclicAMIGAMGInterface/cyclicAMIGAMGInterface.C
|
||||
$(AMI)/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C
|
||||
|
||||
AMICycPatches=$(AMI)/patches/cyclic
|
||||
$(AMICycPatches)/cyclicAMILduInterfaceField/cyclicAMILduInterface.C
|
||||
|
||||
Reference in New Issue
Block a user