From 12fed65820324f4b14f7457b9d263de2ee4937fe Mon Sep 17 00:00:00 2001
From: andy <andy>
Date: Thu, 11 Apr 2013 14:55:35 +0100
Subject: [PATCH] ENH: Updated AMIInterpolation to use new AMIMethods

---
 .../AMIInterpolation/AMIInterpolation.C       | 874 ++----------------
 .../AMIInterpolation/AMIInterpolation.H       | 148 +--
 .../AMIInterpolation/AMIInterpolationI.H      |  10 +-
 .../AMIMethod/AMIMethod/AMIMethodNew.C        |   5 +-
 .../AMIMethod/directAMI/directAMI.C           |  18 +-
 .../faceAreaWeightAMI/faceAreaWeightAMI.C     |   2 +-
 .../faceAreaWeightAMI/faceAreaWeightAMI.H     |   2 +-
 .../AMIMethod/mapNearestAMI/mapNearestAMI.C   |   4 +-
 .../AMIPatchToPatchInterpolation.C            |  44 +
 src/meshTools/Make/files                      |   1 +
 10 files changed, 197 insertions(+), 911 deletions(-)
 create mode 100644 src/meshTools/AMIInterpolation/AMIInterpolation/AMIPatchToPatchInterpolation.C

diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
index f62ea404d9a..291e6a48167 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
@@ -24,128 +24,12 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "AMIInterpolation.H"
+#include "AMIMethod.H"
 #include "meshTools.H"
 #include "mapDistribute.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-template<class SourcePatch, class TargetPatch>
