diff --git a/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.C b/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.C
index fd570cf90fabfe7474f3e286bba10d1c2ff10f26..bc84f3e2dd1359f265126c8737557f35bac89d83 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointBoundaryMesh/pointBoundaryMesh.C
@@ -555,7 +555,7 @@ Foam::label Foam::pointBoundaryMesh::findPatchID
     if (debug)
     {
         Pout<< "label pointBoundaryMesh::findPatchID(const word&) const"
-            << "Patch named " << patchName << " not found.  "
+            << " Patch named " << patchName << " not found.  "
             << "Available patch names: " << names() << endl;
     }
 
@@ -726,6 +726,23 @@ void Foam::pointBoundaryMesh::reorder
     {
         updateMesh();
     }
+
+    if (debug)
+    {
+        pointPatchList& Patches = *this;
+
+        Pout<< "pointBoundaryMesh::reorder"
+            << "(const labelUList&, const bool): "
+            << "reordered pointBoundaryMesh:" << endl;
+        Pout<< incrIndent;
+        for (const auto& pp : Patches)
+        {
+            Pout<< indent
+                << "index:" << pp.index() << " patch:" << pp.name()
+                << " type:" << pp.type() << endl;
+        }
+        Pout<< decrIndent;
+    }
 }
 
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointMesh.C b/src/OpenFOAM/meshes/pointMesh/pointMesh.C
index aa58807f82352bca9de1913331929dcaeef63d30..aa3828c0ef1829205b2ade291addacf26826e1bf 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointMesh.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointMesh.C
@@ -132,6 +132,25 @@ Foam::pointMesh::pointMesh
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+void Foam::pointMesh::setInstance
+(
+    const fileName& inst,
+    const IOobjectOption::writeOption wOpt
+)
+{
+    if (debug)
+    {
+        Pout<< "pointMesh::setInstance(): "
+            << "Setting instance to " << inst << endl;
+    }
+    this->writeOpt(wOpt);
+    this->instance() = inst;
+
+    boundary_.writeOpt(wOpt);
+    boundary_.instance() = inst;
+}
+
+
 bool Foam::pointMesh::movePoints()
 {
     if (debug)
@@ -160,4 +179,19 @@ void Foam::pointMesh::updateMesh(const mapPolyMesh& mpm)
 }
 
 
+bool Foam::pointMesh::writeObject
+(
+    IOstreamOption streamOpt,
+    const bool writeOnProc
+) const
+{
+    if (debug)
+    {
+        Pout<< "pointMesh::writeObject(IOstreamOption, const bool): "
+            << "Writing to " << boundary_.objectRelPath() << endl;
+    }
+    return boundary_.writeObject(streamOpt, writeOnProc);
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/pointMesh/pointMesh.H b/src/OpenFOAM/meshes/pointMesh/pointMesh.H
index 8edc5a8d2d20ac338bd31fe20da37f550a828d67..0981443f5dbd1e1f2e7d5725eec1af368f16da9c 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointMesh.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointMesh.H
@@ -155,6 +155,13 @@ public:
             return GeoMesh<polyMesh>::mesh_.time();
         }
 
+        //- Set the instance for mesh files
+        void setInstance
+        (
+            const fileName& instance,
+            const IOobjectOption::writeOption wOpt = IOobject::AUTO_WRITE
+        );
+
 
     // Volume Mesh
 
@@ -185,6 +192,16 @@ public:
         {
             return &pm == this;
         }
+
+
+    // Write
+
+        //- Write
+        virtual bool writeObject
+        (
+            IOstreamOption streamOpt,
+            const bool writeOnProc = true
+        ) const;
 };
 
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/basic/generic/genericPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/basic/generic/genericPointPatch.H
index fe01c486bde117149f8a8b2027a437075c2dea5f..1ff942519f780afc3efd2094df683e57182a8364 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/basic/generic/genericPointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/basic/generic/genericPointPatch.H
@@ -72,6 +72,39 @@ public:
         :
             facePointPatch(patch, bm)
         {}
