diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C index a66ae7d06b98271b7e39a4d4c45ba5f61e995801..46b57e156bc1d385a1bd5bd2ee05ea7890db5144 100644 --- a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C +++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C @@ -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(); + if (!cyclicACMIPolyPatch_.upToDate(areaTime_)) + { + if (debug) + { + Pout<< "cyclicACMIFvPatch::movePoints() : updating fv areas for " + << name() << " and " << this->nonOverlapPatch().name() + << endl; + } - resetPatchAreas(*this); - resetPatchAreas(nonOverlapPatch); - resetPatchAreas(nbrACMI); - resetPatchAreas(nbrNonOverlapPatch); - // Scale the mesh flux + // Set the patch face areas to be consistent with the changes made + // at the polyPatch level - const labelListList& newSrcAddr = AMI().srcAddress(); - const labelListList& newTgtAddr = AMI().tgtAddress(); + const fvPatch& nonOverlapPatch = this->nonOverlapPatch(); + const cyclicACMIFvPatch& nbrACMI = neighbPatch(); + const fvPatch& nbrNonOverlapPatch = nbrACMI.nonOverlapPatch(); - const fvMesh& mesh = boundaryMesh().mesh(); - surfaceScalarField& meshPhi = const_cast<fvMesh&>(mesh).setPhi(); - surfaceScalarField::Boundary& meshPhiBf = meshPhi.boundaryFieldRef(); + resetPatchAreas(*this); + resetPatchAreas(nonOverlapPatch); + resetPatchAreas(nbrACMI); + resetPatchAreas(nbrNonOverlapPatch); - // 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()]; + // Scale the mesh flux - const auto& localFaces = cyclicACMIPolyPatch_.localFaces(); - const auto& localPoints = cyclicACMIPolyPatch_.localPoints(); + const labelListList& newSrcAddr = AMI().srcAddress(); + const labelListList& newTgtAddr = AMI().tgtAddress(); - forAll(phip, facei) - { - if (newSrcAddr[facei].empty()) + 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) { - // AMI patch with no connection to other coupled faces - phip[facei] = 0.0; + 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(points); + phip[facei] *= magSf()[facei]/geomArea; + } } - else + + forAll(phiNonOverlapp, facei) { - // Scale the mesh flux according to the area fraction - const face& fAMI = localFaces[facei]; - - // Note: using raw point locations to calculate the geometric - // area - faces areas are currently scaled (decoupled from - // mesh points) - const scalar geomArea = fAMI.mag(localPoints); - phip[facei] *= magSf()[facei]/geomArea; + const scalar w = 1.0 - cyclicACMIPolyPatch_.srcMask()[facei]; + phiNonOverlapp[facei] *= w; } - } - - 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 cyclicACMIPolyPatch& nbrPatch = nbrACMI.cyclicACMIPatch(); + scalarField& nbrPhip = meshPhiBf[nbrPatch.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(nbrPhip, facei) { - nbrPhip[facei] = 0.0; + 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(points); + nbrPhip[facei] *= nbrACMI.magSf()[facei]/geomArea; + } } - else - { - const face& fAMI = nbrLocalFaces[facei]; - // Note: using raw point locations to calculate the geometric - // area - faces areas are currently scaled (decoupled from - // mesh points) - const scalar geomArea = fAMI.mag(nbrLocalPoints); - 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_); } } diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H index c3aed02df707219e3826b30a8ee8c8ae7b140df4..687fcc0201bbf59a5102a81732f5ec909471823b 100644 --- a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H +++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H @@ -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 ( diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C index 4e994a6f236185043af6457fa7b607da60537c64..f14f27582804e050a2f543833c14fa9977feb7c9 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.C @@ -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()); -} - - -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()) - { - 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; - } + const polyPatch& nonOverlapPatch = this->nonOverlapPatch(); + const cyclicACMIPolyPatch& nbrPatch = this->neighbPatch(); + const polyPatch& nbrNonOverlapPatch = nbrPatch.nonOverlapPatch(); - forAll(noSf, facei) + if (srcScalePtr_.valid()) { - const scalar w = min(maxTol, max(tolerance_, mask[facei])); - noSf[facei] *= scalar(1) - w; + // Save overlap geometry for later scaling + thisSf_ = this->faceAreas(); + thisNoSf_ = nonOverlapPatch.faceAreas(); + nbrSf_ = nbrPatch.faceAreas(); + nbrNoSf_ = 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; - } - } - } + // In-place scale the patch areas + scalePatchFaceAreas + ( + *this, + srcMask_, // unscaled mask + this->faceAreas(), + nonOverlapPatch.faceAreas() + ); + scalePatchFaceAreas + ( + nbrPatch, + tgtMask_, // unscaled mask + nbrPatch.faceAreas(), + nbrNonOverlapPatch.faceAreas() + ); + + // 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); + } } diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H index 51b0f40b5c3d2e92fcd1eb1a7476ceba05ee4e0b..7813526c858bccc1e212fcf79a1fb0896ab0a700 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatch.H @@ -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; }; diff --git a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchI.H b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchI.H index 50f4022ed63e2ce5204ebda9f9b33b1f653218fa..30759e1bdda24e49e3bdfaf7ee2e078b12fc9d54 100644 --- a/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchI.H +++ b/src/meshTools/AMIInterpolation/patches/cyclicACMI/cyclicACMIPolyPatch/cyclicACMIPolyPatchI.H @@ -55,7 +55,7 @@ inline const Foam::scalarField& Foam::cyclicACMIPolyPatch::mask() const { if (owner()) { - return srcMask_; + return srcMask(); } return neighbPatch().tgtMask(); diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/U b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/U new file mode 100644 index 0000000000000000000000000000000000000000..e3bcd9675e2c69c540ff7277b5299545dccf5cd1 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/U @@ -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; + } +} + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/epsilon b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/epsilon new file mode 100644 index 0000000000000000000000000000000000000000..be113a5271d3fbe76aa700ea58a56989f8799034 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/epsilon @@ -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; + } +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/k b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/k new file mode 100644 index 0000000000000000000000000000000000000000..3b53502f44370d9e199f65ed5426371e96e9c062 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/k @@ -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; + } +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/nuTilda b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/nuTilda new file mode 100644 index 0000000000000000000000000000000000000000..9abcd7a6a68982cae78f8f2aedb218768c074df9 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/nuTilda @@ -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; + } +} + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/nut b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/nut new file mode 100644 index 0000000000000000000000000000000000000000..55a5e85366e12d465aceb551f115387a2bec5a51 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/nut @@ -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; + } +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/p b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/p new file mode 100644 index 0000000000000000000000000000000000000000..0435873f2e8e7261a17ccb5823604a3e485d2ef6 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/p @@ -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; + } +} + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/s b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/s new file mode 100644 index 0000000000000000000000000000000000000000..9fff33f8153341ee7df21aff5f837b2d13e7dd83 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/s @@ -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; + } +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/README.txt b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..5870378f1aa44e12da7ce3c3b429b399dee96100 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/README.txt @@ -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 diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/constant/transportProperties b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/constant/transportProperties new file mode 100644 index 0000000000000000000000000000000000000000..eff376542af9c0780b114a1de0f7d1c58e7860b4 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/constant/transportProperties @@ -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; + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/constant/turbulenceProperties b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/constant/turbulenceProperties new file mode 100644 index 0000000000000000000000000000000000000000..f54930e73de65187dbd7333d143a5e5041062191 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/constant/turbulenceProperties @@ -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; +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/blockMeshDict b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/blockMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..073f45a326a83c17133552272f0cf72406aa5b7f --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/blockMeshDict @@ -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) + ); + } +); + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/controlDict b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/controlDict new file mode 100644 index 0000000000000000000000000000000000000000..31448586883e6096855e83fe1be15e52fb35b18a --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/controlDict @@ -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; + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/decomposeParDict b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/decomposeParDict new file mode 100644 index 0000000000000000000000000000000000000000..913e6535997ac80435e46503f882eb6bca274936 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/decomposeParDict @@ -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; + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/fvSchemes b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/fvSchemes new file mode 100644 index 0000000000000000000000000000000000000000..fee8048b88ee9a08b1bdb45655e76ca619d4a984 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/fvSchemes @@ -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; +} + + +// ************************************************************************* // diff --git a/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/fvSolution b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/fvSolution new file mode 100644 index 0000000000000000000000000000000000000000..a78b57e91a6c674aded007bd9b11e5ad9d1ed969 --- /dev/null +++ b/tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/fvSolution @@ -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; + } +} + + +// ************************************************************************* //