diff --git a/src/TurbulenceModels/turbulenceModels/eddyViscosity/eddyViscosity.C b/src/TurbulenceModels/turbulenceModels/eddyViscosity/eddyViscosity.C
index 47a4e601b60d38ffb4c4baa6bd1a0377b15ba698..65ae0c2d3eab09263961ce84a9b8e47b4e836906 100644
--- a/src/TurbulenceModels/turbulenceModels/eddyViscosity/eddyViscosity.C
+++ b/src/TurbulenceModels/turbulenceModels/eddyViscosity/eddyViscosity.C
@@ -97,7 +97,7 @@ Foam::eddyViscosity<BasicTurbulenceModel>::R() const
         if
         (
            !fvPatchField<symmTensor>::patchConstructorTablePtr_
-                ->found(patchFieldTypes[i])
+                ->contains(patchFieldTypes[i])
         )
         {
             patchFieldTypes[i] = fvPatchFieldBase::calculatedType();
diff --git a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetTemplates.C b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetTemplates.C
index 9dd83ab0e0aed4058f4c5659be6cb1bd59cb60e2..233090cd716ef65635ac3bed837bd0525bb23119 100644
--- a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetTemplates.C
+++ b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetTemplates.C
@@ -159,7 +159,7 @@ Foam::fvMeshSubset::interpolate
                 (
                     vf.boundaryField()[basePatchId],
                     subPatch,
-                    result(),
+                    result.internalField(),
                     mapper
                 )
             );
@@ -526,7 +526,7 @@ Foam::fvMeshSubset::interpolate
                 (
                     vf.boundaryField()[patchMap[patchi]],
                     subPatch,
-                    result(),
+                    result.internalField(),
                     directPointPatchFieldMapper(directAddressing)
                 )
             );
diff --git a/src/finiteVolume/fvMesh/singleCellFvMesh/singleCellFvMeshInterpolate.C b/src/finiteVolume/fvMesh/singleCellFvMesh/singleCellFvMeshInterpolate.C
index 312b763fcc2fcd37a529f91fc74ebc3a40060828..eb9e66b4fc46bd8f9a93b9edd6c5e029597f2e49 100644
--- a/src/finiteVolume/fvMesh/singleCellFvMesh/singleCellFvMeshInterpolate.C
+++ b/src/finiteVolume/fvMesh/singleCellFvMesh/singleCellFvMeshInterpolate.C
@@ -30,38 +30,18 @@ License
 #include "directFvPatchFieldMapper.H"
 #include "Time.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-tmp<GeometricField<Type, fvPatchField, volMesh>> singleCellFvMesh::interpolate
+Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
+Foam::singleCellFvMesh::interpolate
 (
     const GeometricField<Type, fvPatchField, volMesh>& vf
 ) const
 {
     // 1. Create the complete field with dummy patch fields
-    PtrList<fvPatchField<Type>> patchFields(vf.boundaryField().size());
-
-    forAll(patchFields, patchi)
-    {
-        patchFields.set
-        (
-            patchi,
-            fvPatchField<Type>::New
-            (
-                fvPatchFieldBase::calculatedType(),
-                boundary()[patchi],
-                fvPatchField<Type>::Internal::null()
-            )
-        );
-    }
 
-    // Create the complete field from the pieces
-    tmp<GeometricField<Type, fvPatchField, volMesh>> tresF
+    tmp<GeometricField<Type, fvPatchField, volMesh>> tresult
     (
         new GeometricField<Type, fvPatchField, volMesh>
         (
@@ -74,19 +54,18 @@ tmp<GeometricField<Type, fvPatchField, volMesh>> singleCellFvMesh::interpolate
                 IOobject::NO_WRITE
             ),
             *this,
+            Type(gAverage(vf.primitiveField())),
             vf.dimensions(),
-            Field<Type>(1, gAverage(vf)),
-            patchFields
+            fvPatchFieldBase::calculatedType()
         )
     );
-    GeometricField<Type, fvPatchField, volMesh>& resF = tresF.ref();
+    auto& result = tresult.ref();
 
 
     // 2. Change the fvPatchFields to the correct type using a mapper
     //  constructor (with reference to the now correct internal field)
 