+
+        //- Construct given the original patch and a map
+        genericPointPatch
+        (
+            const genericPointPatch& patch,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        )
+        :
+            facePointPatch(patch, bm, index, mapAddressing, reversePointMap)
+        {}
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::NewFrom<genericPointPatch>
+            (
+                *this,
+                bm,
+                index,
+                mapAddressing,
+                reversePointMap
+            );
+        }
 };
 
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.C b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.C
index ccccd2eb51e23c8ac2b161c0977aa0e9a557d269..479c7233c7fca3f7c9b9455af4ef4dd51fd81bf1 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.C
@@ -91,6 +91,20 @@ Foam::cyclicPointPatch::cyclicPointPatch
 {}
 
 
+Foam::cyclicPointPatch::cyclicPointPatch
+(
+    const cyclicPointPatch& patch,
+    const pointBoundaryMesh& bm,
+    const label index,
+    const labelUList& mapAddressing,
+    const labelUList& reversePointMap
+)
+:
+    coupledFacePointPatch(patch, bm, index, mapAddressing, reversePointMap),
+    cyclicPolyPatch_(refCast<const cyclicPolyPatch>(patch.patch()))
+{}
+
+
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::cyclicPointPatch::~cyclicPointPatch()
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.H
index 493c0dc9d5f2b596c9688e5d6846e05a3f05e1b0..e40fd90e64b9922798cce6c67cc765859ce5ec11 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.H
@@ -105,6 +105,36 @@ public:
             const pointBoundaryMesh& bm
         );
 
+        //- Construct given the original patch and a map
+        cyclicPointPatch
+        (
+            const cyclicPointPatch& patch,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        );
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::NewFrom<cyclicPointPatch>
+            (
+                *this,
+                bm,
+                index,
+                mapAddressing,
+                reversePointMap
+            );
+        }
+
 
     //- Destructor
     virtual ~cyclicPointPatch();
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclicSlip/cyclicSlipPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclicSlip/cyclicSlipPointPatch.H
index 7b8d8ec754d5244d764f6c80e91e86d9af136360..d9f6be76df81ee51b026ad9bd55cde4009f11146 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclicSlip/cyclicSlipPointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclicSlip/cyclicSlipPointPatch.H
@@ -73,6 +73,39 @@ public:
             cyclicPointPatch(patch, bm)
         {}
 
+        //- Construct given the original patch and a map
+        cyclicSlipPointPatch
+        (
+            const cyclicSlipPointPatch& patch,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        )
+        :
+            cyclicPointPatch(patch, bm, index, mapAddressing, reversePointMap)
+        {}
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::NewFrom<cyclicSlipPointPatch>
+            (
+                *this,
+                bm,
+                index,
+                mapAddressing,
+                reversePointMap
+            );
+        }
+
 
     //- Destructor
     virtual ~cyclicSlipPointPatch() = default;
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/empty/emptyPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/empty/emptyPointPatch.H
index 629cb53f9ac22b3c620b96c30feea11750526d92..6e4a41fe5d1e41d7fa96fdd3f172aeb9eff8f636 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/empty/emptyPointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/empty/emptyPointPatch.H
@@ -72,6 +72,39 @@ public:
             facePointPatch(patch, bm)
         {}
 
+        //- Construct given the original patch and a map
+        emptyPointPatch
+        (
+            const emptyPointPatch& patch,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        )
+        :
+            facePointPatch(patch, bm, index, mapAddressing, reversePointMap)
+        {}
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::NewFrom<emptyPointPatch>
+            (
+                *this,
+                bm,
+                index,
+                mapAddressing,
+                reversePointMap
+            );
+        }
+
 
     // Member Functions
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/nonuniformTransformCyclic/nonuniformTransformCyclicPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/nonuniformTransformCyclic/nonuniformTransformCyclicPointPatch.H
index 215d66170b539a755e3e84fbbd5907f97b53b235..8721152ad715a943cb3f0d3218a2380b378e27ad 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/nonuniformTransformCyclic/nonuniformTransformCyclicPointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/nonuniformTransformCyclic/nonuniformTransformCyclicPointPatch.H
@@ -73,6 +73,40 @@ public:
             cyclicPointPatch(patch, bm)
         {}
 
