From e0d1fe38c60aad4bb90e2fd2746d2868ef0c2019 Mon Sep 17 00:00:00 2001
From: mattijs <mattijs>
Date: Wed, 9 Jan 2013 11:09:38 +0000
Subject: [PATCH] ENH: mappedPatchBase: added nearest-patch-point sampling

---
 .../mappedPolyPatch/mappedPatchBase.C         | 91 +++++++++++++++++--
 .../mappedPolyPatch/mappedPatchBase.H         | 36 +++++++-
 .../mappedPolyPatch/mappedPatchBaseI.H        |  6 +-
 3 files changed, 120 insertions(+), 13 deletions(-)

diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C
index 73d64b40f3e..30450187018 100644
--- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C
+++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C
@@ -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
@@ -31,6 +31,7 @@ License
 #include "OFstream.H"
 #include "Random.H"
 #include "treeDataFace.H"
+#include "treeDataPoint.H"
 #include "indexedOctree.H"
 #include "polyMesh.H"
 #include "polyPatch.H"
@@ -38,6 +39,7 @@ License
 #include "mapDistribute.H"
 #include "SubField.H"
 #include "triPointRef.H"
+#include "syncTools.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -49,12 +51,13 @@ namespace Foam
     const char* Foam::NamedEnum
     <
         Foam::mappedPatchBase::sampleMode,
-        4
+        5
     >::names[] =
     {
         "nearestCell",
         "nearestPatchFace",
         "nearestPatchFaceAMI",
+        "nearestPatchPoint",
         "nearestFace"
     };
 
@@ -72,7 +75,7 @@ namespace Foam
 }
 
 
-const Foam::NamedEnum<Foam::mappedPatchBase::sampleMode, 4>
+const Foam::NamedEnum<Foam::mappedPatchBase::sampleMode, 5>
     Foam::mappedPatchBase::sampleModeNames_;
 
 const Foam::NamedEnum<Foam::mappedPatchBase::offsetMode, 3>
@@ -315,6 +318,77 @@ void Foam::mappedPatchBase::findSamples
             break;
         }
 
+        case NEARESTPATCHPOINT:
+        {
+            Random rndGen(123456);
+
+            const polyPatch& pp = samplePolyPatch();
+
+            if (pp.empty())
+            {
+                forAll(samples, sampleI)
+                {
+                    nearest[sampleI].second().first() = Foam::sqr(GREAT);
+                    nearest[sampleI].second().second() = Pstream::myProcNo();
+                }
+            }
+            else
+            {
+                // patch (local) points
+                treeBoundBox patchBb
+                (
+                    treeBoundBox(pp.points(), pp.meshPoints()).extend
+                    (
+                        rndGen,
+                        1e-4
+                    )
+                );
+                patchBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
+                patchBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
+
+                indexedOctree<treeDataPoint> boundaryTree
+                (
+                    treeDataPoint   // all information needed to search faces
+                    (
+                        mesh.points(),
+                        pp.meshPoints() // selection of points to search on
+                    ),
+                    patchBb,        // overall search domain
+                    8,              // maxLevel
+                    10,             // leafsize
+                    3.0             // duplicity
+                );
+
+                forAll(samples, sampleI)
+                {
+                    const point& sample = samples[sampleI];
+
+                    pointIndexHit& nearInfo = nearest[sampleI].first();
+                    nearInfo = boundaryTree.findNearest
+                    (
+                        sample,
+                        magSqr(patchBb.span())
+                    );
+
+                    if (!nearInfo.hit())
+                    {
+                        nearest[sampleI].second().first() = Foam::sqr(GREAT);
+                        nearest[sampleI].second().second() =
+                            Pstream::myProcNo();
+                    }
+                    else
+                    {
+                        const point& pt = nearInfo.hitPoint();
+
+                        nearest[sampleI].second().first() = magSqr(pt-sample);
+                        nearest[sampleI].second().second() =
+                            Pstream::myProcNo();
+                    }
+                }
+            }
+            break;
+        }
+
         case NEARESTFACE:
         {
             if (samplePatch_.size() && samplePatch_ != "none")
@@ -373,10 +447,11 @@ void Foam::mappedPatchBase::findSamples
     }
 
 
