diff --git a/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.C b/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.C
index 3bcd500d04cdab78995873cd180db3b7d9508448..e1328495980191aa44fba0f6512325245659d686 100644
--- a/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.C
+++ b/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.C
@@ -34,15 +34,16 @@ const Foam::label Foam::globalIndexAndTransform::base_ = 32;
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-bool Foam::globalIndexAndTransform::matchTransform
+Foam::label Foam::globalIndexAndTransform::matchTransform
 (
     const List<vectorTensorTransform>& refTransforms,
+    label& matchedRefTransformI,
     const vectorTensorTransform& testTransform,
     scalar tolerance,
-    bool bothSigns
+    bool checkBothSigns
 ) const
 {
-    // return min(mag(transforms_ - sepVec)) > tol
+    matchedRefTransformI = -1;
 
     forAll(refTransforms, i)
     {
@@ -82,10 +83,12 @@ bool Foam::globalIndexAndTransform::matchTransform
 
         if (vectorDiff < 1 && tensorDiff < 1)
         {
-            return true;
+            matchedRefTransformI = i;
+
+            return +1;
         }
 
-        if (bothSigns)
+        if (checkBothSigns)
         {
             // Test the inverse transform differences too
 
@@ -106,12 +109,14 @@ bool Foam::globalIndexAndTransform::matchTransform
 
             if (vectorDiff < 1 && tensorDiff < 1)
             {
-                return true;
+                matchedRefTransformI = i;
+
+                return -1;
             }
         }
     }
 
-    return false;
+    return 0;
 }
 
 
@@ -123,6 +128,8 @@ void Foam::globalIndexAndTransform::determineTransforms()
 
     label nextTrans = 0;
 
