From 7be0ae1dbbe5c55e50f0a77779e4094a5af47fdd Mon Sep 17 00:00:00 2001
From: andy <andy>
Date: Tue, 4 Dec 2012 12:52:16 +0000
Subject: [PATCH] ENH: Emabled caching of AMI for inter-region communication

---
 .../regionModel/regionModel/regionModel.C     | 89 ++++++++++++++++++-
 .../regionModel/regionModel/regionModel.H     | 27 ++++--
 .../regionModel/regionModelTemplates.C        | 67 +++++---------
 3 files changed, 129 insertions(+), 54 deletions(-)

diff --git a/src/regionModels/regionModel/regionModel/regionModel.C b/src/regionModels/regionModel/regionModel/regionModel.C
index 227af0adb4f..55ced3fe534 100644
--- a/src/regionModels/regionModel/regionModel/regionModel.C
+++ b/src/regionModels/regionModel/regionModel/regionModel.C
@@ -190,6 +190,88 @@ bool Foam::regionModels::regionModel::read(const dictionary& dict)
 }
 
 
+const Foam::AMIPatchToPatchInterpolation&
+Foam::regionModels::regionModel::interRegionAMI
+(
+    const regionModel& nbrRegion,
+    const label regionPatchI,
+    const label nbrPatchI,
+    const bool flip
+)
+{
+    label nbrRegionID = findIndex(interRegionAMINames_, nbrRegion.name());
+
+    const fvMesh& nbrRegionMesh = nbrRegion.regionMesh();
+
+    if (nbrRegionID != -1)
+    {
+        if (!interRegionAMI_[nbrRegionID].set(regionPatchI))
+        {
+            const polyPatch& p = regionMesh().boundaryMesh()[regionPatchI];
+            const polyPatch& nbrP = nbrRegionMesh.boundaryMesh()[nbrPatchI];
+
+            int oldTag = UPstream::msgType();
+            UPstream::msgType() = oldTag + 1;
+
+            interRegionAMI_[nbrRegionID].set
+            (
+                regionPatchI,
+                new AMIPatchToPatchInterpolation
+                (
+                    p,
+                    nbrP,
+                    faceAreaIntersect::tmMesh,
+                    flip
+                )
+            );
+
+            UPstream::msgType() = oldTag;
+        }
+
+        return interRegionAMI_[nbrRegionID][regionPatchI];
+    }
+    else
+    {
+        label nbrRegionID = interRegionAMINames_.size();
+
+        interRegionAMINames_.append(nbrRegion.name());
+
+        const polyPatch& p = regionMesh().boundaryMesh()[regionPatchI];
+        const polyPatch& nbrP = nbrRegionMesh.boundaryMesh()[nbrPatchI];
+
+        label nPatch = regionMesh().boundaryMesh().size();
+
+
+        interRegionAMI_.resize(nbrRegionID + 1);
+
+        interRegionAMI_.set
+        (
+            nbrRegionID,
+            new PtrList<AMIPatchToPatchInterpolation>(nPatch)
+        );
+
+        int oldTag = UPstream::msgType();
+        UPstream::msgType() = oldTag + 1;
+
+        interRegionAMI_[nbrRegionID].set
+        (
+            regionPatchI,
+            new AMIPatchToPatchInterpolation
+            (
+                p,
+                nbrP,
+                faceAreaIntersect::tmMesh,
+                flip
+            )
+        );
+
+        UPstream::msgType() = oldTag;
+
+        return interRegionAMI_[nbrRegionID][regionPatchI];
+    }
+}
+
+
 Foam::label Foam::regionModels::regionModel::nbrCoupledPatchID
 (
     const regionModel& nbrRegion,
@@ -234,8 +316,7 @@ Foam::label Foam::regionModels::regionModel::nbrCoupledPatchID
 
         FatalErrorIn
         (
-            "Foam::tmp<Foam::Field<Type> > "
-            "Foam::regionModels::regionModel::nbrCoupledPatchID"
+            "Foam::label Foam::regionModels::regionModel::nbrCoupledPatchID"
             "("
                 "const regionModel& , "
                 "const label"
@@ -275,7 +356,9 @@ Foam::regionModels::regionModel::regionModel(const fvMesh& mesh)
     primaryPatchIDs_(),
     intCoupledPatchIDs_(),
     regionName_("none"),
-    functions_(*this)
+    functions_(*this),
+    interRegionAMINames_(),
+    interRegionAMI_()
 {}
 
 
diff --git a/src/regionModels/regionModel/regionModel/regionModel.H b/src/regionModels/regionModel/regionModel/regionModel.H
index c59b8d163d7..589402c1cf9 100644
--- a/src/regionModels/regionModel/regionModel/regionModel.H
+++ b/src/regionModels/regionModel/regionModel/regionModel.H
@@ -122,6 +122,15 @@ protected:
         regionModelFunctionObjectList functions_;
 
 
+        // Inter-region AMI interpolation caching
+
+            //- List of region names this region is coupled to
+            wordList interRegionAMINames_;
+
+            //- List of AMI objects per coupled region
+            PtrList<PtrList<AMIPatchToPatchInterpolation> > interRegionAMI_;
+
+
     // Protected member functions
 
         //- Read control parameters from dictionary
@@ -130,6 +139,14 @@ protected:
         //- Read control parameters from dictionary
         virtual bool read(const dictionary& dict);
 
+        //- Create or return a new inter-region AMI object
+        virtual const Foam::AMIPatchToPatchInterpolation& interRegionAMI
+        (
+            const regionModel& nbrRegion,
+            const label regionPatchI,
+            const label nbrPatchI,
+            const bool flip
+        );
 
 public:
 
@@ -235,28 +252,28 @@ public:
                 const label nbrPatchI,
                 const Field<Type>& nbrField,
                 const bool flip = false
-            ) const;
+            );
 
             //- Map patch field from another region model to local patch
             template<class Type>
             tmp<Field<Type> > mapRegionPatchField
             (
-                const word& regionModelName,
+                const regionModel& nbrRegion,
                 const word& fieldName,
                 const label regionPatchI,
                 const bool flip = false
-            ) const;
+            );
 
             //- Map patch internal field from another region model to local
             //  patch
             template<class Type>
             tmp<Field<Type> > mapRegionPatchInternalField
             (
-                const word& regionModelName,
+                const regionModel& nbrRegion,
                 const word& fieldName,
                 const label regionPatchI,
                 const bool flip = false
-            ) const;
+            );
 
             //- Convert a local region field to the primary region
             template<class Type>