-    typename GeometricField<Type, fvPatchField, volMesh>::
-        Boundary& bf = resF.boundaryFieldRef();
+    auto& bf = result.boundaryFieldRef();
 
     if (agglomerate())
     {
@@ -117,7 +96,7 @@ tmp<GeometricField<Type, fvPatchField, volMesh>> singleCellFvMesh::interpolate
                 (
                     vf.boundaryField()[patchi],
                     boundary()[patchi],
-                    resF(),
+                    result.internalField(),
                     agglomPatchFieldMapper(coarseToFine, coarseWeights)
                 )
             );
@@ -136,19 +115,15 @@ tmp<GeometricField<Type, fvPatchField, volMesh>> singleCellFvMesh::interpolate
                 (
                     vf.boundaryField()[patchi],
                     boundary()[patchi],
-                    resF(),
+                    result.internalField(),
                     directFvPatchFieldMapper(map)
                 )
             );
         }
     }
 
-    return tresF;
+    return tresult;
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/global/createZeroField.H b/src/optimisation/adjointOptimisation/adjoint/global/createZeroField.H
index 384f0f16f40ae41ae2eaf058d0542d72ed3086c9..93035d286f49396320498a04c05999ea0063c71e 100644
--- a/src/optimisation/adjointOptimisation/adjoint/global/createZeroField.H
+++ b/src/optimisation/adjointOptimisation/adjoint/global/createZeroField.H
@@ -94,13 +94,17 @@ createZeroBoundaryPtr
     // on symmetry patches (not a good practice either way)
     const fvBoundaryMesh& bm = mesh.boundary();
     wordList actualPatchTypes(bm.size(), word::null);
-    forAll(actualPatchTypes, pI)
+    forAll(actualPatchTypes, patchi)
     {
-        auto patchTypeCstrIter =
-            fvPatchField<Type>::patchConstructorTablePtr_->cfind(bm[pI].type());
-        if (patchTypeCstrIter.good())
+        if
+        (
+            fvPatchField<Type>::patchConstructorTablePtr_->contains
+            (
+                bm[patchi].type()
+            )
+        )
         {
-            actualPatchTypes[pI] = bm[pI].type();
+            actualPatchTypes[patchi] = bm[patchi].type();
         }
     }
 
diff --git a/src/parallel/decompose/decompose/dimFieldDecomposerTemplates.C b/src/parallel/decompose/decompose/dimFieldDecomposerTemplates.C
index de5e73cc7fccbd49142163a44b2116ab6023dcf3..4ffa33ec85b31a024722f83b74b216c43b71d915 100644
--- a/src/parallel/decompose/decompose/dimFieldDecomposerTemplates.C
+++ b/src/parallel/decompose/decompose/dimFieldDecomposerTemplates.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2021 OpenCFD Ltd.
+    Copyright (C) 2021-2024 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -37,26 +37,17 @@ Foam::dimFieldDecomposer::decomposeField
     const DimensionedField<Type, volMesh>& field
 ) const
 {
-    // Create and map the internal field values
-    Field<Type> mappedField(field, cellAddressing_);
-
     // Create the field for the processor
-    return
-        tmp<DimensionedField<Type, volMesh>>::New
-        (
-            IOobject
-            (
-                field.name(),
-                procMesh_.thisDb().time().timeName(),
-                procMesh_.thisDb(),
-                IOobject::NO_READ,
-                IOobject::NO_WRITE,
-                IOobject::NO_REGISTER
-            ),
-            procMesh_,
-            field.dimensions(),
-            std::move(mappedField)
-        );
+
+    return DimensionedField<Type, volMesh>::New
+    (
+        field.name(),
+        IOobject::NO_REGISTER,
+        procMesh_,
+        field.dimensions(),
+        // Internal field - mapped values
+        Field<Type>(field.field(), cellAddressing_)
+    );
 }
 
 