+    label dummyMatch = -1;
+
     forAll(patches, patchI)
     {
         const polyPatch& pp = patches[patchI];
@@ -145,7 +152,17 @@ void Foam::globalIndexAndTransform::determineTransforms()
 
                         vectorTensorTransform transform(sepVec);
 
-                        if (!matchTransform(transforms_, transform, tol, false))
+                        if
+                        (
+                            matchTransform
+                            (
+                                transforms_,
+                                dummyMatch,
+                                transform,
+                                tol,
+                                false
+                            ) == 0
+                        )
                         {
                             transforms_[nextTrans++] = transform;
                         }
@@ -166,7 +183,7 @@ void Foam::globalIndexAndTransform::determineTransforms()
             }
             else if (!cpp.parallel())
             {
-                const tensorField& transTensors = cpp.forwardT();
+                const tensorField& transTensors = cpp.reverseT();
 
                 forAll(transTensors, tTI)
                 {
@@ -178,7 +195,17 @@ void Foam::globalIndexAndTransform::determineTransforms()
 
                         vectorTensorTransform transform(transT);
 
-                        if (!matchTransform(transforms_, transform, tol, false))
+                        if
+                        (
+                            matchTransform
+                            (
+                                transforms_,
+                                dummyMatch,
+                                transform,
+                                tol,
+                                false
+                            ) == 0
+                        )
                         {
                             transforms_[nextTrans++] = transform;
                         }
@@ -225,7 +252,17 @@ void Foam::globalIndexAndTransform::determineTransforms()
                 {
                     scalar tol = coupledPolyPatch::matchTol;
 
-                    if (!matchTransform(transforms_, transform, tol, true))
+                    if
+                    (
+                        matchTransform
+                        (
+                            transforms_,
+                            dummyMatch,
+                            transform,
+                            tol,
+                            true
+                        ) ==  0
+                    )
                     {
                         transforms_[nextTrans++] = transform;
                     }
@@ -290,6 +327,123 @@ void Foam::globalIndexAndTransform::determineTransformPermutations()
 }
 
 
+void Foam::globalIndexAndTransform::determinePatchTransformSign()
+{
+    const polyBoundaryMesh& patches = mesh_.boundaryMesh();
+
+    patchTransformSign_.setSize(patches.size(), Pair<label>(-1, 0));
+
+    label matchTransI = -1;
+
+    forAll(patches, patchI)
+    {
+        const polyPatch& pp = patches[patchI];
+
+        // Pout<< nl << patchI << " " << pp.name() << endl;
+
+        if (isA<coupledPolyPatch>(pp))
+        {
+            const coupledPolyPatch& cpp =
+            refCast<const coupledPolyPatch>(pp);
+
+            if (cpp.separated())
+            {
+                const vectorField& sepVecs = cpp.separation();
+
+                // Pout<< "sepVecs " << sepVecs << endl;
+
+                // This loop is implicitly expecting only a single
+                // value for separation()
+                forAll(sepVecs, sVI)
+                {
+                    const vector& sepVec = sepVecs[sVI];
+
+                    if (mag(sepVec) > SMALL)
+                    {
+                        scalar tol = coupledPolyPatch::matchTol;
+
+                        vectorTensorTransform t(sepVec);
+
+                        label sign = matchTransform
+                        (
+                            transforms_,
+                            matchTransI,
+                            t,
+                            tol,
+                            true
+                        );
+
+                        // Pout<< sign << " " << matchTransI << endl;
+
+                        // List<label> permutation(transforms_.size(), 0);
+
+                        // permutation[matchTransI] = sign;
+
+                        // Pout<< encodeTransformIndex(permutation) << nl
+                        //     << transformPermutations_
+                        //        [
+                        //            encodeTransformIndex(permutation)
+                        //        ]
+                        //     << endl;
+
+                        patchTransformSign_[patchI] =
+                            Pair<label>(matchTransI, sign);
+                    }
+                }
+
+            }
+            else if (!cpp.parallel())
+            {
+                const tensorField& transTensors = cpp.reverseT();
+
+                // Pout<< "transTensors " << transTensors << endl;
+
+                // This loop is implicitly expecting only a single
+                // value for reverseT()
+                forAll(transTensors, tTI)
+                {
+                    const tensor& transT = transTensors[tTI];
+
+                    if (mag(transT - I) > SMALL)
+                    {
+                        scalar tol = coupledPolyPatch::matchTol;
+
+                        vectorTensorTransform t(transT);
+
+                        label sign = matchTransform
+                        (
+                            transforms_,
+                            matchTransI,
+                            t,
+                            tol,
+                            true
+                        );
+
+                        // Pout<< sign << " " << matchTransI << endl;
+
+                        // List<label> permutation(transforms_.size(), 0);
+
+                        // permutation[matchTransI] = sign;
+
+                        // Pout<< encodeTransformIndex(permutation) << nl
+                        //     << transformPermutations_
+                        //        [
+                        //            encodeTransformIndex(permutation)
+                        //        ]
+                        //     << endl;
+
+                        patchTransformSign_[patchI] =
+                            Pair<label>(matchTransI, sign);
+                    }
+                }
+            }
+        }
+    }
+
+    // Pout<< patchTransformSign_ << endl;
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::globalIndexAndTransform::globalIndexAndTransform
@@ -297,11 +451,16 @@ Foam::globalIndexAndTransform::globalIndexAndTransform
     const polyMesh& mesh
 )
 :
-    mesh_(mesh)
+    mesh_(mesh),
+    transforms_(),
+    transformPermutations_(),
+    patchTransformSign_()
 {
     determineTransforms();
 
     determineTransformPermutations();
+
+    determinePatchTransformSign();
 }
 
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
diff --git a/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.H b/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.H
index 4983fb4c16ea9c2847de07eaa5441cecdf4b1b7e..cba4bc59eb76cd2101c93fedc358c4c00c2e3509 100644
--- a/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.H
+++ b/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransform.H
@@ -82,6 +82,11 @@ class globalIndexAndTransform
         //  transform.
         List<vectorTensorTransform> transformPermutations_;
 
+        //- Mapping from patch index to which transform it matches (or
+        //  -1 for none) (.first()) and what sign to us for it,
+        //  i.e. +/- 1 (.second()).
+        List<Pair<label> > patchTransformSign_;
+
 
     // Private static data
 
@@ -97,13 +102,20 @@ class globalIndexAndTransform
         //- Generate all of the transformation permutations
         void determineTransformPermutations();
 
-        //- Test a list of reference transforms to see if the test transform
-        bool matchTransform
+        //- Determine which patch uses which transform (if any) and which
+        //- sign to use
+        void determinePatchTransformSign();
+
+        //- Test a list of reference transforms to see if the test
+        //  transform matches one.  Return +1 or -1 depending on the
+        //  sign of the match, or 0 if none matches.
+        label matchTransform
         (
             const List<vectorTensorTransform>& refTransforms,
+            label& matchedRefTransformI,
             const vectorTensorTransform& testTransform,
             scalar tolerance,
-            bool bothSigns
+            bool checkBothSigns
         ) const;
 
         //- Disallow default bitwise copy construct
@@ -171,12 +183,33 @@ public:
             inline const List<vectorTensorTransform>&
             transformPermutations() const;
 
+            //- Return access to the per-patch transform-sign pairs
+            inline const List<Pair<label> >& patchTransformSign() const;
+
             //- Access the overall (permuted) transform corresponding
             //  to the transformIndex
             inline const vectorTensorTransform& transform
             (
                 label transformIndex
             ) const;
+
+            //- Access the all of the indices of the transform
+            //  permutations corresponding the transforms of the
+            //  listed patch indices
+            inline labelList transformIndicesForPatches
+            (
+                const labelHashSet& patchIs
+            ) const;
+
+            //- Apply all of the transform permutations
+            //  corresponding the transforms of the listed patch
+            //  indices to the supplied point
+            inline pointField transformPatches
+            (
+                const labelHashSet& patchIs,
+                const point& pt
+            ) const;
+
 };
 
 
diff --git a/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransformI.H b/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransformI.H
index fe2a6034a7ca94db4126b52ddbb0c8c01b399d4b..f2928899f255c1aa809f8298e9021d47f4b51fed 100644
--- a/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransformI.H
+++ b/src/lagrangian/basic/InteractionLists/globalIndexAndTransform/globalIndexAndTransformI.H
@@ -180,6 +180,13 @@ Foam::globalIndexAndTransform::transformPermutations() const
 }
 
 
