diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurfaceRegister.C b/src/sampling/sampledSurface/sampledSurface/sampledSurfaceRegister.C
new file mode 100644
index 0000000000000000000000000000000000000000..c7fa0297d0ca15073c737b0824086f8da78057e4
--- /dev/null
+++ b/src/sampling/sampledSurface/sampledSurface/sampledSurfaceRegister.C
@@ -0,0 +1,294 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2004-2010, 2018-2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+                            | Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "sampledSurface.H"
+#include "polyMesh.H"
+#include "demandDrivenData.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(sampledSurface, 0);
+    defineRunTimeSelectionTable(sampledSurface, word);
+}
+
+
+const Foam::wordList Foam::sampledSurface::surfaceFieldTypes
+({
+    "surfaceScalarField",
+    "surfaceVectorField",
+    "surfaceSphericalTensorField",
+    "surfaceSymmTensorField",
+    "surfaceTensorField"
+});
+
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+void Foam::sampledSurface::clearGeom() const
+{
+    area_ = -1;
+}
+
+
+// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
+
+Foam::autoPtr<Foam::sampledSurface> Foam::sampledSurface::New
+(
+    const word& name,
+    const polyMesh& mesh,
+    const dictionary& dict
+)
+{
+    const word sampleType(dict.get<word>("type"));
+
+    if (debug)
+    {
+        Info<< "Selecting sampledType " << sampleType << endl;
+    }
+
+    auto cstrIter = wordConstructorTablePtr_->cfind(sampleType);
+
+    if (!cstrIter.found())
+    {
+        FatalErrorInFunction
+            << "Unknown sample type "
+            << sampleType << nl << nl
+            << "Valid sample types :" << endl
+            << wordConstructorTablePtr_->sortedToc()
+            << exit(FatalError);
+    }
+
+    return autoPtr<sampledSurface>(cstrIter()(name, mesh, dict));
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::sampledSurface::sampledSurface(const word& name, std::nullptr_t)
+:
+    name_(name),
+    mesh_(NullObjectRef<polyMesh>()),
+    enabled_(true),
+    interpolate_(false),
+    area_(-1),
+    writerType_(),
+    formatOptions_()
+{}
+
+
+Foam::sampledSurface::sampledSurface
+(
+    const word& name,
+    const polyMesh& mesh,
+    const bool interpolate
+)
+:
+    name_(name),
+    mesh_(mesh),
+    enabled_(true),
+    interpolate_(interpolate),
+    area_(-1),
+    writerType_(),
+    formatOptions_()
+{}
+
+
+Foam::sampledSurface::sampledSurface
+(
+    const word& name,
+    const polyMesh& mesh,
+    const dictionary& dict
+)
+:
+    name_(dict.lookupOrDefault<word>("name", name)),
+    mesh_(mesh),
+    enabled_(dict.lookupOrDefault("enabled", true)),
+    interpolate_(dict.lookupOrDefault("interpolate", false)),
+    area_(-1),
+    writerType_(dict.lookupOrDefault<word>("surfaceFormat", "")),
+    formatOptions_(dict.subOrEmptyDict("formatOptions"))
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::sampledSurface::~sampledSurface()
+{
+    clearGeom();
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::scalar Foam::sampledSurface::area() const
+{
+    if (area_ < 0)
+    {
+        area_ = gSum(magSf());
+    }
+
+    return area_;
+}
+
+
+bool Foam::sampledSurface::withSurfaceFields() const
+{
+    return false;
+}
+
+
+Foam::tmp<Foam::scalarField> Foam::sampledSurface::sample
+(
+    const surfaceScalarField& sField
+) const
+{
+    NotImplemented;
+    return nullptr;
+}
+
+
+Foam::tmp<Foam::vectorField> Foam::sampledSurface::sample
+(
+    const surfaceVectorField& sField
+) const
+{
+    NotImplemented;
+    return nullptr;
+}
+
+
+Foam::tmp<Foam::sphericalTensorField> Foam::sampledSurface::sample
+(
+    const surfaceSphericalTensorField& sField
+) const
+{
+    NotImplemented;
+    return nullptr;
+}
+
+
+Foam::tmp<Foam::symmTensorField> Foam::sampledSurface::sample
+(
+    const surfaceSymmTensorField& sField
+) const
+{
+    NotImplemented;
+    return nullptr;
+}
+
+
+Foam::tmp<Foam::tensorField> Foam::sampledSurface::sample
+(
+    const surfaceTensorField& sField
+) const
+{
+    NotImplemented;
+    return nullptr;
+}
+
+
+void Foam::sampledSurface::print(Ostream& os) const
+{
+    os << type();
+}
+
+
+Foam::polySurface* Foam::sampledSurface::getRegistrySurface
+(
+    const objectRegistry& obr,
+    word lookupName
+) const
+{
+    if (lookupName.empty())
+    {
+        lookupName = this->name();
+    }
+
+    return obr.getObjectPtr<polySurface>(lookupName);
+}
+
+
+Foam::polySurface* Foam::sampledSurface::storeRegistrySurface
+(
+    objectRegistry& obr,
+    word lookupName
+) const
+{
+    if (lookupName.empty())
+    {
+        lookupName = this->name();
+    }
+
+    polySurface* surfptr = getRegistrySurface(obr, lookupName);
+
+    if (!surfptr)
+    {
+        surfptr = new polySurface
+        (
+            lookupName,
+            obr,
+            true  // Add to registry - owned by registry
+        );
+    }
+
+    surfptr->deepCopy(*this);   // Copy in geometry (removes old fields)
+
+    return surfptr;
+}
+
+
+bool Foam::sampledSurface::removeRegistrySurface
+(
+    objectRegistry& obr,
+    word lookupName
+) const
+{
+    polySurface* surfptr = getRegistrySurface(obr, lookupName);
+
+    if (surfptr)
+    {
+        return obr.checkOut(*surfptr);
+    }
+
+    return false;
+}
+
+
+// * * * * * * * * * * * * * * * Ostream Operator  * * * * * * * * * * * * * //
+
+Foam::Ostream& Foam::operator<<(Ostream& os, const sampledSurface& s)
+{
+    s.print(os);
+    os.check(FUNCTION_NAME);
+    return os;
+}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/Make/files b/src/surfMesh/Make/files
index d78c9fa9464cb5264f934d37241ad7eb247b134c..c2ca286e1fe8857f95ecaf9441e3a3ca30b2c08d 100644
--- a/src/surfMesh/Make/files
+++ b/src/surfMesh/Make/files
@@ -1,16 +1,17 @@
-surfZone/surfZone.C
-surfZone/surfZoneIOList.C
-
 MeshedSurfaceAllocator/MeshedSurfaceIOAllocator.C
-
 MeshedSurface/MeshedSurfaceCore.C
 MeshedSurface/MeshedSurfaces.C
 UnsortedMeshedSurface/UnsortedMeshedSurfaces.C
-
 MeshedSurfaceProxy/MeshedSurfaceProxys.C
 
 mergedSurf/mergedSurf.C
 
+polySurface/polySurface.C
+polySurface/polySurfaceClear.C
+polySurface/polySurfaceIO.C
+polySurface/fields/polySurfaceFields.C
+polySurface/fields/polySurfacePointFields.C
+
 surfaceRegistry/surfaceRegistry.C
 surfMesh/surfMesh.C
 surfMesh/surfMeshClear.C
@@ -18,6 +19,9 @@ surfMesh/surfMeshIO.C
 surfMesh/fields/surfFields.C
 surfMesh/fields/surfPointFields.C
 
+surfZone/surfZone.C
+surfZone/surfZoneIOList.C
+
 surfaceFormats = surfaceFormats
 $(surfaceFormats)/surfaceFormatsCore.C
 
diff --git a/src/surfMesh/polySurface/fields/polySurfaceFields.C b/src/surfMesh/polySurface/fields/polySurfaceFields.C
new file mode 100644
index 0000000000000000000000000000000000000000..3904ced6a95182571e9941eb6840cd9a51290a18
--- /dev/null
+++ b/src/surfMesh/polySurface/fields/polySurfaceFields.C
@@ -0,0 +1,64 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "polySurfaceFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+template<>
+const word polySurfaceLabelField::typeName
+("polySurfaceLabelField");
+
+template<>
+const word polySurfaceScalarField::typeName
+("polySurfaceScalarField");
+
+template<>
+const word polySurfaceVectorField::typeName
+("polySurfaceVectorField");
+
+template<>
+const word polySurfaceSphericalTensorField::typeName
+("polySurfaceSphericalTensorField");
+
+template<>
+const word polySurfaceSymmTensorField::typeName
+("polySurfaceSymmTensorField");
+
+template<>
+const word polySurfaceTensorField::typeName
+("polySurfaceTensorField");
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/surfMesh/polySurface/fields/polySurfaceFields.H b/src/surfMesh/polySurface/fields/polySurfaceFields.H
new file mode 100644
index 0000000000000000000000000000000000000000..ce0d3271c479f59c4783b72d1af2014b3667b7a8
--- /dev/null
+++ b/src/surfMesh/polySurface/fields/polySurfaceFields.H
@@ -0,0 +1,46 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+InClass
+    Foam::polySurfaceFields
+
+Description
+    Fields for polySurface
+
+SourceFiles
+    polySurfaceFields.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef polySurfaceFields_H
+#define polySurfaceFields_H
+
+#include "DimensionedField.H"
+#include "polySurfaceGeoMesh.H"
+#include "polySurfaceFieldsFwd.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/surfMesh/polySurface/fields/polySurfaceFieldsFwd.H b/src/surfMesh/polySurface/fields/polySurfaceFieldsFwd.H
new file mode 100644
index 0000000000000000000000000000000000000000..59e0a01cc6c6cf2bec6642ee3ab543defe7e4348
--- /dev/null
+++ b/src/surfMesh/polySurface/fields/polySurfaceFieldsFwd.H
@@ -0,0 +1,92 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef polySurfacePointFieldsFwd_H
+#define polySurfacePointFieldsFwd_H
+
+#include "fieldTypes.H"
+#include "polySurface.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template<class Type, class GeoMesh>
+class DimensionedField;
+
+class polySurfaceGeoMesh;
+
+typedef DimensionedField<label, polySurfaceGeoMesh>
+    polySurfaceLabelField;
+
+typedef Foam::DimensionedField<scalar, polySurfaceGeoMesh>
+    polySurfaceScalarField;
+
+typedef Foam::DimensionedField<vector, polySurfaceGeoMesh>
+    polySurfaceVectorField;
+
+typedef Foam::DimensionedField<sphericalTensor, polySurfaceGeoMesh>
+    polySurfaceSphericalTensorField;
+
+typedef Foam::DimensionedField<symmTensor, polySurfaceGeoMesh>
+    polySurfaceSymmTensorField;
+
+typedef Foam::DimensionedField<tensor, polySurfaceGeoMesh>
+    polySurfaceTensorField;
+
+
+class polySurfacePointGeoMesh;
+
+typedef Foam::DimensionedField<label, polySurfacePointGeoMesh>
+    polySurfacePointLabelField;
+
+typedef Foam::DimensionedField<scalar, polySurfacePointGeoMesh>
+    polySurfacePointScalarField;
+
+typedef Foam::DimensionedField<vector, polySurfacePointGeoMesh>
+    polySurfacePointVectorField;
+
+typedef Foam::DimensionedField<sphericalTensor, polySurfacePointGeoMesh>
+    polySurfacePointSphericalTensorField;
+
+typedef Foam::DimensionedField<symmTensor, polySurfacePointGeoMesh>
+    polySurfacePointSymmTensorField;
+
+typedef Foam::DimensionedField<tensor, polySurfacePointGeoMesh>
+    polySurfacePointTensorField;
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/surfMesh/polySurface/fields/polySurfaceGeoMesh.H b/src/surfMesh/polySurface/fields/polySurfaceGeoMesh.H
new file mode 100644
index 0000000000000000000000000000000000000000..eec60d45d77e0396a5cdab2c37b046ffe17af70d
--- /dev/null
+++ b/src/surfMesh/polySurface/fields/polySurfaceGeoMesh.H
@@ -0,0 +1,86 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::polySurfaceGeoMesh
+
+Description
+    The polySurface GeoMesh (for holding fields).
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef polySurfaceGeoMesh_H
+#define polySurfaceGeoMesh_H
+
+#include "polySurface.H"
+#include "GeoMesh.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                    Class polySurfaceGeoMesh Declaration
+\*---------------------------------------------------------------------------*/
+
+class polySurfaceGeoMesh
+:
+    public GeoMesh<polySurface>
+{
+public:
+
+    // Constructors
+
+        //- Construct from polySurface reference
+        explicit polySurfaceGeoMesh(const polySurface& mesh)
+        :
+            GeoMesh<polySurface>(mesh)
+        {}
+
+
+    // Member Functions
+
+        //- Return size
+        static label size(const polySurface& mesh)
+        {
+            return mesh.faces().size();
+        }
+
+        //- Return size
+        label size() const
+        {
+            return size(mesh_);
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/surfMesh/polySurface/fields/polySurfacePointFields.C b/src/surfMesh/polySurface/fields/polySurfacePointFields.C
new file mode 100644
index 0000000000000000000000000000000000000000..c2fcbb3b1d9252f318c251aff12a801fcd2a203b
--- /dev/null
+++ b/src/surfMesh/polySurface/fields/polySurfacePointFields.C
@@ -0,0 +1,64 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "polySurfacePointFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+template<>
+const word polySurfacePointLabelField::typeName
+("polySurfacePointLabelField");
+
+template<>
+const word polySurfacePointScalarField::typeName
+("polySurfacePointScalarField");
+
+template<>
+const word polySurfacePointVectorField::typeName
+("polySurfacePointVectorField");
+
+template<>
+const word polySurfacePointSphericalTensorField::typeName
+("polySurfacePointSphericalTensorField");
+
+template<>
+const word polySurfacePointSymmTensorField::typeName
+("polySurfacePointSymmTensorField");
+
+template<>
+const word polySurfacePointTensorField::typeName
+("polySurfacePointTensorField");
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/surfMesh/polySurface/fields/polySurfacePointFields.H b/src/surfMesh/polySurface/fields/polySurfacePointFields.H
new file mode 100644
index 0000000000000000000000000000000000000000..118d47222c1f8b8612d80fe093314ba4d30f8c30
--- /dev/null
+++ b/src/surfMesh/polySurface/fields/polySurfacePointFields.H
@@ -0,0 +1,46 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+InClass
+    Foam::polySurfacePointFields
+
+Description
+    Point fields for polySurface
+
+SourceFiles
+    polySurfacePointFields.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef polySurfacePointFields_H
+#define polySurfacePointFields_H
+
+#include "DimensionedField.H"
+#include "polySurfacePointGeoMesh.H"
+#include "polySurfacePointFieldsFwd.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/surfMesh/polySurface/fields/polySurfacePointFieldsFwd.H b/src/surfMesh/polySurface/fields/polySurfacePointFieldsFwd.H
new file mode 100644
index 0000000000000000000000000000000000000000..32fed3a65667d0145cc0be69f875077950e8a5ec
--- /dev/null
+++ b/src/surfMesh/polySurface/fields/polySurfacePointFieldsFwd.H
@@ -0,0 +1,71 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef polySurfacePointFieldsFwd_H
+#define polySurfacePointFieldsFwd_H
+
+#include "fieldTypes.H"
+#include "polySurface.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template<class Type, class GeoMesh>
+class DimensionedField;
+
+class polySurfacePointGeoMesh;
+
+typedef Foam::DimensionedField<label, polySurfacePointGeoMesh>
+    polySurfacePointLabelField;
+
+typedef Foam::DimensionedField<scalar, polySurfacePointGeoMesh>
+    polySurfacePointScalarField;
+
+typedef Foam::DimensionedField<vector, polySurfacePointGeoMesh>
+    polySurfacePointVectorField;
+
+typedef Foam::DimensionedField<sphericalTensor, polySurfacePointGeoMesh>
+    polySurfacePointSphericalTensorField;
+
+typedef Foam::DimensionedField<symmTensor, polySurfacePointGeoMesh>
+    polySurfacePointSymmTensorField;
+
+typedef Foam::DimensionedField<tensor, polySurfacePointGeoMesh>
+    polySurfacePointTensorField;
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/surfMesh/polySurface/fields/polySurfacePointGeoMesh.H b/src/surfMesh/polySurface/fields/polySurfacePointGeoMesh.H
new file mode 100644
index 0000000000000000000000000000000000000000..f347d9b0337bae878719a25ac4f2419061532c6d
--- /dev/null
+++ b/src/surfMesh/polySurface/fields/polySurfacePointGeoMesh.H
@@ -0,0 +1,86 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::polySurfacePointGeoMesh
+
+Description
+    The polySurface GeoMesh (for holding point fields).
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef polySurfacePointGeoMesh_H
+#define polySurfacePointGeoMesh_H
+
+#include "polySurface.H"
+#include "GeoMesh.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                   Class polySurfacePointGeoMesh Declaration
+\*---------------------------------------------------------------------------*/
+
+class polySurfacePointGeoMesh
+:
+    public GeoMesh<polySurface>
+{
+public:
+
+    // Constructors
+
+        //- Construct from polySurface reference
+        explicit polySurfacePointGeoMesh(const polySurface& mesh)
+        :
+            GeoMesh<polySurface>(mesh)
+        {}
+
+
+    // Member Functions
+
+        //- Return size
+        static label size(const polySurface& mesh)
+        {
+            return mesh.points().size();
+        }
+
+        //- Return size
+        label size() const
+        {
+            return size(mesh_);
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/surfMesh/polySurface/polySurface.C b/src/surfMesh/polySurface/polySurface.C
new file mode 100644
index 0000000000000000000000000000000000000000..eaed15e8a706e3b2475af6c550a8c5636e607a1f
--- /dev/null
+++ b/src/surfMesh/polySurface/polySurface.C
@@ -0,0 +1,519 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "polySurface.H"
+#include "Time.H"
+#include "ModifiableMeshedSurface.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(polySurface, 0);
+}
+
+const Foam::word Foam::polySurface::pointDataName("PointData");
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::polySurface::calculateZoneIds(const UList<surfZone>& zones)
+{
+    if (returnReduce(zones.empty(), andOp<bool>()))
+    {
+        zoneIds_.clear();
+        return;
+    }
+
+    // Extra safety, ensure we have at some zones
+    // and they cover all the faces - fix start silently
+
+    zoneIds_.resize(size(), Zero);
+
+    label off = 0;
+    for (const surfZone& zn : zones)
+    {
+        const label sz = zn.size();
+
+        SubList<label>(zoneIds_, sz, off) = zn.index();
+
+        off += zn.size();
+    }
+
+    if (off < size())
+    {
+        WarningInFunction
+            << "More faces " << size() << " than zones " << off << endl;
+
+        SubList<label>(zoneIds_, size()-off, off) = zones.last().index();
+    }
+    else if (size() < off)
+    {
+        FatalErrorInFunction
+            << "More zones " << off << " than faces " << size()
+            << exit(FatalError);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::polySurface::polySurface(const IOobject& io, bool doCheckIn)
+:
+    objectRegistry
+    (
+        IOobject
+        (
+            io.name(),
+            io.db().time().constant(),
+            io.db(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE,
+            true
+        )
+    ),
+    MeshReference(faceList(), pointField()),
+    zoneIds_()
+{
+    // Created without a point field sub-registry
+
+    if (doCheckIn)
+    {
+        this->store();
+    }
+}
+
+
+Foam::polySurface::polySurface
+(
+    const word& surfName,
+    const objectRegistry& obr,
+    bool doCheckIn
+)
+:
+    polySurface
+    (
+        IOobject
+        (
+            surfName,
+            obr.time().constant(),
+            obr,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE,
+            true
+        ),
+        doCheckIn
+    )
+{}
+
+
+Foam::polySurface::polySurface
+(
+    const IOobject& io,
+    const MeshedSurface<face>& surf,
+    bool doCheckIn
+)
+:
+    polySurface(io, doCheckIn)
+{
+    copySurface(surf);
+}
+
+
+Foam::polySurface::polySurface
+(
+    const IOobject& io,
+    MeshedSurface<face>&& surf,
+    bool doCheckIn
+)
+:
+    polySurface(io, doCheckIn)
+{
+    transfer(surf);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::polySurface::~polySurface()
+{
+    ///  clearOut(); // Clear addressing
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::label Foam::polySurface::nFaceData() const
+{
+    label count = objectRegistry::size();
+
+    // Remove PointData sub-registry from being included in the count
+    if (objectRegistry::foundObject<objectRegistry>(pointDataName))
+    {
+        --count;
+    }
+
+    return count;
+}
+
+
+Foam::label Foam::polySurface::nPointData() const
+{
+    const objectRegistry* subreg =
+        objectRegistry::cfindObject<objectRegistry>(pointDataName);
+
+    if (subreg)
+    {
+        return subreg->size();
+    }
+
+    return 0;
+}
+
+
+const Foam::objectRegistry& Foam::polySurface::faceData() const
+{
+    return static_cast<const objectRegistry&>(*this);
+}
+
+
+const Foam::objectRegistry& Foam::polySurface::pointData() const
+{
+    // Force create on access
+    return objectRegistry::subRegistry(pointDataName, true);
+}
+
+
+Foam::polySurface::FieldAssociation
+Foam::polySurface::queryFieldAssociation(const word& fieldName) const
+{
+    unsigned where(FieldAssociation::NO_DATA);
+
+    // Face Data
+    {
+        const objectRegistry* regptr = this;
+
+        if (regptr && regptr->found(fieldName))
+        {
+            where |= FieldAssociation::FACE_DATA;
+        }
+    }
+
+    // Point Data
+    {
+        const objectRegistry* regptr =
+            cfindObject<objectRegistry>(pointDataName);
+
+        if (regptr && regptr->found(fieldName))
+        {
+            where |= FieldAssociation::POINT_DATA;
+        }
+    }
+
+    return FieldAssociation(where);
+}
+
+
+const Foam::regIOobject* Foam::polySurface::findFieldObject
+(
+    const word& fieldName,
+    enum FieldAssociation association
+) const
+{
+    const unsigned where(association);
+
+
+    const regIOobject* ioptr = nullptr;
+
+    // Face Data
+    if (where & FieldAssociation::FACE_DATA)
+    {
+        const objectRegistry* regptr = this;
+
+        if (regptr && (ioptr = regptr->cfindObject<regIOobject>(fieldName)))
+        {
+            return ioptr;
+        }
+    }
+
+    // Point Data
+    if (where & FieldAssociation::POINT_DATA)
+    {
+        const objectRegistry* regptr =
+            cfindObject<objectRegistry>(pointDataName);
+
+        if (regptr && (ioptr = regptr->cfindObject<regIOobject>(fieldName)))
+        {
+            return ioptr;
+        }
+    }
+
+    return ioptr;
+}
+
+
+void Foam::polySurface::copySurface
+(
+    const pointField& points,
+    const faceList& faces,
+    bool unused
+)
+{
+    clearOut(); // Clear addressing
+
+    if
+    (
+        this->nPoints() != points.size()
+     || this->nFaces() != faces.size()
+    )
+    {
+        // Geometry changed
+        clearFields();
+    }
+
+    this->storedPoints() = points;
+    this->storedFaces() = faces;
+
+    zoneIds_.clear();
+
+    // if (validate)
+    // {
+    //     checkZones();
+    // }
+}
+
+
+void Foam::polySurface::copySurface
+(
+    const meshedSurf& surf,
+    bool unused
+)
+{
+    clearOut(); // Clear addressing
+
+    if
+    (
+        this->nPoints() != surf.points().size()
+     || this->nFaces() != surf.faces().size()
+    )
+    {
+        // Geometry changed
+        clearFields();
+    }
+
+    this->storedPoints() = surf.points();
+    this->storedFaces() = surf.faces();
+
+    zoneIds_ = surf.zoneIds();
+
+    // if (validate)
+    // {
+    //     checkZones();
+    // }
+}
+
+
+void Foam::polySurface::copySurface
+(
+    const MeshedSurface<face>& surf,
+    bool unused
+)
+{
+    clearOut(); // Clear addressing
+
+    if
+    (
+        this->nPoints() != surf.points().size()
+     || this->nFaces() != surf.surfFaces().size()
+    )
+    {
+        // Geometry changed
+        clearFields();
+    }
+
+    this->storedPoints() = surf.points();
+    this->storedFaces() = surf.surfFaces();
+
+    calculateZoneIds(surf.surfZones());
+
+    // if (validate)
+    // {
+    //     checkZones();
+    // }
+}
+
+
+void Foam::polySurface::transfer
+(
+    pointField&& points,
+    faceList&& faces,
+    labelList&& zoneIds
+)
+{
+    clearOut(); // Clear addressing
+    clearFields();
+
+    this->storedPoints().transfer(points);
+    this->storedFaces().transfer(faces);
+    zoneIds_.transfer(zoneIds);
+}
+
+
+void Foam::polySurface::transfer
+(
+    MeshedSurface<face>& surf,
+    bool unused
+)
+{
+    clearOut(); // Clear addressing
+    clearFields();
+
+    ModifiableMeshedSurface<face> tsurf(std::move(surf));
+
+    this->storedPoints().transfer(tsurf.storedPoints());
+    this->storedFaces().transfer(tsurf.storedFaces());
+
+    calculateZoneIds(tsurf.surfZones());
+
+    // if (validate)
+    // {
+    //     checkZones();
+    // }
+}
+
+
+// void Foam::polySurface::checkZones()
+// {
+//     // Extra safety, ensure we have at some zones
+//     // and they cover all the faces - fix start silently
+//
+//     if (surfZones_.size() <= 1)
+//     {
+//         removeZones();
+//         return;
+//     }
+//
+//     label count = 0;
+//     for (surfZone& zn : surfZones_)
+//     {
+//         zn.start() = count;
+//         count += zn.size();
+//     }
+//
+//     if (count < nFaces())
+//     {
+//         WarningInFunction
+//             << "More faces " << nFaces() << " than zones " << count
+//             << " ... extending final zone"
+//             << endl;
+//
+//         surfZones_.last().size() += count - nFaces();
+//     }
+//     else if (size() < count)
+//     {
+//         FatalErrorInFunction
+//             << "More zones " << count << " than faces " << nFaces()
+//             << exit(FatalError);
+//     }
+// }
+
+
+// * * * * * * * * * * * * * * * Specializations * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+template<>
+const regIOobject* polySurface::findFieldObject<polySurfaceGeoMesh>
+(
+    const word& fieldName
+) const
+{
+    // Face Data (main registry)
+    return cfindObject<regIOobject>(fieldName);
+}
+
+
+template<>
+const regIOobject* polySurface::findFieldObject<polySurfacePointGeoMesh>
+(
+    const word& fieldName
+) const
+{
+    // Point Data (sub-registry)
+
+    const objectRegistry* subreg =
+        objectRegistry::cfindObject<objectRegistry>(pointDataName);
+
+    if (subreg)
+    {
+        return subreg->cfindObject<regIOobject>(fieldName);
+    }
+
+    return nullptr;
+}
+
+
+
+template<>
+const objectRegistry* polySurface::whichRegistry<polySurfaceGeoMesh>
+(
+    const word& fieldName
+) const
+{
+    // Face Data (main registry)
+    const objectRegistry* subreg = this;
+
+    if (subreg->found(fieldName))
+    {
+        return subreg;
+    }
+
+    return nullptr;
+}
+
+
+template<>
+const objectRegistry* polySurface::whichRegistry<polySurfacePointGeoMesh>
+(
+    const word& fieldName
+) const
+{
+    // Point Data (sub registry)
+
+    const objectRegistry* subreg =
+        objectRegistry::cfindObject<objectRegistry>(pointDataName);
+
+    if (subreg && subreg->found(fieldName))
+    {
+        return subreg;
+    }
+
+    return nullptr;
+}
+
+} // End of namespace
+
+// ************************************************************************* //
diff --git a/src/surfMesh/polySurface/polySurface.H b/src/surfMesh/polySurface/polySurface.H
new file mode 100644
index 0000000000000000000000000000000000000000..a7e51f946f19053f5b59d8c37064a5c9d37a1b19
--- /dev/null
+++ b/src/surfMesh/polySurface/polySurface.H
@@ -0,0 +1,483 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::polySurface
+
+Description
+    A surface mesh consisting of general polygon faces and capable of
+    holding fields.
+
+SourceFiles
+    polySurface.C
+    polySurfaceClear.C
+    polySurfaceIO.C
+    polySurfaceTemplates.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef polySurface_H
+#define polySurface_H
+
+#include "objectRegistry.H"
+#include "PrimitivePatch.H"
+#include "meshedSurf.H"
+#include "polySurfaceFieldsFwd.H"
+#include "polySurfacePointFieldsFwd.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declarations
+class dimensionSet;
+class surfZone;
+class polySurfaceGeoMesh;
+class polySurfacePointGeoMesh;
+
+template<class Face> class MeshedSurface;
+
+
+/*---------------------------------------------------------------------------*\
+                         Class polySurface Declaration
+\*---------------------------------------------------------------------------*/
+
+class polySurface
+:
+    public objectRegistry,
+    public PrimitivePatch<face, ::Foam::List, pointField, point>,
+    public meshedSurf
+{
+public:
+
+    //- Enumeration for the field association
+    enum FieldAssociation
+    {
+        NO_DATA = 0,            //!< No associated data
+        FACE_DATA = 0x1,        //!< Data associated with faces
+        POINT_DATA = 0x2,       //!< Data associated with points
+        FACE_POINT_DATA = 0x3   //!< Data associated with faces and points
+    };
+
+
+private:
+
+    // Private Typedefs
+
+        typedef PrimitivePatch
+        <
+            face,
+            ::Foam::List,
+            pointField,
+            point
+        >
+        MeshReference;
+
+
+    // Private Data
+
+        //- Per-face zone/region information
+        labelList zoneIds_;
+
+
+    // Private Member Functions
+
+        //- Calculate per-face zone/region information
+        void calculateZoneIds(const UList<surfZone>& zones);
+
+        //- No copy construct
+        polySurface(const polySurface&) = delete;
+
+        //- No copy assignment
+        void operator=(const polySurface&) = delete;
+
+
+protected:
+
+    // Protected Member Functions
+
+        //- Non-const access to points
+        pointField& storedPoints()
+        {
+            return const_cast<pointField&>(MeshReference::points());
+        }
+
+        //- Non-const access to the faces
+        faceList& storedFaces()
+        {
+            return static_cast<faceList&>(static_cast<MeshReference&>(*this));
+        }
+
+        //- Const access to the faces
+        const faceList& storedFaces() const
+        {
+            return
+                static_cast<const faceList&>
+                (
+                    static_cast<const MeshReference&>(*this)
+                );
+        }
+
+
+        //- Update with new contents
+        void copyContents(const MeshedSurface<face>& surf, bool validate=false);
+
+
+public:
+
+    // Public Typedefs
+
+    //- Typedef required for GeoMesh
+    typedef polySurface Mesh;
+
+    //- Placeholder only, for GeoMesh
+    typedef bool BoundaryMesh;
+
+    //- Name for point fields sub-registry
+    static const word pointDataName;
+
+
+    //- Runtime type information
+    TypeName("polySurface");
+
+
+    // Constructors
+
+        //- Construct null with NO_READ, NO_WRITE
+        //- optionally with a checkIn on the parent registry.
+        //  Created without a PointData sub-registry
+        explicit polySurface(const IOobject& io, bool doCheckIn = false);
+
+        //- Construct null with specified name on the given registry,
+        //- optionally with a checkIn on the parent registry.
+        //  Created without a PointData sub-registry
+        polySurface
+        (
+            const word& surfName,
+            const objectRegistry& obr,
+            bool doCheckIn = false
+        );
+
+        //- Copy construct from MeshedSurface<face> contents
+        //- with NO_READ, NO_WRITE
+        //- optionally with a checkIn on the parent registry.
+        //  Created without a PointData sub-registry
+        polySurface
+        (
+            const IOobject& io,
+            const MeshedSurface<face>& surf,
+            bool doCheckIn = false
+        );
+
+        //- Move construct from MeshedSurface<face> contents
+        //- with NO_READ, NO_WRITE
+        //- optionally with a checkIn on the parent registry.
+        //  Created without a PointData sub-registry
+        polySurface
+        (
+            const IOobject& io,
+            MeshedSurface<face>&& surf,
+            bool doCheckIn = false
+        );
+
+
+    //- Destructor
+    virtual ~polySurface();
+
+
+    // Member Functions
+
+    // Resolve iterator ambiguity in favour of Patch (not registry)
+
+        using MeshReference::end;
+        using MeshReference::cend;
+        using MeshReference::begin;
+        using MeshReference::cbegin;
+
+
+    // Access
+
+        //- Return the number of points
+        virtual label nPoints() const
+        {
+            return MeshReference::points().size();
+        }
+
+        //- Return the number of faces
+        virtual label nFaces() const
+        {
+            return MeshReference::size();
+        }
+
+        //- Return number of faces
+        virtual label size() const
+        {
+            return MeshReference::size();
+        }
+
+
+        //- Return points
+        virtual const pointField& points() const
+        {
+            return MeshReference::points();
+        }
+
+        //- Return faces
+        virtual const faceList& faces() const
+        {
+            return this->storedFaces();
+        }
+
+        //- Const access to per-face zone/region information (demand-driven)
+        virtual const labelList& zoneIds() const
+        {
+            return zoneIds_;
+        }
+
+        //- Return face area vectors (normals)
+        inline const vectorField& Sf() const
+        {
+            return MeshReference::faceAreas();
+        }
+
+        //- Return face area magnitudes
+        inline const scalarField& magSf() const
+        {
+            return MeshReference::magFaceAreas();
+        }
+
+        //- Face centres
+        inline const vectorField& Cf() const
+        {
+            return MeshReference::faceCentres();
+        }
+
+
+    // Modification
+
+        //- Update with new contents
+        void copySurface
+        (
+            const pointField& points,
+            const faceList& faces,
+            bool unused=false
+        );
+
+        //- Update with new contents
+        void copySurface
+        (
+            const meshedSurf& surf,
+            bool unused=false
+        );
+
+        //- Update with new contents
+        void copySurface
+        (
+            const MeshedSurface<face>& surf,
+            bool unused=false
+        );
+
+        //- Transfer the contents of the argument and annul the argument
+        //  Optionally validate the zone coverage.
+        void transfer
+        (
+            pointField&& points,
+            faceList&& faces,
+            labelList&& zoneIds = labelList()
+        );
+
+        //- Transfer the contents of the argument and annul the argument
+        //  Optionally validate the zone coverage.
+        void transfer
+        (
+            MeshedSurface<face>& surf,
+            bool validate=false
+        );
+
+
+    // Fields
+
+        //- Number of main entries, without PointData sub-registry
+        label nFaceData() const;
+
+        //- Number of entries on PointData sub-registry (if it exists)
+        label nPointData() const;
+
+        //- Query the field association (FACE or POINT)
+        FieldAssociation queryFieldAssociation(const word& fieldName) const;
+
+        //- Find the field object with the given name and required
+        //- FieldAssociation (FACE or POINT).
+        //  For FACE_POINT_DATA, face data are checked first.
+        //  \return nullptr is the field was not found
+        const regIOobject* findFieldObject
+        (
+            const word& fieldName,
+            const FieldAssociation association
+        ) const;
+
+        //- General finding of the field object (FACE or POINT)
+        //  Later specializations are used to restrict the scope.
+        //  \return nullptr is the field was not found
+        template<class GeoMeshType = void>
+        const regIOobject* findFieldObject(const word& fieldName) const;
+
+        //- General finding of the registry with the field object
+        //- (FACE or POINT).
+        //  Later specializations are used to restrict the scope.
+        //  \return nullptr is the field was not found
+        template<class GeoMeshType = void>
+        const objectRegistry* whichRegistry(const word& fieldName) const;
+
+        //- Regular data are stored directly on the registry
+        template<class DataType>
+        inline const objectRegistry& fieldData() const
+        {
+            return static_cast<const objectRegistry&>(*this);
+        }
+
+        //- Face data are stored directly on the registry
+        const objectRegistry& faceData() const;
+
+        //- Point data are stored in a sub-registry
+        //  Note that this method with automatically create the corresponding
+        //  sub-registry if it did not previously exist.
+        //  Use the nPointData() methods instead if you wish to test for
+        //  content without this side-effect.
+        const objectRegistry& pointData() const;
+
+
+        //- Copy/store named field as face or point data (template parameter).
+        //
+        //  Default is face-data (polySurfaceGeoMesh as template).
+        //  For point data use (polySurfacePointGeoMesh as template).
+        template<class Type, class GeoMeshType = polySurfaceGeoMesh>
+        void storeField
+        (
+            const word& fieldName,
+            const dimensionSet& dims,
+            const Field<Type>& values
+        );
+
+        //- Move/store named field as face or point data (template parameter).
+        //
+        //  Default is face-data (polySurfaceGeoMesh as template).
+        //  For point data use (polySurfacePointGeoMesh as template).
+        template<class Type, class GeoMeshType = polySurfaceGeoMesh>
+        void storeField
+        (
+            const word& fieldName,
+            const dimensionSet& dims,
+            Field<Type>&& values
+        );
+
+
+    // Writing
+
+        //- Write all components using given format, version and compression
+        virtual bool writeObject
+        (
+            IOstream::streamFormat fmt,
+            IOstream::versionNumber ver,
+            IOstream::compressionType cmp,
+            const bool valid
+        ) const;
+
+
+    // Storage Management
+
+        //- Clear geometry
+        void clearGeom();
+
+        //- Clear addressing
+        void clearAddressing();
+
+        //- Clear all geometry and addressing unnecessary for CFD
+        void clearOut();
+
+        //- Clear primitive data (points, faces and cells)
+        void clearPrimitives();
+
+        //- Clear stored fields
+        void clearFields();
+};
+
+
+//- Find face field object (on main registry).
+template<>
+const regIOobject* polySurface::findFieldObject<polySurfaceGeoMesh>
+(
+    const word& fieldName
+) const;
+
+
+//- Find point field object (on sub-registry)
+template<>
+const regIOobject* polySurface::findFieldObject<polySurfacePointGeoMesh>
+(
+    const word& fieldName
+) const;
+
+
+//- Return field object (on main registry).
+//- Face data field found on main registry?
+template<>
+const objectRegistry* polySurface::whichRegistry<polySurfaceGeoMesh>
+(
+    const word& fieldName
+) const;
+
+
+//- Point data field found on sub-registry?
+template<>
+const objectRegistry* polySurface::whichRegistry<polySurfaceGeoMesh>
+(
+    const word& fieldName
+) const;
+
+
+//- Point data are stored in a sub-registry
+template<>
+inline const objectRegistry&
+polySurface::fieldData<polySurfacePointGeoMesh>() const
+{
+    return pointData();
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "polySurfaceTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/surfMesh/polySurface/polySurfaceClear.C b/src/surfMesh/polySurface/polySurfaceClear.C
new file mode 100644
index 0000000000000000000000000000000000000000..f83541e84d25552f2582e1097748d68290094077
--- /dev/null
+++ b/src/surfMesh/polySurface/polySurfaceClear.C
@@ -0,0 +1,66 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "polySurface.H"
+#include "globalMeshData.H"
+#include "demandDrivenData.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::polySurface::clearGeom()
+{
+    DebugInFunction << "Clearing geometric data" << endl;
+
+    MeshReference::clearGeom();
+}
+
+
+void Foam::polySurface::clearAddressing()
+{
+    DebugInFunction << "Clearing topology" << endl;
+
+    MeshReference::clearPatchMeshAddr();
+}
+
+
+void Foam::polySurface::clearOut()
+{
+    MeshReference::clearOut();
+
+    clearGeom();
+    clearAddressing();
+}
+
+
+void Foam::polySurface::clearFields()
+{
+    // Clear the entire registry
+    objectRegistry::clear();
+
+    // Do not reinstate PointData sub-registry
+}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/polySurface/polySurfaceIO.C b/src/surfMesh/polySurface/polySurfaceIO.C
new file mode 100644
index 0000000000000000000000000000000000000000..83de0ceb56ca6c65010cf5f5bb1def2dbae80a90
--- /dev/null
+++ b/src/surfMesh/polySurface/polySurfaceIO.C
@@ -0,0 +1,42 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "polySurface.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::polySurface::writeObject
+(
+    IOstream::streamFormat fmt,
+    IOstream::versionNumber ver,
+    IOstream::compressionType cmp,
+    const bool valid
+) const
+{
+    return true; // no-op
+}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/polySurface/polySurfaceTemplates.C b/src/surfMesh/polySurface/polySurfaceTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..b7f2cb799627b205d8a36528e3029e2102d97c12
--- /dev/null
+++ b/src/surfMesh/polySurface/polySurfaceTemplates.C
@@ -0,0 +1,174 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "polySurface.H"
+#include "polySurfaceFields.H"
+#include "polySurfacePointFields.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class GeoMeshType>
+const Foam::regIOobject* Foam::polySurface::findFieldObject
+(
+    const word& fieldName
+) const
+{
+    // Face Data first (main registry)
+
+    const objectRegistry& obr = *this;
+
+    const auto* ioptr = obr.cfindObject<regIOobject>(fieldName);
+
+    if (ioptr)
+    {
+        return ioptr;
+    }
+
+    forAllConstIters(obr, iter)
+    {
+        const objectRegistry* subreg = isA<objectRegistry>(iter.val());
+
+        if (subreg && (ioptr = subreg->cfindObject<regIOobject>(fieldName)))
+        {
+            return ioptr;
+        }
+    }
+
+    return ioptr;
+}
+
+
+template<class GeoMeshType>
+const Foam::objectRegistry* Foam::polySurface::whichRegistry
+(
+    const word& fieldName
+) const
+{
+    // Face Data first (main registry)
+
+    const objectRegistry& obr = *this;
+
+    if (obr.found(fieldName))
+    {
+        return this;
+    }
+
+    forAllConstIters(obr, iter)
+    {
+        const objectRegistry* subreg = isA<objectRegistry>(iter.val());
+
+        if (subreg && subreg->found(fieldName))
+        {
+            return subreg;
+        }
+    }
+
+    return nullptr;
+}
+
+
+template<class Type, class GeoMeshType>
+void Foam::polySurface::storeField
+(
+    const word& fieldName,
+    const dimensionSet& dims,
+    const Field<Type>& values
+)
+{
+    // Force creates field database if needed.
+    const objectRegistry& fieldDb = this->fieldData<GeoMeshType>();
+
+    auto* dimfield =
+        fieldDb.getObjectPtr<DimensionedField<Type, GeoMeshType>>(fieldName);
+
+    if (dimfield)
+    {
+        dimfield->dimensions() = dims;
+        dimfield->field() = values;
+    }
+    else
+    {
+        dimfield = new DimensionedField<Type, GeoMeshType>
+        (
+            IOobject
+            (
+                fieldName,
+                fieldDb,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                true
+            ),
+            *this,
+            dims,
+            values
+        );
+
+        dimfield->store();
+    }
+}
+
+
+template<class Type, class GeoMeshType>
+void Foam::polySurface::storeField
+(
+    const word& fieldName,
+    const dimensionSet& dims,
+    Field<Type>&& values
+)
+{
+    // Force creates field database if needed.
+    const objectRegistry& fieldDb = this->fieldData<GeoMeshType>();
+
+    auto* dimfield =
+        fieldDb.getObjectPtr<DimensionedField<Type, GeoMeshType>>(fieldName);
+
+    if (dimfield)
+    {
+        dimfield->dimensions() = dims;
+        dimfield->field() = std::move(values);
+    }
+    else
+    {
+        dimfield = new DimensionedField<Type, GeoMeshType>
+        (
+            IOobject
+            (
+                fieldName,
+                fieldDb,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                true
+            ),
+            *this,
+            dims,
+            std::move(values)
+        );
+
+        dimfield->store();
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/surfMesh/surfMesh.C b/src/surfMesh/surfMesh/surfMesh.C
index 6bfd870b8f308f468c5c94e084a9f41b12241b4b..bc67756f31fe174381fb8ddb7da7351643d357c0 100644
--- a/src/surfMesh/surfMesh/surfMesh.C
+++ b/src/surfMesh/surfMesh/surfMesh.C
@@ -26,6 +26,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "surfMesh.H"
+#include "meshedSurf.H"
 #include "MeshedSurfaceProxy.H"
 
 #include "Time.H"
@@ -118,6 +119,51 @@ Foam::surfMesh::surfMesh(const IOobject& io, const word& surfName)
 {}
 
 
+Foam::surfMesh::surfMesh
+(
+    const word& surfName,
+    const objectRegistry& obr
+)
+:
+    surfaceRegistry(obr, surfName),
+    Allocator
+    (
+        IOobject
+        (
+            "points",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        IOobject
+        (
+            "faces",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        )
+    ),
+    MeshReference(this->storedIOFaces(), this->storedIOPoints()),
+
+    surfZones_
+    (
+        IOobject
+        (
+            "surfZones",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        )
+    )
+{}
+
+
 Foam::surfMesh::surfMesh
 (
     const IOobject& io,
@@ -170,7 +216,7 @@ Foam::surfMesh::surfMesh
         <<"  dbDir: " << io.db().dbDir() << nl
         <<"creating surfMesh at instance " << instance() << endl;
 
-    copyContents(surf);
+    copySurface(surf);
 }
 
 
@@ -272,7 +318,64 @@ void Foam::surfMesh::updateRefs()
 }
 
 
-void Foam::surfMesh::copyContents
+void Foam::surfMesh::copySurface
+(
+    const pointField& points,
+    const faceList& faces,
+    bool validate
+)
+{
+    clearOut(); // Clear addressing
+
+    if
+    (
+        this->nPoints() != points.size()
+     || this->nFaces() != faces.size()
+    )
+    {
+        // Geometry changed
+        clearFields();
+    }
+
+    this->storedIOPoints() = points;
+    this->storedIOFaces() = faces;
+    surfZones_.clear();
+
+    this->updateRefs();
+
+    // No zones
+}
+
+
+void Foam::surfMesh::copySurface
+(
+    const meshedSurf& surf,
+    bool validate
+)
+{
+    clearOut(); // Clear addressing
+
+    if
+    (
+        this->nPoints() != surf.points().size()
+     || this->nFaces() != surf.faces().size()
+    )
+    {
+        // Geometry changed
+        clearFields();
+    }
+
+    this->storedIOPoints() = surf.points();
+    this->storedIOFaces() = surf.faces();
+    surfZones_.clear();
+
+    this->updateRefs();
+
+    // No zones
+}
+
+
+void Foam::surfMesh::copySurface
 (
     const MeshedSurface<face>& surf,
     bool validate
@@ -280,6 +383,16 @@ void Foam::surfMesh::copyContents
 {
     clearOut(); // Clear addressing
 
+    if
+    (
+        this->nPoints() != surf.points().size()
+     || this->nFaces() != surf.surfFaces().size()
+    )
+    {
+        // Geometry changed
+        clearFields();
+    }
+
     this->storedIOPoints() = surf.points();
     this->storedIOFaces() = surf.surfFaces();
     surfZones_ = surf.surfZones();
@@ -327,6 +440,7 @@ Foam::surfMesh::releaseGeom()
 
     this->updateRefs(); // This may not be needed...
     clearOut(); // Clear addressing.
+    clearFields();
 
     return aptr;
 }
diff --git a/src/surfMesh/surfMesh/surfMesh.H b/src/surfMesh/surfMesh/surfMesh.H
index 195117fbae50b00b1ffe41445f57b76e72ccf9e7..fab3011176fd5e6fd2b31636e3f0aa9c94bd4608 100644
--- a/src/surfMesh/surfMesh/surfMesh.H
+++ b/src/surfMesh/surfMesh/surfMesh.H
@@ -45,12 +45,16 @@ SourceFiles
 #include "SubField.H"
 #include "surfZoneIOList.H"
 
+#include "surfFieldsFwd.H"
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
 // Forward declarations
+class dimensionSet;
+class meshedSurf;
 template<class Face> class MeshedSurface;
 
 /*---------------------------------------------------------------------------*\
@@ -141,9 +145,6 @@ protected:
         //- Update references to storedPoints/storedFaces
         virtual void updateRefs();
 
-        //- Update with new contents
-        void copyContents(const MeshedSurface<face>& surf, bool validate=false);
-
 
 public:
 
@@ -173,6 +174,9 @@ public:
         //  Writing = NO_WRITE
         surfMesh(const IOobject& io, const word& surfName);
 
+        //- Construct null with specified name on the given registry.
+        surfMesh(const word& surfName, const objectRegistry& obr);
+
         //- Copy construct from MeshedSurface<face>
         surfMesh
         (
@@ -283,6 +287,28 @@ public:
 
     // Modification
 
+        //- Update with new contents
+        void copySurface
+        (
+            const pointField& points,
+            const faceList& faces,
+            bool validate=false
+        );
+
+        //- Update with new contents
+        void copySurface
+        (
+            const meshedSurf& surf,
+            bool validate=false
+        );
+
+        //- Update with new contents
+        void copySurface
+        (
+            const MeshedSurface<face>& surf,
+            bool validate=false
+        );
+
         //- Transfer the contents of the argument and annul the argument
         //  Optionally validate the zone coverage.
         void transfer(MeshedSurface<face>& surf, bool validate=false);
@@ -291,6 +317,31 @@ public:
         virtual readUpdateState readUpdate();
 
 
+    // Fields
+
+        //- Copy/store named field as face or point data (template parameter).
+        //
+        //  Default is face-data (surfGeoMesh as template).
+        template<class Type, class GeoMeshType = surfGeoMesh>
+        void storeField
+        (
+            const word& fieldName,
+            const dimensionSet& dims,
+            const Field<Type>& values
+        );
+
+        //- Move/store named field as face or point data (template parameter).
+        //
+        //  Default is face-data (surfGeoMesh as template).
+        template<class Type, class GeoMeshType = surfGeoMesh>
+        void storeField
+        (
+            const word& fieldName,
+            const dimensionSet& dims,
+            Field<Type>&& values
+        );
+
+
     // Writing
 
         //- Avoid masking the normal objectRegistry write
@@ -341,6 +392,9 @@ public:
         //- Clear primitive data (points, faces and cells)
         void clearPrimitives();
 
+        //- Clear stored fields
+        void clearFields();
+
         //- Remove all files from mesh instance
         void removeFiles(const fileName& instanceDir) const;
 
@@ -355,6 +409,12 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+#ifdef NoRepository
+    #include "surfMeshTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
 #endif
 
 // ************************************************************************* //
diff --git a/src/surfMesh/surfMesh/surfMeshClear.C b/src/surfMesh/surfMesh/surfMeshClear.C
index 96a088cf289d22e303ceb85cd23d50c244fefcc5..5636305d6e56647ff136cb84f60d05f828f02810 100644
--- a/src/surfMesh/surfMesh/surfMeshClear.C
+++ b/src/surfMesh/surfMesh/surfMeshClear.C
@@ -69,4 +69,11 @@ void Foam::surfMesh::clearOut()
 }
 
 
+void Foam::surfMesh::clearFields()
+{
+    // Clear the entire registry
+    surfaceRegistry::clear();
+}
+
+
 // ************************************************************************* //
diff --git a/src/surfMesh/surfMesh/surfMeshTemplates.C b/src/surfMesh/surfMesh/surfMeshTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..5dbd1c90dd9733b6079f5ab315230b57b79ca419
--- /dev/null
+++ b/src/surfMesh/surfMesh/surfMeshTemplates.C
@@ -0,0 +1,111 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "surfMesh.H"
+#include "surfFields.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class Type, class GeoMeshType>
+void Foam::surfMesh::storeField
+(
+    const word& fieldName,
+    const dimensionSet& dims,
+    const Field<Type>& values
+)
+{
+    const objectRegistry& fieldDb = *this;
+
+    auto* dimfield =
+        fieldDb.getObjectPtr<DimensionedField<Type, GeoMeshType>>(fieldName);
+
+    if (dimfield)
+    {
+        dimfield->dimensions() = dims;
+        dimfield->field() = values;
+    }
+    else
+    {
+        dimfield = new DimensionedField<Type, GeoMeshType>
+        (
+            IOobject
+            (
+                fieldName,
+                fieldDb,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                true
+            ),
+            *this,
+            dims,
+            values
+        );
+
+        dimfield->store();
+    }
+}
+
+
+template<class Type, class GeoMeshType>
+void Foam::surfMesh::storeField
+(
+    const word& fieldName,
+    const dimensionSet& dims,
+    Field<Type>&& values
+)
+{
+    const objectRegistry& fieldDb = *this;
+
+    auto* dimfield =
+        fieldDb.getObjectPtr<DimensionedField<Type, GeoMeshType>>(fieldName);
+
+    if (dimfield)
+    {
+        dimfield->dimensions() = dims;
+        dimfield->field() = std::move(values);
+    }
+    else
+    {
+        dimfield = new DimensionedField<Type, GeoMeshType>
+        (
+            IOobject
+            (
+                fieldName,
+                fieldDb,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                true
+            ),
+            *this,
+            dims,
+            std::move(values)
+        );
+
+        dimfield->store();
+    }
+}
+
+
+// ************************************************************************* //