+        //- Construct given the original patch and a map
+        nonuniformTransformCyclicPointPatch
+        (
+            const nonuniformTransformCyclicPointPatch& patch,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        )
+        :
+            cyclicPointPatch(patch, bm, index, mapAddressing, reversePointMap)
+        {}
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::
+                NewFrom<nonuniformTransformCyclicPointPatch>
+                (
+                    *this,
+                    bm,
+                    index,
+                    mapAddressing,
+                    reversePointMap
+                );
+        }
+
 
     // Destructor
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.C b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.C
index 2190e44f8407add2d9ab9402699a0b421308c183..b81fab03d566f3b6119def2d7a1fe087e7963d17 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.C
@@ -117,4 +117,20 @@ Foam::processorPointPatch::processorPointPatch
 {}
 
 
+Foam::processorPointPatch::processorPointPatch
+(
+    const processorPointPatch& patch,
+    const pointBoundaryMesh& bm,
+    const label index,
+    const labelUList& mapAddressing,
+    const labelUList& reversePointMap
+)
+:
+    coupledFacePointPatch(patch, bm, index, mapAddressing, reversePointMap),
+    procPolyPatch_(refCast<const processorPolyPatch>(patch.patch()))
+{
+    //? map reverseMeshPoints_ or leave demand-driven
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.H
index df6a488b417bd9645b22800978697affab758cbc..2c59c5c9f357112ae07c81f909a183edcfeb2506 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.H
@@ -111,6 +111,36 @@ public:
             const pointBoundaryMesh& bm
         );
 
+        //- Construct given the original patch and a map
+        processorPointPatch
+        (
+            const processorPointPatch& patch,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        );
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::NewFrom<processorPointPatch>
+            (
+                *this,
+                bm,
+                index,
+                mapAddressing,
+                reversePointMap
+            );
+        }
+
 
     //- Destructor
     virtual ~processorPointPatch() = default;
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.C b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.C
index c195173f03926c5450aeef9e2873a5dd60f74226..0b933a27575c47bb3e585361d4b0c17b99bffe33 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.C
@@ -59,6 +59,20 @@ processorCyclicPointPatch::processorCyclicPointPatch
 {}
 
 
+Foam::processorCyclicPointPatch::processorCyclicPointPatch
+(
+    const processorCyclicPointPatch& patch,
+    const pointBoundaryMesh& bm,
+    const label index,
+    const labelUList& mapAddressing,
+    const labelUList& reversePointMap
+)
+:
+    processorPointPatch(patch, bm, index, mapAddressing, reversePointMap),
+    procCycPolyPatch_(refCast<const processorCyclicPolyPatch>(patch.patch()))
+{}
+
+
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 processorCyclicPointPatch::~processorCyclicPointPatch()
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.H
index c24d0324544db53466717ce7562b909d6b5d49bf..1132df269ef4f6c02b401a749486181ada3f97d5 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.H
@@ -89,6 +89,36 @@ public:
             const pointBoundaryMesh& bm
         );
 
+        //- Construct given the original patch and a map
+        processorCyclicPointPatch
+        (
+            const processorCyclicPointPatch& patch,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        );
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::NewFrom<processorCyclicPointPatch>
+            (
+                *this,
+                bm,
+                index,
+                mapAddressing,
+                reversePointMap
+            );
+        }
+
 
     //- Destructor
     virtual ~processorCyclicPointPatch();
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/symmetry/symmetryPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/symmetry/symmetryPointPatch.H
index d1dccb9125e6b8364d1e0d25e4e2f373e17fc956..6061b2aa8265c598b0b6d4b22f17e49288109642 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/symmetry/symmetryPointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/symmetry/symmetryPointPatch.H
@@ -75,6 +75,38 @@ public:
             facePointPatch(patch, bm)
         {}
 