+const Foam::List<Foam::Pair<Foam::label> >&
+Foam::globalIndexAndTransform::patchTransformSign() const
+{
+    return patchTransformSign_;
+}
+
+
 const Foam::vectorTensorTransform& Foam::globalIndexAndTransform::transform
 (
     label transformIndex
@@ -189,4 +196,214 @@ const Foam::vectorTensorTransform& Foam::globalIndexAndTransform::transform
 }
 
 
+Foam::labelList Foam::globalIndexAndTransform::transformIndicesForPatches
+(
+    const labelHashSet& patchIs
+) const
+{
+    List<label> permutation(transforms_.size(), 0);
+
+    labelList selectedTransformIs(0);
+
+    if (patchIs.empty() || transforms_.empty())
+    {
+        return selectedTransformIs;
+    }
+
+    forAllConstIter(labelHashSet, patchIs, iter)
+    {
+        label patchI = iter.key();
+
+        const Pair<label>& transSign = patchTransformSign_[patchI];
+
+        label matchTransI = transSign.first();
+
+        if (matchTransI > -1)
+        {
+            label sign = transSign.second();
+
+            // If this transform been found already by a patch?
+            if (permutation[matchTransI] != 0)
+            {
+                // If so, if they have opposite signs, then this is
+                // considered an error.  They are allowed to be the
+                // same sign, but this only results in a single
+                // transform.
+                if (permutation[matchTransI] != sign)
+                {
+                    FatalErrorIn
+                    (
+                        "const Foam::List<Foam::vectorTensorTransform>& "
+                        "Foam::globalIndexAndTransform::transformsForPatches"
+                        "("
+                            "const labelList& patchIs"
+                        ") const"
+                    )
+                        << "More than one patch accessing the same transform "
+                        << "but not of the same sign."
+                        << exit(FatalError);
+                }
+            }
+            else
+            {
+                permutation[matchTransI] = sign;
+            }
+        }
+    }
+
+    label nUsedTrans = sum(mag(permutation));
+
+    if (nUsedTrans == 0)
+    {
+        return selectedTransformIs;
+    }
+
+    // Number of selected transformations
+    label nSelTrans = pow(2, nUsedTrans) - 1;
+
+    // Pout<< nl << permutation << nl << endl;
+
+    selectedTransformIs.setSize(nSelTrans);
+
+    switch (nUsedTrans)
+    {
+        case 1:
+        {
+            selectedTransformIs[0] = encodeTransformIndex(permutation);
+
+            break;
+        }
+        case 2:
+        {
+            List<label> tempPermutation = permutation;
+
+            label a = 0;
+            label b = 1;
+
+            // When there are two selected transforms out of three, we
+            // need to choose which of them are being permuted
+            if (transforms_.size() > nUsedTrans)
+            {
+                if (permutation[0] == 0)
+                {
+                    a = 1;
+                    b = 2;
+                }
+                else if (permutation[1] == 0)
+                {
+                    a = 0;
+                    b = 2;
+                }
+                else if (permutation[2] == 0)
+                {
+                    a = 0;
+                    b = 1;
+                }
+            }
+
+            tempPermutation[a] = a;
+            tempPermutation[b] = permutation[b];
+
+            selectedTransformIs[0] = encodeTransformIndex(tempPermutation);
+
+            tempPermutation[a] = permutation[a];
+            tempPermutation[b] = a;
+
+            selectedTransformIs[1] = encodeTransformIndex(tempPermutation);
+
+            tempPermutation[a] = permutation[a];
+            tempPermutation[b] = permutation[b];
+
+            selectedTransformIs[2] = encodeTransformIndex(tempPermutation);
+
+            break;
+        }
+        case 3:
+        {
+            List<label> tempPermutation = permutation;
+
+            tempPermutation[0] = 0;
+            tempPermutation[1] = 0;
+            tempPermutation[2] = permutation[2];
+
+            selectedTransformIs[0] = encodeTransformIndex(tempPermutation);
+
+            tempPermutation[0] = 0;
+            tempPermutation[1] = permutation[1];
+            tempPermutation[2] = 0;
+
+            selectedTransformIs[1] = encodeTransformIndex(tempPermutation);
+
+            tempPermutation[0] = 0;
+            tempPermutation[1] = permutation[1];
+            tempPermutation[2] = permutation[2];
+
+            selectedTransformIs[2] = encodeTransformIndex(tempPermutation);
+
+            tempPermutation[0] = permutation[0];
+            tempPermutation[1] = 0;
+            tempPermutation[2] = 0;
+
+            selectedTransformIs[3] = encodeTransformIndex(tempPermutation);
+
+            tempPermutation[0] = permutation[0];
+            tempPermutation[1] = 0;
+            tempPermutation[2] = permutation[2];
+
+            selectedTransformIs[4] = encodeTransformIndex(tempPermutation);
+
+            tempPermutation[0] = permutation[0];
+            tempPermutation[1] = permutation[1];
+            tempPermutation[2] = 0;
+
+            selectedTransformIs[5] = encodeTransformIndex(tempPermutation);
+
+            tempPermutation[0] = permutation[0];
+            tempPermutation[1] = permutation[1];
+            tempPermutation[2] = permutation[2];
+
+            selectedTransformIs[6] = encodeTransformIndex(tempPermutation);
+
+            break;
+        }
+        default:
+        {
+            FatalErrorIn
+            (
+                "const Foam::List<Foam::vectorTensorTransform>& "
+                "Foam::globalIndexAndTransform::transformsForPatches"
+                "("
+                    "const labelList& patchIs"
+                ") const"
+            )
+                << "Only 1-3 transforms are possible."
+                << exit(FatalError);
+        }
+    }
+
+    return selectedTransformIs;
+}
+
+
+Foam::pointField Foam::globalIndexAndTransform::transformPatches
+(
+    const labelHashSet& patchIs,
+    const point& pt
+) const
+{
+    labelList transIs = transformIndicesForPatches(patchIs);
+
+    // Pout<< patchIs << nl << transIs << endl;
+
+    pointField transPts(transIs.size());
+
+    forAll(transIs, tII)
+    {
+        transPts[tII] = transformPermutations_[transIs[tII]].transform(pt);
+    }
+
+    return transPts;
+}
+
+
 // ************************************************************************* //