diff --git a/src/regionModels/regionModel/regionModel/regionModelTemplates.C b/src/regionModels/regionModel/regionModel/regionModelTemplates.C
index 4e98b2e2fb2..5855ee59061 100644
--- a/src/regionModels/regionModel/regionModel/regionModelTemplates.C
+++ b/src/regionModels/regionModel/regionModel/regionModelTemplates.C
@@ -32,18 +32,13 @@ Foam::regionModels::regionModel::mapRegionPatchField
     const label nbrPatchI,
     const Field<Type>& nbrField,
     const bool flip
-) const
+)
 {
-    const fvMesh& nbrRegionMesh = nbrRegion.regionMesh();
-
-    const polyPatch& p = regionMesh().boundaryMesh()[regionPatchI];
-
-    const polyPatch& nbrP = nbrRegionMesh.boundaryMesh()[nbrPatchI];
-
     int oldTag = UPstream::msgType();
     UPstream::msgType() = oldTag + 1;
 
-    AMIPatchToPatchInterpolation ami(p, nbrP, faceAreaIntersect::tmMesh, flip);
+    const AMIPatchToPatchInterpolation& ami =
+        interRegionAMI(nbrRegion, regionPatchI, nbrPatchI, flip);
 
     tmp<Field<Type> > tresult(ami.interpolateToSource(nbrField));
 
@@ -57,40 +52,28 @@ template<class Type>
 Foam::tmp<Foam::Field<Type> >
 Foam::regionModels::regionModel::mapRegionPatchField
 (
-    const word& regionModelName,
+    const regionModel& nbrRegion,
     const word& fieldName,
     const label regionPatchI,
     const bool flip
-) const
+)
 {
     typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
 
-    const regionModel& nbrRegion =
-        this->primaryMesh_.lookupObject<regionModel>(regionModelName);
-
     const fvMesh& nbrRegionMesh = nbrRegion.regionMesh();
 
-    const polyPatch& p = regionMesh().boundaryMesh()[regionPatchI];
-
     if (nbrRegionMesh.foundObject<fieldType>(fieldName))
     {
-        const fieldType& nbrField =
-            nbrRegionMesh.lookupObject<fieldType>(fieldName);
-
         const label nbrPatchI = nbrCoupledPatchID(nbrRegion, regionPatchI);
 
-        const polyPatch& nbrP = nbrRegionMesh.boundaryMesh()[nbrPatchI];
-
         int oldTag = UPstream::msgType();
         UPstream::msgType() = oldTag + 1;
 
-        AMIPatchToPatchInterpolation ami
-        (
-            p,
-            nbrP,
-            faceAreaIntersect::tmMesh,
-            flip
-        );
+        const AMIPatchToPatchInterpolation& ami =
+            interRegionAMI(nbrRegion, regionPatchI, nbrPatchI, flip);
+
+        const fieldType& nbrField =
+            nbrRegionMesh.lookupObject<fieldType>(fieldName);
 
         const Field<Type>& nbrFieldp = nbrField.boundaryField()[nbrPatchI];
 
@@ -102,6 +85,8 @@ Foam::regionModels::regionModel::mapRegionPatchField
     }
     else
     {
+        const polyPatch& p = regionMesh().boundaryMesh()[regionPatchI];
+
         return
             tmp<Field<Type> >
             (
@@ -119,40 +104,28 @@ template<class Type>
 Foam::tmp<Foam::Field<Type> >
 Foam::regionModels::regionModel::mapRegionPatchInternalField
 (
-    const word& regionModelName,
+    const regionModel& nbrRegion,
     const word& fieldName,
     const label regionPatchI,
     const bool flip
-) const
+)
 {
     typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
 
-    const regionModel& nbrRegion =
-        this->primaryMesh_.lookupObject<regionModel>(regionModelName);
-
     const fvMesh& nbrRegionMesh = nbrRegion.regionMesh();
 
-    const polyPatch& p = regionMesh().boundaryMesh()[regionPatchI];
-
     if (nbrRegionMesh.foundObject<fieldType>(fieldName))
     {
-        const fieldType& nbrField =
-            nbrRegionMesh.lookupObject<fieldType>(fieldName);
-
         const label nbrPatchI = nbrCoupledPatchID(nbrRegion, regionPatchI);
 
-        const polyPatch& nbrP = nbrRegionMesh.boundaryMesh()[nbrPatchI];
-
         int oldTag = UPstream::msgType();
         UPstream::msgType() = oldTag + 1;
 
-        AMIPatchToPatchInterpolation ami
-        (
-            p,
-            nbrP,
-            faceAreaIntersect::tmMesh,
-            flip
-        );
+        const AMIPatchToPatchInterpolation& ami =
+            interRegionAMI(nbrRegion, regionPatchI, nbrPatchI, flip);
+
+        const fieldType& nbrField =
+            nbrRegionMesh.lookupObject<fieldType>(fieldName);
 
         const fvPatchField<Type>& nbrFieldp =
             nbrField.boundaryField()[nbrPatchI];
@@ -168,6 +141,8 @@ Foam::regionModels::regionModel::mapRegionPatchInternalField
     }
     else
     {
+        const polyPatch& p = regionMesh().boundaryMesh()[regionPatchI];
+
         return
             tmp<Field<Type> >
             (
-- 
GitLab