+        //- Construct given the original patch and a map
+        symmetryPointPatch
+        (
+            const symmetryPointPatch& patch,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ):
+            facePointPatch(patch, bm, index, mapAddressing, reversePointMap)
+        {}
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::NewFrom<symmetryPointPatch>
+            (
+                *this,
+                bm,
+                index,
+                mapAddressing,
+                reversePointMap
+            );
+        }
+
 
     // Member Functions
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/symmetryPlane/symmetryPlanePointPatch.C b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/symmetryPlane/symmetryPlanePointPatch.C
index 57e66e7cc467fb3fae03d7eb2278c1b11efef341..52bfbfe9f010aeff616e339789e7d4b197f9fb34 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/symmetryPlane/symmetryPlanePointPatch.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/symmetryPlane/symmetryPlanePointPatch.C
@@ -58,6 +58,23 @@ Foam::symmetryPlanePointPatch::symmetryPlanePointPatch
 {}
 
 
+Foam::symmetryPlanePointPatch::symmetryPlanePointPatch
+(
+    const symmetryPlanePointPatch& patch,
+    const pointBoundaryMesh& bm,
+    const label index,
+    const labelUList& mapAddressing,
+    const labelUList& reversePointMap
+)
+:
+    facePointPatch(patch, bm, index, mapAddressing, reversePointMap),
+    symmetryPlanePolyPatch_
+    (
+        refCast<const symmetryPlanePolyPatch>(patch.patch())
+    )
+{}
+
+
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 void Foam::symmetryPlanePointPatch::applyConstraint
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/symmetryPlane/symmetryPlanePointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/symmetryPlane/symmetryPlanePointPatch.H
index cbca7e1f3c86f2ed92bac7587e98b5ab55f34063..869a8725709bf5d9761e859063bf63ed873c75ba 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/symmetryPlane/symmetryPlanePointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/symmetryPlane/symmetryPlanePointPatch.H
@@ -74,6 +74,36 @@ public:
             const pointBoundaryMesh& bm
         );
 
+        //- Construct given the original patch and a map
+        symmetryPlanePointPatch
+        (
+            const symmetryPlanePointPatch& patch,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        );
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::NewFrom<symmetryPlanePointPatch>
+            (
+                *this,
+                bm,
+                index,
+                mapAddressing,
+                reversePointMap
+            );
+        }
+
 
     // Member Functions
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/wedge/wedgePointPatch.C b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/wedge/wedgePointPatch.C
index 13989369045ffb8034e3f5f2c6c74800a9ab2921..84b1181045b43884361a44faa5853fdf7b2f1bf6 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/wedge/wedgePointPatch.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/wedge/wedgePointPatch.C
@@ -58,6 +58,20 @@ Foam::wedgePointPatch::wedgePointPatch
 {}
 
 
+Foam::wedgePointPatch::wedgePointPatch
+(
+    const wedgePointPatch& patch,
+    const pointBoundaryMesh& bm,
+    const label index,
+    const labelUList& mapAddressing,
+    const labelUList& reversePointMap
+)
+:
+    facePointPatch(patch, bm, index, mapAddressing, reversePointMap),
+    wedgePolyPatch_(refCast<const wedgePolyPatch>(patch.patch()))
+{}
+
+
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 void Foam::wedgePointPatch::applyConstraint
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/wedge/wedgePointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/wedge/wedgePointPatch.H
index e0100939cd68d5db63019cc5845c8ae0c0253e8e..a21513d04f8d23b1d294ae8153c2d9d8be9c5874 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/wedge/wedgePointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/wedge/wedgePointPatch.H
@@ -74,6 +74,36 @@ public:
             const pointBoundaryMesh& bm
         );
 
+        //- Construct given the original patch and a map
+        wedgePointPatch
+        (
+            const wedgePointPatch& pp,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        );
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::NewFrom<wedgePointPatch>
+            (
+                *this,
+                bm,
+                index,
+                mapAddressing,
+                reversePointMap
+            );
+        }
+
 
     // Member Functions
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.C b/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.C
index 40ab33cdd97714dfa3fc48b28da589a2918f9a6e..0dcb653a0523663cd7f7d61a5971f79cf4d0ca67 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.C
@@ -50,4 +50,19 @@ Foam::coupledFacePointPatch::coupledFacePointPatch
 {}
 
 
