ENH: cyclicACMI: optional scaling with PatchFunction1.
Added 'scale' parameter to cyclicACMI. Scales the amount of 'coupledness' (= mask). Allows opening/closing without mesh motion.
This commit is contained in:
parent
6ac8e06245
commit
31ecf0d732
@ -43,6 +43,43 @@ namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
|
||||
|
||||
bool Foam::cyclicACMIFvPatch::updateAreas() const
|
||||
{
|
||||
// Give AMI chance to update itself
|
||||
bool updated = cyclicACMIPolyPatch_.updateAreas();
|
||||
|
||||
if (!cyclicACMIPolyPatch_.owner())
|
||||
{
|
||||
return updated;
|
||||
}
|
||||
|
||||
if (updated || !cyclicACMIPolyPatch_.upToDate(areaTime_))
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicACMIFvPatch::updateAreas() : updating fv areas for "
|
||||
<< name() << " and " << this->nonOverlapPatch().name()
|
||||
<< endl;
|
||||
}
|
||||
|
||||
const fvPatch& nonOverlapPatch = this->nonOverlapPatch();
|
||||
const cyclicACMIFvPatch& nbrACMI = neighbPatch();
|
||||
const fvPatch& nbrNonOverlapPatch = nbrACMI.nonOverlapPatch();
|
||||
|
||||
resetPatchAreas(*this);
|
||||
resetPatchAreas(nonOverlapPatch);
|
||||
resetPatchAreas(nbrACMI);
|
||||
resetPatchAreas(nbrNonOverlapPatch);
|
||||
|
||||
updated = true;
|
||||
|
||||
// Mark my data to be up to date with ACMI polyPatch level
|
||||
cyclicACMIPolyPatch_.setUpToDate(areaTime_);
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicACMIFvPatch::resetPatchAreas(const fvPatch& fvp) const
|
||||
{
|
||||
const_cast<vectorField&>(fvp.Sf()) = fvp.patch().faceAreas();
|
||||
@ -100,6 +137,35 @@ void Foam::cyclicACMIFvPatch::makeWeights(scalarField& w) const
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::cyclicACMIFvPatch::cyclicACMIFvPatch
|
||||
(
|
||||
const polyPatch& patch,
|
||||
const fvBoundaryMesh& bm
|
||||
)
|
||||
:
|
||||
coupledFvPatch(patch, bm),
|
||||
cyclicACMILduInterface(),
|
||||
cyclicACMIPolyPatch_(refCast<const cyclicACMIPolyPatch>(patch)),
|
||||
areaTime_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"areaTime",
|
||||
boundaryMesh().mesh().pointsInstance(),
|
||||
boundaryMesh().mesh(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
dimensionedScalar("time", dimTime, -GREAT)
|
||||
)
|
||||
{
|
||||
areaTime_.eventNo() = -1;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::cyclicACMIFvPatch::coupled() const
|
||||
@ -178,91 +244,103 @@ void Foam::cyclicACMIFvPatch::movePoints()
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the patch face areas to be consistent with the changes made at the
|
||||
// polyPatch level
|
||||
|
||||
const fvPatch& nonOverlapPatch = this->nonOverlapPatch();
|
||||
const cyclicACMIFvPatch& nbrACMI = neighbPatch();
|
||||
const fvPatch& nbrNonOverlapPatch = nbrACMI.nonOverlapPatch();
|
||||
|
||||
resetPatchAreas(*this);
|
||||
resetPatchAreas(nonOverlapPatch);
|
||||
resetPatchAreas(nbrACMI);
|
||||
resetPatchAreas(nbrNonOverlapPatch);
|
||||
|
||||
// Scale the mesh flux
|
||||
|
||||
const labelListList& newSrcAddr = AMI().srcAddress();
|
||||
const labelListList& newTgtAddr = AMI().tgtAddress();
|
||||
|
||||
const fvMesh& mesh = boundaryMesh().mesh();
|
||||
surfaceScalarField& meshPhi = const_cast<fvMesh&>(mesh).setPhi();
|
||||
surfaceScalarField::Boundary& meshPhiBf = meshPhi.boundaryFieldRef();
|
||||
|
||||
// Note: phip and phiNonOverlapp will be different sizes if new faces
|
||||
// have been added
|
||||
scalarField& phip = meshPhiBf[cyclicACMIPolyPatch_.index()];
|
||||
scalarField& phiNonOverlapp =
|
||||
meshPhiBf[nonOverlapPatch.patch().index()];
|
||||
|
||||
const auto& localFaces = cyclicACMIPolyPatch_.localFaces();
|
||||
const auto& localPoints = cyclicACMIPolyPatch_.localPoints();
|
||||
|
||||
forAll(phip, facei)
|
||||
if (!cyclicACMIPolyPatch_.upToDate(areaTime_))
|
||||
{
|
||||
if (newSrcAddr[facei].empty())
|
||||
if (debug)
|
||||
{
|
||||
// AMI patch with no connection to other coupled faces
|
||||
phip[facei] = 0.0;
|
||||
Pout<< "cyclicACMIFvPatch::movePoints() : updating fv areas for "
|
||||
<< name() << " and " << this->nonOverlapPatch().name()
|
||||
<< endl;
|
||||
}
|
||||
else
|
||||
|
||||
|
||||
// Set the patch face areas to be consistent with the changes made
|
||||
// at the polyPatch level
|
||||
|
||||
const fvPatch& nonOverlapPatch = this->nonOverlapPatch();
|
||||
const cyclicACMIFvPatch& nbrACMI = neighbPatch();
|
||||
const fvPatch& nbrNonOverlapPatch = nbrACMI.nonOverlapPatch();
|
||||
|
||||
resetPatchAreas(*this);
|
||||
resetPatchAreas(nonOverlapPatch);
|
||||
resetPatchAreas(nbrACMI);
|
||||
resetPatchAreas(nbrNonOverlapPatch);
|
||||
|
||||
// Scale the mesh flux
|
||||
|
||||
const labelListList& newSrcAddr = AMI().srcAddress();
|
||||
const labelListList& newTgtAddr = AMI().tgtAddress();
|
||||
|
||||
const fvMesh& mesh = boundaryMesh().mesh();
|
||||
surfaceScalarField& meshPhi = const_cast<fvMesh&>(mesh).setPhi();
|
||||
surfaceScalarField::Boundary& meshPhiBf = meshPhi.boundaryFieldRef();
|
||||
|
||||
// Note: phip and phiNonOverlap will be different sizes if new faces
|
||||
// have been added
|
||||
scalarField& phip = meshPhiBf[cyclicACMIPolyPatch_.index()];
|
||||
scalarField& phiNonOverlapp =
|
||||
meshPhiBf[nonOverlapPatch.patch().index()];
|
||||
|
||||
const auto& points = mesh.points();
|
||||
|
||||
forAll(phip, facei)
|
||||
{
|
||||
// Scale the mesh flux according to the area fraction
|
||||
const face& fAMI = localFaces[facei];
|
||||
if (newSrcAddr[facei].empty())
|
||||
{
|
||||
// AMI patch with no connection to other coupled faces
|
||||
phip[facei] = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Scale the mesh flux according to the area fraction
|
||||
const face& fAMI = cyclicACMIPolyPatch_[facei];
|
||||
|
||||
// Note: using raw point locations to calculate the geometric
|
||||
// area - faces areas are currently scaled (decoupled from
|
||||
// mesh points)
|
||||
const scalar geomArea = fAMI.mag(localPoints);
|
||||
phip[facei] *= magSf()[facei]/geomArea;
|
||||
// Note: using raw point locations to calculate the geometric
|
||||
// area - faces areas are currently scaled (decoupled from
|
||||
// mesh points)
|
||||
const scalar geomArea = fAMI.mag(points);
|
||||
phip[facei] *= magSf()[facei]/geomArea;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forAll(phiNonOverlapp, facei)
|
||||
{
|
||||
const scalar w = 1.0 - cyclicACMIPolyPatch_.srcMask()[facei];
|
||||
phiNonOverlapp[facei] *= w;
|
||||
}
|
||||
|
||||
scalarField& nbrPhip = meshPhiBf[nbrACMI.patch().index()];
|
||||
scalarField& nbrPhiNonOverlapp =
|
||||
meshPhiBf[nbrNonOverlapPatch.patch().index()];
|
||||
|
||||
const auto& nbrLocalFaces = nbrACMI.patch().localFaces();
|
||||
const auto& nbrLocalPoints = nbrACMI.patch().localPoints();
|
||||
|
||||
forAll(nbrPhip, facei)
|
||||
{
|
||||
if (newTgtAddr[facei].empty())
|
||||
forAll(phiNonOverlapp, facei)
|
||||
{
|
||||
nbrPhip[facei] = 0.0;
|
||||
const scalar w = 1.0 - cyclicACMIPolyPatch_.srcMask()[facei];
|
||||
phiNonOverlapp[facei] *= w;
|
||||
}
|
||||
else
|
||||
|
||||
const cyclicACMIPolyPatch& nbrPatch = nbrACMI.cyclicACMIPatch();
|
||||
scalarField& nbrPhip = meshPhiBf[nbrPatch.index()];
|
||||
scalarField& nbrPhiNonOverlapp =
|
||||
meshPhiBf[nbrNonOverlapPatch.patch().index()];
|
||||
|
||||
forAll(nbrPhip, facei)
|
||||
{
|
||||
const face& fAMI = nbrLocalFaces[facei];
|
||||
if (newTgtAddr[facei].empty())
|
||||
{
|
||||
nbrPhip[facei] = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
const face& fAMI = nbrPatch[facei];
|
||||
|
||||
// Note: using raw point locations to calculate the geometric
|
||||
// area - faces areas are currently scaled (decoupled from
|
||||
// mesh points)
|
||||
const scalar geomArea = fAMI.mag(nbrLocalPoints);
|
||||
nbrPhip[facei] *= nbrACMI.magSf()[facei]/geomArea;
|
||||
// Note: using raw point locations to calculate the geometric
|
||||
// area - faces areas are currently scaled (decoupled from
|
||||
// mesh points)
|
||||
const scalar geomArea = fAMI.mag(points);
|
||||
nbrPhip[facei] *= nbrACMI.magSf()[facei]/geomArea;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forAll(nbrPhiNonOverlapp, facei)
|
||||
{
|
||||
const scalar w = 1.0 - cyclicACMIPolyPatch_.tgtMask()[facei];
|
||||
nbrPhiNonOverlapp[facei] *= w;
|
||||
forAll(nbrPhiNonOverlapp, facei)
|
||||
{
|
||||
const scalar w = 1.0 - cyclicACMIPolyPatch_.tgtMask()[facei];
|
||||
nbrPhiNonOverlapp[facei] *= w;
|
||||
}
|
||||
|
||||
// Mark my data to be up to date with ACMI polyPatch level
|
||||
cyclicACMIPolyPatch_.setUpToDate(areaTime_);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -60,11 +61,18 @@ class cyclicACMIFvPatch
|
||||
|
||||
const cyclicACMIPolyPatch& cyclicACMIPolyPatch_;
|
||||
|
||||
//- Flag to detect whether AMI is up to date with mesh points
|
||||
mutable uniformDimensionedScalarField areaTime_;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member functions
|
||||
|
||||
//- Update the AMI and patch areas. Return true if anything updated
|
||||
virtual bool updateAreas() const;
|
||||
|
||||
//- Helper function to reset the FV patch areas from the primitive patch
|
||||
void resetPatchAreas(const fvPatch& fvp) const;
|
||||
|
||||
@ -84,12 +92,7 @@ public:
|
||||
// Constructors
|
||||
|
||||
//- Construct from polyPatch
|
||||
cyclicACMIFvPatch(const polyPatch& patch, const fvBoundaryMesh& bm)
|
||||
:
|
||||
coupledFvPatch(patch, bm),
|
||||
cyclicACMILduInterface(),
|
||||
cyclicACMIPolyPatch_(refCast<const cyclicACMIPolyPatch>(patch))
|
||||
{}
|
||||
cyclicACMIFvPatch(const polyPatch& patch, const fvBoundaryMesh& bm);
|
||||
|
||||
|
||||
// Member functions
|
||||
@ -181,6 +184,9 @@ public:
|
||||
const Field<Type>& fld
|
||||
) const
|
||||
{
|
||||
// Make sure areas are up-to-date
|
||||
updateAreas();
|
||||
|
||||
return
|
||||
cyclicACMIPolyPatch_.cyclicAMIPolyPatch::interpolate
|
||||
(
|
||||
|
@ -43,6 +43,117 @@ namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
bool Foam::cyclicACMIPolyPatch::updateAreas() const
|
||||
{
|
||||
const polyMesh& mesh = boundaryMesh().mesh();
|
||||
|
||||
bool updated = false;
|
||||
|
||||
if (!owner())
|
||||
{
|
||||
return updated;
|
||||
}
|
||||
|
||||
// Check if underlying AMI up to date
|
||||
if (!mesh.upToDatePoints(AMITime_))
|
||||
{
|
||||
// This should not happen normally since resetAMI is triggered
|
||||
// by any point motion.
|
||||
FatalErrorInFunction << "Problem : AMI is up to event:"
|
||||
<< AMITime_.eventNo()
|
||||
<< " mesh points are up to time " << mesh.pointsInstance()
|
||||
<< " patch:" << this->name()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Check if scaling enabled (and necessary)
|
||||
if
|
||||
(
|
||||
srcScalePtr_.valid()
|
||||
&& (updated || prevTimeIndex_ != mesh.time().timeIndex())
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicACMIPolyPatch::updateAreas() :"
|
||||
<< " patch:" << this->name()
|
||||
<< " neighbPatch:" << this->neighbPatch().name()
|
||||
<< " AMITime_:" << AMITime_.eventNo()
|
||||
<< " uptodate:" << mesh.upToDatePoints(AMITime_)
|
||||
<< " mesh.time().timeIndex():" << mesh.time().timeIndex()
|
||||
<< " prevTimeIndex_:" << prevTimeIndex_
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if (createAMIFaces_)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Topology changes and scaling currently not supported."
|
||||
<< " Patch " << this->name() << endl;
|
||||
}
|
||||
|
||||
const scalar t = mesh.time().timeOutputValue();
|
||||
|
||||
// Note: ideally preserve src/tgtMask before clipping to tolerance ...
|
||||
srcScaledMask_ =
|
||||
min
|
||||
(
|
||||
scalar(1) - tolerance_,
|
||||
max(tolerance_, srcScalePtr_->value(t)*srcMask_)
|
||||
);
|
||||
|
||||
|
||||
if (!tgtScalePtr_.valid())
|
||||
{
|
||||
tgtScalePtr_= srcScalePtr_.clone(neighbPatch());
|
||||
}
|
||||
|
||||
tgtScaledMask_ =
|
||||
min
|
||||
(
|
||||
scalar(1) - tolerance_,
|
||||
max(tolerance_, tgtScalePtr_->value(t)*tgtMask_)
|
||||
);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "cyclicACMIPolyPatch::updateAreas : scaling masks"
|
||||
<< " for " << name() << " mask " << gAverage(srcScaledMask_)
|
||||
<< " and " << nonOverlapPatch().name()
|
||||
<< " mask " << gAverage(srcScaledMask_) << endl;
|
||||
}
|
||||
|
||||
// Calculate areas from the masks
|
||||
cyclicACMIPolyPatch& cpp = const_cast<cyclicACMIPolyPatch&>(*this);
|
||||
const cyclicACMIPolyPatch& nbrCpp = neighbPatch();
|
||||
|
||||
cpp.scalePatchFaceAreas(*this, srcScaledMask_, thisSf_, thisNoSf_);
|
||||
cpp.scalePatchFaceAreas(nbrCpp, tgtScaledMask_, nbrSf_, nbrNoSf_);
|
||||
|
||||
prevTimeIndex_ = mesh.time().timeIndex();
|
||||
AMITime_.setUpToDate();
|
||||
updated = true;
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::cyclicACMIPolyPatch::upToDate(const regIOobject& io) const
|
||||
{
|
||||
// Is io up to date with
|
||||
// - underlying AMI
|
||||
// - scaling
|
||||
return io.upToDate(AMITime_);
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicACMIPolyPatch::setUpToDate(regIOobject& io) const
|
||||
{
|
||||
io.setUpToDate();
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicACMIPolyPatch::reportCoverage
|
||||
(
|
||||
const word& name,
|
||||
@ -72,6 +183,85 @@ void Foam::cyclicACMIPolyPatch::reportCoverage
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicACMIPolyPatch::scalePatchFaceAreas
|
||||
(
|
||||
const cyclicACMIPolyPatch& acmipp,
|
||||
const scalarField& mask, // srcMask_
|
||||
const vectorList& faceArea, // this->faceAreas();
|
||||
const vectorList& noFaceArea // nonOverlapPatch.faceAreas()
|
||||
)
|
||||
{
|
||||
// Primitive patch face areas have been cleared/reset based on the raw
|
||||
// points - need to reset to avoid double-accounting of face areas
|
||||
|
||||
const scalar maxTol = scalar(1) - tolerance_;
|
||||
|
||||
const polyPatch& nonOverlapPatch = acmipp.nonOverlapPatch();
|
||||
vectorField::subField noSf = nonOverlapPatch.faceAreas();
|
||||
|
||||
DebugPout
|
||||
<< "rescaling non-overlap patch areas for: "
|
||||
<< nonOverlapPatch.name() << endl;
|
||||
|
||||
if (mask.size() != noSf.size())
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Inconsistent sizes for patch: " << acmipp.name()
|
||||
<< " - not manipulating patches" << nl
|
||||
<< " - size: " << size() << nl
|
||||
<< " - non-overlap patch size: " << noSf.size() << nl
|
||||
<< " - mask size: " << mask.size() << nl
|
||||
<< "This is OK for decomposition but"
|
||||
<< " should be considered fatal at run-time" << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
forAll(noSf, facei)
|
||||
{
|
||||
const scalar w = min(maxTol, max(tolerance_, mask[facei]));
|
||||
noSf[facei] = noFaceArea[facei]*(scalar(1) - w);
|
||||
}
|
||||
|
||||
if (!createAMIFaces_)
|
||||
{
|
||||
// Note: for topological update (createAMIFaces_ = true)
|
||||
// AMI coupled patch face areas are updated as part of the topological
|
||||
// updates, e.g. by the calls to cyclicAMIPolyPatch's setTopology and
|
||||
// initMovePoints
|
||||
DebugPout
|
||||
<< "scaling coupled patch areas for: " << acmipp.name() << endl;
|
||||
|
||||
// Scale the coupled patch face areas
|
||||
vectorField::subField Sf = acmipp.faceAreas();
|
||||
|
||||
forAll(Sf, facei)
|
||||
{
|
||||
Sf[facei] = faceArea[facei]*max(tolerance_, mask[facei]);
|
||||
}
|
||||
|
||||
// Re-normalise the weights since the effect of overlap is already
|
||||
// accounted for in the area
|
||||
auto& weights = const_cast<scalarListList&>(acmipp.weights());
|
||||
auto& weightsSum = const_cast<scalarField&>(acmipp.weightsSum());
|
||||
forAll(weights, i)
|
||||
{
|
||||
scalarList& wghts = weights[i];
|
||||
if (wghts.size())
|
||||
{
|
||||
scalar& sum = weightsSum[i];
|
||||
|
||||
forAll(wghts, j)
|
||||
{
|
||||
wghts[j] /= sum;
|
||||
}
|
||||
sum = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::cyclicACMIPolyPatch::resetAMI() const
|
||||
{
|
||||
resetAMI(boundaryMesh().mesh().points());
|
||||
@ -164,86 +354,37 @@ void Foam::cyclicACMIPolyPatch::scalePatchFaceAreas()
|
||||
return;
|
||||
}
|
||||
|
||||
scalePatchFaceAreas(*this);
|
||||
scalePatchFaceAreas(this->neighbPatch());
|
||||
}
|
||||
const polyPatch& nonOverlapPatch = this->nonOverlapPatch();
|
||||
const cyclicACMIPolyPatch& nbrPatch = this->neighbPatch();
|
||||
const polyPatch& nbrNonOverlapPatch = nbrPatch.nonOverlapPatch();
|
||||
|
||||
|
||||
void Foam::cyclicACMIPolyPatch::scalePatchFaceAreas
|
||||
(
|
||||
const cyclicACMIPolyPatch& acmipp
|
||||
)
|
||||
{
|
||||
// Primitive patch face areas have been cleared/reset based on the raw
|
||||
// points - need to reset to avoid double-accounting of face areas
|
||||
|
||||
const scalar maxTol = scalar(1) - tolerance_;
|
||||
const scalarField& mask = acmipp.mask();
|
||||
|
||||
const polyPatch& nonOverlapPatch = acmipp.nonOverlapPatch();
|
||||
vectorField::subField noSf = nonOverlapPatch.faceAreas();
|
||||
|
||||
DebugPout
|
||||
<< "rescaling non-overlap patch areas for: " << nonOverlapPatch.name()
|
||||
<< endl;
|
||||
|
||||
|
||||
if (mask.size() != noSf.size())
|
||||
if (srcScalePtr_.valid())
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Inconsistent sizes for patch: " << acmipp.name()
|
||||
<< " - not manipulating patches" << nl
|
||||
<< " - size: " << size() << nl
|
||||
<< " - non-overlap patch size: " << noSf.size() << nl
|
||||
<< " - mask size: " << mask.size() << nl
|
||||
<< "This is OK for decomposition but should be considered fatal "
|
||||
<< "at run-time" << endl;
|
||||
|
||||
return;
|
||||
// Save overlap geometry for later scaling
|
||||
thisSf_ = this->faceAreas();
|
||||
thisNoSf_ = nonOverlapPatch.faceAreas();
|
||||
nbrSf_ = nbrPatch.faceAreas();
|
||||
nbrNoSf_ = nbrNonOverlapPatch.faceAreas();
|
||||
}
|
||||
|
||||
forAll(noSf, facei)
|
||||
{
|
||||
const scalar w = min(maxTol, max(tolerance_, mask[facei]));
|
||||
noSf[facei] *= scalar(1) - w;
|
||||
}
|
||||
// In-place scale the patch areas
|
||||
scalePatchFaceAreas
|
||||
(
|
||||
*this,
|
||||
srcMask_, // unscaled mask
|
||||
this->faceAreas(),
|
||||
nonOverlapPatch.faceAreas()
|
||||
);
|
||||
scalePatchFaceAreas
|
||||
(
|
||||
nbrPatch,
|
||||
tgtMask_, // unscaled mask
|
||||
nbrPatch.faceAreas(),
|
||||
nbrNonOverlapPatch.faceAreas()
|
||||
);
|
||||
|
||||
if (!createAMIFaces_)
|
||||
{
|
||||
// Note: for topological update (createAMIFaces_ = true)
|
||||
// AMI coupled patch face areas are updated as part of the topological
|
||||
// updates, e.g. by the calls to cyclicAMIPolyPatch's setTopology and
|
||||
// initMovePoints
|
||||
DebugPout
|
||||
<< "scaling coupled patch areas for: " << acmipp.name() << endl;
|
||||
|
||||
// Scale the coupled patch face areas
|
||||
vectorField::subField Sf = acmipp.faceAreas();
|
||||
|
||||
forAll(Sf, facei)
|
||||
{
|
||||
Sf[facei] *= max(tolerance_, mask[facei]);
|
||||
}
|
||||
|
||||
// Re-normalise the weights since the effect of overlap is already
|
||||
// accounted for in the area
|
||||
auto& weights = const_cast<scalarListList&>(acmipp.weights());
|
||||
auto& weightsSum = const_cast<scalarField&>(acmipp.weightsSum());
|
||||
forAll(weights, i)
|
||||
{
|
||||
scalarList& wghts = weights[i];
|
||||
if (wghts.size())
|
||||
{
|
||||
scalar& sum = weightsSum[i];
|
||||
|
||||
forAll(wghts, j)
|
||||
{
|
||||
wghts[j] /= sum;
|
||||
}
|
||||
sum = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Mark current AMI as up to date with points
|
||||
boundaryMesh().mesh().setUpToDatePoints(AMITime_);
|
||||
}
|
||||
|
||||
|
||||
@ -328,13 +469,33 @@ void Foam::cyclicACMIPolyPatch::clearGeom()
|
||||
|
||||
const Foam::scalarField& Foam::cyclicACMIPolyPatch::srcMask() const
|
||||
{
|
||||
return srcMask_;
|
||||
if (srcScalePtr_.valid())
|
||||
{
|
||||
// Make sure areas are up-to-date
|
||||
updateAreas();
|
||||
|
||||
return srcScaledMask_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return srcMask_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Foam::scalarField& Foam::cyclicACMIPolyPatch::tgtMask() const
|
||||
{
|
||||
return tgtMask_;
|
||||
if (tgtScalePtr_.valid())
|
||||
{
|
||||
// Make sure areas are up-to-date
|
||||
updateAreas();
|
||||
|
||||
return tgtScaledMask_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return tgtMask_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -366,7 +527,21 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
|
||||
nonOverlapPatchName_(word::null),
|
||||
nonOverlapPatchID_(-1),
|
||||
srcMask_(),
|
||||
tgtMask_()
|
||||
tgtMask_(),
|
||||
AMITime_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"AMITime",
|
||||
boundaryMesh().mesh().pointsInstance(),
|
||||
boundaryMesh().mesh(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
dimensionedScalar("time", dimTime, -GREAT)
|
||||
),
|
||||
prevTimeIndex_(-1)
|
||||
{
|
||||
AMIPtr_->setRequireMatch(false);
|
||||
|
||||
@ -389,7 +564,27 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
|
||||
nonOverlapPatchName_(dict.get<word>("nonOverlapPatch")),
|
||||
nonOverlapPatchID_(-1),
|
||||
srcMask_(),
|
||||
tgtMask_()
|
||||
tgtMask_(),
|
||||
srcScalePtr_
|
||||
(
|
||||
dict.found("scale")
|
||||
? PatchFunction1<scalar>::New(*this, "scale", dict)
|
||||
: nullptr
|
||||
),
|
||||
AMITime_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"AMITime",
|
||||
boundaryMesh().mesh().pointsInstance(),
|
||||
boundaryMesh().mesh(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
dimensionedScalar("time", dimTime, -GREAT)
|
||||
),
|
||||
prevTimeIndex_(-1)
|
||||
{
|
||||
AMIPtr_->setRequireMatch(false);
|
||||
|
||||
@ -416,7 +611,27 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
|
||||
nonOverlapPatchName_(pp.nonOverlapPatchName_),
|
||||
nonOverlapPatchID_(-1),
|
||||
srcMask_(),
|
||||
tgtMask_()
|
||||
tgtMask_(),
|
||||
srcScalePtr_
|
||||
(
|
||||
pp.srcScalePtr_.valid()
|
||||
? pp.srcScalePtr_.clone(*this)
|
||||
: nullptr
|
||||
),
|
||||
AMITime_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"AMITime",
|
||||
boundaryMesh().mesh().pointsInstance(),
|
||||
boundaryMesh().mesh(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
dimensionedScalar("time", dimTime, -GREAT)
|
||||
),
|
||||
prevTimeIndex_(-1)
|
||||
{
|
||||
AMIPtr_->setRequireMatch(false);
|
||||
|
||||
@ -440,7 +655,27 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
|
||||
nonOverlapPatchName_(nonOverlapPatchName),
|
||||
nonOverlapPatchID_(-1),
|
||||
srcMask_(),
|
||||
tgtMask_()
|
||||
tgtMask_(),
|
||||
srcScalePtr_
|
||||
(
|
||||
pp.srcScalePtr_.valid()
|
||||
? pp.srcScalePtr_.clone(*this)
|
||||
: nullptr
|
||||
),
|
||||
AMITime_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"AMITime",
|
||||
boundaryMesh().mesh().pointsInstance(),
|
||||
boundaryMesh().mesh(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
dimensionedScalar("time", dimTime, -GREAT)
|
||||
),
|
||||
prevTimeIndex_(-1)
|
||||
{
|
||||
AMIPtr_->setRequireMatch(false);
|
||||
|
||||
@ -470,7 +705,27 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
|
||||
nonOverlapPatchName_(pp.nonOverlapPatchName_),
|
||||
nonOverlapPatchID_(-1),
|
||||
srcMask_(),
|
||||
tgtMask_()
|
||||
tgtMask_(),
|
||||
srcScalePtr_
|
||||
(
|
||||
pp.srcScalePtr_.valid()
|
||||
? pp.srcScalePtr_.clone(*this)
|
||||
: nullptr
|
||||
),
|
||||
AMITime_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"AMITime",
|
||||
boundaryMesh().mesh().pointsInstance(),
|
||||
boundaryMesh().mesh(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
dimensionedScalar("time", dimTime, -GREAT)
|
||||
),
|
||||
prevTimeIndex_(-1)
|
||||
{
|
||||
AMIPtr_->setRequireMatch(false);
|
||||
}
|
||||
@ -481,6 +736,17 @@ Foam::cyclicACMIPolyPatch::cyclicACMIPolyPatch
|
||||
const Foam::cyclicACMIPolyPatch& Foam::cyclicACMIPolyPatch::neighbPatch() const
|
||||
{
|
||||
const polyPatch& pp = this->boundaryMesh()[neighbPatchID()];
|
||||
|
||||
// Bit of checking now we know neighbour patch
|
||||
if (!owner() && srcScalePtr_.valid())
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Ignoring \"scale\" setting in slave patch " << name()
|
||||
<< endl;
|
||||
srcScalePtr_.clear();
|
||||
tgtScalePtr_.clear();
|
||||
}
|
||||
|
||||
return refCast<const cyclicACMIPolyPatch>(pp);
|
||||
}
|
||||
|
||||
@ -578,6 +844,11 @@ void Foam::cyclicACMIPolyPatch::write(Ostream& os) const
|
||||
cyclicAMIPolyPatch::write(os);
|
||||
|
||||
os.writeEntry("nonOverlapPatch", nonOverlapPatchName_);
|
||||
|
||||
if (owner() && srcScalePtr_.valid())
|
||||
{
|
||||
srcScalePtr_->writeData(os);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,7 +28,29 @@ Class
|
||||
Foam::cyclicACMIPolyPatch
|
||||
|
||||
Description
|
||||
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI)
|
||||
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI).
|
||||
|
||||
Mixes cyclicAMI behaviour with non-coupled patch behaviour using
|
||||
the overlap area fraction. The non-coupled patch is specified through
|
||||
the nonOverlapPatch keyword.
|
||||
|
||||
Usage
|
||||
Example of the patch specification:
|
||||
|
||||
type cyclicACMI;
|
||||
neighbourPatch ACMI2_couple; // cyclicAMI neighbour patch
|
||||
nonOverlapPatch ACMI1_blockage; // patch for uncoupled faces
|
||||
|
||||
// Optional time-dependent scaling (PatchFunction1)
|
||||
scale table
|
||||
(
|
||||
(0.00 1.0)
|
||||
(0.02 1.0)
|
||||
(0.0201 0.0)
|
||||
);
|
||||
|
||||
See also
|
||||
cyclicAMIPolyPatch.C
|
||||
|
||||
SourceFiles
|
||||
cyclicACMIPolyPatch.C
|
||||
@ -42,6 +64,9 @@ SourceFiles
|
||||
#include "AMIPatchToPatchInterpolation.H"
|
||||
#include "polyBoundaryMesh.H"
|
||||
#include "partialFaceAreaWeightAMI.H"
|
||||
#include "PatchFunction1.H"
|
||||
#include "uniformDimensionedFields.H"
|
||||
#include "vectorList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -74,6 +99,34 @@ private:
|
||||
mutable scalarField tgtMask_;
|
||||
|
||||
|
||||
// Scaling of overlap (optional)
|
||||
|
||||
//- Weighting for source mask
|
||||
mutable autoPtr<PatchFunction1<scalar>> srcScalePtr_;
|
||||
|
||||
//- Weighting for target mask
|
||||
mutable autoPtr<PatchFunction1<scalar>> tgtScalePtr_;
|
||||
|
||||
//- Stored face areas
|
||||
mutable vectorField thisSf_;
|
||||
mutable vectorField thisNoSf_;
|
||||
mutable vectorField nbrSf_;
|
||||
mutable vectorField nbrNoSf_;
|
||||
|
||||
//- Scaled version of source mask
|
||||
mutable scalarField srcScaledMask_;
|
||||
|
||||
//- Scaled version of target mask
|
||||
mutable scalarField tgtScaledMask_;
|
||||
|
||||
//- Flag to detect whether AMI is up to date with mesh points
|
||||
mutable uniformDimensionedScalarField AMITime_;
|
||||
|
||||
//- Flag to detect whether scaled masks are up to date with
|
||||
// current time
|
||||
mutable label prevTimeIndex_;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
@ -96,7 +149,13 @@ protected:
|
||||
virtual void scalePatchFaceAreas();
|
||||
|
||||
//- Scale patch face areas to maintain physical area
|
||||
virtual void scalePatchFaceAreas(const cyclicACMIPolyPatch& acmipp);
|
||||
virtual void scalePatchFaceAreas
|
||||
(
|
||||
const cyclicACMIPolyPatch& acmipp,
|
||||
const scalarField& mask,
|
||||
const vectorList& faceArea,
|
||||
const vectorList& noFaceArea
|
||||
);
|
||||
|
||||
//- Initialise the calculation of the patch geometry
|
||||
virtual void initGeometry(PstreamBuffers&);
|
||||
@ -297,6 +356,20 @@ public:
|
||||
|
||||
//- Write the polyPatch data as a dictionary
|
||||
virtual void write(Ostream&) const;
|
||||
|
||||
// Handling optional scaling (time dependency)
|
||||
|
||||
//- Update the AMI and patch areas. Return true if anything
|
||||
// updated
|
||||
virtual bool updateAreas() const;
|
||||
|
||||
//- Return true if given object is up to date with *this
|
||||
// (note : like regIOobject::upToDate but operates on object)
|
||||
bool upToDate(const regIOobject&) const;
|
||||
|
||||
//- Set object up to date with *this
|
||||
// (note : like regIOobject::setUpToDate but operates on object)
|
||||
void setUpToDate(regIOobject&) const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -55,7 +55,7 @@ inline const Foam::scalarField& Foam::cyclicACMIPolyPatch::mask() const
|
||||
{
|
||||
if (owner())
|
||||
{
|
||||
return srcMask_;
|
||||
return srcMask();
|
||||
}
|
||||
|
||||
return neighbPatch().tgtMask();
|
||||
|
@ -0,0 +1,52 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volVectorField;
|
||||
object U;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 1 -1 0 0 0 0];
|
||||
|
||||
internalField uniform (0 0 0);
|
||||
|
||||
boundaryField
|
||||
{
|
||||
//- Set patchGroups for constraint patches
|
||||
#includeEtc "caseDicts/setConstraintTypes"
|
||||
|
||||
inlet
|
||||
{
|
||||
type pressureInletOutletVelocity;
|
||||
value uniform (0 0 0);
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue uniform (0 0 0);
|
||||
value uniform (0 0 0);
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue uniform (0 0 0);
|
||||
value uniform (0 0 0);
|
||||
}
|
||||
|
||||
wall
|
||||
{
|
||||
type noSlip;
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,54 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
location "0";
|
||||
object epsilon;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 2 -3 0 0 0 0];
|
||||
|
||||
internalField uniform 200;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
//- Set patchGroups for constraint patches
|
||||
#includeEtc "caseDicts/setConstraintTypes"
|
||||
|
||||
inlet
|
||||
{
|
||||
type turbulentMixingLengthDissipationRateInlet;
|
||||
mixingLength 0.01; // 1cm - half channel height
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue $internalField;
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue $internalField;
|
||||
}
|
||||
|
||||
wall
|
||||
{
|
||||
type epsilonWallFunction;
|
||||
value $internalField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,54 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
location "0";
|
||||
object k;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 2 -2 0 0 0 0];
|
||||
|
||||
internalField uniform 0.2;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
//- Set patchGroups for constraint patches
|
||||
#includeEtc "caseDicts/setConstraintTypes"
|
||||
|
||||
inlet
|
||||
{
|
||||
type turbulentIntensityKineticEnergyInlet;
|
||||
intensity 0.05; // 5% turbulent intensity
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue $internalField;
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue $internalField;
|
||||
}
|
||||
|
||||
wall
|
||||
{
|
||||
type kqRWallFunction;
|
||||
value uniform 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,47 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object nuTilda;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 2 -1 0 0 0 0];
|
||||
|
||||
internalField uniform 0;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
//- Set patchGroups for constraint patches
|
||||
#includeEtc "caseDicts/setConstraintTypes"
|
||||
|
||||
inlet
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
wall
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,53 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
location "0";
|
||||
object nut;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 2 -1 0 0 0 0];
|
||||
|
||||
internalField uniform 0;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
//- Set patchGroups for constraint patches
|
||||
#includeEtc "caseDicts/setConstraintTypes"
|
||||
|
||||
inlet
|
||||
{
|
||||
type calculated;
|
||||
value uniform 0;
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type calculated;
|
||||
value uniform 0;
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type calculated;
|
||||
value uniform 0;
|
||||
}
|
||||
|
||||
wall
|
||||
{
|
||||
type nutkWallFunction;
|
||||
value uniform 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,55 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object p;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 2 -2 0 0 0 0];
|
||||
|
||||
internalField uniform 0;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
//- Set patchGroups for constraint patches
|
||||
#includeEtc "caseDicts/setConstraintTypes"
|
||||
|
||||
inlet
|
||||
{
|
||||
type uniformTotalPressure;
|
||||
p0 table
|
||||
(
|
||||
(0 40)
|
||||
//(0 10)
|
||||
//(1 40)
|
||||
);
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type fixedValue;
|
||||
value uniform 10;
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type fixedValue;
|
||||
value uniform 10;
|
||||
}
|
||||
|
||||
wall
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,52 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
location "0";
|
||||
object s;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 0 0 0 0 0 0];
|
||||
|
||||
internalField uniform 0;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
//- Set patchGroups for constraint patches
|
||||
#includeEtc "caseDicts/setConstraintTypes"
|
||||
|
||||
inlet
|
||||
{
|
||||
type fixedValue;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue $internalField;
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue $internalField;
|
||||
}
|
||||
|
||||
wall
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,2 @@
|
||||
Copy of T-junction tutorial. Inlet on left, one outlet at bottom, one at top.
|
||||
cyclicAMI with switching to direct flow to bottom or top
|
@ -0,0 +1,22 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "constant";
|
||||
object transportProperties;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
transportModel Newtonian;
|
||||
|
||||
nu 1e-05;
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,30 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "constant";
|
||||
object turbulenceProperties;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
simulationType RAS;
|
||||
|
||||
RAS
|
||||
{
|
||||
RASModel kEpsilon;
|
||||
|
||||
turbulence on;
|
||||
|
||||
printCoeffs on;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,284 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object blockMeshDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// outlet1
|
||||
// +-+
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// +-----------+-+
|
||||
// |inlet | |
|
||||
// +-----------+-+
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// +-+
|
||||
// outlet2
|
||||
|
||||
scale 1;
|
||||
|
||||
vertices
|
||||
(
|
||||
(0.0 -0.01 0) //0
|
||||
(0.19 -0.01 0)
|
||||
(0.19 0.01 0) //2
|
||||
(0.0 0.01 0)
|
||||
|
||||
(0.19 -0.02 0) //4
|
||||
(0.23 -0.02 0)
|
||||
(0.23 0.02 0) //6
|
||||
(0.19 0.02 0)
|
||||
|
||||
(0.2 -0.21 0) //8
|
||||
(0.22 -0.21 0)
|
||||
(0.22 -0.02 0) //10
|
||||
(0.2 -0.02 0)
|
||||
|
||||
(0.2 0.02 0) //12
|
||||
(0.22 0.02 0)
|
||||
(0.22 0.21 0) //14
|
||||
(0.2 0.21 0)
|
||||
|
||||
// Z
|
||||
(0.0 -0.01 0.01)
|
||||
(0.19 -0.01 0.01)
|
||||
(0.19 0.01 0.01)
|
||||
(0.0 0.01 0.01)
|
||||
|
||||
(0.19 -0.02 0.01)
|
||||
(0.23 -0.02 0.01)
|
||||
(0.23 0.02 0.01)
|
||||
(0.19 0.02 0.01)
|
||||
|
||||
(0.2 -0.21 0.01)
|
||||
(0.22 -0.21 0.01)
|
||||
(0.22 -0.02 0.01)
|
||||
(0.2 -0.02 0.01)
|
||||
|
||||
(0.2 0.02 0.01)
|
||||
(0.22 0.02 0.01)
|
||||
(0.22 0.21 0.01)
|
||||
(0.2 0.21 0.01)
|
||||
);
|
||||
|
||||
blocks
|
||||
(
|
||||
// inlet block
|
||||
hex (0 1 2 3 16 17 18 19) inlet (50 5 1) simpleGrading (1 1 1)
|
||||
|
||||
// central block
|
||||
hex (4 5 6 7 20 21 22 23) central (12 12 1) simpleGrading (1 1 1)
|
||||
|
||||
// bottom block
|
||||
hex (8 9 10 11 24 25 26 27) bottom (5 50 1) simpleGrading (1 1 1)
|
||||
|
||||
// top block
|
||||
hex (12 13 14 15 28 29 30 31) top (5 50 1) simpleGrading (1 1 1)
|
||||
);
|
||||
|
||||
edges
|
||||
(
|
||||
);
|
||||
|
||||
boundary
|
||||
(
|
||||
inlet
|
||||
{
|
||||
type patch;
|
||||
faces
|
||||
(
|
||||
(0 16 19 3)
|
||||
);
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type patch;
|
||||
faces
|
||||
(
|
||||
(8 9 25 24)
|
||||
);
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type patch;
|
||||
faces
|
||||
(
|
||||
(14 15 31 30)
|
||||
);
|
||||
}
|
||||
|
||||
walls
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
// Inlet block
|
||||
(2 3 19 18)
|
||||
(0 1 17 16)
|
||||
// Central block
|
||||
(5 6 22 21)
|
||||
// Bottom block
|
||||
(8 24 27 11)
|
||||
(9 10 26 25)
|
||||
// Top block
|
||||
(13 14 30 29)
|
||||
(12 28 31 15)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Inlet - Central block
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
inlet_central_couple
|
||||
{
|
||||
type cyclicACMI;
|
||||
neighbourPatch central_inlet_couple;
|
||||
nonOverlapPatch inlet_central_blockage;
|
||||
faces
|
||||
(
|
||||
(1 2 18 17)
|
||||
);
|
||||
}
|
||||
inlet_central_blockage
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(1 2 18 17)
|
||||
);
|
||||
}
|
||||
central_inlet_couple
|
||||
{
|
||||
type cyclicACMI;
|
||||
neighbourPatch inlet_central_couple;
|
||||
nonOverlapPatch central_inlet_blockage;
|
||||
faces
|
||||
(
|
||||
(4 20 23 7)
|
||||
);
|
||||
}
|
||||
central_inlet_blockage
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(4 20 23 7)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Central - Bottom block
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
bottom_central_couple
|
||||
{
|
||||
type cyclicACMI;
|
||||
neighbourPatch central_bottom_couple;
|
||||
nonOverlapPatch bottom_central_blockage;
|
||||
faces
|
||||
(
|
||||
(10 11 27 26)
|
||||
);
|
||||
|
||||
scale table
|
||||
(
|
||||
(0.00 1.0)
|
||||
(0.20 1.0)
|
||||
(0.30 0.0)
|
||||
);
|
||||
}
|
||||
bottom_central_blockage
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(10 11 27 26)
|
||||
);
|
||||
}
|
||||
central_bottom_couple
|
||||
{
|
||||
type cyclicACMI;
|
||||
neighbourPatch bottom_central_couple;
|
||||
nonOverlapPatch central_bottom_blockage;
|
||||
faces
|
||||
(
|
||||
(4 5 21 20)
|
||||
);
|
||||
}
|
||||
central_bottom_blockage
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(4 5 21 20)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Central - Top block
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
top_central_couple
|
||||
{
|
||||
type cyclicACMI;
|
||||
neighbourPatch central_top_couple;
|
||||
nonOverlapPatch top_central_blockage;
|
||||
faces
|
||||
(
|
||||
(12 13 29 28)
|
||||
);
|
||||
|
||||
scale table
|
||||
(
|
||||
(0.00 0.0)
|
||||
(0.20 0.0)
|
||||
(0.30 1.0)
|
||||
);
|
||||
}
|
||||
top_central_blockage
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(12 13 29 28)
|
||||
);
|
||||
}
|
||||
central_top_couple
|
||||
{
|
||||
type cyclicACMI;
|
||||
neighbourPatch top_central_couple;
|
||||
nonOverlapPatch central_top_blockage;
|
||||
faces
|
||||
(
|
||||
(6 7 23 22)
|
||||
);
|
||||
}
|
||||
central_top_blockage
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(6 7 23 22)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,52 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "system";
|
||||
object controlDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
application pimpleFoam;
|
||||
|
||||
startFrom startTime;
|
||||
|
||||
startTime 0;
|
||||
|
||||
stopAt endTime;
|
||||
|
||||
endTime 0.4;
|
||||
|
||||
deltaT 0.001;
|
||||
|
||||
writeControl adjustableRunTime;
|
||||
writeInterval 0.01;
|
||||
|
||||
purgeWrite 0;
|
||||
|
||||
writeFormat ascii;
|
||||
|
||||
writePrecision 6;
|
||||
|
||||
writeCompression off;
|
||||
|
||||
timeFormat general;
|
||||
|
||||
timePrecision 6;
|
||||
|
||||
runTimeModifiable true;
|
||||
|
||||
adjustTimeStep yes;
|
||||
|
||||
maxCo 1.0;
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,21 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object decomposeParDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
numberOfSubdomains 3;
|
||||
|
||||
method scotch;
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,57 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "system";
|
||||
object fvSchemes;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
ddtSchemes
|
||||
{
|
||||
default Euler;
|
||||
}
|
||||
|
||||
gradSchemes
|
||||
{
|
||||
default Gauss linear;
|
||||
}
|
||||
|
||||
divSchemes
|
||||
{
|
||||
default none;
|
||||
div(phi,U) Gauss limitedLinearV 1;
|
||||
div(phi,k) Gauss limitedLinear 1;
|
||||
div(phi,epsilon) Gauss limitedLinear 1;
|
||||
div(phi,R) Gauss limitedLinear 1;
|
||||
div(phi,s) Gauss limitedLinear 1;
|
||||
div(R) Gauss linear;
|
||||
div(phi,nuTilda) Gauss limitedLinear 1;
|
||||
div((nuEff*dev2(T(grad(U))))) Gauss linear;
|
||||
}
|
||||
|
||||
laplacianSchemes
|
||||
{
|
||||
default Gauss linear corrected;
|
||||
}
|
||||
|
||||
interpolationSchemes
|
||||
{
|
||||
default linear;
|
||||
}
|
||||
|
||||
snGradSchemes
|
||||
{
|
||||
default corrected;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,74 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1906 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "system";
|
||||
object fvSolution;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
solvers
|
||||
{
|
||||
p
|
||||
{
|
||||
solver GAMG;
|
||||
tolerance 1e-06;
|
||||
relTol 0.01;
|
||||
smoother GaussSeidel;
|
||||
}
|
||||
|
||||
"(pFinal|pcorrFinal)"
|
||||
{
|
||||
solver GAMG;
|
||||
tolerance 1e-06;
|
||||
relTol 0;
|
||||
smoother GaussSeidel;
|
||||
}
|
||||
|
||||
"(U|k|epsilon|s)"
|
||||
{
|
||||
solver smoothSolver;
|
||||
smoother symGaussSeidel;
|
||||
tolerance 1e-05;
|
||||
relTol 0.1;
|
||||
}
|
||||
|
||||
"(U|k|epsilon|s)Final"
|
||||
{
|
||||
$U;
|
||||
tolerance 1e-05;
|
||||
relTol 0;
|
||||
}
|
||||
}
|
||||
|
||||
PIMPLE
|
||||
{
|
||||
nOuterCorrectors 1;
|
||||
nCorrectors 2;
|
||||
nNonOrthogonalCorrectors 0;
|
||||
pRefCell 0;
|
||||
pRefValue 0;
|
||||
correctPhi false;
|
||||
}
|
||||
|
||||
relaxationFactors
|
||||
{
|
||||
equations
|
||||
{
|
||||
"U.*" 1;
|
||||
"k.*" 1;
|
||||
"epsilon.*" 1;
|
||||
"s.*" 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
Loading…
Reference in New Issue
Block a user