diff --git a/src/parallel/decompose/decompose/fvFieldDecomposerTemplates.C b/src/parallel/decompose/decompose/fvFieldDecomposerTemplates.C
index 007ee5d3d0fd9c0ff68db940aa28b81037507d76..9e5cfd727b7882051ca43f2adab0e32004d1facf 100644
--- a/src/parallel/decompose/decompose/fvFieldDecomposerTemplates.C
+++ b/src/parallel/decompose/decompose/fvFieldDecomposerTemplates.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2021 OpenCFD Ltd.
+    Copyright (C) 2021-2024 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -44,26 +44,17 @@ Foam::fvFieldDecomposer::decomposeField
     const DimensionedField<Type, volMesh>& field
 ) const
 {
-    // Create and map the internal field values
-    Field<Type> mappedField(field, cellAddressing_);
-
     // Create the field for the processor
-    return
-        tmp<DimensionedField<Type, volMesh>>::New
-        (
-            IOobject
-            (
-                field.name(),
-                procMesh_.thisDb().time().timeName(),
-                procMesh_.thisDb(),
-                IOobject::NO_READ,
-                IOobject::NO_WRITE,
-                IOobject::NO_REGISTER
-            ),
-            procMesh_,
-            field.dimensions(),
-            std::move(mappedField)
-        );
+
+    return DimensionedField<Type, volMesh>::New
+    (
+        field.name(),
+        IOobject::NO_REGISTER,
+        procMesh_,
+        field.dimensions(),
+        // Internal field - mapped values
+        Field<Type>(field.field(), cellAddressing_)
+    );
 }
 
 