+Foam::coupledFacePointPatch::coupledFacePointPatch
+(
+    const coupledFacePointPatch& patch,
+    const pointBoundaryMesh& bm,
+    const label index,
+    const labelUList& mapAddressing,
+    const labelUList& reversePointMap
+)
+:
+    facePointPatch(patch, bm, index, mapAddressing, reversePointMap),
+    coupledPointPatch(bm),
+    coupledPolyPatch_(refCast<const coupledPolyPatch>(patch.patch()))
+{}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.H
index e3701771b458f868aaf1f2507bd04057b4205ea1..34724847dd21927a9d9dfd4b4f21913a3b77eeb8 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.H
@@ -91,6 +91,16 @@ public:
             const pointBoundaryMesh& bm
         );
 
+        //- Construct given the original patch and a map
+        coupledFacePointPatch
+        (
+            const coupledFacePointPatch& pp,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        );
+
 
     //- Destructor
     virtual ~coupledFacePointPatch() = default;
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/wall/wallPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/wall/wallPointPatch.H
index a69065029fa195e4f1ebb7110cdc3545f62ed68a..bc7b4c0fd0145ee97e8bf472d0fad3d6771af00a 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/wall/wallPointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/wall/wallPointPatch.H
@@ -71,6 +71,39 @@ public:
         :
             facePointPatch(patch, bm)
         {}
+
+        //- Construct given the original patch and a map
+        wallPointPatch
+        (
+            const wallPointPatch& patch,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        )
+        :
+            facePointPatch(patch, bm, index, mapAddressing, reversePointMap)
+        {}
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::NewFrom<wallPointPatch>
+            (
+                *this,
+                bm,
+                index,
+                mapAddressing,
+                reversePointMap
+            );
+        }
 };
 
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/facePointPatch/facePointPatch.C b/src/OpenFOAM/meshes/pointMesh/pointPatches/facePointPatch/facePointPatch.C
index 3c5c772141ddb13be59af57ef82d7c44949b1647..594061a96f86db8e35047afbb09e93920837fa85 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/facePointPatch/facePointPatch.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/facePointPatch/facePointPatch.C
@@ -89,4 +89,25 @@ Foam::facePointPatch::facePointPatch
 {}
 
 
+Foam::facePointPatch::facePointPatch
+(
+    const facePointPatch& pp,
+    const pointBoundaryMesh& bm,
+    const label index,
+    const labelUList& mapAddressing,
+    const labelUList& reversePointMap
+)
+:
+    pointPatch
+    (
+        pp.name(),
+        index,
+        bm,
+        pp.physicalType(),
+        pp.inGroups()
+    ),
+    polyPatch_(pp.patch())
+{}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/facePointPatch/facePointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/facePointPatch/facePointPatch.H
index efb6c4789956a1af827230db19a9487f4351a1f7..a988d533116e8c38d9ac482fd613296240ed810c 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/facePointPatch/facePointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/facePointPatch/facePointPatch.H
@@ -128,6 +128,36 @@ public:
             const pointBoundaryMesh& pm
         );
 
+        //- Construct given the original patch and a map
+        facePointPatch
+        (
+            const facePointPatch& pp,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        );
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::NewFrom<facePointPatch>
+            (
+                *this,
+                bm,
+                index,
+                mapAddressing,
+                reversePointMap
+            );
+        }
+
 
     // Selectors
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/meshPointPatch/meshPointPatch.C b/src/OpenFOAM/meshes/pointMesh/pointPatches/meshPointPatch/meshPointPatch.C
index bbc5bd4442553f00e192f3e893ec4e495750191a..e65ef019ef4890517d725c6968f0f5711d9e9150 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/meshPointPatch/meshPointPatch.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/meshPointPatch/meshPointPatch.C
@@ -93,6 +93,27 @@ Foam::meshPointPatch::meshPointPatch
 {}
 
 
