diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
index 090a3812a2f6105a93362af93ecb9a0bcf7ebc97..610affe33c2365a97a4eb02c4ab195135e1fa54d 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
@@ -66,7 +66,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::patchMagSf
     const faceAreaIntersect::triangulationMode triMode
 )
 {
-    tmp<scalarField> tResult(new scalarField(patch.size(), Zero));
+    auto tResult = tmp<scalarField>::New(patch.size(), Zero);
     scalarField& result = tResult.ref();
 
     const pointField& patchPoints = patch.localPoints();
@@ -538,7 +538,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::constructFromSurface
     if (surfPtr.valid())
     {
         // Create new patches for source and target
-        pointField srcPoints = srcPatch.points();
+        pointField srcPoints(srcPatch.points());
         SourcePatch srcPatch0
         (
             SubList<face>
@@ -559,7 +559,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::constructFromSurface
             }
         }
 
-        pointField tgtPoints = tgtPatch.points();
+        pointField tgtPoints(tgtPatch.points());
         TargetPatch tgtPatch0
         (
             SubList<face>
@@ -610,27 +610,18 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
     const bool reverseTarget
 )
 :
-    methodName_(interpolationMethodNames_[method]),
-    reverseTarget_(reverseTarget),
-    requireMatch_(requireMatch),
-    singlePatchProc_(-999),
-    lowWeightCorrection_(lowWeightCorrection),
-    srcMagSf_(),
-    srcAddress_(),
-    srcWeights_(),
-    srcWeightsSum_(),
-    srcCentroids_(),
-    tgtMagSf_(),
-    tgtAddress_(),
-    tgtWeights_(),
-    tgtWeightsSum_(),
-    tgtCentroids_(),
-    triMode_(triMode),
-    srcMapPtr_(nullptr),
-    tgtMapPtr_(nullptr)
-{
-    update(srcPatch, tgtPatch);
-}
+    AMIInterpolation
+    (
+        srcPatch,
+        tgtPatch,
+        nullptr,
+        triMode,
+        requireMatch,
+        method,
+        lowWeightCorrection,
+        reverseTarget
+    )
+{}
 
 
 template<class SourcePatch, class TargetPatch>
@@ -645,27 +636,18 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
     const bool reverseTarget
 )
 :
-    methodName_(methodName),
-    reverseTarget_(reverseTarget),
-    requireMatch_(requireMatch),
-    singlePatchProc_(-999),
-    lowWeightCorrection_(lowWeightCorrection),
-    srcMagSf_(),
-    srcAddress_(),
-    srcWeights_(),
-    srcWeightsSum_(),
-    srcCentroids_(),
-    tgtMagSf_(),
-    tgtAddress_(),
-    tgtWeights_(),
-    tgtWeightsSum_(),
-    tgtCentroids_(),
-    triMode_(triMode),
-    srcMapPtr_(nullptr),
-    tgtMapPtr_(nullptr)
-{
-    update(srcPatch, tgtPatch);
-}
+    AMIInterpolation
+    (
+        srcPatch,
+        tgtPatch,
+        nullptr,
+        triMode,
+        requireMatch,
+        interpolationMethodNames_.get(methodName),
+        lowWeightCorrection,
+        reverseTarget
+    )
+{}
 
 
 template<class SourcePatch, class TargetPatch>
@@ -717,27 +699,18 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
     const bool reverseTarget
 )
 :
-    methodName_(methodName),
-    reverseTarget_(reverseTarget),
-    requireMatch_(requireMatch),
-    singlePatchProc_(-999),
-    lowWeightCorrection_(lowWeightCorrection),
-    srcMagSf_(),
-    srcAddress_(),
-    srcWeights_(),
-    srcWeightsSum_(),
-    srcCentroids_(),
-    tgtMagSf_(),
-    tgtAddress_(),
-    tgtWeights_(),
-    tgtWeightsSum_(),
-    tgtCentroids_(),
-    triMode_(triMode),
-    srcMapPtr_(nullptr),
-    tgtMapPtr_(nullptr)
-{
-    constructFromSurface(srcPatch, tgtPatch, surfPtr);
-}
+    AMIInterpolation
+    (
+        srcPatch,
+        tgtPatch,
+        surfPtr,
+        triMode,
+        requireMatch,
+        interpolationMethodNames_.get(methodName),
+        lowWeightCorrection,
+        reverseTarget
+    )
+{}
 
 
 template<class SourcePatch, class TargetPatch>
@@ -873,188 +846,37 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
         << tgtTotalSize << " target faces"
         << endl;
 
-    // Calculate if patches present on multiple processors
-    singlePatchProc_ = calcDistribution(srcPatch, tgtPatch);
 
-    if (singlePatchProc_ == -1)
-    {
-        // Convert local addressing to global addressing
-        globalIndex globalSrcFaces(srcPatch.size());
-        globalIndex globalTgtFaces(tgtPatch.size());
-
-        // Create processor map of overlapping faces. This map gets
-        // (possibly remote) faces from the tgtPatch such that they (together)
-        // cover all of the srcPatch
-        autoPtr<mapDistribute> mapPtr = calcProcMap(srcPatch, tgtPatch);
-        const mapDistribute& map = mapPtr();
-
-        // Create new target patch that fully encompasses source patch
-
-        // Faces and points
-        faceList newTgtFaces;
-        pointField newTgtPoints;
-
-        // Original faces from tgtPatch (in globalIndexing since might be
-        // remote)
-        labelList tgtFaceIDs;
-        distributeAndMergePatches
+    // Calculate AMI interpolation
+    autoPtr<AMIMethod<SourcePatch, TargetPatch>> AMIPtr
+    (
+        AMIMethod<SourcePatch, TargetPatch>::New
         (
-            map,
+            methodName_,
+            srcPatch,
             tgtPatch,
-            globalTgtFaces,
-            newTgtFaces,
-            newTgtPoints,
-            tgtFaceIDs
-        );
-
-        const TargetPatch
-            newTgtPatch
-            (
-                SubList<face>
-                (
-                    newTgtFaces,
-                    newTgtFaces.size()
-                ),
-                newTgtPoints
-            );
-
-        // Calculate AMI interpolation
-        autoPtr<AMIMethod<SourcePatch, TargetPatch>> AMIPtr
-        (
-            AMIMethod<SourcePatch, TargetPatch>::New
-            (
-                methodName_,
-                srcPatch,
-                newTgtPatch,
-                triMode_,
-                reverseTarget_,
-                requireMatch_ && (lowWeightCorrection_ < 0)
-            )
-        );
-
-        AMIPtr->calculate
-        (
-            srcAddress_,
-            srcWeights_,
-            srcCentroids_,
-            tgtAddress_,
-            tgtWeights_
-        );
-
-
-        // Note: using patch face areas calculated by the AMI method
-        // - TODO: move into the calculate or normalise method?
-        AMIPtr->setMagSf(tgtPatch, map, srcMagSf_, tgtMagSf_);
-
-
-        // Now
-        // ~~~
-        //  srcAddress_ :   per srcPatch face a list of the newTgtPatch (not
-        //                  tgtPatch) faces it overlaps
-        //  tgtAddress_ :   per newTgtPatch (not tgtPatch) face a list of the
-        //                  srcPatch faces it overlaps
-
-        if (debug)
-        {
-            writeFaceConnectivity(srcPatch, newTgtPatch, srcAddress_);
-        }
-
-
-        // Rework newTgtPatch indices into globalIndices of tgtPatch
-        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-
-        for (labelList& addressing : srcAddress_)
-        {
-            for (label& addr : addressing)
-            {
-                addr = tgtFaceIDs[addr];
-            }
-        }
-
-        for (labelList& addressing : tgtAddress_)
-        {
-            globalSrcFaces.inplaceToGlobal(addressing);
-        }
-
-        // Send data back to originating procs. Note that contributions
-        // from different processors get added (ListOps::appendEqOp)
-
-        mapDistributeBase::distribute
-        (
-            Pstream::commsTypes::nonBlocking,
-            List<labelPair>(),
-            tgtPatch.size(),
-            map.constructMap(),
-            false,                      // has flip
-            map.subMap(),
-            false,                      // has flip
-            tgtAddress_,
-            ListOps::appendEqOp<label>(),
-            flipOp(),                   // flip operation
-            labelList()
-        );
-
-        mapDistributeBase::distribute
-        (
-            Pstream::commsTypes::nonBlocking,
-            List<labelPair>(),
-            tgtPatch.size(),
-            map.constructMap(),
-            false,
-            map.subMap(),
-            false,
-            tgtWeights_,
-            ListOps::appendEqOp<scalar>(),
-            flipOp(),
-            scalarList()
-        );
-
-        // weights normalisation
-        AMIPtr->normaliseWeights(true, *this);
-
-        // Cache maps and reset addresses
-        List<Map<label>> cMapSrc;
-        srcMapPtr_.reset
-        (
-            new mapDistribute(globalSrcFaces, tgtAddress_, cMapSrc)
-        );
-        List<Map<label>> cMapTgt;
-        tgtMapPtr_.reset
-        (
-            new mapDistribute(globalTgtFaces, srcAddress_, cMapTgt)
-        );
-    }
-    else
-    {
-        // Calculate AMI interpolation
-        autoPtr<AMIMethod<SourcePatch, TargetPatch>> AMIPtr
-        (
-            AMIMethod<SourcePatch, TargetPatch>::New
-            (
-                methodName_,
-                srcPatch,
-                tgtPatch,
-                triMode_,
-                reverseTarget_,
-                requireMatch_ && (lowWeightCorrection_ < 0)
-            )
-        );
+            triMode_,
+            reverseTarget_,
+            requireMatch_ && (lowWeightCorrection_ < 0)
+        )
+    );
 
