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;
+    }
+}
+
+
+// ************************************************************************* //