@@ -75,52 +66,26 @@ Foam::fvFieldDecomposer::decomposeField
     const bool allowUnknownPatchFields
 ) const
 {
-    typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
-
-    // 1. Create the complete field with dummy patch fields
-    PtrList<fvPatchField<Type>> patchFields(boundaryAddressing_.size());
-
-    forAll(boundaryAddressing_, patchi)
-    {
-        patchFields.set
-        (
-            patchi,
-            fvPatchField<Type>::New
-            (
-                fvPatchFieldBase::calculatedType(),
-                procMesh_.boundary()[patchi],
-                fvPatchField<Type>::Internal::null()
-            )
-        );
-    }
-
     // Create the field for the processor
-    tmp<VolFieldType> tresF
+    // - with dummy patch fields
+    auto tresult = GeometricField<Type, fvPatchField, volMesh>::New
     (
-        new VolFieldType
-        (
-            IOobject
-            (
-                field.name(),
-                procMesh_.thisDb().time().timeName(),
-                procMesh_.thisDb(),
-                IOobject::NO_READ,
-                IOobject::NO_WRITE
-            ),
-            procMesh_,
-            field.dimensions(),
-            Field<Type>(field.primitiveField(), cellAddressing_),
-            patchFields
-        )
+        field.name(),
+        IOobject::NO_REGISTER,
+        procMesh_,
+        field.dimensions(),
+        // Internal field - mapped values
+        Field<Type>(field.primitiveField(), cellAddressing_),
+        fvPatchFieldBase::calculatedType()
     );
-    VolFieldType& resF = tresF.ref();
-    resF.oriented() = field().oriented();
+    auto& result = tresult.ref();
+    result.oriented() = field.oriented();
 
 
     // 2. Change the fvPatchFields to the correct type using a mapper
     //  constructor (with reference to the now correct internal field)
 
-    auto& bf = resF.boundaryFieldRef();
+    auto& bf = result.boundaryFieldRef();
 
     forAll(bf, patchi)
     {
@@ -133,7 +98,7 @@ Foam::fvFieldDecomposer::decomposeField
                 (
                     field.boundaryField()[boundaryAddressing_[patchi]],
                     procMesh_.boundary()[patchi],
-                    resF(),
+                    result.internalField(),
                     patchFieldDecomposerPtrs_[patchi]
                 )
             );
@@ -146,7 +111,7 @@ Foam::fvFieldDecomposer::decomposeField
                 new processorCyclicFvPatchField<Type>
                 (
                     procMesh_.boundary()[patchi],
-                    resF(),
+                    result.internalField(),
                     Field<Type>
                     (
                         field.primitiveField(),
@@ -163,7 +128,7 @@ Foam::fvFieldDecomposer::decomposeField
                 new processorFvPatchField<Type>
                 (
                     procMesh_.boundary()[patchi],
-                    resF(),
+                    result.internalField(),
                     Field<Type>
                     (
                         field.primitiveField(),
@@ -180,7 +145,7 @@ Foam::fvFieldDecomposer::decomposeField
                 new emptyFvPatchField<Type>
                 (
                     procMesh_.boundary()[patchi],
-                    resF()
+                    result.internalField()
                 )
             );
         }
@@ -192,7 +157,7 @@ Foam::fvFieldDecomposer::decomposeField
     }
 
     // Create the field for the processor
-    return tresF;
+    return tresult;
 }
 
 
@@ -203,27 +168,15 @@ Foam::fvFieldDecomposer::decomposeField
     const GeometricField<Type, fvsPatchField, surfaceMesh>& field
 ) const
 {
-    typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
-
     labelList mapAddr
     (
-        labelList::subList
-        (
-            faceAddressing_,
-            procMesh_.nInternalFaces()
-        )
+        labelList::subList(faceAddressing_, procMesh_.nInternalFaces())
     );
     forAll(mapAddr, i)
     {
         mapAddr[i] -= 1;
     }
 
-    // Create and map the internal field values
-    Field<Type> internalField
-    (
-        field.primitiveField(),
-        mapAddr
-    );
 
     // Problem with addressing when a processor patch picks up both internal
     // faces and faces from cyclic boundaries. This is a bit of a hack, but
@@ -232,66 +185,40 @@ Foam::fvFieldDecomposer::decomposeField
     // (i.e. using slices)
     Field<Type> allFaceField(field.mesh().nFaces());
 
-    forAll(field.primitiveField(), i)
     {
-        allFaceField[i] = field.primitiveField()[i];
-    }
+        SubList<Type>(allFaceField, field.primitiveField().size()) =
+            field.primitiveField();
 
-    forAll(field.boundaryField(), patchi)
-    {
-        const Field<Type>& p = field.boundaryField()[patchi];
+        forAll(field.boundaryField(), patchi)
+        {
+            const Field<Type>& pfld = field.boundaryField()[patchi];
 
-        const label patchStart = field.mesh().boundaryMesh()[patchi].start();
+            const label start = field.mesh().boundaryMesh()[patchi].start();
 
-        forAll(p, i)
-        {
-            allFaceField[patchStart + i] = p[i];
+            SubList<Type>(allFaceField, pfld.size(), start) = pfld;
         }
     }
 
 
     // 1. Create the complete field with dummy patch fields
-    PtrList<fvsPatchField<Type>> patchFields(boundaryAddressing_.size());
 
-    forAll(boundaryAddressing_, patchi)
-    {
-        patchFields.set
-        (
-            patchi,
-            fvsPatchField<Type>::New
-            (
-                fvsPatchFieldBase::calculatedType(),
-                procMesh_.boundary()[patchi],
-                fvsPatchField<Type>::Internal::null()
-            )
-        );
-    }
-
-    tmp<SurfaceFieldType> tresF
+    auto tresult = GeometricField<Type, fvsPatchField, surfaceMesh>::New
     (
-        new SurfaceFieldType
-        (
-            IOobject
-            (
-                field.name(),
-                procMesh_.thisDb().time().timeName(),
-                procMesh_.thisDb(),
-                IOobject::NO_READ,
-                IOobject::NO_WRITE
-            ),
-            procMesh_,
-            field.dimensions(),
-            Field<Type>(field.primitiveField(), mapAddr),
-            patchFields
-        )
+        field.name(),
+        IOobject::NO_REGISTER,
+        procMesh_,
+        field.dimensions(),
+        // Internal field - mapped values
+        Field<Type>(field.primitiveField(), mapAddr),
+        fvsPatchFieldBase::calculatedType()
     );
-    SurfaceFieldType& resF = tresF.ref();
-    resF.oriented() = field().oriented();
+    auto& result = tresult.ref();
+    result.oriented() = field.oriented();
 
     // 2. Change the fvsPatchFields to the correct type using a mapper
     //  constructor (with reference to the now correct internal field)
 
-    auto& bf = resF.boundaryFieldRef();
+    auto& bf = result.boundaryFieldRef();
 
     forAll(boundaryAddressing_, patchi)
     {
@@ -304,7 +231,7 @@ Foam::fvFieldDecomposer::decomposeField
                 (
                     field.boundaryField()[boundaryAddressing_[patchi]],
                     procMesh_.boundary()[patchi],
-                    resF(),
+                    result.internalField(),
                     patchFieldDecomposerPtrs_[patchi]
                 )
             );
@@ -317,7 +244,7 @@ Foam::fvFieldDecomposer::decomposeField
                 new processorCyclicFvsPatchField<Type>
                 (
                     procMesh_.boundary()[patchi],
-                    resF(),
+                    result.internalField(),
                     Field<Type>
                     (
                         allFaceField,
@@ -326,7 +253,7 @@ Foam::fvFieldDecomposer::decomposeField
                 )
             );
 
-            if (resF.is_oriented())
+            if (result.is_oriented())
             {
                 bf[patchi] *= faceSign_[patchi];
             }
@@ -339,7 +266,7 @@ Foam::fvFieldDecomposer::decomposeField
                 new processorFvsPatchField<Type>
                 (
                     procMesh_.boundary()[patchi],
-                    resF(),
+                    result.internalField(),
                     Field<Type>
                     (
                         allFaceField,
@@ -348,7 +275,7 @@ Foam::fvFieldDecomposer::decomposeField
                 )
             );
 
-            if (resF.is_oriented())
+            if (result.is_oriented())
             {
                 bf[patchi] *= faceSign_[patchi];
             }
@@ -361,7 +288,7 @@ Foam::fvFieldDecomposer::decomposeField
     }
 
     // Create the field for the processor
-    return tresF;
+    return tresult;
 }
 
 