-void Foam::AMIInterpolation<SourcePatch, TargetPatch>::writeIntersectionOBJ
-(
-    const scalar area,
-    const face& f1,
-    const face& f2,
-    const pointField& f1Points,
-    const pointField& f2Points
-) const
-{
-    static label count = 1;
-
-    const pointField f1pts = f1.points(f1Points);
-    const pointField f2pts = f2.points(f2Points);
-
-    Pout<< "Face intersection area (" << count <<  "):" << nl
-        << "    f1 face = " << f1 << nl
-        << "    f1 pts  = " << f1pts << nl
-        << "    f2 face = " << f2 << nl
-        << "    f2 pts  = " << f2pts << nl
-        << "    area    = " << area
-        << endl;
-
-    OFstream os("areas" + name(count) + ".obj");
-
-    forAll(f1pts, i)
-    {
-        meshTools::writeOBJ(os, f1pts[i]);
-    }
-    os<< "l";
-    forAll(f1pts, i)
-    {
-        os<< " " << i + 1;
-    }
-    os<< " 1" << endl;
-
-
-    forAll(f2pts, i)
-    {
-        meshTools::writeOBJ(os, f2pts[i]);
-    }
-    os<< "l";
-    forAll(f2pts, i)
-    {
-        os<< " " << f1pts.size() + i + 1;
-    }
-    os<< " " << f1pts.size() + 1 << endl;
-
-    count++;
-}
-
-
-template<class SourcePatch, class TargetPatch>
-void Foam::AMIInterpolation<SourcePatch, TargetPatch>::checkPatches
-(
-    const SourcePatch& srcPatch,
-    const TargetPatch& tgtPatch
-) 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);
-
-    boundBox bbTgtInf(bbTgt);
-    bbTgtInf.inflate(maxBoundsError);
-
-    if (!bbTgtInf.contains(bbSrc))
-    {
-        WarningIn
-        (
-            "AMIInterpolation<SourcePatch, TargetPatch>::checkPatches"
-            "("
-                "const SourcePatch&, "
-                "const TargetPatch&"
-            ")"
-        )   << "Source and target patch bounding boxes are not similar" << nl
-            << "    source box span     : " << bbSrc.span() << nl
-            << "    target box span     : " << bbTgt.span() << nl
-            << "    source box          : " << bbSrc << nl
-            << "    target box          : " << bbTgt << nl
-            << "    inflated target box : " << bbTgtInf << endl;
-    }
-}
-
-
-template<class SourcePatch, class TargetPatch>
-void Foam::AMIInterpolation<SourcePatch, TargetPatch>::resetTree
-(
-    const TargetPatch& tgtPatch
-)
-{
-    // Clear the old octree
-    treePtr_.clear();
-
-
-    treeBoundBox bb(tgtPatch.points());
-    bb.inflate(0.01);
-
-    if (!treePtr_.valid())
-    {
-        treePtr_.reset
-        (
-            new indexedOctree<treeType>
-            (
-                treeType(false, tgtPatch),
-                bb,                         // overall search domain
-                8,                          // maxLevel
-                10,                         // leaf size
-                3.0                         // duplicity
-            )
-        );
-    }
-}
-
-
 template<class SourcePatch, class TargetPatch>
 void Foam::AMIInterpolation<SourcePatch, TargetPatch>::projectPointsToSurface
 (
@@ -182,7 +66,8 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::projectPointsToSurface
     {
         FatalErrorIn
         (
-            "void Foam::projectPointsToSurface"
+            "void Foam::AMIInterpolation<SourcePatch, TargetPatch>::"
+            "projectPointsToSurface"
             "("
                 "const searchableSurface&, "
                 "pointField&"
@@ -195,635 +80,6 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::projectPointsToSurface
 }
 
 
-template<class SourcePatch, class TargetPatch>
-Foam::label Foam::AMIInterpolation<SourcePatch, TargetPatch>::findTargetFace
-(
-    const label srcFaceI,
-    const SourcePatch& srcPatch
-) const
-{
-    label targetFaceI = -1;
-
-    const pointField& srcPts = srcPatch.points();
-    const face& srcFace = srcPatch[srcFaceI];
-    const point srcPt = srcFace.centre(srcPts);
-    const scalar srcFaceArea = srcMagSf_[srcFaceI];
-
-    pointIndexHit sample = treePtr_->findNearest(srcPt, 10.0*srcFaceArea);
-
-
-    if (debug)
-    {
-        Pout<< "Source point = " << srcPt << ", Sample point = "
-            << sample.hitPoint() << ", Sample index = " << sample.index()
-            << endl;
-    }
-
-    if (sample.hit())
-    {
-        targetFaceI = sample.index();
-    }
-
-    return targetFaceI;
-}
-
-
-template<class SourcePatch, class TargetPatch>
-void Foam::AMIInterpolation<SourcePatch, TargetPatch>::appendNbrFaces
-(
-    const label faceI,
-    const TargetPatch& patch,
-    const DynamicList<label>& visitedFaces,
-    DynamicList<label>& faceIDs
-) const
-{
-    const labelList& nbrFaces = patch.faceFaces()[faceI];
-
-    // filter out faces already visited from src face neighbours
-    forAll(nbrFaces, i)
-    {
-        label nbrFaceI = nbrFaces[i];
-        bool valid = true;
-        forAll(visitedFaces, j)
-        {
-            if (nbrFaceI == visitedFaces[j])
-            {
-                valid = false;
-                break;
-            }
-        }
-
-        if (valid)
-        {
-            forAll(faceIDs, j)
-            {
-                if (nbrFaceI == faceIDs[j])
-                {
-                    valid = false;
-                    break;
-                }
-            }
-        }
-
-        if (valid)
-        {
-            faceIDs.append(nbrFaceI);
-        }
-    }
-}
-
-
-template<class SourcePatch, class TargetPatch>
-bool Foam::AMIInterpolation<SourcePatch, TargetPatch>::processSourceFace
-(
-    const SourcePatch& srcPatch,
-    const TargetPatch& tgtPatch,
-    const label srcFaceI,
-    const label tgtStartFaceI,
-
-    // list of tgt face neighbour faces
-    DynamicList<label>& nbrFaces,
-    // list of faces currently visited for srcFaceI to avoid multiple hits
-    DynamicList<label>& visitedFaces,
-
-    // temporary storage for addressing and weights
-    List<DynamicList<label> >& srcAddr,
-    List<DynamicList<scalar> >& srcWght,
-    List<DynamicList<label> >& tgtAddr,
-    List<DynamicList<scalar> >& tgtWght
-)
-{
-    nbrFaces.clear();
-    visitedFaces.clear();
-
-    // append initial target face and neighbours
-    nbrFaces.append(tgtStartFaceI);
-    appendNbrFaces(tgtStartFaceI, tgtPatch, visitedFaces, nbrFaces);
-
-    bool faceProcessed = false;
-
-    do
-    {
-        // process new target face
-        label tgtFaceI = nbrFaces.remove();
-        visitedFaces.append(tgtFaceI);
-        scalar area = interArea(srcFaceI, tgtFaceI, srcPatch, tgtPatch);
-
-        // store when intersection area > 0
-        if (area > 0)
-        {
-            srcAddr[srcFaceI].append(tgtFaceI);
-            srcWght[srcFaceI].append(area);
-
-            tgtAddr[tgtFaceI].append(srcFaceI);
-            tgtWght[tgtFaceI].append(area);
-
-            appendNbrFaces(tgtFaceI, tgtPatch, visitedFaces, nbrFaces);
-
-            faceProcessed = true;
-        }
-
-    } while (nbrFaces.size() > 0);
-
-    return faceProcessed;
-}
-
-
-template<class SourcePatch, class TargetPatch>
-void Foam::AMIInterpolation<SourcePatch, TargetPatch>::setNextFaces
-(
-    label& startSeedI,
-    label& srcFaceI,
-    label& tgtFaceI,
-    const SourcePatch& srcPatch0,
-    const TargetPatch& tgtPatch0,
-    const boolList& mapFlag,
-    labelList& seedFaces,
-    const DynamicList<label>& visitedFaces
-) const
-{
-    const labelList& srcNbrFaces = srcPatch0.faceFaces()[srcFaceI];
-
-    // set possible seeds for later use
-    bool valuesSet = false;
-    forAll(srcNbrFaces, i)
-    {
-        label faceS = srcNbrFaces[i];
-
-        if (mapFlag[faceS] && seedFaces[faceS] == -1)
-        {
-            forAll(visitedFaces, j)
-            {
-                label faceT = visitedFaces[j];
-                scalar area = interArea(faceS, faceT, srcPatch0, tgtPatch0);
-
-                // Check that faces have enough overlap for robust walking
-                if (area/srcMagSf_[srcFaceI] > faceAreaIntersect::tolerance())
-                {
-                    // TODO - throwing area away - re-use in next iteration?
-
-                    seedFaces[faceS] = faceT;
-
-                    if (!valuesSet)
-                    {
-                        srcFaceI = faceS;
-                        tgtFaceI = faceT;
-                        valuesSet = true;
-                    }
-                }
-            }
-        }
-    }
-
-    // set next src and tgt faces if not set above
-    if (valuesSet)
-    {
-        return;
-    }
-    else
-    {
-        // try to use existing seed
-        bool foundNextSeed = false;
-        for (label faceI = startSeedI; faceI < mapFlag.size(); faceI++)
-        {
-            if (mapFlag[faceI])
-            {
-                if (!foundNextSeed)
-                {
-                    startSeedI = faceI;
-                    foundNextSeed = true;
-                }
-
-                if (seedFaces[faceI] != -1)
-                {
-                    srcFaceI = faceI;
-                    tgtFaceI = seedFaces[faceI];
-
-                    return;
-                }
-            }
-        }
-
-        // perform new search to find match
-        if (debug)
-        {
-            Pout<< "Advancing front stalled: searching for new "
-                << "target face" << endl;
-        }
-
-        foundNextSeed = false;
-        for (label faceI = startSeedI; faceI < mapFlag.size(); faceI++)
-        {
-            if (mapFlag[faceI])
-            {
-                if (!foundNextSeed)
-                {
-                    startSeedI = faceI + 1;
-                    foundNextSeed = true;
-                }
-
-                srcFaceI = faceI;
-                tgtFaceI = findTargetFace(srcFaceI, srcPatch0);
-
-                if (tgtFaceI >= 0)
-                {
-                    return;
-                }
-            }
-        }
-
-        FatalErrorIn
-        (
-            "void Foam::AMIInterpolation<SourcePatch, TargetPatch>::"
-            "setNextFaces"
-            "("
-                "label&, "
-                "label&, "
-                "label&, "
-                "const SourcePatch&, "
-                "const TargetPatch&, "
-                "const boolList&, "
-                "labelList&, "
-                "const DynamicList<label>&"
-            ") const"
-        )  << "Unable to set source and target faces" << abort(FatalError);
-    }
-}
-
-
-template<class SourcePatch, class TargetPatch>
-Foam::scalar Foam::AMIInterpolation<SourcePatch, TargetPatch>::interArea
-(
-    const label srcFaceI,
-    const label tgtFaceI,
-    const SourcePatch& srcPatch,
-    const TargetPatch& tgtPatch
-) const
-{
-    const pointField& srcPoints = srcPatch.points();
-    const pointField& tgtPoints = tgtPatch.points();
-
-    // references to candidate faces
-    const face& src = srcPatch[srcFaceI];
-    const face& tgt = tgtPatch[tgtFaceI];
-
-    // quick reject if either face has zero area
-    // Note: do not used stored face areas for target patch
-    if ((srcMagSf_[srcFaceI] < ROOTVSMALL) || (tgt.mag(tgtPoints) < ROOTVSMALL))
-    {
-        return 0.0;
-    }
-
-    // create intersection object
-    faceAreaIntersect inter(srcPoints, tgtPoints, reverseTarget_);
-
-    // crude resultant norm
-    vector n(-src.normal(srcPoints));
-    if (reverseTarget_)
-    {
-        n -= tgt.normal(tgtPoints);
-    }
-    else
-    {
-        n += tgt.normal(tgtPoints);
-    }
-    n *= 0.5;
-
-    scalar area = 0;
-    if (mag(n) > ROOTVSMALL)
-    {
-        area = inter.calc(src, tgt, n, triMode_);
-    }
-    else
-    {
-        WarningIn
-        (
-            "void Foam::AMIInterpolation<SourcePatch, TargetPatch>::"
-            "interArea"
-            "("
-                "const label, "
-                "const label, "
-                "const SourcePatch&, "
-                "const TargetPatch&"
-            ") const"
-        )   << "Invalid normal for source face " << srcFaceI
-            << " points " << UIndirectList<point>(srcPoints, src)
-            << " target face " << tgtFaceI
-            << " points " << UIndirectList<point>(tgtPoints, tgt)
-            << endl;
-    }
-
-
-    if ((debug > 1) && (area > 0))
-    {
-        writeIntersectionOBJ(area, src, tgt, srcPoints, tgtPoints);
-    }
-
-    return area;
-}
-
-
-template<class SourcePatch, class TargetPatch>
-void Foam::AMIInterpolation<SourcePatch, TargetPatch>::
-restartUncoveredSourceFace
-(
-    const SourcePatch& srcPatch,
-    const TargetPatch& tgtPatch,
-    List<DynamicList<label> >& srcAddr,
-    List<DynamicList<scalar> >& srcWght,
-    List<DynamicList<label> >& tgtAddr,
-    List<DynamicList<scalar> >& tgtWght
-)
-{
-    // Collect all src faces with a low weight
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-    labelHashSet lowWeightFaces(100);
-    forAll(srcWght, srcFaceI)
-    {
-        scalar s = sum(srcWght[srcFaceI]);
-        scalar t = s/srcMagSf_[srcFaceI];
-
-        if (t < 0.5)
-        {
-            lowWeightFaces.insert(srcFaceI);
-        }
-    }
-
-    if (debug)
-    {
-        Pout<< "AMIInterpolation: restarting search on "
-            << lowWeightFaces.size() << " faces since sum of weights < 0.5"
-            << endl;
-    }
-
-    if (lowWeightFaces.size() > 0)
-    {
-        // Erase all the lowWeight source faces from the target
-        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-        DynamicList<label> okSrcFaces(10);
-        DynamicList<scalar> okSrcWeights(10);
-        forAll(tgtAddr, tgtFaceI)
-        {
-            okSrcFaces.clear();
-            okSrcWeights.clear();
-            DynamicList<label>& srcFaces = tgtAddr[tgtFaceI];
-            DynamicList<scalar>& srcWeights = tgtWght[tgtFaceI];
-            forAll(srcFaces, i)
-            {
-                if (!lowWeightFaces.found(srcFaces[i]))
-                {
-                    okSrcFaces.append(srcFaces[i]);
-                    okSrcWeights.append(srcWeights[i]);
-                }
-            }
-            if (okSrcFaces.size() < srcFaces.size())
-            {
-                srcFaces.transfer(okSrcFaces);
-                srcWeights.transfer(okSrcWeights);
-            }
-        }
-
-
-
-        // Restart search from best hit
-        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-        // list of tgt face neighbour faces
-        DynamicList<label> nbrFaces(10);
-
-        // list of faces currently visited for srcFaceI to avoid multiple hits
-        DynamicList<label> visitedFaces(10);
-
-        forAllConstIter(labelHashSet, lowWeightFaces, iter)
-        {
-            label srcFaceI = iter.key();
-            label tgtFaceI = findTargetFace(srcFaceI, srcPatch);
-            if (tgtFaceI != -1)
-            {
-                //bool faceProcessed =
-                processSourceFace
-                (
-                    srcPatch,
-                    tgtPatch,
-                    srcFaceI,
-                    tgtFaceI,
-
-                    nbrFaces,
-                    visitedFaces,
-
-                    srcAddr,
-                    srcWght,
-                    tgtAddr,
-                    tgtWght
-                );
-                // ? Check faceProcessed to see if restarting has worked.
-            }
-        }
-    }
-}
-
-
-template<class SourcePatch, class TargetPatch>
-void Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcAddressing
-(
-    const SourcePatch& srcPatch,
-    const TargetPatch& tgtPatch,
-    label srcFaceI,
-    label tgtFaceI
-)
-{
-    // Pre-size to handle early exit
-    srcAddress_.setSize(srcPatch.size());
-    srcWeights_.setSize(srcPatch.size());
-    tgtAddress_.setSize(tgtPatch.size());
-    tgtWeights_.setSize(tgtPatch.size());
-
-
-    if (debug && (!srcPatch.size() || !tgtPatch.size()))
-    {
-        Pout<< "AMI: Patches not on processor: Source faces = "
-            << srcPatch.size() << ", target faces = " << tgtPatch.size()
-            << endl;
-    }
-
-    if (!srcPatch.size())
-    {
-        return;
-    }
-    else if (!tgtPatch.size())
-    {
-        WarningIn
-        (
-            "void Foam::AMIInterpolation<SourcePatch, TargetPatch>::"
-            "calcAddressing"
-            "("
-                "const SourcePatch&, "
-                "const TargetPatch&, "
-                "label, "
-                "label"
-            ")"
-        ) << "Have " << srcPatch.size() << " source faces but no target faces."
-          << endl;
-
-        return;
-    }
-
-    resetTree(tgtPatch);
-
-    // temporary storage for addressing and weights
-    List<DynamicList<label> > srcAddr(srcPatch.size());
-    List<DynamicList<scalar> > srcWght(srcPatch.size());
-    List<DynamicList<label> > tgtAddr(tgtPatch.size());
-    List<DynamicList<scalar> > tgtWght(tgtPatch.size());
-
-
-    // find initial face match using brute force/octree search
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    if ((srcFaceI == -1) || (tgtFaceI == -1))
-    {
-        srcFaceI = 0;
-        tgtFaceI = 0;
-        bool foundFace = false;
-        forAll(srcPatch, faceI)
-        {
-            tgtFaceI = findTargetFace(faceI, srcPatch);
-            if (tgtFaceI >= 0)
-            {
-                srcFaceI = faceI;
-                foundFace = true;
-                break;
-            }
-        }
-
-        if (!foundFace)
-        {
-            FatalErrorIn
-            (
-                "void Foam::AMIInterpolation<SourcePatch, TargetPatch>::"
-                "calcAddressing"
-                "("
-                    "const SourcePatch&, "
-                    "const TargetPatch&, "
-                    "label, "
-                    "label"
-                ")"
-            )   << "Unable to find initial target face" << abort(FatalError);
-        }
-    }
-
-    if (debug)
-    {
-        Pout<< "AMI: initial target face = " << tgtFaceI << endl;
-    }
-
-
-    // construct weights and addressing
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    label nFacesRemaining = srcPatch.size();
-
-    // list of tgt face neighbour faces
-    DynamicList<label> nbrFaces(10);
-
-    // list of faces currently visited for srcFaceI to avoid multiple hits
-    DynamicList<label> visitedFaces(10);
-
-    // list to keep track of tgt faces used to seed src faces
-    labelList seedFaces(nFacesRemaining, -1);
-    seedFaces[srcFaceI] = tgtFaceI;
-
-    // list to keep track of whether src face can be mapped
-    boolList mapFlag(nFacesRemaining, true);
-
-    // reset starting seed
-    label startSeedI = 0;
-
-    DynamicList<label> nonOverlapFaces;
-    do
-    {
-        // Do advancing front starting from srcFaceI,tgtFaceI
-        bool faceProcessed = processSourceFace
-        (
-            srcPatch,
-            tgtPatch,
-            srcFaceI,
-            tgtFaceI,
-
-            nbrFaces,
-            visitedFaces,
-
-            srcAddr,
-            srcWght,
-            tgtAddr,
-            tgtWght
-        );
-
-        mapFlag[srcFaceI] = false;
-
-        nFacesRemaining--;
-
-        if (!faceProcessed)
-        {
-            nonOverlapFaces.append(srcFaceI);
-        }
-
-        // choose new src face from current src face neighbour
-        if (nFacesRemaining > 0)
-        {
-            setNextFaces
-            (
-                startSeedI,
-                srcFaceI,
-                tgtFaceI,
-                srcPatch,
-                tgtPatch,
-                mapFlag,
-                seedFaces,
-                visitedFaces
-            );
-        }
-    } while (nFacesRemaining > 0);
-
-    if (nonOverlapFaces.size() != 0)
-    {
-        Pout<< "AMI: " << nonOverlapFaces.size()
-            << " non-overlap faces identified"
-            << endl;
-
-        srcNonOverlap_.transfer(nonOverlapFaces);
-    }
-
-
-    // Check for badly covered faces
-    if (debug)
-    {
-        restartUncoveredSourceFace
-        (
-            srcPatch,
-            tgtPatch,
-            srcAddr,
-            srcWght,
-            tgtAddr,
-            tgtWght
-        );
-    }
-
-
-    // transfer data to persistent storage
-    forAll(srcAddr, i)
-    {
-        srcAddress_[i].transfer(srcAddr[i]);
-        srcWeights_[i].transfer(srcWght[i]);
-    }
-    forAll(tgtAddr, i)
-    {
-        tgtAddress_[i].transfer(tgtAddr[i]);
-        tgtWeights_[i].transfer(tgtWght[i]);
-    }
-}
-
-
 template<class SourcePatch, class TargetPatch>
 void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
 (
@@ -1136,30 +392,23 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
     const SourcePatch& srcPatch,
     const TargetPatch& tgtPatch,
     const faceAreaIntersect::triangulationMode& triMode,
+    const interpolationMethod& method,
     const bool reverseTarget
 )
 :
+    method_(method),
     reverseTarget_(reverseTarget),
     singlePatchProc_(-999),
     srcAddress_(),
     srcWeights_(),
     srcWeightsSum_(),
-    srcNonOverlap_(),
     tgtAddress_(),
     tgtWeights_(),
     tgtWeightsSum_(),
-    treePtr_(NULL),
     triMode_(triMode),
     srcMapPtr_(NULL),
     tgtMapPtr_(NULL)
 {
-    label srcSize = returnReduce(srcPatch.size(), sumOp<label>());
-    label tgtSize = returnReduce(tgtPatch.size(), sumOp<label>());
-
-    IInfo<< "AMI: Creating addressing and weights between "
-        << srcSize << " source faces and " << tgtSize << " target faces"
-        << endl;
-
     update(srcPatch, tgtPatch);
 }
 
@@ -1171,30 +420,23 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
     const TargetPatch& tgtPatch,
     const autoPtr<searchableSurface>& surfPtr,
     const faceAreaIntersect::triangulationMode& triMode,
+    const interpolationMethod& method,
     const bool reverseTarget
 )
 :
+    method_(method),
     reverseTarget_(reverseTarget),
     singlePatchProc_(-999),
     srcAddress_(),
     srcWeights_(),
     srcWeightsSum_(),
-    srcNonOverlap_(),
     tgtAddress_(),
     tgtWeights_(),
     tgtWeightsSum_(),
-    treePtr_(NULL),
     triMode_(triMode),
     srcMapPtr_(NULL),
     tgtMapPtr_(NULL)
 {
-    label srcSize = returnReduce(srcPatch.size(), sumOp<label>());
-    label tgtSize = returnReduce(tgtPatch.size(), sumOp<label>());
-
-    IInfo<< "AMI: Creating addressing and weights between "
-        << srcSize << " source faces and " << tgtSize << " target faces"
-        << endl;
-
     if (surfPtr.valid())
     {
         // create new patches for source and target
@@ -1264,16 +506,15 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
     const labelList& targetRestrictAddressing
 )
 :
+    method_(fineAMI.method_),
     reverseTarget_(fineAMI.reverseTarget_),
     singlePatchProc_(fineAMI.singlePatchProc_),
     srcAddress_(),
     srcWeights_(),
     srcWeightsSum_(),
-    srcNonOverlap_(),
     tgtAddress_(),
     tgtWeights_(),
     tgtWeightsSum_(),
-    treePtr_(NULL),
     triMode_(fineAMI.triMode_),
     srcMapPtr_(NULL),
     tgtMapPtr_(NULL)
@@ -1392,6 +633,52 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::~AMIInterpolation()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+template<class SourcePatch, class TargetPatch>
+Foam::word
+Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolationMethodToWord
+(
+    const interpolationMethod& im
+) const
+{
+    word method = "unknown-interpolationMethod";
+
+    switch (im)
+    {
+        case imDirect:
+        {
+            method = "directAMI";
+            break;
+        }
+        case imMapNearest:
+        {
+            method = "mapNearestAMI";
+            break;
+        }
+        case imFaceAreaWeight:
+        {
+            method = "faceAreaWeightAMI";
+            break;
+        }
+        default:
+        {
+            FatalErrorIn
+            (
+                "const Foam::word"
+                "Foam::AMIInterpolation<SourcePatch, TargetPatch>::"
+                "interpolationMethodToWord"
+                "("
+                    "const interpolationMethod&"
+                ") const"
+            )
+                << "Unhandled interpolationMethod enumeration " << method
+                << abort(FatalError);
+        }
+    }
+
+    return method;
+}
+
+
 template<class SourcePatch, class TargetPatch>
 void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
 (
@@ -1456,11 +743,32 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
                 newTgtPoints
             );
 
-        checkPatches(srcPatch, newTgtPatch);
-
 
         // calculate AMI interpolation
-        calcAddressing(srcPatch, newTgtPatch);
+        {
+            autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr
+            (
+                AMIMethod<SourcePatch, TargetPatch>::New
+                (
+                    interpolationMethodToWord(method_),
+                    srcPatch,
+                    newTgtPatch,
+                    srcMagSf_,
+                    tgtMagSf_,
+                    triMode_,
+                    reverseTarget_
+                )
+            );
+
+            AMIPtr->calculate
+            (
+                srcAddress_,
+                srcWeights_,
+                tgtAddress_,
+                tgtWeights_
+            );
+        }
+
 
         // Now
         // ~~~
@@ -1552,9 +860,31 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
     }
     else
     {
-        checkPatches(srcPatch, tgtPatch);
 
-        calcAddressing(srcPatch, tgtPatch);
+        // calculate AMI interpolation
+        {
+            autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr
+            (
+                AMIMethod<SourcePatch, TargetPatch>::New
+                (
+                    interpolationMethodToWord(method_),
+                    srcPatch,
+                    tgtPatch,
+                    srcMagSf_,
+                    tgtMagSf_,
+                    triMode_,
+                    reverseTarget_
+                )
+            );
+
+            AMIPtr->calculate
+            (
+                srcAddress_,
+                srcWeights_,
+                tgtAddress_,
+                tgtWeights_
+            );
+        }
 
         normaliseWeights
         (
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
index 9f94fa41169..886b23fd783 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
@@ -50,14 +50,11 @@ SourceFiles
 #define AMIInterpolation_H
 
 #include "className.H"
-#include "DynamicList.H"
 #include "searchableSurface.H"
+#include "treeBoundBoxList.H"
 #include "boolList.H"
 #include "primitivePatch.H"
 #include "faceAreaIntersect.H"
-#include "indexedOctree.H"
-#include "treeDataPrimitivePatch.H"
-#include "treeBoundBoxList.H"
 #include "globalIndex.H"
 #include "ops.H"
 
@@ -82,12 +79,26 @@ class AMIInterpolation
 :
     public AMIInterpolationName
 {
-    //- local typedef to octree tree-type
-    typedef treeDataPrimitivePatch<TargetPatch> treeType;
+public:
+
+    // Public data types
 
+        //- Enumeration specifying interpolation method
+        enum interpolationMethod
+        {
+            imDirect,
+            imMapNearest,
+            imFaceAreaWeight
+        };
+
+
+private:
 
     // Private data
 
+        //- Interpolation method
+        interpolationMethod method_;
+
         //- Flag to indicate that the two patches are co-directional and
         //  that the orientation of the target patch should be reversed
         const bool reverseTarget_;
@@ -96,6 +107,7 @@ class AMIInterpolation
         //  cases
         label singlePatchProc_;
 
+
         // Source patch
 
             //- Source face areas
@@ -110,10 +122,6 @@ class AMIInterpolation
             //- Sum of weights of target faces per source face
             scalarField srcWeightsSum_;
 
-            //- Labels of faces that are not overlapped by any target faces
-            //  (should be empty for correct functioning)
-            labelList srcNonOverlap_;
-
 
         // Target patch
 
@@ -130,9 +138,6 @@ class AMIInterpolation
             scalarField tgtWeightsSum_;
 
 
-        //- Octree used to find face seeds
-        autoPtr<indexedOctree<treeType> > treePtr_;
-
         //- Face triangulation mode
         const faceAreaIntersect::triangulationMode triMode_;
 
@@ -152,30 +157,6 @@ class AMIInterpolation
         void operator=(const AMIInterpolation&);
 
 
-        // Helper functions
-
-            //- Write triangle intersection to OBJ file
-            void writeIntersectionOBJ
-            (
-                const scalar area,
-                const face& f1,
-                const face& f2,
-                const pointField& f1Points,
-                const pointField& f2Points
-            ) const;
-
-            //- Check that patches are valid
-            void checkPatches
-            (
-                const SourcePatch& srcPatch,
-                const TargetPatch& tgtPatch
-            ) const;
-
-            //- Reset the octree for the traget patch face search
-            void resetTree(const TargetPatch& tgtPatch);
-
-
-
         // Parallel functionality
 
             //- Calculate if patches are on multiple processors
@@ -229,83 +210,8 @@ class AMIInterpolation
             ) const;
 
 
-        // Marching front
-
-            //- Find face on target patch that overlaps source face
-            label findTargetFace
-            (
-                const label srcFaceI,
-                const SourcePatch& srcPatch
-            ) const;
-
-            //- Add faces neighbouring faceI to the ID list
-            void appendNbrFaces
-            (
-                const label faceI,
-                const TargetPatch& patch,
-                const DynamicList<label>& visitedFaces,
-                DynamicList<label>& faceIDs
-            ) const;
-
-            bool processSourceFace
-            (
-                const SourcePatch& srcPatch,
-                const TargetPatch& tgtPatch,
-                const label srcFaceI,
-                const label tgtStartFaceI,
-
-                DynamicList<label>& nbrFaces,
-                DynamicList<label>& visitedFaces,
-                List<DynamicList<label> >& srcAddr,
-                List<DynamicList<scalar> >& srcWght,
-                List<DynamicList<label> >& tgtAddr,
-                List<DynamicList<scalar> >& tgtWght
-            );
-
-            void restartUncoveredSourceFace
-            (
-                const SourcePatch& srcPatch,
-                const TargetPatch& tgtPatch,
-                List<DynamicList<label> >& srcAddr,
-                List<DynamicList<scalar> >& srcWght,
-                List<DynamicList<label> >& tgtAddr,
-                List<DynamicList<scalar> >& tgtWght
-            );
-
-            //- Set the source and target seed faces
-            void setNextFaces
-            (
-                label& startSeedI,
-                label& srcFaceI,
-                label& tgtFaceI,
-                const SourcePatch& srcPatch0,
-                const TargetPatch& tgtPatch0,
-                const boolList& mapFlag,
-                labelList& seedFaces,
-                const DynamicList<label>& visitedFaces
-            ) const;
-
-
         // Evaluation
 
-            //- Area of intersection between source and target faces
-            scalar interArea
-            (
-                const label srcFaceI,
-                const label tgtFaceI,
-                const SourcePatch& srcPatch,
-                const TargetPatch& tgtPatch
-            ) const;
-
-            //- Calculate addressing
-            void calcAddressing
-            (
-                const SourcePatch& srcPatch,
-                const TargetPatch& tgtPatch,
-                label srcFaceI = -1,
-                label tgtFaceI = -1
-            );
-
             //- Normalise the (area) weights - suppresses numerical error in
             //  weights calculation
             //  NOTE: if area weights are incorrect by 'a significant amount'
@@ -352,6 +258,7 @@ public:
             const SourcePatch& srcPatch,
             const TargetPatch& tgtPatch,
             const faceAreaIntersect::triangulationMode& triMode,
+            const interpolationMethod& method = imFaceAreaWeight,
             const bool reverseTarget = false
         );
 
@@ -362,6 +269,7 @@ public:
             const TargetPatch& tgtPatch,
             const autoPtr<searchableSurface>& surf,
             const faceAreaIntersect::triangulationMode& triMode,
+            const interpolationMethod& method = imFaceAreaWeight,
             const bool reverseTarget = false
         );
 
@@ -378,6 +286,12 @@ public:
     //- Destructor
     ~AMIInterpolation();
 
+    // Typedef to SourcePatch type this AMIInterplation is instantiated on
+    typedef SourcePatch sourcePatchType;
+
+    // Typedef to TargetPatch type this AMIInterplation is instantiated on
+    typedef TargetPatch targetPatchType;
+
 
     // Member Functions
 
@@ -387,6 +301,12 @@ public:
             //  the AMI
             label singlePatchProc() const;
 
+            //- Convert interpolationMethod to word representation
+            word interpolationMethodToWord
+            (
+                const interpolationMethod& method
+            ) const;
+
 
             // Source patch
 
@@ -403,10 +323,6 @@ public:
                 //  patch weights (i.e. the sum before normalisation)
                 inline const scalarField& srcWeightsSum() const;
 
-                //- Labels of faces that are not overlapped by any target faces
-                //  (should be empty for correct functioning)
-                inline const labelList& srcNonOverlap() const;
-
                 //- Source map pointer - valid only if singlePatchProc = -1
                 //  This gets source data into a form to be consumed by
                 //  tgtAddress, tgtWeights
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H
index f2782bad886..84291ce326c 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -55,14 +55,6 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeights() const
 }
 
 