-    // Find nearest
+    // Find nearest. Combine on master.
     Pstream::listCombineGather(nearest, nearestEqOp());
     Pstream::listCombineScatter(nearest);
 
+
     if (debug)
     {
         Info<< "mappedPatchBase::findSamples on mesh " << sampleRegion_
@@ -388,8 +463,9 @@ void Foam::mappedPatchBase::findSamples
 
             Info<< "    " << sampleI << " coord:"<< samples[sampleI]
                 << " found on processor:" << procI
-                << " in local cell/face:" << localI
-                << " with cc:" << nearest[sampleI].first().rawPoint() << endl;
+                << " in local cell/face/point:" << localI
+                << " with location:" << nearest[sampleI].first().rawPoint()
+                << endl;
         }
     }
 
@@ -599,7 +675,8 @@ void Foam::mappedPatchBase::calcMapping() const
           + "_mapped.obj"
         );
         Pout<< "Dumping mapping as lines from patch faceCentres to"
-            << " sampled cell/faceCentres to file " << str.name() << endl;
+            << " sampled cell/faceCentres/points to file " << str.name()
+            << endl;
 
         label vertI = 0;
 
diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H
index f9afc00cdff..f72f407d810 100644
--- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H
+++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.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
@@ -39,6 +39,10 @@ Description
                                    - patches need not conform
                                    - uses AMI interpolation
         // - nearestFace         : nearest boundary face on any patch
+        // - nearestPatchPoint   : nearest patch point (for coupled points
+        //                         this might be any of the points so you have
+        //                         to guarantee the point data is synchronised
+        //                         beforehand)
         sampleMode nearestCell;
 
         // If sampleMod is nearestPatchFace : patch to find faces of
@@ -99,8 +103,9 @@ public:
         enum sampleMode
         {
             NEARESTCELL,         // nearest cell
-            NEARESTPATCHFACE,    // faces on selected patch
+            NEARESTPATCHFACE,    // nearest face on selected patch
             NEARESTPATCHFACEAMI, // nearest patch face + AMI interpolation
+            NEARESTPATCHPOINT,   // nearest point on selected patch
             NEARESTFACE          // nearest face
         };
 
@@ -112,7 +117,7 @@ public:
             NORMAL              // use face normal + distance
         };
 
-        static const NamedEnum<sampleMode, 4> sampleModeNames_;
+        static const NamedEnum<sampleMode, 5> sampleModeNames_;
 
         static const NamedEnum<offsetMode, 3> offsetModeNames_;
 
@@ -145,6 +150,27 @@ public:
         }
     };
 
+    class maxProcEqOp
+    {
+
+    public:
+
+        void operator()(nearInfo& x, const nearInfo& y) const
+        {
+            if (y.first().hit())
+            {
+                if (!x.first().hit())
+                {
+                    x = y;
+                }
+                else if (y.second().second() > x.second().second())
+                {
+                    x = y;
+                }
+            }
+        }
+    };
+
 
 protected:
 
@@ -159,7 +185,7 @@ protected:
         //- What to sample
         const sampleMode mode_;
 
-        //- Patch (only if NEARESTPATCHFACE)
+        //- Patch (if in sampleMode NEARESTPATCH*)
         const word samplePatch_;
 
         //- How to obtain samples
@@ -187,7 +213,7 @@ protected:
             mutable autoPtr<mapDistribute> mapPtr_;
 
 
-        // AMI interpolator
+        // AMI interpolator (only for NEARESTPATCHFACEAMI)
 
             //- Pointer to AMI interpolator
             mutable autoPtr<AMIPatchToPatchInterpolation> AMIPtr_;
diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseI.H b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseI.H
index 928fa86ad7d..927534210f1 100644
--- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseI.H
+++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseI.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
@@ -58,6 +58,10 @@ inline Foam::label Foam::mappedPatchBase::sampleSize() const
         {
             return samplePolyPatch().size();
         }
+        case NEARESTPATCHPOINT:
+        {
+            return samplePolyPatch().nPoints();
+        }
         case NEARESTFACE:
         {
             const polyMesh& mesh = sampleMesh();
-- 
GitLab