From 41b6794e2dd47af145ac476dc6be1a098a3fd81f Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Thu, 26 Oct 2023 15:08:20 +0200
Subject: [PATCH] ENH: add global (serial) path accessor to IOobject (#3007)

- new methods added to IOobject to ease mixed (serial vs parallel)
  file locations. Some redirect to Time, others are defined for
  IOobject only.

    | "normal" (serial/parallel) | "global" (serial locations) |
    | ---------------------------|-----------------------------|
    | caseName()                 | globalCaseName()            |
    | path()                     | globalPath()          *new* |
    | path(...)                  | globalPath(...)       *new* |
    | objectPath()               | globalObjectPath()    *new* |
---
 src/OpenFOAM/db/IOobject/IOobject.C  | 81 +++++++++++++++++++---------
 src/OpenFOAM/db/IOobject/IOobject.H  | 22 ++++++--
 src/OpenFOAM/db/IOobject/IOobjectI.H |  6 +++
 3 files changed, 80 insertions(+), 29 deletions(-)

diff --git a/src/OpenFOAM/db/IOobject/IOobject.C b/src/OpenFOAM/db/IOobject/IOobject.C
index 4fb2ae1e39a..055d69f76f8 100644
--- a/src/OpenFOAM/db/IOobject/IOobject.C
+++ b/src/OpenFOAM/db/IOobject/IOobject.C
@@ -141,6 +141,31 @@ namespace Foam
 //! \endcond
 
 
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
+
+// A file is 'outside' of the case if it has been specified using an
+// absolute path.
+//
+// Like 'fileName::isAbsolute' but with even fewer checks since the
+// swapping of '\\' with '/' will have already occurred.
+static inline bool file_isOutsideCase(const std::string& str)
+{
+    return !str.empty() &&
+    (
+        // Starts with '/'
+        (str[0] == '/')
+
+#ifdef _WIN32
+         // Filesytem root - eg, d:/path
+     || (
+            (str.length() > 2 && str[1] == ':')
+         && (str[2] == '/')
+        )
+#endif
+    );
+}
+
+
 // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
 
 bool Foam::IOobject::fileNameComponents
@@ -441,34 +466,28 @@ const Foam::Time& Foam::IOobject::time() const noexcept
 }
 
 
-const Foam::fileName& Foam::IOobject::rootPath() const
+const Foam::fileName& Foam::IOobject::rootPath() const noexcept
 {
     return time().rootPath();
 }
 
 
-const Foam::fileName& Foam::IOobject::caseName() const
+const Foam::fileName& Foam::IOobject::caseName() const noexcept
 {
     return time().caseName();
 }
 
 
-Foam::fileName Foam::IOobject::path() const
+const Foam::fileName& Foam::IOobject::globalCaseName() const noexcept
 {
-    // A file is 'outside' of the case if it has been specified using an
-    // absolute path
+    return time().globalCaseName();
+}
 
-    const auto first = instance().find('/');
 
-    if
-    (
-        first == 0
-        #ifdef _WIN32
-     || (first == 2 && instance()[1] == ':')  // Eg, d:/path
-        #endif
-    )
+Foam::fileName Foam::IOobject::path() const
+{
+    if (file_isOutsideCase(instance()))
     {
-        // Absolute path (starts with '/' or 'd:/')
         return instance();
     }
 
@@ -476,6 +495,17 @@ Foam::fileName Foam::IOobject::path() const
 }
 
 
+Foam::fileName Foam::IOobject::globalPath() const
+{
+    if (file_isOutsideCase(instance()))
+    {
+        return instance();
+    }
+
+    return rootPath()/globalCaseName()/instance()/db_.dbDir()/local();
+}
+
+
 Foam::fileName Foam::IOobject::path
 (
     const word& instance,
@@ -487,22 +517,21 @@ Foam::fileName Foam::IOobject::path
 }
 
 
-Foam::fileName Foam::IOobject::objectRelPath() const
+Foam::fileName Foam::IOobject::globalPath
+(
+    const word& instance,
+    const fileName& local
+) const
 {
-    // A file is 'outside' of the case if it has been specified using an
-    // absolute path
+    // Note: can only be called with relative instance since is word type
+    return rootPath()/globalCaseName()/instance/db_.dbDir()/local;
+}
 
-    const auto first = instance().find('/');
 
-    if
-    (
-        first == 0
-        #ifdef _WIN32
-     || (first == 2 && instance()[1] == ':')  // Eg, d:/path
-        #endif
-    )
+Foam::fileName Foam::IOobject::objectRelPath() const
+{
+    if (file_isOutsideCase(instance()))
     {
-        // Absolute path (starts with '/' or 'd:/')
         return instance()/name();
     }
 
diff --git a/src/OpenFOAM/db/IOobject/IOobject.H b/src/OpenFOAM/db/IOobject/IOobject.H
index d73bade5c0b..44a78b0af1f 100644
--- a/src/OpenFOAM/db/IOobject/IOobject.H
+++ b/src/OpenFOAM/db/IOobject/IOobject.H
@@ -541,10 +541,13 @@ public:
         inline word member() const;
 
         //- Return the Time::rootPath()
-        const fileName& rootPath() const;
+        const fileName& rootPath() const noexcept;
 
         //- Return the Time::caseName()
-        const fileName& caseName() const;
+        const fileName& caseName() const noexcept;
+
+        //- Return the Time::globalCaseName()
+        const fileName& globalCaseName() const noexcept;
 
         //- Read access to instance path component
         inline const fileName& instance() const noexcept;
@@ -555,9 +558,12 @@ public:
         //- Read access to local path component
         inline const fileName& local() const noexcept;
 
-        //- The complete path
+        //- The complete path for the object (with instance, local,...).
         fileName path() const;
 
+        //- The complete global path for the object (with instance, local,...)
+        fileName globalPath() const;
+
         //- The complete path with alternative instance and local
         fileName path
         (
@@ -565,9 +571,19 @@ public:
             const fileName& local = fileName::null
         ) const;
 
+        //- The complete global path with alternative instance and local
+        fileName globalPath
+        (
+            const word& instance,
+            const fileName& local = fileName::null
+        ) const;
+
         //- The complete path + object name
         inline fileName objectPath() const;
 
+        //- The complete global path + object name
+        inline fileName globalObjectPath() const;
+
         //- The object path relative to the root
         fileName objectRelPath() const;
 
diff --git a/src/OpenFOAM/db/IOobject/IOobjectI.H b/src/OpenFOAM/db/IOobject/IOobjectI.H
index f0d0c114b6a..ba7f684240f 100644
--- a/src/OpenFOAM/db/IOobject/IOobjectI.H
+++ b/src/OpenFOAM/db/IOobject/IOobjectI.H
@@ -294,6 +294,12 @@ inline Foam::fileName Foam::IOobject::objectPath() const
 }
 
 
+inline Foam::fileName Foam::IOobject::globalObjectPath() const
+{
+    return globalPath()/name();
+}
+
+
 // Error Handling
 
 inline bool Foam::IOobject::good() const noexcept
-- 
GitLab