-template<class SourcePatch, class TargetPatch>
-inline const Foam::labelList&
-Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcNonOverlap() const
-{
-    return srcNonOverlap_;
-}
-
-
 template<class SourcePatch, class TargetPatch>
 inline const Foam::scalarField&
 Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeightsSum() const
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodNew.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodNew.C
index f2ba968316d..83289d2d8b3 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodNew.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodNew.C
@@ -36,7 +36,10 @@ Foam::AMIMethod<SourcePatch, TargetPatch>::New
     const bool reverseTarget
 )
 {
-    Info<< "Selecting AMIMethod " << methodName << endl;
+    if (debug)
+    {
+        Info<< "Selecting AMIMethod " << methodName << endl;
+    }
 
     typename componentsConstructorTable::iterator cstrIter =
         componentsConstructorTablePtr_->find(methodName);
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.C
index 9a47f132878..fa5d0b73e12 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.C
@@ -72,13 +72,13 @@ void Foam::directAMI<SourcePatch, TargetPatch>::appendToDirectSeeds
 
                     break;
                 }
+            }
 
-                if (!found)
-                {
-                    // no match available for source face srcI
-                    mapFlag[srcI] = false;
-                    nonOverlapFaces.append(srcI);
-                }
+            if (!found)
+            {
+                // no match available for source face srcI
+                mapFlag[srcI] = false;
+                nonOverlapFaces.append(srcI);
             }
         }
     }