+Foam::meshPointPatch::meshPointPatch
+(
+    const meshPointPatch& pp,
+    const pointBoundaryMesh& bm,
+    const label index,
+    const labelUList& mapAddressing,
+    const labelUList& reversePointMap
+)
+:
+    meshPointPatch
+    (
+        pp.name(),
+        labelList(reversePointMap, labelList(pp.meshPoints(), mapAddressing)),
+        vectorField(pp.pointNormals(), mapAddressing),
+        index,
+        bm,
+        pp.type()
+    )
+{}
+
+
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 void Foam::meshPointPatch::movePoints(PstreamBuffers&, const pointField& p)
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/meshPointPatch/meshPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/meshPointPatch/meshPointPatch.H
index dfefa219c6066ae3af3927ff3ea3dfd687d0a124..6d112edb2775b127c3a9c5ab1dd5fabe370573b5 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/meshPointPatch/meshPointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/meshPointPatch/meshPointPatch.H
@@ -56,8 +56,6 @@ namespace Foam
 class meshPointPatch
 :
     public pointPatch
-//,
-//    public patchIdentifier
 {
 private:
 
@@ -121,6 +119,36 @@ public:
             const word& patchType
         );
 
+        //- Construct given the original patch and a map
+        meshPointPatch
+        (
+            const meshPointPatch& pp,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        );
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const
+        {
+            return autoPtr<pointPatch>::NewFrom<meshPointPatch>
+            (
+                *this,
+                bm,
+                index,
+                mapAddressing,
+                reversePointMap
+            );
+        }
+
 
     //- Destructor
     virtual ~meshPointPatch() = default;
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/pointPatch/pointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/pointPatch/pointPatch.H
index c938ccb30a9dea9b515de7d2771902096b31acb8..6af214b3192ee84b4e2d4bfccb03a461641f79c4 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/pointPatch/pointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/pointPatch/pointPatch.H
@@ -166,6 +166,30 @@ public:
             boundaryMesh_(bm)
         {}
 
+        //- Construct given the original patch and a map
+        explicit pointPatch
+        (
+            const pointPatch& pp,
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        )
+        :
+            patchIdentifier(pp.name(), index, pp.physicalType(), pp.inGroups()),
+            boundaryMesh_(bm)
+        {}
+
+        //- Construct and return a subset clone,
+        //- resetting the point list and boundary mesh
+        virtual autoPtr<pointPatch> clone
+        (
+            const pointBoundaryMesh& bm,
+            const label index,
+            const labelUList& mapAddressing,
+            const labelUList& reversePointMap
+        ) const = 0;
+
 
     // Selectors
 
diff --git a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C
index de5d2dfed045681f8dc81026a5bc6c788a066976..f0e552d157c62c4a03f40a25083b580c9b89195f 100644
--- a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C
+++ b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2015-2022 OpenCFD Ltd.
+    Copyright (C) 2015-2022,2024 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -32,10 +32,16 @@ License
 #include "cyclicPolyPatch.H"
 #include "emptyPolyPatch.H"
 #include "processorPolyPatch.H"
+#include "meshPointPatch.H"
+#include "processorPointPatch.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-Foam::word Foam::fvMeshSubset::exposedPatchName("oldInternalFaces");
+namespace Foam
+{
+    word fvMeshSubset::exposedPatchName("oldInternalFaces");
+    defineTypeNameAndDebug(fvMeshSubset, 0);
+}
 
 
 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
@@ -522,6 +528,16 @@ void Foam::fvMeshSubset::reset
 
 void Foam::fvMeshSubset::reset(const Foam::zero)
 {
+    // Was old pointMesh present?
+    const auto* basePointMeshPtr =
+            baseMesh_.thisDb().cfindObject<pointMesh>(pointMesh::typeName);
+    if (basePointMeshPtr)
+    {
+        DebugPout<< "fvMeshSubset::reset(const Foam::zero) :"
+                << " Detected pointMesh" << endl;
+    }
+
+
     clear();
 
     // Create zero-sized subMesh
@@ -573,6 +589,46 @@ void Foam::fvMeshSubset::reset(const Foam::zero)
     }
 
 
