From 31ecf0d73215fd2231607a5fbac789c946cea8e1 Mon Sep 17 00:00:00 2001 From: Mattijs Janssens Date: Fri, 11 Dec 2020 10:35:06 +0000 Subject: [PATCH] ENH: cyclicACMI: optional scaling with PatchFunction1. Added 'scale' parameter to cyclicACMI. Scales the amount of 'coupledness' (= mask). Allows opening/closing without mesh motion. --- .../constraint/cyclicACMI/cyclicACMIFvPatch.C | 220 ++++++--- .../constraint/cyclicACMI/cyclicACMIFvPatch.H | 18 +- .../cyclicACMIPolyPatch/cyclicACMIPolyPatch.C | 435 ++++++++++++++---- .../cyclicACMIPolyPatch/cyclicACMIPolyPatch.H | 77 +++- .../cyclicACMIPolyPatchI.H | 2 +- .../pimpleFoam/RAS/TJunctionSwitching/0/U | 52 +++ .../RAS/TJunctionSwitching/0/epsilon | 54 +++ .../pimpleFoam/RAS/TJunctionSwitching/0/k | 54 +++ .../RAS/TJunctionSwitching/0/nuTilda | 47 ++ .../pimpleFoam/RAS/TJunctionSwitching/0/nut | 53 +++ .../pimpleFoam/RAS/TJunctionSwitching/0/p | 55 +++ .../pimpleFoam/RAS/TJunctionSwitching/0/s | 52 +++ .../RAS/TJunctionSwitching/README.txt | 2 + .../constant/transportProperties | 22 + .../constant/turbulenceProperties | 30 ++ .../TJunctionSwitching/system/blockMeshDict | 284 ++++++++++++ .../RAS/TJunctionSwitching/system/controlDict | 52 +++ .../system/decomposeParDict | 21 + .../RAS/TJunctionSwitching/system/fvSchemes | 57 +++ .../RAS/TJunctionSwitching/system/fvSolution | 74 +++ 20 files changed, 1499 insertions(+), 162 deletions(-) create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/U create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/epsilon create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/k create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/nuTilda create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/nut create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/p create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/0/s create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/README.txt create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/constant/transportProperties create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/constant/turbulenceProperties create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/blockMeshDict create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/controlDict create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/decomposeParDict create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/fvSchemes create mode 100644 tutorials/incompressible/pimpleFoam/RAS/TJunctionSwitching/system/fvSolution diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C index a66ae7d06b..46b57e156b 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(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(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(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(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_); } } diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H index c3aed02df7..687fcc0201 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(patch)) - {} + cyclicACMIFvPatch(const polyPatch& patch, const fvBoundaryMesh& bm); // Member functions @@ -181,6 +184,9 @@ public: const Field& 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 4e994a6f23..f14f275828 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(*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(acmipp.weights()); + auto& weightsSum = const_cast(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(acmipp.weights()); - auto& weightsSum = const_cast(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("nonOverlapPatch")), nonOverlapPatchID_(-1), srcMask_(), - tgtMask_() + tgtMask_(), + srcScalePtr_ + ( + dict.found("scale") + ? PatchFunction1::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(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 51b0f40b5c..7813526c85 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> srcScalePtr_; + + //- Weighting for target mask + mutable autoPtr> 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 50f4022ed6..30759e1bdd 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 0000000000..e3bcd9675e --- /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 0000000000..be113a5271 --- /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 0000000000..3b53502f44 --- /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 0000000000..9abcd7a6a6 --- /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 0000000000..55a5e85366 --- /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 0000000000..0435873f2e --- /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 0000000000..9fff33f815 --- /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 0000000000..5870378f1a --- /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 0000000000..eff376542a --- /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 0000000000..f54930e73d --- /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 0000000000..073f45a326 --- /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 0000000000..3144858688 --- /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 0000000000..913e653599 --- /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 0000000000..fee8048b88 --- /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 0000000000..a78b57e91a --- /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; + } +} + + +// ************************************************************************* //