From 3154b7766d63aa1942c806895b034010fa419378 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Wed, 13 Dec 2023 15:39:34 +0100
Subject: [PATCH] ENH: preserve origId in foamFormatConvert (fixes# #3051)

- previously read the cloud directly without any of the
  passiveParticle fields (origProcId, origId), which meant they would
  not actually be converted.
---
 .../foamFormatConvert/foamFormatConvert.C     | 161 +++++++-----------
 .../foamFormatConvert/writeMeshObject.H       |   3 +-
 2 files changed, 59 insertions(+), 105 deletions(-)

diff --git a/applications/utilities/miscellaneous/foamFormatConvert/foamFormatConvert.C b/applications/utilities/miscellaneous/foamFormatConvert/foamFormatConvert.C
index a75f0ed6506..041c2b0309f 100644
--- a/applications/utilities/miscellaneous/foamFormatConvert/foamFormatConvert.C
+++ b/applications/utilities/miscellaneous/foamFormatConvert/foamFormatConvert.C
@@ -73,8 +73,7 @@ Usage
 #include "tensorIOField.H"
 #include "labelFieldIOField.H"
 #include "vectorFieldIOField.H"
-#include "Cloud.H"
-#include "passiveParticle.H"
+#include "passiveParticleCloud.H"
 #include "fieldDictionary.H"
 
 #include "writeMeshObject.H"
@@ -95,7 +94,7 @@ bool writeZones
     const word& name,
     const fileName& meshDir,
     Time& runTime,
-    const IOstreamOption::compressionType compression
+    IOstreamOption::compressionType compression
 )
 {
     IOobject io
@@ -123,11 +122,11 @@ bool writeZones
 
         IOPtrList<entry> meshObject(io);
 
-        forAll(meshObject, i)
+        for (entry& e : meshObject)
         {
-            if (meshObject[i].isDict())
+            if (e.isDict())
             {
-                dictionary& d = meshObject[i].dict();
+                dictionary& d = e.dict();
 
                 if (d.found("faceLabels"))
                 {
@@ -197,13 +196,13 @@ struct uniqueEqOp
 };
 
 
-template<class T>
+template<class Type>
 bool writeOptionalMeshObject
 (
     const word& name,
     const fileName& meshDir,
     Time& runTime,
-    const bool writeOnProc
+    bool writeOnProc
 )
 {
     IOobject io
@@ -217,22 +216,26 @@ bool writeOptionalMeshObject
         IOobject::NO_REGISTER
     );
 
-    bool writeOk = false;
-    const bool haveFile = io.typeHeaderOk<regIOobject>(false);
+    // Check if available and the correct type.
+    // Done as typeHeaderOk<regIOobject> + isHeaderClass to ensure
+    // local-only reading and circumvent is_globalIOobject<Type> check
+    // in typeHeaderOk<Type>
+
+    bool readOnProc =
+    (
+        io.typeHeaderOk<regIOobject>(false)
+     && io.isHeaderClass<Type>()
+    );
 
-    // Make sure all know if there is a valid class name
-    wordList classNames(1, io.headerClassName());
-    Pstream::combineReduce(classNames, uniqueEqOp<word>());
+    bool writeOk = false;
 
-    // Check for correct type
-    if (classNames[0] == T::typeName)
+    if (returnReduceOr(readOnProc))
     {
-        Info<< "        Reading " << classNames[0]
-            << " : " << name << endl;
-        T meshObject(io, writeOnProc && haveFile);
+        Info<< "        Reading " << Type::typeName << " : " << name << endl;
+        Type meshObject(io, readOnProc && writeOnProc);
 
         Info<< "        Writing " << name << endl;
-        writeOk = meshObject.regIOobject::write(writeOnProc && haveFile);
+        writeOk = meshObject.regIOobject::write(readOnProc && writeOnProc);
     }
 
     return writeOk;
@@ -416,7 +419,6 @@ int main(int argc, char *argv[])
         }
 
 
-
         // Check for lagrangian
         fileNameList lagrangianDirs
         (
@@ -451,12 +453,14 @@ int main(int argc, char *argv[])
                             polyMesh::defaultRegion,
                             runTime.timeName(),
                             runTime,
-                            Foam::IOobject::MUST_READ
+                            IOobject::MUST_READ
                         )
                     )
                 );
             }
 
