diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H
index eaa54bab7210357f4d3e6912af02785287cc6b63..2d5157abf160ab097a713f898a9ea97ea396c1b0 100644
--- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H
+++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H
@@ -660,9 +660,9 @@ public:
         //  alpha is read from controlDict
         void relax();
 
-        //- Select the final iteration parameters if `final' is true
-        //  by returning the field name + "Final"
-        //  otherwise the standard parameters by returning the field name
+        //- Select the final iteration parameters if \c final is true
+        //- by returning the field name + "Final"
+        //- otherwise the standard parameters by returning the field name
         word select(bool final) const;
 
         //- Helper function to write the min and max to an Ostream
diff --git a/src/OpenFOAM/meshes/data/data.C b/src/OpenFOAM/meshes/data/data.C
index 15e419193fb30629e65203aad28c5496c7d3f7c1..083304d26fc6c8f124a7d89b4d8b084c2c73209f 100644
--- a/src/OpenFOAM/meshes/data/data.C
+++ b/src/OpenFOAM/meshes/data/data.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2015 OpenFOAM Foundation
-    Copyright (C) 2020 OpenCFD Ltd.
+    Copyright (C) 2020-2023 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -29,50 +29,37 @@ License
 #include "data.H"
 #include "Time.H"
 
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-int Foam::data::debug(Foam::debug::debugSwitch("data", 0));
-
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::data::data(const objectRegistry& obr)
+Foam::data::data
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary* content
+)
 :
     IOdictionary
     (
         IOobject
         (
-            "data",
+            name,
             obr.time().system(),
             obr,
             IOobject::NO_READ,
-            IOobject::NO_WRITE
-        )
+            IOobject::NO_WRITE,
+            IOobject::REGISTER
+        ),
+        content
     ),
-    prevTimeIndex_(0)
+    prevTimeIndex_(-1)
 {
-    set("solverPerformance", dictionary());
+    if (content == nullptr || !findDict("solverPerformance", keyType::LITERAL))
+    {
+        set("solverPerformance", dictionary());
+    }
 }
 
 
-Foam::data::data(const objectRegistry& obr, const dictionary& dict)
-:
-    IOdictionary
-    (
-        IOobject
-        (
-            "data",
-            obr.time().system(),
-            obr,
-            IOobject::NO_READ,
-            IOobject::NO_WRITE
-        ),
-        dict
-    ),
-    prevTimeIndex_(0)
-{}
-
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 const Foam::dictionary& Foam::data::solverPerformanceDict() const
diff --git a/src/OpenFOAM/meshes/data/data.H b/src/OpenFOAM/meshes/data/data.H
index 91da9a93d4401f22c55519cd0282a7085e49fd69..202419a4c6402f275f3ff42b049554c6dbb2a92b 100644
--- a/src/OpenFOAM/meshes/data/data.H
+++ b/src/OpenFOAM/meshes/data/data.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2020 OpenCFD Ltd.
+    Copyright (C) 2020-2023 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -30,16 +30,17 @@ Class
 Description
     Database for solution data, solver performance and other reduced data.
 
-    fvMesh is derived from data so that all fields have access to the data from
-    the mesh reference they hold.
+    Both faMesh and fvMesh are derived from this class so that every
+    GeometricField has access to this data via their mesh reference.
 
 SourceFiles
     data.C
+    dataTemplates.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef data_H
-#define data_H
+#ifndef Foam_data_H
+#define Foam_data_H
 
 #include "IOdictionary.H"
 #include "solverPerformance.H"
