diff --git a/applications/utilities/parallelProcessing/redistributePar/parFaFieldDistributorCache.C b/applications/utilities/parallelProcessing/redistributePar/parFaFieldDistributorCache.C
index e5c4954cc1d3b2552f0a74feac7c12c69e04a5ef..04d3ba8857ec59dec4944023ad3ec97413a73a90 100644
--- a/applications/utilities/parallelProcessing/redistributePar/parFaFieldDistributorCache.C
+++ b/applications/utilities/parallelProcessing/redistributePar/parFaFieldDistributorCache.C
@@ -76,14 +76,10 @@ void Foam::parFaFieldDistributorCache::read
     // Missing an area mesh somewhere?
     if (areaMeshOnProc.found(false))
     {
-        const bool oldParRun = Pstream::parRun(false);
-
         // A zero-sized mesh with boundaries.
         // This is used to create zero-sized fields.
         subsetterPtr.reset(new faMeshSubset(mesh, zero{}));
 
-        Pstream::parRun(oldParRun);
-
         // Deregister from polyMesh ...
         auto& obr = const_cast<objectRegistry&>
         (
diff --git a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
index 5ac924fd1c14d63b6b91c7eeaa31e7d0777ea9af..15e57b0befb1845da5ccc425bfdc0032b8fffeb0 100644
--- a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
+++ b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
@@ -631,13 +631,9 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
         // Missing a volume mesh somewhere?
         if (volMeshOnProc.found(false))
         {
-            const bool oldParRun = Pstream::parRun(false);
-
             // A zero-sized mesh with boundaries.
             // This is used to create zero-sized fields.
             subsetterPtr.reset(new fvMeshSubset(mesh, zero{}));
-
-            Pstream::parRun(oldParRun);
         }
 
 
diff --git a/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMesh.C b/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMesh.C
index 7b3fe124edf1c974471698090f3bb4276e37d6be..5b5a6dd2ea4716bb3b7d6258cb6b884b98327bff 100644
--- a/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMesh.C
+++ b/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMesh.C
@@ -105,11 +105,11 @@ bool Foam::dynamicFvMesh::init(const bool doInit)
 Foam::dynamicFvMesh::dynamicFvMesh
 (
     const IOobject& io,
-    const zero,
-    const bool syncPar
+    const Foam::zero,
+    bool syncPar
 )
 :
-    fvMesh(io, Zero, syncPar),
+    fvMesh(io, Foam::zero{}, syncPar),
     timeControl_(io.time(), "update")
 {
     readDict();
diff --git a/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMesh.H b/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMesh.H
index 8622bb0ecb9b16518dcab927de9f9be71b15fcb6..5972583873811715d5a6a070833b7fe7ce61a777 100644
--- a/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMesh.H
+++ b/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMesh.H
@@ -115,12 +115,12 @@ public:
 
     // Constructors
 
-        //- Construct from an IOobject
+        //- Construct from IOobject
         explicit dynamicFvMesh(const IOobject& io, const bool doInit=true);
 
-        //- Construct from components without boundary.
+        //- Construct from IOobject or as zero-sized mesh
         //  Boundary is added using addFvPatches() member function
-        dynamicFvMesh(const IOobject& io, const zero, const bool syncPar=true);
+        dynamicFvMesh(const IOobject& io, const Foam::zero, bool syncPar=true);
 
         //- Construct from components without boundary.
         //  Boundary is added using addFvPatches() member function
diff --git a/src/finiteArea/faMesh/faMesh.C b/src/finiteArea/faMesh/faMesh.C
index 87ad1d36406e9bead768a2d485f1b095d44c5a49..34b43b2380be06de7a83368c05373c12c4ed81a4 100644
--- a/src/finiteArea/faMesh/faMesh.C
+++ b/src/finiteArea/faMesh/faMesh.C
@@ -307,6 +307,12 @@ Foam::faMesh::faMesh(const polyMesh& pMesh, const Foam::zero)
 {}
 
 
+Foam::faMesh::faMesh(const faMesh& baseMesh, const Foam::zero)
+:
+    faMesh(baseMesh, labelList())
+{}
+
+
 Foam::faMesh::faMesh
 (
     const polyMesh& pMesh,
@@ -483,6 +489,85 @@ Foam::faMesh::faMesh
 {}
 
 
+Foam::faMesh::faMesh
+(
+    const faMesh& baseMesh,
+    labelList&& faceLabels
+)
+:
+    MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>(baseMesh.mesh()),
+    faSchemes
+    (
+        mesh(),
+        static_cast<const faSchemes&>(baseMesh)
+    ),
+    edgeInterpolation(*this),
+    faSolution
+    (
+        mesh(),
+        static_cast<const faSolution&>(baseMesh)
+    ),
+    data
+    (
+        mesh(),
+        static_cast<const data&>(baseMesh)
+    ),
+    faceLabels_
+    (
+        IOobject
+        (
+            "faceLabels",
+            mesh().facesInstance(),
+            faMesh::meshSubDir,
+            mesh(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        std::move(faceLabels)
+    ),
+    boundary_
+    (
+        IOobject
+        (
+            "faBoundary",
+            mesh().facesInstance(),
+            faMesh::meshSubDir,
+            mesh(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        *this,
+        label(0)
+    ),
+    comm_(Pstream::worldComm),
+    curTimeIndex_(time().timeIndex()),
+
+    patchPtr_(nullptr),
+    bndConnectPtr_(nullptr),
+    lduPtr_(nullptr),
+
+    SPtr_(nullptr),
+    S0Ptr_(nullptr),
+    S00Ptr_(nullptr),
+    patchStartsPtr_(nullptr),
+    LePtr_(nullptr),
+    magLePtr_(nullptr),
+    centresPtr_(nullptr),
+    edgeCentresPtr_(nullptr),
+    faceAreaNormalsPtr_(nullptr),
+    edgeAreaNormalsPtr_(nullptr),
+    pointAreaNormalsPtr_(nullptr),
+    faceCurvaturesPtr_(nullptr),
+    edgeTransformTensorsPtr_(nullptr),
+    correctPatchPointNormalsPtr_(nullptr),
+    globalMeshDataPtr_(nullptr),
+
+    haloMapPtr_(nullptr),
+    haloFaceCentresPtr_(nullptr),
+    haloFaceNormalsPtr_(nullptr)
+{}
+
+
 Foam::faMesh::faMesh(const polyPatch& pp, const bool doInit)
 :
     faMesh
diff --git a/src/finiteArea/faMesh/faMesh.H b/src/finiteArea/faMesh/faMesh.H
index 633ecd56fc29e9ba2f11e3bcfc44fe97c1e9ebf4..62734dfe186e4db4a1f368cc781479302a2725c9 100644
--- a/src/finiteArea/faMesh/faMesh.H
+++ b/src/finiteArea/faMesh/faMesh.H
@@ -514,6 +514,16 @@ public:
         //  Boundary is added using addFaPatches() member function
         faMesh(const polyMesh& pMesh, const Foam::zero);
 
+        //- Construct as copy (for dictionaries) and zero-sized
+        //- without boundary, using IOobject properties from polyMesh.
+        //  Boundary is added using addFaPatches() member function
+        faMesh(const faMesh& baseMesh, const Foam::zero);
+
+        //- Construct as copy (for dictionaries) and faceLabels
+        //- without boundary, using IOobject properties from polyMesh.
+        //  Boundary is added using addFaPatches() member function
+        faMesh(const faMesh& baseMesh, labelList&& faceLabels);
+
         //- Construct from components (face labels) without boundary,
         //- using IOobject properties from polyMesh.
         //  Boundary is added using addFaPatches() member function.
diff --git a/src/finiteArea/faMesh/faMeshSubset/faMeshSubset.C b/src/finiteArea/faMesh/faMeshSubset/faMeshSubset.C
index 5a088e3a239bb6ead5690eb1be8744b39a1980bf..5310332f11230085b34891652cb08663f439e9af 100644
--- a/src/finiteArea/faMesh/faMeshSubset/faMeshSubset.C
+++ b/src/finiteArea/faMesh/faMeshSubset/faMeshSubset.C
@@ -103,19 +103,7 @@ void Foam::faMeshSubset::reset(const Foam::zero)
     // Create zero-sized subMesh
     subMeshPtr_.reset
     (
-        new faMesh
-        (
-            baseMesh_.mesh(),   // The polyMesh
-            // IOobject
-            // (
-            //     baseMesh_.name(),
-            //     baseMesh_.time().timeName(),
-            //     baseMesh_.time(),
-            //     IOobject::READ_IF_PRESENT,  // Read fa* if present
-            //     IOobject::NO_WRITE
-            // ),
-            Foam::zero{}                    // zero-sized
-        )
+        new faMesh(baseMesh_, Foam::zero{})
     );
     auto& newSubMesh = subMeshPtr_();
 
diff --git a/src/finiteArea/faSolution/faSolution.H b/src/finiteArea/faSolution/faSolution.H
index 935121e6b90ab3288bdf8497e2a5b09eba5cefbe..8e4ffa380262352a75fc1434b6cdefdc2ad9e413 100644
--- a/src/finiteArea/faSolution/faSolution.H
+++ b/src/finiteArea/faSolution/faSolution.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2016-2017 Wikki Ltd
-    Copyright (C) 2021 OpenCFD Ltd.
+    Copyright (C) 2021-2022 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -117,6 +117,14 @@ public:
         :
             solution(obr, "faSolution", fallback)
         {}
+
+        //- Construct for objectRegistry with the
+        //- default dictionary name ("faSolution") and optional contents.
+        //  Uses the readOption from the registry.
+        faSolution(const objectRegistry& obr, const dictionary& dict)
+        :
+            solution(obr, "faSolution", &dict)
+        {}
 };
 
 
diff --git a/src/finiteVolume/fvMesh/fvMesh.C b/src/finiteVolume/fvMesh/fvMesh.C
index dcb018ef8c09d972ee6db706cd2ea627240a780a..b5a79252a488e1483f664d15e9e74df9d54f8ee1 100644
--- a/src/finiteVolume/fvMesh/fvMesh.C
+++ b/src/finiteVolume/fvMesh/fvMesh.C
@@ -434,12 +434,33 @@ Foam::fvMesh::fvMesh
 }
 
 
-Foam::fvMesh::fvMesh(const IOobject& io, const zero, const bool syncPar)
+Foam::fvMesh::fvMesh(const IOobject& io, const Foam::zero, const bool syncPar)
 :
     fvMesh(io, pointField(), faceList(), labelList(), labelList(), syncPar)
 {}
 
 
+Foam::fvMesh::fvMesh
+(
+    const IOobject& io,
+    const fvMesh& baseMesh,
+    const Foam::zero,
+    const bool syncPar
+)
+:
+    fvMesh
+    (
+        io,
+        baseMesh,
+        pointField(),
+        faceList(),
+        labelList(),  // owner
+        labelList(),  // neighbour
+        syncPar
+    )
+{}
+
+
 Foam::fvMesh::fvMesh
 (
     const IOobject& io,
diff --git a/src/finiteVolume/fvMesh/fvMesh.H b/src/finiteVolume/fvMesh/fvMesh.H
index 58a4d3d8a8f93af276dfba0980163bd4639fe32e..aa8d6f494c7f52e1430bc888c36dc027c38629d2 100644
--- a/src/finiteVolume/fvMesh/fvMesh.H
+++ b/src/finiteVolume/fvMesh/fvMesh.H
@@ -194,7 +194,17 @@ public:
 
         //- Construct from IOobject or as zero-sized mesh
         //  Boundary is added using addFvPatches() member function
-        fvMesh(const IOobject& io, const zero, bool syncPar=true);
+        fvMesh(const IOobject& io, const Foam::zero, bool syncPar=true);
+
+        //- Construct as copy (for dictionaries) and zero-sized components.
+        //  Boundary is added using addFvPatches() member function
+        fvMesh
+        (
+            const IOobject& io,
+            const fvMesh& baseMesh,
+            const Foam::zero,
+            const bool syncPar = true
+        );
 
         //- Construct from components without boundary.
         //  Boundary is added using addFvPatches() member function
@@ -219,8 +229,8 @@ public:
             const bool syncPar = true
         );
 
-        //- Construct as copy (for dictionaries) and components without
-        //  boundary. Boundary is added using addFvPatches() member function
+        //- Copy construct (for dictionaries) with components, without boundary.
+        //  Boundary is added using addFvPatches() member function
         fvMesh
         (
             const IOobject& io,
@@ -232,9 +242,8 @@ public:
             const bool syncPar = true
         );
 
-        //- Construct as copy (for dictionaries) without boundary from cells
-        //  rather than owner/neighbour. Boundary is added using addFvPatches()
-        //  member function
+        //- Copy construct (for dictionaries) with cells, without boundary.
+        //  Boundary is added using addFvPatches() member function
         fvMesh
         (
             const IOobject& io,
diff --git a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C
index fbac703933d6f25ac78489ad994b0551c085c869..308a55300901718f904c1b6e1e33dc98b8ebec00 100644
--- a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C
+++ b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C
@@ -535,10 +535,11 @@ void Foam::fvMeshSubset::reset(const Foam::zero)
                 baseMesh_.name(),
                 baseMesh_.time().timeName(),
                 baseMesh_.time(),
-                IOobject::READ_IF_PRESENT,  // Read fv* if present
+                IOobject::NO_READ,      // Do not read any dictionaries
                 IOobject::NO_WRITE
             ),
-            Foam::zero{}                    // zero-sized
+            baseMesh_,                  // Get dictionaries from base mesh
+            Foam::zero{}                // zero-sized
             // Uses syncPar (bounds) - should generally be OK
         )
     );
@@ -1001,13 +1002,13 @@ void Foam::fvMeshSubset::reset
     (
         IOobject
         (
-            baseMesh().name(),
-            baseMesh().time().timeName(),
-            baseMesh().time(),
-            IOobject::NO_READ,      // do not read any dictionaries
+            baseMesh_.name(),
+            baseMesh_.time().timeName(),
+            baseMesh_.time(),
+            IOobject::NO_READ,          // Do not read any dictionaries
             IOobject::NO_WRITE
         ),
-        baseMesh(),                 // get dictionaries from base mesh
+        baseMesh_,                      // Get dictionaries from base mesh
         std::move(newPoints),
         std::move(newFaces),
         std::move(newCells),
diff --git a/tutorials/IO/fileHandler/Allrun-redistribute b/tutorials/IO/fileHandler/Test-distributed
similarity index 92%
rename from tutorials/IO/fileHandler/Allrun-redistribute
rename to tutorials/IO/fileHandler/Test-distributed
index 1eac6a371f672bc7fcdf16f6b186c4b323e58a5c..462f6bbd9af9a170227be9f6b9eee87fe0a92269 100755
--- a/tutorials/IO/fileHandler/Allrun-redistribute
+++ b/tutorials/IO/fileHandler/Test-distributed
@@ -3,6 +3,8 @@ cd "${0%/*}" || exit                                # Run from this directory
 . ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions        # Tutorial run functions
 #------------------------------------------------------------------------------
 
+# ./Allclean
+
 if isTest "$@"
 then
     # Reset the controlDict
@@ -44,7 +46,7 @@ CASE_ROOTS
 
 #export FOAM_ABORT=true
 
-runParallel redistributePar -decompose -case test-distribute/machineA/testcase
+runParallel -s decompose redistributePar -decompose -case test-distribute/machineA/testcase
 
 runParallel checkMesh -case test-distribute/machineA/testcase
 
diff --git a/tutorials/incompressible/pimpleFoam/laminar/filmPanel0/Allclean b/tutorials/incompressible/pimpleFoam/laminar/filmPanel0/Allclean
index fb1f3847301c377e02e12439ba58cbf303af3ef9..8141b3ae7b079d836c46c59786cac41be310df35 100755
--- a/tutorials/incompressible/pimpleFoam/laminar/filmPanel0/Allclean
+++ b/tutorials/incompressible/pimpleFoam/laminar/filmPanel0/Allclean
@@ -5,4 +5,6 @@ cd "${0%/*}" || exit                                # Run from this directory
 
 cleanCase0
 
+rm -rf test-*
+
 #------------------------------------------------------------------------------
diff --git a/tutorials/incompressible/pimpleFoam/laminar/filmPanel0/Test-distributed b/tutorials/incompressible/pimpleFoam/laminar/filmPanel0/Test-distributed
new file mode 100755
index 0000000000000000000000000000000000000000..d7069fd573a073cc92cc64c27d9f74f080e6535a
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/laminar/filmPanel0/Test-distributed
@@ -0,0 +1,58 @@
+#!/bin/sh
+cd "${0%/*}" || exit                                # Run from this directory
+. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions        # Tutorial run functions
+#------------------------------------------------------------------------------
+
+## ./Allclean
+
+restore0Dir
+
+runApplication blockMesh
+
+rm -rf test-distribute
+masterDecompParDict="test-distribute/machineA/testcase/system/decomposeParDict"
+
+for subdir in machineA machineB machineC machineD
+do
+    mkdir -p test-distribute/"$subdir"/testcase
+done
+
+# master
+cp -R 0 constant system test-distribute/machineA/testcase
+# others (nothing to copy)
+
+
+cat<< CASE_ROOTS >> "$masterDecompParDict"
+
+distributed true;
+
+roots
+(
+    //master: "$PWD/test-distribute/machineA"
+    "$PWD/test-distribute/machineA"
+    "$PWD/test-distribute/machineA"
+
+    "$PWD/test-distribute/machineB"
+    "$PWD/test-distribute/machineB"
+    "$PWD/test-distribute/machineB"
+
+    "$PWD/test-distribute/machineC"
+    "$PWD/test-distribute/machineC"
+    "$PWD/test-distribute/machineC"
+
+    "$PWD/test-distribute/machineD"
+    "$PWD/test-distribute/machineD"
+    "$PWD/test-distribute/machineD"
+);
+CASE_ROOTS
+
+#export FOAM_ABORT=true
+
+runParallel -s decompose redistributePar -decompose -case test-distribute/machineA/testcase
+
+# Currently fails (OpenFOAM-v2206)
+runParallel checkFaMesh -case test-distribute/machineA/testcase
+
+exit 0
+
+#------------------------------------------------------------------------------