+            const auto& mesh = meshPtr();
+
             fileNameList cloudDirs
             (
                 fileHandler().readDir
@@ -468,11 +472,14 @@ int main(int argc, char *argv[])
 
             Pstream::combineReduce(cloudDirs, uniqueEqOp<fileName>());
 
-            forAll(cloudDirs, i)
+            for (const auto& cloudDir : cloudDirs)
             {
-                fileName dir(cloud::prefix/cloudDirs[i]);
+                fileName dir(cloud::prefix/cloudDir);
+
+                // Read with origProcId,origId fields
+                passiveParticleCloud parcels(mesh, cloudDir, true);
 
-                Cloud<passiveParticle> parcels(meshPtr(), cloudDirs[i], false);
+                const bool writeOnProc = parcels.size();
 
                 parcels.writeObject
                 (
@@ -481,7 +488,7 @@ int main(int argc, char *argv[])
                         runTime.writeFormat(),
                         runTime.writeCompression()
                     ),
-                    parcels.size()
+                    writeOnProc
                 );
 
 
@@ -496,10 +503,7 @@ int main(int argc, char *argv[])
 
                 for (const word& name : cloudFields)
                 {
-                    // Note: try the various field types. Make sure to
-                    //       exit once successful conversion to avoid re-read
-                    //       converted file.
-
+                    // These ones already done by cloud itself
                     if
                     (
                         name == "positions"
@@ -511,81 +515,32 @@ int main(int argc, char *argv[])
                         continue;
                     }
 
-                    bool writeOk = writeOptionalMeshObject<labelIOField>
-                    (
-                        name,
-                        dir,
-                        runTime,
-                        parcels.size() > 0
-                    );
-                    if (writeOk) continue;
-
-                    writeOk = writeOptionalMeshObject<scalarIOField>
-                    (
-                        name,
-                        dir,
-                        runTime,
-                        parcels.size() > 0
-                    );
-                    if (writeOk) continue;
-
-                    writeOk = writeOptionalMeshObject<vectorIOField>
-                    (
-                        name,
-                        dir,
-                        runTime,
-                        parcels.size() > 0
-                    );
-                    if (writeOk) continue;
-
-                    writeOk = writeOptionalMeshObject<sphericalTensorIOField>
-                    (
-                        name,
-                        dir,
-                        runTime,
-                        parcels.size() > 0
-                    );
-                    if (writeOk) continue;
-
-                    writeOk = writeOptionalMeshObject<symmTensorIOField>
-                    (
-                        name,
-                        dir,
-                        runTime,
-                        parcels.size() > 0
-                    );
-                    if (writeOk) continue;
-
-                    writeOk = writeOptionalMeshObject<tensorIOField>
-                    (
-                        name,
-                        dir,
-                        runTime,
-                        parcels.size() > 0
-                    );
-                    if (writeOk) continue;
-
-                    writeOk = writeOptionalMeshObject<labelFieldIOField>
-                    (
-                        name,
-                        dir,
-                        runTime,
-                        parcels.size() > 0
-                    );
-                    if (writeOk) continue;
-
-                    writeOk = writeOptionalMeshObject<vectorFieldIOField>
-                    (
-                        name,
-                        dir,
-                        runTime,
-                        parcels.size() > 0
-                    );
-
-                    if (!writeOk)
-                    {
-                        Info<< "        Failed converting " << name << endl;
+                    #undef  doLocalCode
+                    #define doLocalCode(Type)                                 \
+                    if                                                        \
+                    (                                                         \
+                        writeOptionalMeshObject<Type>                         \
+                        (                                                     \
+                            name, dir, runTime, writeOnProc                   \
+                        )                                                     \
+                    )                                                         \
+                    {                                                         \
+                        continue;                                             \
                     }
+
+                    doLocalCode(labelIOField);
+                    doLocalCode(scalarIOField);
+                    doLocalCode(vectorIOField);
+                    doLocalCode(sphericalTensorIOField);
+                    doLocalCode(symmTensorIOField);
+                    doLocalCode(tensorIOField);
+
+                    doLocalCode(labelFieldIOField);
+                    doLocalCode(vectorFieldIOField);
+
+                    #undef doLocalCode
+
+                    Info<< "        Failed converting " << name << endl;
                 }
             }
         }
diff --git a/applications/utilities/miscellaneous/foamFormatConvert/writeMeshObject.H b/applications/utilities/miscellaneous/foamFormatConvert/writeMeshObject.H
index 7dffa765762..de7a73f3d7a 100644
--- a/applications/utilities/miscellaneous/foamFormatConvert/writeMeshObject.H
+++ b/applications/utilities/miscellaneous/foamFormatConvert/writeMeshObject.H
@@ -71,10 +71,9 @@ inline bool writeMeshObject
 
         // Switch off type checking (for reading e.g. faceZones as
         // generic list of dictionaries).
-        word oldTypeName;
+        const word oldTypeName = Type::typeName;
         if (disableHeaderChecking)
         {
-            oldTypeName = Type::typeName;
             const_cast<word&>(Type::typeName) = word::null;
         }
 
-- 
GitLab