@@ -198,7 +198,7 @@ void Foam::directAMI<SourcePatch, TargetPatch>::calculate
 
     if (nonOverlapFaces.size() != 0)
     {
-        Pout<< "AMI: " << nonOverlapFaces.size()
+        Pout<< "    AMI: " << nonOverlapFaces.size()
             << " non-overlap faces identified"
             << endl;
 
@@ -210,13 +210,13 @@ void Foam::directAMI<SourcePatch, TargetPatch>::calculate
     {
         scalar magSf = this->srcMagSf_[i];
         srcAddress[i].transfer(srcAddr[i]);
-        srcWeights[i] = scalarList(srcAddr[i].size(), magSf);
+        srcWeights[i] = scalarList(1, magSf);
     }
     forAll(tgtAddr, i)
     {
         scalar magSf = this->tgtMagSf_[i];
         tgtAddress[i].transfer(tgtAddr[i]);
-        tgtWeights[i] = scalarList(tgtAddr[i].size(), magSf);
+        tgtWeights[i] = scalarList(1, magSf);
     }
 }
 
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C
index 0356b52c0e6..6aea34e9458 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C
@@ -515,7 +515,7 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
 
     if (nonOverlapFaces.size() != 0)
     {
-        Pout<< "AMI: " << nonOverlapFaces.size()
+        Pout<< "    AMI: " << nonOverlapFaces.size()
             << " non-overlap faces identified"
             << endl;
 
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H
index 0d76fe4d1bb..82061d2727a 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H
@@ -111,7 +111,7 @@ private:
 public:
 
     //- Runtime type information
-    TypeName("faceAreaWeight");
+    TypeName("faceAreaWeightAMI");
 
 
     // Constructors
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.C
index 39e059273d1..61ed01727e2 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.C
@@ -329,13 +329,13 @@ void Foam::mapNearestAMI<SourcePatch, TargetPatch>::calculate
     {
         scalar magSf = this->srcMagSf_[i];
         srcAddress[i].transfer(srcAddr[i]);
-        srcWeights[i] = scalarList(srcAddr[i].size(), magSf);
+        srcWeights[i] = scalarList(1, magSf);
     }
     forAll(tgtAddr, i)
     {
         scalar magSf = this->tgtMagSf_[i];
         tgtAddress[i].transfer(tgtAddr[i]);
-        tgtWeights[i] = scalarList(tgtAddr[i].size(), magSf);
+        tgtWeights[i] = scalarList(1, magSf);
     }
 }
 
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIPatchToPatchInterpolation.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIPatchToPatchInterpolation.C
new file mode 100644
index 00000000000..6cb5678aafd
--- /dev/null
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIPatchToPatchInterpolation.C
@@ -0,0 +1,44 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "AMIPatchToPatchInterpolation.H"
+#include "AMIMethod.H"
+#include "directAMI.H"
+#include "mapNearestAMI.H"
+#include "faceAreaWeightAMI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    makeAMIMethod(AMIPatchToPatchInterpolation);
+
+    makeAMIMethodType(AMIPatchToPatchInterpolation, directAMI);
+    makeAMIMethodType(AMIPatchToPatchInterpolation, mapNearestAMI);
+    makeAMIMethodType(AMIPatchToPatchInterpolation, faceAreaWeightAMI);
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files
index d46d774d887..f11e6fc4712 100644
--- a/src/meshTools/Make/files
+++ b/src/meshTools/Make/files
@@ -170,6 +170,7 @@ twoDPointCorrector/twoDPointCorrector.C
 
 AMI=AMIInterpolation
 $(AMI)/AMIInterpolation/AMIInterpolationName.C
+$(AMI)/AMIInterpolation/AMIPatchToPatchInterpolation.C
 $(AMI)/faceAreaIntersect/faceAreaIntersect.C
 $(AMI)/GAMG/interfaces/cyclicAMIGAMGInterface/cyclicAMIGAMGInterface.C
 $(AMI)/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C
-- 
GitLab