@@ -57,7 +58,7 @@ class data
 :
     public IOdictionary
 {
-    // Private data
+    // Private Data
 
         //- Previously used time-index, used for reset between iterations
         mutable label prevTimeIndex_;
@@ -65,26 +66,69 @@ class data
 
     // Private Member Functions
 
+        //- True if boolean entry exists and is set
+        bool getBoolEntry(const word& keyword) const
+        {
+            bool value = false;
+            return readIfPresent(keyword, value) && value;
+        }
+
+        //- Add/remove boolean entry
+        void setBoolEntry(const word& keyword, bool on)
+        {
+            if (on)
+            {
+                add(keyword, true);
+            }
+            else
+            {
+                remove(keyword);
+            }
+        }
+
         //- No copy construct
         data(const data&) = delete;
 
         //- No copy assignment
         void operator=(const data&) = delete;
 
-
 public:
 
-    //- Debug switch
-    static int debug;
-
-
     // Constructors
 
-        //- Construct for objectRegistry
-        data(const objectRegistry& obr);
+        //- Construct for objectRegistry (registered with specified name)
+        //- optionally with initial content
+        data
+        (
+            const word& name,
+            const objectRegistry& obr,
+            const dictionary* content = nullptr
+        );
+
+        //- Construct for objectRegistry (registered as "data")
+        explicit data(const objectRegistry& obr)
+        :
+            data("data", obr)
+        {}
+
+        //- Construct for objectRegistry (registered with specified name)
+        //- copying initial content
+        data
+        (
+            const word& name,
+            const objectRegistry& obr,
+            const dictionary& dict
+        )
+        :
+            data(name, obr, &dict)
+        {}
 
-        //- Construct for objectRegistry and initial contents
-        data(const objectRegistry& obr, const dictionary& dict);
+        //- Construct for objectRegistry (registered as "data")
+        //- copying initial content
+        data(const objectRegistry& obr, const dictionary& dict)
+        :
+            data("data", obr, &dict)
+        {}
 
 
     // Member Functions
@@ -93,6 +137,31 @@ public:
         //- includes initial and final residuals for convergence checking
         const dictionary& solverPerformanceDict() const;
 
+        //- True if "firstIteration" entry exists and is set
+        bool isFirstIteration() const
+        {
+            return getBoolEntry("firstIteration");
+        }
+
+        //- True if "finalIteration" entry exists and is set
+        bool isFinalIteration() const
+        {
+            return getBoolEntry("finalIteration");
+        }
+
+        //- Add/remove "firstIteration" entry
+        void isFirstIteration(bool on)
+        {
+            return setBoolEntry("firstIteration", on);
+        }
+
+        //- Add/remove "finalIteration" entry
+        void isFinalIteration(bool on)
+        {
+            return setBoolEntry("finalIteration", on);
+        }
+
+
         //- Add/set the solverPerformance entry for the named field
         template<class Type>
         void setSolverPerformance
diff --git a/src/OpenFOAM/meshes/data/dataTemplates.C b/src/OpenFOAM/meshes/data/dataTemplates.C
index baa9c6f403fb1a7b5a3a4e8ec2508d554d4fd6b3..8bef786dd33e4722644fca9bcdecaf90d68a3129 100644
--- a/src/OpenFOAM/meshes/data/dataTemplates.C
+++ b/src/OpenFOAM/meshes/data/dataTemplates.C
@@ -53,8 +53,7 @@ void Foam::data::setSolverPerformance
         dict.readIfPresent(name, perfs);
     }
 
-    // Append to list
-    perfs.setSize(perfs.size()+1, sp);
+    perfs.push_back(sp);
 
     dict.set(name, perfs);
 }
diff --git a/src/finiteArea/faMesh/faMesh.C b/src/finiteArea/faMesh/faMesh.C
index eadb9eb7a05c1d94ebff28543f903f0615e69e6c..95c5081bbe273e65898bb43ac2edf8aac704e136 100644
--- a/src/finiteArea/faMesh/faMesh.C
+++ b/src/finiteArea/faMesh/faMesh.C
@@ -350,7 +350,7 @@ Foam::faMesh::faMesh
     faSchemes(mesh()),
     edgeInterpolation(*this),
     faSolution(mesh()),
-    data(mesh()),   // Always NO_READ, NO_WRITE
+    data(faMesh::thisDb()),   // Always NO_READ, NO_WRITE
     faceLabels_
     (
         IOobject
@@ -473,7 +473,7 @@ Foam::faMesh::faMesh
     faSchemes(mesh(), io.readOpt()),
     edgeInterpolation(*this),
     faSolution(mesh(), io.readOpt()),
-    data(mesh()),   // Always NO_READ, NO_WRITE
+    data(faMesh::thisDb()),   // Always NO_READ, NO_WRITE
     faceLabels_
     (
         IOobject
@@ -558,7 +558,7 @@ Foam::faMesh::faMesh
     ),
     data
     (
-        mesh(),
+        faMesh::thisDb(),
         static_cast<const data&>(baseMesh)
     ),
     faceLabels_