From 620fe96c02a245167f435fea35daa6e874a063c1 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Fri, 11 Jun 2021 12:01:53 +0200
Subject: [PATCH] ENH: multi-region support for rotateMesh (#2072)

---
 .../mesh/manipulation/rotateMesh/Make/options |   6 +-
 .../mesh/manipulation/rotateMesh/rotateMesh.C | 104 +++++++++++++-----
 .../transformPoints/transformPoints.C         |  17 ++-
 3 files changed, 91 insertions(+), 36 deletions(-)

diff --git a/applications/utilities/mesh/manipulation/rotateMesh/Make/options b/applications/utilities/mesh/manipulation/rotateMesh/Make/options
index fa15f124528..d27c95d033d 100644
--- a/applications/utilities/mesh/manipulation/rotateMesh/Make/options
+++ b/applications/utilities/mesh/manipulation/rotateMesh/Make/options
@@ -1,5 +1,7 @@
 EXE_INC = \
-    -I$(LIB_SRC)/finiteVolume/lnInclude
+    -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/meshTools/lnInclude
 
 EXE_LIBS = \
-    -lfiniteVolume
+    -lfiniteVolume \
+    -lmeshTools
diff --git a/applications/utilities/mesh/manipulation/rotateMesh/rotateMesh.C b/applications/utilities/mesh/manipulation/rotateMesh/rotateMesh.C
index 2582c90f07c..d2dd0fe8796 100644
--- a/applications/utilities/mesh/manipulation/rotateMesh/rotateMesh.C
+++ b/applications/utilities/mesh/manipulation/rotateMesh/rotateMesh.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -41,33 +41,58 @@ Description
 #include "fvMesh.H"
 #include "volFields.H"
 #include "surfaceFields.H"
+#include "regionProperties.H"
 #include "transformGeometricField.H"
 #include "IOobjectList.H"
 
 using namespace Foam;
 
-template<class GeometricField>
-void RotateFields
+template<class GeoField>
+void ReadAndRotateFields
 (
     const fvMesh& mesh,
     const IOobjectList& objects,
-    const tensor& rotT
+    const dimensionedTensor& rotT
 )
 {
     // Objects of field type
-    IOobjectList fields(objects.lookupClass(GeometricField::typeName));
+    IOobjectList fields(objects.lookupClass<GeoField>());
 
     forAllConstIters(fields, fieldIter)
     {
-        Info<< "    Rotating " << (*fieldIter)->name() << endl;
-
-        GeometricField fld(*fieldIter(), mesh);
-        transform(fld, dimensionedTensor(rotT), fld);
+        GeoField fld(*fieldIter(), mesh);
+        Info<< "    Rotating " << fld.name() << endl;
+        transform(fld, rotT, fld);
         fld.write();
     }
 }
 
 
+void rotateFields
+(
+    const fvMesh& mesh,
+    const Time& runTime,
+    const tensor& rotationT
+)
+{
+    // Need dimensionedTensor for geometric fields
+    const dimensionedTensor rotT(rotationT);
+
+    // Search for list of objects for this time
+    IOobjectList objects(mesh, runTime.timeName());
+
+    ReadAndRotateFields<volVectorField>(mesh, objects, rotT);
+    ReadAndRotateFields<volSphericalTensorField>(mesh, objects, rotT);
+    ReadAndRotateFields<volSymmTensorField>(mesh, objects, rotT);
+    ReadAndRotateFields<volTensorField>(mesh, objects, rotT);
+
+    ReadAndRotateFields<surfaceVectorField>(mesh, objects, rotT);
+    ReadAndRotateFields<surfaceSphericalTensorField>(mesh, objects, rotT);
+    ReadAndRotateFields<surfaceSymmTensorField>(mesh, objects, rotT);
+    ReadAndRotateFields<surfaceTensorField>(mesh, objects, rotT);
+}
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 int main(int argc, char *argv[])
@@ -83,22 +108,44 @@ int main(int argc, char *argv[])
     argList::addArgument("from", "The vector to rotate from");
     argList::addArgument("to",   "The vector to rotate to");
 
+    #include "addAllRegionOptions.H"
     #include "setRootCase.H"
-    #include "createTime.H"
 
     const vector n1(args.get<vector>(1).normalise());
     const vector n2(args.get<vector>(2).normalise());
 
     const tensor rotT(rotationTensor(n1, n2));
 
+    // ------------------------------------------------------------------------
+
+    #include "createTime.H"
+
+    // Handle -allRegions, -regions, -region
+    #include "getAllRegionOptions.H"
+
+    // ------------------------------------------------------------------------
+
+    forAll(regionNames, regioni)
     {
+        const word& regionName = regionNames[regioni];
+        const word& regionDir =
+        (
+            regionName == polyMesh::defaultRegion ? word::null : regionName
+        );
+        const fileName meshDir = regionDir/polyMesh::meshSubDir;
+
+        if (regionNames.size() > 1)
+        {
+            Info<< "region=" << regionName << nl;
+        }
+
         pointIOField points
         (
             IOobject
             (
                 "points",
-                runTime.findInstance(polyMesh::meshSubDir, "points"),
-                polyMesh::meshSubDir,
+                runTime.findInstance(meshDir, "points"),
+                meshDir,
                 runTime,
                 IOobject::MUST_READ,
                 IOobject::NO_WRITE,
@@ -111,36 +158,35 @@ int main(int argc, char *argv[])
         // Set the precision of the points data to 10
         IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
 
-        Info<< "Writing points into directory " << points.path() << nl << endl;
+        Info<< "Writing points into directory "
+            << runTime.relativePath(points.path()) << nl
+            << endl;
         points.write();
     }
 
-
     instantList timeDirs = timeSelector::select0(runTime, args);
 
-    #include "createNamedMesh.H"
+    #include "createNamedMeshes.H"
 
-    forAll(timeDirs, timeI)
+    forAll(timeDirs, timei)
     {
-        runTime.setTime(timeDirs[timeI], timeI);
+        runTime.setTime(timeDirs[timei], timei);
 
         Info<< "Time = " << runTime.timeName() << endl;
 
-        // Search for list of objects for this time
-        IOobjectList objects(mesh, runTime.timeName());
-
-        RotateFields<volVectorField>(mesh, objects, rotT);
-        RotateFields<volSphericalTensorField>(mesh, objects, rotT);
-        RotateFields<volSymmTensorField>(mesh, objects, rotT);
-        RotateFields<volTensorField>(mesh, objects, rotT);
+        forAll(regionNames, regioni)
+        {
+            const word& regionName = regionNames[regioni];
+            if (regionNames.size() > 1)
+            {
+                Info<< "region=" << regionName << nl;
+            }
 
-        RotateFields<surfaceVectorField>(mesh, objects, rotT);
-        RotateFields<surfaceSphericalTensorField>(mesh, objects, rotT);
-        RotateFields<surfaceSymmTensorField>(mesh, objects, rotT);
-        RotateFields<surfaceTensorField>(mesh, objects, rotT);
+            rotateFields(meshes[regioni], runTime, rotT);
+        }
     }
 
-    Info<< "End\n" << endl;
+    Info<< "\nEnd\n" << endl;
 
     return 0;
 }
diff --git a/applications/utilities/mesh/manipulation/transformPoints/transformPoints.C b/applications/utilities/mesh/manipulation/transformPoints/transformPoints.C
index 4b7c885187c..2fdcf6edd0e 100644
--- a/applications/utilities/mesh/manipulation/transformPoints/transformPoints.C
+++ b/applications/utilities/mesh/manipulation/transformPoints/transformPoints.C
@@ -77,8 +77,8 @@ Note
 #include "fvMesh.H"
 #include "volFields.H"
 #include "surfaceFields.H"
-#include "ReadFields.H"
 #include "pointFields.H"
+#include "ReadFields.H"
 #include "regionProperties.H"
 #include "transformField.H"
 #include "transformGeometricField.H"
@@ -95,7 +95,7 @@ void readAndRotateFields
 (
     PtrList<GeoField>& flds,
     const fvMesh& mesh,
-    const tensor& rotT,
+    const dimensionedTensor& rotT,
     const IOobjectList& objects
 )
 {
@@ -103,14 +103,21 @@ void readAndRotateFields
     for (GeoField& fld : flds)
     {
         Info<< "Transforming " << fld.name() << endl;
-        const dimensionedTensor dimT("t", fld.dimensions(), rotT);
-        transform(fld, dimT, fld);
+        transform(fld, rotT, fld);
     }
 }
 
 
-void rotateFields(const word& regionName, const Time& runTime, const tensor& T)
+void rotateFields
+(
+    const word& regionName,
+    const Time& runTime,
+    const tensor& rotT
+)
 {
+    // Need dimensionedTensor for geometric fields
+    const dimensionedTensor T(rotT);
+
     #include "createRegionMesh.H"
 
     // Read objects in time directory
-- 
GitLab