+    // Clone old additional point patches
+    if (basePointMeshPtr)
+    {
+        DebugPout<< "Subsetting pointMesh" << endl;
+        const auto& basePointMesh = *basePointMeshPtr;
+        const auto& oldPointBoundary = basePointMesh.boundary();
+
+        // 1. Generate pointBoundaryMesh from polyBoundaryMesh (so ignoring
+        //    any additional patches
+        const auto& newSubPointMesh = pointMesh::New(newSubMesh);
+
+        auto& newBoundary =
+            const_cast<pointBoundaryMesh&>(newSubPointMesh.boundary());
+
+        // Start off from (poly)patch map
+        pointPatchMap_ = patchMap_;
+
+        // 2. Explicitly add subsetted meshPointPatches
+        for (const auto& oldPointPatch : oldPointBoundary)
+        {
+            const auto* mppPtr = isA<meshPointPatch>(oldPointPatch);
+            if (mppPtr && (newBoundary.findPatchID(mppPtr->name()) == -1))
+            {
+                newBoundary.push_back
+                (
+                    mppPtr->clone
+                    (
+                        newBoundary,
+                        newBoundary.size(),
+                        labelList::null(), // map
+                        labelList::null()  // map
+                    )
+                );
+            }
+        }
+
+        // Extend patchMap with -1
+        pointPatchMap_.setSize(newBoundary.size(), -1);
+    }
+
     // Add the zones
     subsetZones();
 }
@@ -585,6 +641,16 @@ void Foam::fvMeshSubset::reset
     const bool syncPar
 )
 {
+    // Was old pointMesh present?
+    const auto* basePointMeshPtr =
+            baseMesh_.thisDb().cfindObject<pointMesh>(pointMesh::typeName);
+    if (basePointMeshPtr)
+    {
+        DebugPout<< "fvMeshSubset::reset(const bitSet&) :"
+                << " Detected pointMesh" << endl;
+    }
+
+
     // Clear all old maps and pointers
     clear();
 
@@ -1125,6 +1191,8 @@ void Foam::fvMeshSubset::reset
 
     // Inserted patch
 
+    label newInternalPatchID = -1;
+
     if (wantedPatchID == -1)
     {
         label oldInternalSize = boundaryPatchSizes[oldInternalPatchID];
@@ -1158,6 +1226,7 @@ void Foam::fvMeshSubset::reset
             // the internal faces
             patchStart += boundaryPatchSizes[oldInternalPatchID];
             patchMap_[nNewPatches] = -1;
+            newInternalPatchID = nNewPatches;
             ++nNewPatches;
         }
     }
@@ -1232,6 +1301,98 @@ void Foam::fvMeshSubset::reset
 
     // Subset and add any zones
     subsetZones();