diff --git a/src/parallel/decompose/decompose/pointFieldDecomposerTemplates.C b/src/parallel/decompose/decompose/pointFieldDecomposerTemplates.C
index 0c01857cd7eba0f9d53be2fdb30a37a1e70a387d..cc2671e98fdb7921f0f836ce814cf0e2de2bf941 100644
--- a/src/parallel/decompose/decompose/pointFieldDecomposerTemplates.C
+++ b/src/parallel/decompose/decompose/pointFieldDecomposerTemplates.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2021 OpenCFD Ltd.
+    Copyright (C) 2021-2024 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -38,9 +38,6 @@ Foam::pointFieldDecomposer::decomposeField
     const GeometricField<Type, pointPatchField, pointMesh>& field
 ) const
 {
-    // Create and map the internal field values
-    Field<Type> internalField(field.primitiveField(), pointAddressing_);
-
     // Create a list of pointers for the patchFields
     PtrList<pointPatchField<Type>> patchFields(boundaryAddressing_.size());
 
@@ -76,23 +73,17 @@ Foam::pointFieldDecomposer::decomposeField
     }
 
     // Create the field for the processor
-    return
-        tmp<GeometricField<Type, pointPatchField, pointMesh>>::New
-        (
-            IOobject
-            (
-                field.name(),
-                procMesh_.thisDb().time().timeName(),
-                procMesh_.thisDb(),
-                IOobject::NO_READ,
-                IOobject::NO_WRITE,
-                IOobject::NO_REGISTER
-            ),
-            procMesh_,
-            field.dimensions(),
-            internalField,
-            patchFields
-        );
+    return GeometricField<Type, pointPatchField, pointMesh>::New
+    (
+        field.name(),
+        IOobject::NO_REGISTER,
+        procMesh_,
+        field.dimensions(),
+        // Internal field - mapped values
+        Field<Type>(field.primitiveField(), pointAddressing_),
+        // Boundary field
+        patchFields
+    );
 }