-        AMIPtr->calculate
-        (
-            srcAddress_,
-            srcWeights_,
-            srcCentroids_,
-            tgtAddress_,
-            tgtWeights_
-        );
+    AMIPtr->calculate
+    (
+        srcAddress_,
+        srcWeights_,
+        srcCentroids_,
+        tgtAddress_,
+        tgtWeights_,
+        srcMagSf_,
+        tgtMagSf_,
+        srcMapPtr_,
+        tgtMapPtr_
+    );
 
-        srcMagSf_.transfer(AMIPtr->srcMagSf());
-        tgtMagSf_.transfer(AMIPtr->tgtMagSf());
+    AMIPtr->normaliseWeights(true, *this);
 
-        AMIPtr->normaliseWeights(true, *this);
-    }
+    singlePatchProc_ = AMIPtr->distributed() ? -1 : 0;
 
     if (debug)
     {
@@ -1115,18 +937,15 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::append
     addProfiling(ami, "AMIInterpolation::append");
 
     // Create a new interpolation
-    autoPtr<AMIInterpolation<SourcePatch, TargetPatch>> newPtr
+    auto newPtr = autoPtr<AMIInterpolation<SourcePatch, TargetPatch>>::New
     (
-        new AMIInterpolation<SourcePatch, TargetPatch>
-        (
-            srcPatch,
-            tgtPatch,
-            triMode_,
-            requireMatch_,
-            methodName_,
-            lowWeightCorrection_,
-            reverseTarget_
-        )
+        srcPatch,
+        tgtPatch,
+        triMode_,
+        requireMatch_,
+        methodName_,
+        lowWeightCorrection_,
+        reverseTarget_
     );
 
     // If parallel then combine the mapDistribution and re-index
@@ -1514,14 +1333,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
     const UList<Type>& defaultValues
 ) const
 {
-    tmp<Field<Type>> tresult
-    (
-        new Field<Type>
-        (
-            srcAddress_.size(),
-            Zero
-        )
-    );
+    auto tresult = tmp<Field<Type>>::New(srcAddress_.size(), Zero);
 
     interpolateToSource
     (
@@ -1559,14 +1371,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
     const UList<Type>& defaultValues
 ) const
 {
-    tmp<Field<Type>> tresult
-    (
-        new Field<Type>
-        (
-            tgtAddress_.size(),
-            Zero
-        )
-    );
+    auto tresult = tmp<Field<Type>>::New(tgtAddress_.size(), Zero);
 
     interpolateToTarget
     (
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
index 2e57a3c7dd3da042b11e146eacdacbe8ae2f7f9d..a3c5a61aa223a59d3e8ebd006afcc01c6db4432a 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
@@ -188,49 +188,6 @@ private:
         void operator=(const AMIInterpolation&) = delete;
 
 
-        // Parallel functionality
-
-            //- Calculate if patches are on multiple processors
-            label calcDistribution
-            (
-                const SourcePatch& srcPatch,
-                const TargetPatch& tgtPatch
-            ) const;
-
-            label calcOverlappingProcs
-            (
-                const List<treeBoundBoxList>& procBb,
-                const treeBoundBox& bb,
-                boolList& overlaps
-            ) const;
-
-            void distributePatches
-            (
-                const mapDistribute& map,
-                const TargetPatch& pp,
-                const globalIndex& gi,
-                List<faceList>& faces,
-                List<pointField>& points,
-                List<labelList>& tgtFaceIDs
-            ) const;
-
-            void distributeAndMergePatches
-            (
-                const mapDistribute& map,
-                const TargetPatch& tgtPatch,
-                const globalIndex& gi,
-                faceList& tgtFaces,
-                pointField& tgtPoints,
-                labelList& tgtFaceIDs
-            ) const;
-
-            autoPtr<mapDistribute> calcProcMap
-            (
-                const SourcePatch& srcPatch,
-                const TargetPatch& tgtPatch
-            ) const;
-
-
         // Initialisation
 
             //- Project points to surface
@@ -637,7 +594,6 @@ public:
 
 #ifdef NoRepository
     #include "AMIInterpolation.C"
-    #include "AMIInterpolationParallelOps.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C
index 5a8f11ec74b6d925f1fa0ec55ec074b517a27ceb..f4265f155ab08f7619c1222e28fd110761953c2f 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2013-2016 OpenFOAM Foundation
-    Copyright (C) 2015-2018 OpenCFD Ltd.
+    Copyright (C) 2015-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -38,10 +38,13 @@ License
 template<class SourcePatch, class TargetPatch>
 void Foam::AMIMethod<SourcePatch, TargetPatch>::checkPatches() const
 {
-    if (debug && (!srcPatch_.size() || !tgtPatch_.size()))
+    const auto& src = srcPatch();
+    const auto& tgt = tgtPatch();
+
+    if (debug && (!src.size() || !tgt.size()))
     {
         Pout<< "AMI: Patches not on processor: Source faces = "
-            << srcPatch_.size() << ", target faces = " << tgtPatch_.size()
+            << src.size() << ", target faces = " << tgt.size()
             << endl;
     }
 
@@ -50,9 +53,9 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::checkPatches() const
     {
         const scalar maxBoundsError = 0.05;
 
-        // check bounds of source and target
-        boundBox bbSrc(srcPatch_.points(), srcPatch_.meshPoints(), true);
-        boundBox bbTgt(tgtPatch_.points(), tgtPatch_.meshPoints(), true);
+        // Check bounds of source and target
+        boundBox bbSrc(src.points(), src.meshPoints(), true);
+        boundBox bbTgt(tgt.points(), tgt.meshPoints(), true);
 
         boundBox bbTgtInf(bbTgt);
         bbTgtInf.inflate(maxBoundsError);
@@ -72,6 +75,56 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::checkPatches() const
 }
 
 
+template<class SourcePatch, class TargetPatch>
+Foam::autoPtr<TargetPatch>
+Foam::AMIMethod<SourcePatch, TargetPatch>::createExtendedTgtPatch
+(
+    const SourcePatch& srcPatch,
+    const TargetPatch& tgtPatch,
+    const globalIndex& globalTgtFaces,
+    autoPtr<mapDistribute>& mapPtr,
+    labelList& extendedTgtFaceIDs
+) const
+{
+    // Create a representation of the src mesh that is extended to overlap the
+    // tgt mesh
+
+    // Create processor map of extended cells. This map gets (possibly
+    // remote) cells from the src mesh such that they (together) cover
+    // all of tgt
+    mapPtr = calcProcMap(srcPatch, tgtPatch);
+    const mapDistribute& map = mapPtr();
+
+    // Create new target patch that fully encompasses source patch
+
+    // Faces and points
+    // faceList newTgtFaces_;
+    // pointField newTgtPoints_;
+
+    // Original faces from tgtPatch (in globalIndexing since might be
+    // remote)
+    distributeAndMergePatches
+    (
+        map,
+        tgtPatch,
+        globalTgtFaces,
+        newTgtFaces_,
+        newTgtPoints_,
+        extendedTgtFaceIDs
+    );
+
+    return autoPtr<TargetPatch>::New
+    (
+        SubList<face>
+        (
+            newTgtFaces_,
+            newTgtFaces_.size()
+        ),
+        newTgtPoints_
+    );
+}
+
+
 template<class SourcePatch, class TargetPatch>
 bool Foam::AMIMethod<SourcePatch, TargetPatch>::initialise
 (
@@ -83,38 +136,41 @@ bool Foam::AMIMethod<SourcePatch, TargetPatch>::initialise
     label& tgtFacei
 )
 {
+    const auto& src = srcPatch();
+    const auto& tgt = tgtPatch();
+
     checkPatches();
 
-    // set initial sizes for weights and addressing - must be done even if
+    // Set initial sizes for weights and addressing - must be done even if
     // returns false below
-    srcAddress.setSize(srcPatch_.size());
-    srcWeights.setSize(srcPatch_.size());
-    tgtAddress.setSize(tgtPatch_.size());
-    tgtWeights.setSize(tgtPatch_.size());
+    srcAddress.setSize(src.size());
+    srcWeights.setSize(srcAddress.size());
+    tgtAddress.setSize(tgt.size());
+    tgtWeights.setSize(tgtAddress.size());
 
-    // check that patch sizes are valid
-    if (!srcPatch_.size())
+    // Check that patch sizes are valid
+    if (!src.size())
     {
         return false;
     }
-    else if (!tgtPatch_.size())
+    else if (!tgt.size())
     {
         WarningInFunction
-            << srcPatch_.size() << " source faces but no target faces" << endl;
+            << src.size() << " source faces but no target faces" << endl;
 
         return false;
     }
 
-    // reset the octree
+    // Reset the octree
     resetTree();
 
-    // find initial face match using brute force/octree search
+    // Find initial face match using brute force/octree search
     if ((srcFacei == -1) || (tgtFacei == -1))
     {
         srcFacei = 0;
         tgtFacei = 0;
         bool foundFace = false;
-        forAll(srcPatch_, facei)
+        forAll(src, facei)
         {
             tgtFacei = findTargetFace(facei);
             if (tgtFacei >= 0)
@@ -202,10 +258,12 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::writeIntersectionOBJ
 template<class SourcePatch, class TargetPatch>
 void Foam::AMIMethod<SourcePatch, TargetPatch>::resetTree()
 {
+    const auto& tgt = tgtPatch();
+
     // Clear the old octree
     treePtr_.clear();
 
-    treeBoundBox bb(tgtPatch_.points(), tgtPatch_.meshPoints());
+    treeBoundBox bb(tgt.points(), tgt.meshPoints());
     bb.inflate(0.01);
 
     if (!treePtr_.valid())
@@ -217,7 +275,7 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::resetTree()
                 treeType
                 (
                     false,
-                    tgtPatch_,
+                    tgt,
                     indexedOctree<treeType>::perturbTol()
                 ),
                 bb,                         // overall search domain
@@ -238,10 +296,12 @@ Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::findTargetFace
     const label srcFacePti
 ) const
 {
+    const auto& src = srcPatch();
+
     label targetFacei = -1;
 
-    const pointField& srcPts = srcPatch_.points();
-    const face& srcFace = srcPatch_[srcFacei];
+    const pointField& srcPts = src.points();
+    const face& srcFace = src[srcFacei];
 
     findNearestMaskedOp<TargetPatch> fnOp(*treePtr_, excludeFaces);
 
@@ -282,7 +342,7 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::appendNbrFaces
 
     const labelList& nbrFaces = patch.faceFaces()[facei];
 
-    // filter out faces already visited from face neighbours
+    // Filter out faces already visited from face neighbours
     for (const label nbrFacei : nbrFaces)
     {
         bool valid = true;
@@ -307,7 +367,7 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::appendNbrFaces
             }
         }
 
-        // prevent addition of face if it is not on the same plane-ish
+        // Prevent addition of face if it is not on the same plane-ish
         if (valid)
         {
             const vector& n1 = patch.faceNormals()[facei];
@@ -382,14 +442,14 @@ Foam::AMIMethod<SourcePatch, TargetPatch>::AMIMethod
     const bool requireMatch
 )
 :
-    srcPatch_(srcPatch),
-    tgtPatch_(tgtPatch),
+    srcPatch0_(srcPatch),
+    tgtPatch0_(tgtPatch),
+    extendedTgtPatchPtr_(nullptr),
     reverseTarget_(reverseTarget),
     requireMatch_(requireMatch),
-    srcMagSf_(srcPatch.size(), 1.0),
-    tgtMagSf_(tgtPatch.size(), 1.0),
     srcNonOverlap_(),
-    triMode_(triMode)
+    triMode_(triMode),
+    singleMeshProc_(calcDistribution(srcPatch, tgtPatch))
 {
     // Note: setting srcMagSf and tgtMagSf to 1 by default for 1-to-1 methods
     // - others will need to overwrite as necessary
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.H
index e019c384cea9d5997738eeaf75ce2b69046d8199..e702f8366ab38747eef861057f593da17257c86f 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.H
@@ -72,6 +72,48 @@ private:
         //- No copy assignment
         void operator=(const AMIMethod&) = delete;
 
+        // Parallel operations
+
+            //- Calculate if patches are on multiple processors
+            label calcDistribution
+            (
+                const SourcePatch& srcPatch,
+                const TargetPatch& tgtPatch
+            ) const;
+
+            label calcOverlappingProcs
+            (
+                const List<treeBoundBoxList>& procBb,
+                const treeBoundBox& bb,
+                boolList& overlaps
+            ) const;
+
+            void distributePatches
+            (
+                const mapDistribute& map,
+                const TargetPatch& pp,
+                const globalIndex& gi,
+                List<faceList>& faces,
+                List<pointField>& points,
+                List<labelList>& tgtFaceIDs
+            ) const;
+
+            void distributeAndMergePatches
+            (
+                const mapDistribute& map,
+                const TargetPatch& tgtPatch,
+                const globalIndex& gi,
+                faceList& tgtFaces,
+                pointField& tgtPoints,
+                labelList& tgtFaceIDs
+            ) const;
+
+            autoPtr<mapDistribute> calcProcMap
+            (
+                const SourcePatch& srcPatch,
+                const TargetPatch& tgtPatch
+            ) const;
+
 
 protected:
 
@@ -82,10 +124,13 @@ protected:
     // Protected data
 
         //- Reference to source patch
-        const SourcePatch& srcPatch_;
+        const SourcePatch& srcPatch0_;
 
         //- Reference to target patch
-        const TargetPatch& tgtPatch_;
+        const TargetPatch& tgtPatch0_;
+
+        //- Demand-driven extended target mesh (distributed parallel usage)
+        autoPtr<TargetPatch> extendedTgtPatchPtr_;
 
         //- Flag to indicate that the two patches are co-directional and
         //- that the orientation of the target patch should be reversed
@@ -95,12 +140,6 @@ protected:
         //- exists between them
         const bool requireMatch_;
 
-        //- Source face areas
-        List<scalar> srcMagSf_;
-
-        //- Target face areas
-        List<scalar> tgtMagSf_;
-
         //- Labels of faces that are not overlapped by any target faces
         //- (should be empty for correct functioning for fully covered AMIs)
         labelList srcNonOverlap_;
@@ -111,11 +150,27 @@ protected:
         //- Face triangulation mode
         const faceAreaIntersect::triangulationMode triMode_;
 
+        //- Label of processor containing all meshes
+        //- Note: set to -1 if distributed
+        label singleMeshProc_;
+
+    mutable faceList newTgtFaces_;
+    mutable pointField newTgtPoints_;
 
     // Protected Member Functions
 
         // Helper functions
 
+            //- Create a map that extends tgtPatch so that it covers srcPatch
+            autoPtr<TargetPatch> createExtendedTgtPatch
+            (
+                const SourcePatch& srcPatch,
+                const TargetPatch& tgtPatch,
+                const globalIndex& globalTgtFaces,
+                autoPtr<mapDistribute>& mapPtr,
+                labelList& extendedTgtFaceIDs
+            ) const;
+
             //- Check AMI patch coupling
             void checkPatches() const;
 
@@ -229,6 +284,15 @@ public:
 
         // Access
 
+            //- Return const access to the source patch
+            inline const SourcePatch& srcPatch() const;
+
+            //- Return const access to the target patch
+            inline const TargetPatch& tgtPatch() const;
+
+            //- Return true if the patches are split across multiple processors
+            inline bool distributed() const;
+
             //- Labels of faces that are not overlapped by any target faces
             //  Note: this should be empty for correct functioning
             inline const labelList& srcNonOverlap() const;
@@ -236,42 +300,25 @@ public:
             //- Flag to indicate that interpolation patches are conformal
             virtual bool conformal() const;
 
-            //- Return const access to source patch face areas
-            inline const List<scalar>& srcMagSf() const;
-
-            //- Return access to source patch face areas
-            inline List<scalar>& srcMagSf();
-
-            //- Return const access to target patch face areas
-            inline const List<scalar>& tgtMagSf() const;
-
-            //- Return access to target patch face areas
-            inline List<scalar>& tgtMagSf();
-
 
         // Manipulation
 
             //- Update addressing and weights
-            virtual void calculate
+            virtual bool calculate
             (
                 labelListList& srcAddress,
                 scalarListList& srcWeights,
                 pointListList& srcCentroids,
                 labelListList& tgtAddress,
                 scalarListList& tgtWeights,
+                scalarList& srcMagSf,
+                scalarList& tgtMagSf,
+                autoPtr<mapDistribute>& srcMapPtr,
+                autoPtr<mapDistribute>& tgtMapPtr,
                 label srcFacei = -1,
                 label tgtFacei = -1
             ) = 0;
 
-            //- Set the face areas for parallel runs
-            virtual void setMagSf
-            (
-                const TargetPatch& tgtPatch,
-                const mapDistribute& map,
-                scalarList& srcMagSf,
-                scalarList& tgtMagSf
-            ) const = 0;
-
             //- Normalise the weight. Can optionally subset addressing
             //- (e.g. for mapNearest)
             virtual void normaliseWeights
@@ -318,6 +365,7 @@ public:
 #ifdef NoRepository
     #include "AMIMethod.C"
     #include "AMIMethodNew.C"
+    #include "AMIMethodParallelOps.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodI.H
index caea348e2df5fad06cea4bee21328e7bad7df2d2..8c740cdcb1c5ce837f2c21b2dbf0d44b2ff1058f 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodI.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodI.H
@@ -26,34 +26,30 @@ License
 \*---------------------------------------------------------------------------*/
 
 template<class SourcePatch, class TargetPatch>
-inline const Foam::List<Foam::scalar>&
-Foam::AMIMethod<SourcePatch, TargetPatch>::srcMagSf() const
+inline const SourcePatch&
+Foam::AMIMethod<SourcePatch, TargetPatch>::srcPatch() const
 {
-    return srcMagSf_;
+    return srcPatch0_;
 }
 
 
 template<class SourcePatch, class TargetPatch>
-inline Foam::List<Foam::scalar>&
-Foam::AMIMethod<SourcePatch, TargetPatch>::srcMagSf()
+inline const TargetPatch&
+Foam::AMIMethod<SourcePatch, TargetPatch>::tgtPatch() const
 {
-    return srcMagSf_;
-}
-
+    if (extendedTgtPatchPtr_)
+    {
+        return extendedTgtPatchPtr_();
+    }
 
-template<class SourcePatch, class TargetPatch>
-inline const Foam::List<Foam::scalar>&
-Foam::AMIMethod<SourcePatch, TargetPatch>::tgtMagSf() const
-{
-    return tgtMagSf_;
+    return tgtPatch0_;
 }
 
 
 template<class SourcePatch, class TargetPatch>
-inline Foam::List<Foam::scalar>&
-Foam::AMIMethod<SourcePatch, TargetPatch>::tgtMagSf()
+bool Foam::AMIMethod<SourcePatch, TargetPatch>::distributed() const
 {
-    return tgtMagSf_;
+    return singleMeshProc_ == -1;
 }
 
 
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationParallelOps.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodParallelOps.C
similarity index 96%
rename from src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationParallelOps.C
rename to src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodParallelOps.C
index ad3a9ec83ad7d43af7c87deaea3155f2eccc4bc3..1066943f293fe26b9cacea3288998abbc22162c4 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationParallelOps.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodParallelOps.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2020 OpenCFD Ltd.
+    Copyright (C) 2018-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,8 +25,6 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 \*---------------------------------------------------------------------------*/
-
-#include "AMIInterpolation.H"
 #include "mergePoints.H"
 #include "mapDistribute.H"
 #include "AABBTree.H"
@@ -34,7 +32,7 @@ License
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class SourcePatch, class TargetPatch>
-Foam::label Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcDistribution
+Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::calcDistribution
 (
     const SourcePatch& srcPatch,
     const TargetPatch& tgtPatch
@@ -80,8 +78,7 @@ Foam::label Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcDistribution
 
 
 template<class SourcePatch, class TargetPatch>
-Foam::label
-Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcOverlappingProcs
+Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::calcOverlappingProcs
 (
     const List<treeBoundBoxList>& procBb,
     const treeBoundBox& bb,
@@ -102,7 +99,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcOverlappingProcs
             if (tbb.overlaps(bb))
             {
                 overlaps[proci] = true;
-                nOverlaps++;
+                ++nOverlaps;
                 break;
             }
         }
@@ -113,7 +110,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcOverlappingProcs
 
 
 template<class SourcePatch, class TargetPatch>
-void Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributePatches
+void Foam::AMIMethod<SourcePatch, TargetPatch>::distributePatches
 (
     const mapDistribute& map,
     const TargetPatch& pp,
@@ -198,7 +195,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributePatches
 
 
 template<class SourcePatch, class TargetPatch>
-void Foam::AMIInterpolation<SourcePatch, TargetPatch>::
+void Foam::AMIMethod<SourcePatch, TargetPatch>::
 distributeAndMergePatches
 (
     const mapDistribute& map,
@@ -313,7 +310,7 @@ distributeAndMergePatches
 
 template<class SourcePatch, class TargetPatch>
 Foam::autoPtr<Foam::mapDistribute>
-Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcProcMap
+Foam::AMIMethod<SourcePatch, TargetPatch>::calcProcMap
 (
     const SourcePatch& srcPatch,
     const TargetPatch& tgtPatch
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.C
index 14989fdfbed58aa035df160d765e266136da3f37..58170bbe322eeac96b0d2838590436b6c0f452a2 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.C
@@ -40,20 +40,20 @@ void Foam::directAMI<SourcePatch, TargetPatch>::appendToDirectSeeds
     label& tgtFacei
 ) const
 {
-    const labelList& srcNbr = this->srcPatch_.faceFaces()[srcFacei];
-    const labelList& tgtNbr = this->tgtPatch_.faceFaces()[tgtFacei];
+    const labelList& srcNbr = this->srcPatch().faceFaces()[srcFacei];
+    const labelList& tgtNbr = this->tgtPatch().faceFaces()[tgtFacei];
 
-    const pointField& srcPoints = this->srcPatch_.points();
-    const pointField& tgtPoints = this->tgtPatch_.points();
+    const pointField& srcPoints = this->srcPatch().points();
+    const pointField& tgtPoints = this->tgtPatch().points();
 
-    const vectorField& srcCf = this->srcPatch_.faceCentres();
+    const vectorField& srcCf = this->srcPatch().faceCentres();
 
     for (const label srcI : srcNbr)
     {
         if ((mapFlag[srcI] == 0) && (srcTgtSeed[srcI] == -1))
         {
             // first attempt: match by comparing face centres
-            const face& srcF = this->srcPatch_[srcI];
+            const face& srcF = this->srcPatch()[srcI];
             const point& srcC = srcCf[srcI];
 
             scalar tol = GREAT;
@@ -71,7 +71,7 @@ void Foam::directAMI<SourcePatch, TargetPatch>::appendToDirectSeeds
             bool found = false;
             for (const label tgtI : tgtNbr)
             {
-                const face& tgtF = this->tgtPatch_[tgtI];
+                const face& tgtF = this->tgtPatch()[tgtI];
                 const point tgtC = tgtF.centre(tgtPoints);
 
                 if (mag(srcC - tgtC) < tol)
@@ -93,7 +93,7 @@ void Foam::directAMI<SourcePatch, TargetPatch>::appendToDirectSeeds
 
                 for (const label tgtI : tgtNbr)
                 {
-                    const face& tgtF = this->tgtPatch_[tgtI];
+                    const face& tgtF = this->tgtPatch()[tgtI];
                     pointHit ray = tgtF.ray(srcCf[srcI], srcN, tgtPoints);
 
                     if (ray.hit())
@@ -126,7 +126,7 @@ void Foam::directAMI<SourcePatch, TargetPatch>::appendToDirectSeeds
                     Pout<< "target neighbours:" << nl;
                     for (const label tgtI : tgtNbr)
                     {
-                        const face& tgtF = this->tgtPatch_[tgtI];
+                        const face& tgtF = this->tgtPatch()[tgtI];
 
                         Pout<< "face id: " << tgtI
                             << " centre=" << tgtF.centre(tgtPoints)
@@ -208,13 +208,17 @@ Foam::directAMI<SourcePatch, TargetPatch>::directAMI
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class SourcePatch, class TargetPatch>
-void Foam::directAMI<SourcePatch, TargetPatch>::calculate
+bool Foam::directAMI<SourcePatch, TargetPatch>::calculate
 (
     labelListList& srcAddress,
     scalarListList& srcWeights,
     pointListList& srcCentroids,
     labelListList& tgtAddress,
     scalarListList& tgtWeights,
+    scalarList& srcMagSf,
+    scalarList& tgtMagSf,
+    autoPtr<mapDistribute>& srcMapPtr,
+    autoPtr<mapDistribute>& tgtMapPtr,
     label srcFacei,
     label tgtFacei
 )
@@ -232,13 +236,13 @@ void Foam::directAMI<SourcePatch, TargetPatch>::calculate
 
     if (!ok)
     {
-        return;
+        return false;
     }
 
-
+    NotImplemented;
     // temporary storage for addressing and weights
-    List<DynamicList<label>> srcAddr(this->srcPatch_.size());
-    List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
+    List<DynamicList<label>> srcAddr(this->srcPatch0_.size());
+    List<DynamicList<label>> tgtAddr(this->tgtPatch0_.size());
 
 
     // construct weights and addressing
@@ -277,7 +281,7 @@ void Foam::directAMI<SourcePatch, TargetPatch>::calculate
             tgtFacei
         );
 
-        if (srcFacei < 0 && nTested < this->srcPatch_.size())
+        if (srcFacei < 0 && nTested < this->srcPatch().size())
         {
             restartAdvancingFront(mapFlag, nonOverlapFaces, srcFacei, tgtFacei);
         }
@@ -306,20 +310,8 @@ void Foam::directAMI<SourcePatch, TargetPatch>::calculate
         tgtAddress[i].transfer(tgtAddr[i]);
         tgtWeights[i] = scalarList(1, magSf);
     }
-}
 
-
-template<class SourcePatch, class TargetPatch>
-void Foam::directAMI<SourcePatch, TargetPatch>::setMagSf
-(
-    const TargetPatch& tgtPatch,
-    const mapDistribute& map,
-    scalarList& srcMagSf,
-    scalarList& tgtMagSf
-) const
-{
-    srcMagSf = std::move(this->srcMagSf_);
-    tgtMagSf = scalarList(tgtPatch.size(), 1.0);
+    return true;
 }
 
 
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.H
index a07aa4f617b08122b838da3f1722e1112ef9417f..9eaf8df29e0b57c8be1afe6730723d799667a7b9 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.H
@@ -126,26 +126,21 @@ public:
         // Manipulation
 
             //- Update addressing and weights
-            virtual void calculate
+            virtual bool calculate
             (
                 labelListList& srcAddress,
                 scalarListList& srcWeights,
                 pointListList& srcCentroids,
                 labelListList& tgtAddress,
                 scalarListList& tgtWeights,
+                scalarList& srcMagSf,
+                scalarList& tgtMagSf,
+                autoPtr<mapDistribute>& srcMapPtr,
+                autoPtr<mapDistribute>& tgtMapPtr,
                 label srcFacei = -1,
                 label tgtFacei = -1
             );
 
-            //- Set the face areas for parallel runs
-            virtual void setMagSf
-            (
-                const TargetPatch& tgtPatch,
-                const mapDistribute& map,
-                scalarList& srcMagSf,
-                scalarList& tgtMagSf
-            ) const;
-
             //- Normalise the weight. Can optionally subset addressing
             //  (e.g. for mapNearest)
             virtual void normaliseWeights
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C
index f770dfbb58e99f7fef51ee95ab427f15d29aaf7b..8eba124a3a9de5870034939ad7f72cecb2d583b5 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2013-2016 OpenFOAM Foundation
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -32,6 +32,76 @@ License
 
 // * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //
 
+template<class SourcePatch, class TargetPatch>
+void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::initGeom
+(
+    const globalIndex& globalTgtFaces,
+    labelList& extendedTgtFaceIDs
+)
+{
+    // Create a representation of the target patch that covers the source patch
+    if (this->distributed())
+    {
+        this->extendedTgtPatchPtr_ =
+            this->createExtendedTgtPatch
+            (
+                this->srcPatch0_,
+                this->tgtPatch0_,
+                globalTgtFaces,
+                extendedTgtMapPtr_,
+                extendedTgtFaceIDs
+            );
+    }
+
+    const auto& src = this->srcPatch();
+    const auto& tgt = this->tgtPatch();
+
+    // Initialise area magnitudes
+    srcMagSf_.setSize(src.size(), 1.0);
+    tgtMagSf_.setSize(tgt.size(), 1.0);
+
+    // Source and target patch triangulations
+    this->triangulatePatch(src, srcTris_, srcMagSf_);
+    this->triangulatePatch(tgt, tgtTris_, tgtMagSf_);
+
+    if (debug)
+    {
+        static label nAMI = 0;
+
+        // Write out triangulated surfaces as OBJ files
+        OBJstream srcTriObj("srcTris_" + Foam::name(nAMI) + ".obj");
+        const pointField& srcPts = src.points();
+        forAll(srcTris_, facei)
+        {
+            const DynamicList<face>& faces = srcTris_[facei];
+            for (const face& f : faces)
+            {
+                srcTriObj.write
+                (
+                    triPointRef(srcPts[f[0]], srcPts[f[1]], srcPts[f[2]])
+                );
+            }
+        }
+
+        OBJstream tgtTriObj("tgtTris_" + Foam::name(nAMI) + ".obj");
+        const pointField& tgtPts = tgt.points();
+        forAll(tgtTris_, facei)
+        {
+            const DynamicList<face>& faces = tgtTris_[facei];
+            for (const face& f : faces)
+            {
+                tgtTriObj.write
+                (
+                    triPointRef(tgtPts[f[0]], tgtPts[f[1]], tgtPts[f[2]])
+                );
+            }
+        }
+
+        ++nAMI;
+    }
+}
+
+
 template<class SourcePatch, class TargetPatch>
 void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing
 (
@@ -148,7 +218,7 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
     this->appendNbrFaces
     (
         tgtStartFacei,
-        this->tgtPatch_,
+        this->tgtPatch(),
         visitedFaces,
         nbrFaces
     );
@@ -184,7 +254,7 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
             this->appendNbrFaces
             (
                 tgtFacei,
-                this->tgtPatch_,
+                this->tgtPatch(),
                 visitedFaces,
                 nbrFaces
             );
@@ -219,7 +289,7 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
 {
     addProfiling(ami, "faceAreaWeightAMI::setNextFaces");
 
-    const labelList& srcNbrFaces = this->srcPatch_.faceFaces()[srcFacei];
+    const labelList& srcNbrFaces = this->srcPatch().faceFaces()[srcFacei];
 
     // initialise tgtFacei
     tgtFacei = -1;
@@ -327,12 +397,12 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcInterArea
 {
     addProfiling(ami, "faceAreaWeightAMI::interArea");
 
-    const pointField& srcPoints = this->srcPatch_.points();
-    const pointField& tgtPoints = this->tgtPatch_.points();
+    const pointField& srcPoints = this->srcPatch().points();
+    const pointField& tgtPoints = this->tgtPatch().points();
 
     // references to candidate faces
-    const face& src = this->srcPatch_[srcFacei];
-    const face& tgt = this->tgtPatch_[tgtFacei];
+    const face& src = this->srcPatch()[srcFacei];
+    const face& tgt = this->tgtPatch()[tgtFacei];
 
     // quick reject if either face has zero area
     if
@@ -356,14 +426,14 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcInterArea
     );
 
     // crude resultant norm
-    vector n(-this->srcPatch_.faceNormals()[srcFacei]);
+    vector n(-this->srcPatch().faceNormals()[srcFacei]);
     if (this->reverseTarget_)
     {
-        n -= this->tgtPatch_.faceNormals()[tgtFacei];
+        n -= this->tgtPatch().faceNormals()[tgtFacei];
     }
     else
     {
-        n += this->tgtPatch_.faceNormals()[tgtFacei];
+        n += this->tgtPatch().faceNormals()[tgtFacei];
     }
     scalar magN = mag(n);
 
@@ -410,12 +480,12 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::overlaps
     const scalar threshold
 ) const
 {
-    const pointField& srcPoints = this->srcPatch_.points();
-    const pointField& tgtPoints = this->tgtPatch_.points();
+    const pointField& srcPoints = this->srcPatch().points();
+    const pointField& tgtPoints = this->tgtPatch().points();
 
     // references to candidate faces
-    const face& src = this->srcPatch_[srcFacei];
-    const face& tgt = this->tgtPatch_[tgtFacei];
+    const face& src = this->srcPatch()[srcFacei];
+    const face& tgt = this->tgtPatch()[tgtFacei];
 
     // quick reject if either face has zero area
     if
@@ -438,14 +508,14 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::overlaps
     );
 
     // crude resultant norm
-    vector n(-this->srcPatch_.faceNormals()[srcFacei]);
+    vector n(-this->srcPatch().faceNormals()[srcFacei]);
     if (this->reverseTarget_)
     {
-        n -= this->tgtPatch_.faceNormals()[tgtFacei];
+        n -= this->tgtPatch().faceNormals()[tgtFacei];
     }
     else
     {
-        n += this->tgtPatch_.faceNormals()[tgtFacei];
+        n += this->tgtPatch().faceNormals()[tgtFacei];
     }
     scalar magN = mag(n);
 
@@ -500,7 +570,7 @@ restartUncoveredSourceFace
         {
             ++nBelowMinWeight;
 
-            const face& f = this->srcPatch_[srcFacei];
+            const face& f = this->srcPatch()[srcFacei];
 
             forAll(f, fpi)
             {
@@ -563,66 +633,42 @@ Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::faceAreaWeightAMI
         requireMatch
     ),
     restartUncoveredSourceFace_(restartUncoveredSourceFace),
+    srcMagSf_(),
+    tgtMagSf_(),
     srcTris_(),
-    tgtTris_()
-{
-    this->triangulatePatch(srcPatch, srcTris_, this->srcMagSf_);
-    this->triangulatePatch(tgtPatch, tgtTris_, this->tgtMagSf_);
-
-    if (debug)
-    {
-        static label nAMI = 0;
-
-        // Write out triangulated surfaces as OBJ files
-        OBJstream srcTriObj("srcTris_" + Foam::name(nAMI) + ".obj");
-        const pointField& srcPts = srcPatch.points();
-        forAll(srcTris_, facei)
-        {
-            const DynamicList<face>& faces = srcTris_[facei];
-            for (const face& f : faces)
-            {
-                srcTriObj.write
-                (
-                    triPointRef(srcPts[f[0]], srcPts[f[1]], srcPts[f[2]])
-                );
-            }
-        }
-
-        OBJstream tgtTriObj("tgtTris_" + Foam::name(nAMI) + ".obj");
-        const pointField& tgtPts = tgtPatch.points();
-        forAll(tgtTris_, facei)
-        {
-            const DynamicList<face>& faces = tgtTris_[facei];
-            for (const face& f : faces)
-            {
-                tgtTriObj.write
-                (
-                    triPointRef(tgtPts[f[0]], tgtPts[f[1]], tgtPts[f[2]])
-                );
-            }
-        }
-
-        ++nAMI;
-    }
-}
+    tgtTris_(),
+    extendedTgtMapPtr_(nullptr)
+{}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class SourcePatch, class TargetPatch>
-void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
+bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
 (
     labelListList& srcAddress,
     scalarListList& srcWeights,
     pointListList& srcCentroids,
     labelListList& tgtAddress,
     scalarListList& tgtWeights,
+    scalarList& srcMagSf,
+    scalarList& tgtMagSf,
+    autoPtr<mapDistribute>& srcMapPtr,
+    autoPtr<mapDistribute>& tgtMapPtr,
     label srcFacei,
     label tgtFacei
 )
 {
     addProfiling(ami, "faceAreaWeightAMI::calculate");
 
+    // Create global indexing for each patch
+    globalIndex globalSrcFaces(this->srcPatch0_.size());
+    globalIndex globalTgtFaces(this->tgtPatch0_.size());
+
+    // Initialise the geometry
+    labelList extendedTgtFaceIDs;
+    initGeom(globalTgtFaces, extendedTgtFaceIDs);
+
     bool ok =
         this->initialise
         (
@@ -636,51 +682,55 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
 
     srcCentroids.setSize(srcAddress.size());
 
+    const auto& src = this->srcPatch();
+    const auto& tgt = this->tgtPatch();
 
-    if (!ok)
-    {
-        return;
-    }
-
-    // temporary storage for addressing and weights
-    List<DynamicList<label>> srcAddr(this->srcPatch_.size());
+    // Temporary storage for addressing and weights
+    List<DynamicList<label>> srcAddr(src.size());
     List<DynamicList<scalar>> srcWght(srcAddr.size());
     List<DynamicList<point>> srcCtr(srcAddr.size());
-    List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
+    List<DynamicList<label>> tgtAddr(tgt.size());
     List<DynamicList<scalar>> tgtWght(tgtAddr.size());
 
-    calcAddressing
-    (
-        srcAddr,
-        srcWght,
-        srcCtr,
-        tgtAddr,
-        tgtWght,
-        srcFacei,
-        tgtFacei
-    );
-
-    if (debug && !this->srcNonOverlap_.empty())
-    {
-        Pout<< "    AMI: " << this->srcNonOverlap_.size()
-            << " non-overlap faces identified"
-            << endl;
-    }
-
-
-    // Check for badly covered faces
-    if (restartUncoveredSourceFace_)
+    if (ok)
     {
-        restartUncoveredSourceFace
+        calcAddressing
         (
             srcAddr,
             srcWght,
             srcCtr,
             tgtAddr,
-            tgtWght
+            tgtWght,
+            srcFacei,
+            tgtFacei
         );
+
+        if (debug && !this->srcNonOverlap_.empty())
+        {
+            Pout<< "    AMI: " << this->srcNonOverlap_.size()
+                << " non-overlap faces identified"
+                << endl;
+        }
+
+        // Check for badly covered faces
+        if (restartUncoveredSourceFace_)
+        {
+            restartUncoveredSourceFace
+            (
+                srcAddr,
+                srcWght,
+                srcCtr,
+                tgtAddr,
+                tgtWght
+            );
+        }
     }
 
+
+    // Set the patch face areas
+    srcMagSf = std::move(srcMagSf_);
+    tgtMagSf = std::move(tgtMagSf_);
+
     // Transfer data to persistent storage
     forAll(srcAddr, i)
     {
@@ -688,26 +738,76 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
         srcWeights[i].transfer(srcWght[i]);
         srcCentroids[i].transfer(srcCtr[i]);
     }
+
     forAll(tgtAddr, i)
     {
         tgtAddress[i].transfer(tgtAddr[i]);
         tgtWeights[i].transfer(tgtWght[i]);
     }
-}
 
+    if (this->distributed())
+    {
+        for (labelList& addressing : srcAddress)
+        {
+            for (label& addr : addressing)
+            {
+                addr = extendedTgtFaceIDs[addr];
+            }
+        }
 
-template<class SourcePatch, class TargetPatch>
-void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setMagSf
-(
-    const TargetPatch& tgtPatch,
-    const mapDistribute& map,
-    scalarList& srcMagSf,
-    scalarList& tgtMagSf
-) const
-{
-    srcMagSf = std::move(this->srcMagSf_);
-    tgtMagSf = std::move(this->tgtMagSf_);
-    map.reverseDistribute(tgtPatch.size(), tgtMagSf);
+        for (labelList& addressing : tgtAddress)
+        {
+            globalSrcFaces.inplaceToGlobal(addressing);
+        }
+
+        // Send data back to originating procs. Note that contributions
+        // from different processors get added (ListOps::appendEqOp)
+
+        mapDistributeBase::distribute
+        (
+            Pstream::commsTypes::nonBlocking,
+            List<labelPair>(),
+            this->tgtPatch0_.size(),
+            extendedTgtMapPtr_->constructMap(),
+            false,                      // has flip
+            extendedTgtMapPtr_->subMap(),
+            false,                      // has flip
+            tgtAddress,
+            ListOps::appendEqOp<label>(),
+            flipOp(),                   // flip operation
+            labelList()
+        );
+
+        mapDistributeBase::distribute
+        (
+            Pstream::commsTypes::nonBlocking,
+            List<labelPair>(),
+            this->tgtPatch0_.size(),
+            extendedTgtMapPtr_->constructMap(),
+            false,
+            extendedTgtMapPtr_->subMap(),
+            false,
+            tgtWeights,
+            ListOps::appendEqOp<scalar>(),
+            flipOp(),
+            scalarList()
+        );
+
+        // Note: using patch face areas calculated by the AMI method
+        extendedTgtMapPtr_->reverseDistribute
+        (
+            this->tgtPatch0_.size(),
+            tgtMagSf
+        );
+
+        // Cache maps and reset addresses
+        List<Map<label>> cMapSrc;
+        srcMapPtr.reset(new mapDistribute(globalSrcFaces, tgtAddress, cMapSrc));
+        List<Map<label>> cMapTgt;
+        tgtMapPtr.reset(new mapDistribute(globalTgtFaces, srcAddress, cMapTgt));
+    }
+
+    return true;
 }
 
 
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H
index 10622d727a13580a49d044f5d0264c91242d45e9..04fe248b78f74d38139b2f37e873c102d0a22349 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H
@@ -61,6 +61,12 @@ private:
         //- Flag to restart uncovered source faces
         const bool restartUncoveredSourceFace_;
 
+        //- Source face areas
+        List<scalar> srcMagSf_;
+
+        //- Target face areas
+        List<scalar> tgtMagSf_;
+
         //- Storage for src-side triangle decomposition
         List<DynamicList<face>> srcTris_;
 
@@ -70,6 +76,9 @@ private:
 
 protected:
 
+    autoPtr<mapDistribute> extendedTgtMapPtr_;
+
+
     // Protected Member Functions
 
         //- No copy construct
@@ -78,6 +87,14 @@ protected:
         //- No copy assignment
         void operator=(const faceAreaWeightAMI&) = delete;
 
+        //- Initialise the geometry
+        void initGeom
+        (
+            const globalIndex& globalTgtFaces,
+            labelList& extendedTgtFaceIDs
+        );
+
+
         // Marching front
 
             //- Calculate addressing, weights and centroids using temporary
@@ -179,26 +196,21 @@ public:
         // Manipulation
 
             //- Update addressing, weights and centroids
-            virtual void calculate
+            virtual bool calculate
             (
                 labelListList& srcAddress,
                 scalarListList& srcWeights,
                 pointListList& srcCentroids,
                 labelListList& tgtAddress,
                 scalarListList& tgtWeights,
+                scalarList& srcMagSf,
+                scalarList& tgtMagSf,
+                autoPtr<mapDistribute>& srcMapPtr,
+                autoPtr<mapDistribute>& tgtMapPtr,
                 label srcFacei = -1,
                 label tgtFacei = -1
             );
 
-            //- Set the face areas for parallel runs
-            virtual void setMagSf
-            (
-                const TargetPatch& tgtPatch,
-                const mapDistribute& map,
-                scalarList& srcMagSf,
-                scalarList& tgtMagSf
-            ) const;
-
             //- Normalise the weight. Can optionally subset addressing
             //- (e.g. for mapNearest)
             virtual void normaliseWeights
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.C
index a159fae7a0ba328d906ee66fce64556855ae0472..e2d57b8599d2e591aa84f4fffe0660f5cb5a7cc3 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.C
@@ -84,7 +84,7 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::setNextNearestFaces
     label& tgtFacei
 ) const
 {
-    const labelList& srcNbr = this->srcPatch_.faceFaces()[srcFacei];
+    const labelList& srcNbr = this->srcPatch().faceFaces()[srcFacei];
 
     srcFacei = -1;
 
@@ -108,7 +108,7 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::setNextNearestFaces
 
             if (tgtFacei == -1)
             {
-                const vectorField& srcCf = this->srcPatch_.faceCentres();
+                const vectorField& srcCf = this->srcPatch().faceCentres();
 
                 FatalErrorInFunction
                     << "Unable to find target face for source face "
@@ -149,7 +149,7 @@ Foam::label Foam::mapNearestAMI<SourcePatch, TargetPatch>::findMappedSrcFace
             }
             else
             {
-                const labelList& nbrFaces = this->tgtPatch_.faceFaces()[tgtI];
+                const labelList& nbrFaces = this->tgtPatch().faceFaces()[tgtI];
 
                 for (const label nbrFacei : nbrFaces)
                 {
@@ -193,13 +193,17 @@ Foam::mapNearestAMI<SourcePatch, TargetPatch>::mapNearestAMI
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class SourcePatch, class TargetPatch>
-void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
+bool Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
 (
     labelListList& srcAddress,
     scalarListList& srcWeights,
     pointListList& srcCentroids,
     labelListList& tgtAddress,
     scalarListList& tgtWeights,
+    scalarList& srcMagSf,
+    scalarList& tgtMagSf,
+    autoPtr<mapDistribute>& srcMapPtr,
+    autoPtr<mapDistribute>& tgtMapPtr,
     label srcFacei,
     label tgtFacei
 )
@@ -217,13 +221,13 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
 
     if (!ok)
     {
-        return;
+        return false;
     }
 
 
     // temporary storage for addressing and weights
-    List<DynamicList<label>> srcAddr(this->srcPatch_.size());
-    List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
+    List<DynamicList<label>> srcAddr(this->srcPatch().size());
+    List<DynamicList<label>> tgtAddr(this->tgtPatch().size());
 
 
     // construct weights and addressing
@@ -238,7 +242,7 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
     DynamicList<label> nonOverlapFaces;
     do
     {
-        findNearestFace(this->srcPatch_, this->tgtPatch_, srcFacei, tgtFacei);
+        findNearestFace(this->srcPatch(), this->tgtPatch(), srcFacei, tgtFacei);
 
         srcAddr[srcFacei].append(tgtFacei);
         tgtAddr[tgtFacei].append(srcFacei);
@@ -258,8 +262,8 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
 
     // for the case of multiple source faces per target face, select the
     // nearest source face only and discard the others
-    const vectorField& srcCf = this->srcPatch_.faceCentres();
-    const vectorField& tgtCf = this->tgtPatch_.faceCentres();
+    const vectorField& srcCf = this->srcPatch().faceCentres();
+    const vectorField& tgtCf = this->tgtPatch().faceCentres();
 
     forAll(tgtAddr, targetFacei)
     {
@@ -301,8 +305,8 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
                 // note - reversed search from src->tgt to tgt->src
                 findNearestFace
                 (
-                    this->tgtPatch_,
-                    this->srcPatch_,
+                    this->tgtPatch(),
+                    this->srcPatch(),
                     tgtFacei,
                     srcFacei
                 );
@@ -314,8 +318,8 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
 
 
     // transfer data to persistent storage
-    const pointField& srcFc = this->srcPatch_.faceCentres();
-    const pointField& tgtFc = this->tgtPatch_.faceCentres();
+    const pointField& srcFc = this->srcPatch().faceCentres();
+    const pointField& tgtFc = this->tgtPatch().faceCentres();
 
     forAll(srcAddr, srcI)
     {
@@ -341,6 +345,8 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
             tgtWeights[tgtI][i] = magSqr(tgtPt-srcFc[addr[i]]);
         }
     }
+
+    return true;
 }
 
 
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.H
index f347fcc7676455e875d77ee1a0ff82d3cc8cef3f..791c370332d0d097339a64f9340e916f5c75b93b 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.H
@@ -131,13 +131,17 @@ public:
         // Manipulation
 
             //- Update addressing and weights
-            virtual void calculate
+            virtual bool calculate
             (
                 labelListList& srcAddress,
                 scalarListList& srcWeights,
                 pointListList& srcCentroids,
                 labelListList& tgtAddress,
                 scalarListList& tgtWeights,
+                scalarList& srcMagSf,
+                scalarList& tgtMagSf,
+                autoPtr<mapDistribute>& srcMapPtr,
+                autoPtr<mapDistribute>& tgtMapPtr,
                 label srcFacei = -1,
                 label tgtFacei = -1
             );
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.C
index 5692a656baaf96b738d1c99b6bf2235694aea5e6..4e15ead5600e8a655e80c5a427f9babd0e4452b9 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.C
@@ -73,7 +73,8 @@ partialFaceAreaWeightAMI
         tgtPatch,
         triMode,
         reverseTarget,
-        requireMatch
+        requireMatch,
+        true // false // Not performing restart on low weights - valid for partial match
     )
 {}
 
@@ -88,93 +89,60 @@ bool Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::conformal() const
 
 
 template<class SourcePatch, class TargetPatch>
-void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
+bool Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
 (
     labelListList& srcAddress,
     scalarListList& srcWeights,
     pointListList& srcCentroids,
     labelListList& tgtAddress,
     scalarListList& tgtWeights,
+    scalarList& srcMagSf,
+    scalarList& tgtMagSf,
+    autoPtr<mapDistribute>& srcMapPtr,
+    autoPtr<mapDistribute>& tgtMapPtr,
     label srcFacei,
     label tgtFacei
 )
 {
-    bool ok =
-        this->initialise
+     bool ok =
+        faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
         (
             srcAddress,
             srcWeights,
+            srcCentroids,
             tgtAddress,
             tgtWeights,
+            srcMagSf,
+            tgtMagSf,
+            srcMapPtr,
+            tgtMapPtr,
             srcFacei,
             tgtFacei
         );
 
-    if (!ok)
+    if (ok)
     {
-        return;
+        if (this->distributed())
+        {
+            scalarList newTgtMagSf(std::move(tgtMagSf));
+
+            // Assign default sizes. Override selected values with
+            // calculated values. This is to support ACMI
+            // where some of the target faces are never used (so never get sent
+            // over and hence never assigned to)
+            tgtMagSf = this->tgtPatch0_.magFaceAreas();
+
+            for (const labelList& smap : this->extendedTgtMapPtr_->subMap())
+            {
+                UIndirectList<scalar>(tgtMagSf, smap) =
+                    UIndirectList<scalar>(newTgtMagSf, smap);
+            }
+        }
+
+        return true;
     }
 
-    srcCentroids.setSize(srcAddress.size());
-
-    // temporary storage for addressing and weights
-    List<DynamicList<label>> srcAddr(this->srcPatch_.size());
-    List<DynamicList<scalar>> srcWght(srcAddr.size());
-    List<DynamicList<point>> srcCtr(srcAddr.size());
-    List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
-    List<DynamicList<scalar>> tgtWght(tgtAddr.size());
-
-    faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing
-    (
-        srcAddr,
-        srcWght,
-        srcCtr,
-        tgtAddr,
-        tgtWght,
-        srcFacei,
-        tgtFacei
-    );
-
-    // transfer data to persistent storage
-    forAll(srcAddr, i)
-    {
-        srcAddress[i].transfer(srcAddr[i]);
-        srcWeights[i].transfer(srcWght[i]);
-        srcCentroids[i].transfer(srcCtr[i]);
-    }
-    forAll(tgtAddr, i)
-    {
-        tgtAddress[i].transfer(tgtAddr[i]);
-        tgtWeights[i].transfer(tgtWght[i]);
-    }
-}
-
-
-template<class SourcePatch, class TargetPatch>
-void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::setMagSf
-(
-    const TargetPatch& tgtPatch,
-    const mapDistribute& map,
-    scalarList& srcMagSf,
-    scalarList& tgtMagSf
-) const
-{
-    srcMagSf = std::move(this->srcMagSf_);
-
-    scalarList newTgtMagSf(std::move(this->tgtMagSf_));
-    map.reverseDistribute(tgtPatch.size(), newTgtMagSf);
-
-    // Assign default sizes. Override selected values with
-    // calculated values. This is to support ACMI
-    // where some of the target faces are never used (so never get sent
-    // over and hence never assigned to)
-    tgtMagSf = tgtPatch.magFaceAreas();
-
-    for (const labelList& smap : map.subMap())
-    {
-        UIndirectList<scalar>(tgtMagSf, smap) =
-            UIndirectList<scalar>(newTgtMagSf, smap);
-    }
+    return false;
 }
 
 
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.H
index 2d0255d6dcb4ca659736e23f0c6756dfda3e1891..ef46251bd6f00007c3d526158c20f875e4f895ff 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/partialFaceAreaWeightAMI/partialFaceAreaWeightAMI.H
@@ -117,25 +117,20 @@ public:
         // Manipulation
 
             //- Update addressing and weights
-            virtual void calculate
+            virtual bool calculate
             (
                 labelListList& srcAddress,
                 scalarListList& srcWeights,
                 pointListList& srcCentroids,
                 labelListList& tgtAddress,
                 scalarListList& tgtWeights,
+                scalarList& srcMagSf,
+                scalarList& tgtMagSf,
+                autoPtr<mapDistribute>& srcMapPtr,
+                autoPtr<mapDistribute>& tgtMapPtr,
                 label srcFacei = -1,
                 label tgtFacei = -1
             );
-
-            //- Set the face areas for parallel runs
-            virtual void setMagSf
-            (
-                const TargetPatch& tgtPatch,
-                const mapDistribute& map,
-                scalarList& srcMagSf,
-                scalarList& tgtMagSf
-            ) const;
 };