+
+
+    if (basePointMeshPtr)
+    {
+        DebugPout<< "Subsetting pointMesh" << endl;
+        const auto& basePointMesh = *basePointMeshPtr;
+        const auto& oldPointBoundary = basePointMesh.boundary();
+
+        // 1. Generate pointBoundaryMesh from polyBoundaryMesh (so ignoring
+        //    any additional patches
+        const auto& newSubPointMesh = pointMesh::New(subMeshPtr_());
+
+        pointPatchMap_ = patchMap_;
+
+        auto& newBoundary =
+            const_cast<pointBoundaryMesh&>(newSubPointMesh.boundary());
+
+
+        // 2. Explicitly add subsetted meshPointPatches
+        labelList oldToNewPoints(baseMesh_.nPoints(), -1);
+        forAll(pointMap_, i)
+        {
+            oldToNewPoints[pointMap_[i]] = i;
+        }
+
+
+        // Add meshPointPatches
+        pointPatchMap_.setSize(newBoundary.size(), -1);
+
+        for (const auto& oldPointPatch : oldPointBoundary)
+        {
+            const auto* mppPtr = isA<meshPointPatch>(oldPointPatch);
+            if (mppPtr && (newBoundary.findPatchID(mppPtr->name()) == -1))
+            {
+                const auto& mp = mppPtr->meshPoints();
+                DynamicList<label> subPointMap(mp.size());
+                forAll(mp, i)
+                {
+                    const label newPointi = oldToNewPoints[mp[i]];
+                    if (newPointi != -1)
+                    {
+                        subPointMap.append(i);
+                    }
+                }
+
+                pointPatchMap_.push_back(mppPtr->index());
+
+                newBoundary.push_back
+                (
+                    mppPtr->clone
+                    (
+                        newBoundary,
+                        newBoundary.size(),
+                        subPointMap,        // map
+                        oldToNewPoints
+                    )
+                );
+            }
+        }
+
+
+        // 3. rotate into place:
+        //      - global patches (including meshPointPatches)
+        //      - optional 'internalFaces' patch
+        //      - processor patches
+        labelList oldToNew(newBoundary.size());
+        label newPatchi = 0;
+        forAll(newBoundary, patchi)
+        {
+            if
+            (
+                patchi != newInternalPatchID
+            && !isA<processorPointPatch>(newBoundary[patchi])
+            )
+            {
+                oldToNew[patchi] = newPatchi++;
+            }
+        }
+        if (newInternalPatchID != -1)
+        {
+            oldToNew[newInternalPatchID] = newPatchi++;
+        }
+        forAll(newBoundary, patchi)
+        {
+            if (isA<processorPointPatch>(newBoundary[patchi]))
+            {
+                oldToNew[patchi] = newPatchi++;
+            }
+        }
+        newBoundary.reorder(oldToNew, true);
+        inplaceReorder(oldToNew, pointPatchMap_);
+    }
 }
 
 
diff --git a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.H b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.H
index bedb48e44345d5c8809e14c33459c65e21dd9eb1..d4ce7781a0a7ad2dd2aedad2926ca783996f15b0 100644
--- a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.H
+++ b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.H
@@ -102,6 +102,9 @@ class fvMeshSubset
         //- Patch mapping array
         labelList patchMap_;
 
+        //- PointPatch mapping array
+        labelList pointPatchMap_;
+
 
     // Private Member Functions
 
@@ -135,6 +138,10 @@ protected:
 
 public:
 
+    // Declare name of the class and its debug switch
+    ClassName("fvMeshSubset");
+
+
     // Static Data Members
 
         //- Name for exposed internal faces (default: oldInternalFaces)
@@ -225,6 +232,10 @@ public:
         //- Return patch map
         inline const labelList& patchMap() const;
 
+        //- Return point-patch map. Usually identical to patchMap except if
+        //- additional patches are added to the pointMesh.
+        inline const labelList& pointPatchMap() const;
+
 
     // Edit
 
diff --git a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetI.H b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetI.H
index c1bef91d564a504571a5cc351fa6a3e500cfdd06..b2f47f119c6a49eab63285505e0e66eef936a90c 100644
--- a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetI.H
+++ b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetI.H
@@ -104,4 +104,19 @@ inline const Foam::labelList& Foam::fvMeshSubset::patchMap() const
 }
 
 
+inline const Foam::labelList& Foam::fvMeshSubset::pointPatchMap() const
+{
+    checkHasSubMesh();
+
+    if (pointPatchMap_.empty())
+    {
+        return patchMap_;
+    }
+    else
+    {
+        return pointPatchMap_;
+    }
+}
+
+
 // ************************************************************************* //
diff --git a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetTemplates.C b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetTemplates.C
index 233090cd716ef65635ac3bed837bd0525bb23119..5d260498a2a7f9a4f2360d49cfc9b71443e64280 100644
--- a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetTemplates.C
+++ b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetTemplates.C
@@ -554,7 +554,7 @@ Foam::fvMeshSubset::interpolate
     (
         sf,
         pointMesh::New(subMesh()),     // subsetted point mesh
-        patchMap(),
+        pointPatchMap(),
         pointMap()
     );
 }