diff --git a/applications/utilities/parallelProcessing/redistributePar/Make/files b/applications/utilities/parallelProcessing/redistributePar/Make/files
index 6e45d2d8cc66dbe1e97b35afc59eeb6dbf998428..2dacc462a991ed7201c109c5eebf849cf13672e0 100644
--- a/applications/utilities/parallelProcessing/redistributePar/Make/files
+++ b/applications/utilities/parallelProcessing/redistributePar/Make/files
@@ -1,7 +1,9 @@
 passivePositionParticleCloud.C
-parLagrangianRedistributor.C
+parLagrangianDistributor.C
+parLagrangianDistributorFields.C
 parPointFieldDistributor.C
-parFvFieldReconstructor.C
+parFvFieldDistributor.C
+parFvFieldDistributorFields.C
 
 loadOrCreateMesh.C
 redistributePar.C
diff --git a/applications/utilities/parallelProcessing/redistributePar/parFvFieldReconstructor.C b/applications/utilities/parallelProcessing/redistributePar/parFvFieldDistributor.C
similarity index 65%
rename from applications/utilities/parallelProcessing/redistributePar/parFvFieldReconstructor.C
rename to applications/utilities/parallelProcessing/redistributePar/parFvFieldDistributor.C
index 45acf1bf566b982a02c71757c8608188f439a55b..16187c06fc1222b2f35c6519bf9e480f398e7a40 100644
--- a/applications/utilities/parallelProcessing/redistributePar/parFvFieldReconstructor.C
+++ b/applications/utilities/parallelProcessing/redistributePar/parFvFieldDistributor.C
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2015 OpenFOAM Foundation
+    Copyright (C) 2022 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,48 +26,47 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "parFvFieldReconstructor.H"
+#include "parFvFieldDistributor.H"
+#include "bitSet.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+int Foam::parFvFieldDistributor::verbose_ = 1;
+
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::parFvFieldReconstructor::createPatchFaceMaps()
+void Foam::parFvFieldDistributor::createPatchFaceMaps()
 {
-    const fvBoundaryMesh& fvb = procMesh_.boundary();
+    const fvBoundaryMesh& fvb = srcMesh_.boundary();
 
-    patchFaceMaps_.setSize(fvb.size());
-    forAll(fvb, patchI)
+    patchFaceMaps_.resize(fvb.size());
+
+    forAll(fvb, patchi)
     {
-        if (!isA<processorFvPatch>(fvb[patchI]))
+        if (!isA<processorFvPatch>(fvb[patchi]))
         {
-            // Create map for patch faces only
-
-            // Mark all used elements (i.e. destination patch faces)
-            boolList faceIsUsed(distMap_.faceMap().constructSize(), false);
-            const polyPatch& basePatch = baseMesh_.boundaryMesh()[patchI];
-            forAll(basePatch, i)
-            {
-                faceIsUsed[basePatch.start()+i] = true;
-            }
+            // Create compact map for patch faces only
+            // - compact for used faces only (destination patch faces)
+            labelList oldToNewSub;
+            labelList oldToNewConstruct;
 
             // Copy face map
             patchFaceMaps_.set
             (
-                patchI,
+                patchi,
                 new mapDistributeBase(distMap_.faceMap())
             );
 
-            // Compact out unused elements
-            labelList oldToNewSub;
-            labelList oldToNewConstruct;
-            patchFaceMaps_[patchI].compact
+            patchFaceMaps_[patchi].compactRemoteData
             (
-                faceIsUsed,
-                procMesh_.nFaces(),      // maximum index of subMap
+                bitSet(tgtMesh_.boundaryMesh()[patchi].range()),
                 oldToNewSub,
                 oldToNewConstruct,
+                srcMesh_.nFaces(),   // max index of subMap
                 UPstream::msgType()
             );
-            //Pout<< "patchMap:" << patchFaceMaps_[patchI] << endl;
+            //Pout<< "patchMap:" << patchFaceMaps_[patchi] << endl;
         }
     }
 }
@@ -74,16 +74,16 @@ void Foam::parFvFieldReconstructor::createPatchFaceMaps()
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::parFvFieldReconstructor::parFvFieldReconstructor
+Foam::parFvFieldDistributor::parFvFieldDistributor
 (
-    fvMesh& baseMesh,
-    const fvMesh& procMesh,
+    const fvMesh& srcMesh,
+    fvMesh& tgtMesh,
     const mapDistributePolyMesh& distMap,
     const bool isWriteProc
 )
 :
-    baseMesh_(baseMesh),
-    procMesh_(procMesh),
+    srcMesh_(srcMesh),
+    tgtMesh_(tgtMesh),
     distMap_(distMap),
     isWriteProc_(isWriteProc)
 {
@@ -93,7 +93,7 @@ Foam::parFvFieldReconstructor::parFvFieldReconstructor
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void Foam::parFvFieldReconstructor::reconstructPoints()
+void Foam::parFvFieldDistributor::reconstructPoints()
 {
     // Reconstruct the points for moving mesh cases and write them out
     distributedFieldMapper mapper
@@ -101,11 +101,13 @@ void Foam::parFvFieldReconstructor::reconstructPoints()
         labelUList::null(),
         distMap_.pointMap()
     );
-    pointField basePoints(procMesh_.points(), mapper);
-    baseMesh_.movePoints(basePoints);
+
+    pointField newPoints(srcMesh_.points(), mapper);
+    tgtMesh_.movePoints(newPoints);
+
     if (Pstream::master())
     {
-        baseMesh_.write();
+        tgtMesh_.write();
     }
 }
 
diff --git a/applications/utilities/parallelProcessing/redistributePar/parFvFieldReconstructor.H b/applications/utilities/parallelProcessing/redistributePar/parFvFieldDistributor.H
similarity index 60%
rename from applications/utilities/parallelProcessing/redistributePar/parFvFieldReconstructor.H
rename to applications/utilities/parallelProcessing/redistributePar/parFvFieldDistributor.H
index 374c5bf8d1976a1e259199aa683a6d82df68c21f..cb4a76a304f8abbb9d72a074cf35db72aa2be73d 100644
--- a/applications/utilities/parallelProcessing/redistributePar/parFvFieldReconstructor.H
+++ b/applications/utilities/parallelProcessing/redistributePar/parFvFieldDistributor.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2015 OpenFOAM Foundation
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2022 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,22 +25,24 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::parFvFieldReconstructor
+    Foam::parFvFieldDistributor
 
 Description
     Finite volume reconstructor for volume and surface fields.
 
-    Runs in parallel. Reconstructs from procMesh to baseMesh. baseMesh
-    is non-zero cells on processor0 only.
+    Runs in parallel.
+    Reconstructs/redistributes from procMesh to baseMesh.
+    baseMesh is non-zero cells on processor0 only.
 
 SourceFiles
-    parFvFieldReconstructor.C
-    parFvFieldReconstructorFields.C
+    parFvFieldDistributor.C
+    parFvFieldDistributorFields.C
+    parFvFieldDistributorTemplates.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef parFvFieldReconstructor_H
-#define parFvFieldReconstructor_H
+#ifndef Foam_parFvFieldDistributor_H
+#define Foam_parFvFieldDistributor_H
 
 #include "PtrList.H"
 #include "fvMesh.H"
@@ -50,34 +52,34 @@ SourceFiles
 namespace Foam
 {
 
-// Forward declarations
+// Forward Declarations
 class mapDistributePolyMesh;
 class mapDistributeBase;
 class IOobjectList;
 
 /*---------------------------------------------------------------------------*\
-                    Class parFvFieldReconstructor Declaration
+                    Class parFvFieldDistributor Declaration
 \*---------------------------------------------------------------------------*/
 
-class parFvFieldReconstructor
+class parFvFieldDistributor
 {
-    // Private data
+    // Private Data
 
-        //- Reconstructed mesh reference
-        fvMesh& baseMesh_;
+        //- Processor mesh reference (source mesh)
+        const fvMesh& srcMesh_;
 
-        //- Processor mesh reference
-        const fvMesh& procMesh_;
+        //- Destination mesh reference (eg, reconstructed mesh)
+        fvMesh& tgtMesh_;
 
         //- Distribution map reference
         const mapDistributePolyMesh& distMap_;
 
-        //- Do I need to to write (usually master only)
-        const bool isWriteProc_;
-
         //- Patch mappers
         PtrList<mapDistributeBase> patchFaceMaps_;
 
+        //- Do I need to write (eg, master only for reconstruct)
+        bool isWriteProc_;
+
 
     // Private Member Functions
 
@@ -85,21 +87,30 @@ class parFvFieldReconstructor
         void createPatchFaceMaps();
 
         //- No copy construct
-        parFvFieldReconstructor(const parFvFieldReconstructor&) = delete;
+        parFvFieldDistributor(const parFvFieldDistributor&) = delete;
 
         //- No copy assignment
-        void operator=(const parFvFieldReconstructor&) = delete;
+        void operator=(const parFvFieldDistributor&) = delete;
 
 
 public:
 
+    //- Output verbosity when writing
+    static int verbose_;
+
+
     // Constructors
 
         //- Construct from components
-        parFvFieldReconstructor
+        //
+        //  \param srcMesh  The source mesh (eg, processor)
+        //  \param tgtMesh  The target mesh (eg, reconstructed)
+        //  \param distMap  The distribution map
+        //  \param isWriteProc  Tagged for output writing (on this proc)
+        parFvFieldDistributor
         (
-            fvMesh& baseMesh,
-            const fvMesh& procMesh,
+            const fvMesh& srcMesh,
+            fvMesh& tgtMesh,
             const mapDistributePolyMesh& distMap,
             const bool isWriteProc
         );
@@ -107,61 +118,85 @@ public:
 
     // Member Functions
 
-        //- Reconstruct volume internal field
+        //- Get status of write enabled (on this proc)
+        bool isWriteProc() const noexcept
+        {
+            return isWriteProc_;
+        }
+
+        //- Change status of write enabled (on this proc)
+        bool isWriteProc(const bool on) noexcept
+        {
+            bool old(isWriteProc_);
+            isWriteProc_ = on;
+            return old;
+        }
+
+
+        //- Helper: reconstruct and write mesh points
+        //  (note: should be moved to something like processorMeshes class)
+        void reconstructPoints();
+
+        //- Distribute all fields for known field types
+        void distributeAllFields
+        (
+            const IOobjectList& objects,
+            const wordRes& selectedFields
+        ) const;
+
+        //- Redistribute volume internal field
         template<class Type>
         tmp<DimensionedField<Type, volMesh>>
-        reconstructFvVolumeInternalField
+        distributeField
         (
             const DimensionedField<Type, volMesh>&
         ) const;
 
-        //- Read and reconstruct volume internal field
+        //- Read and distribute volume internal field
         template<class Type>
         tmp<DimensionedField<Type, volMesh>>
-        reconstructFvVolumeInternalField(const IOobject& fieldIoObject) const;
-
+        distributeInternalField(const IOobject& fieldObject) const;
 
 
-        //- Reconstruct volume field
+        //- Redistribute volume field
         template<class Type>
         tmp<GeometricField<Type, fvPatchField, volMesh>>
-        reconstructFvVolumeField
+        distributeField
         (
             const GeometricField<Type, fvPatchField, volMesh>& fld
         ) const;
 
-        //- Read and reconstruct volume field
+        //- Read and distribute volume field
         template<class Type>
         tmp<GeometricField<Type, fvPatchField, volMesh>>
-        reconstructFvVolumeField(const IOobject& fieldIoObject) const;
+        distributeVolumeField(const IOobject& fieldObject) const;
 
 
-
-        //- Reconstruct surface field
+        //- Redistribute surface field
         template<class Type>
         tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
-        reconstructFvSurfaceField
+        distributeField
         (
             const GeometricField<Type, fvsPatchField, surfaceMesh>&
         ) const;
 
-        //- Read and reconstruct surface field
+        //- Read and distribute surface field
         template<class Type>
         tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
-        reconstructFvSurfaceField(const IOobject& fieldIoObject) const;
+        distributeSurfaceField(const IOobject& fieldObject) const;
 
 
-        //- Read, reconstruct and write all/selected volume internal fields
+        //- Read, redistribute and write all/selected volume internal fields
         template<class Type>
-        label reconstructFvVolumeInternalFields
+        label distributeInternalFields
         (
             const IOobjectList& objects,
             const wordRes& selectedFields = wordRes()
         ) const;
 
-        //- Read, reconstruct and write all/selected volume fields
+        //- Read, redistribute and write all/selected volume fields
         template<class Type>
-        label reconstructFvVolumeFields
+        label distributeVolumeFields
         (
             const IOobjectList& objects,
             const wordRes& selectedFields = wordRes()
@@ -169,15 +204,11 @@ public:
 
         //- Read, reconstruct and write all/selected surface fields
         template<class Type>
-        label reconstructFvSurfaceFields
+        label distributeSurfaceFields
         (
             const IOobjectList& objects,
             const wordRes& selectedFields = wordRes()
         ) const;
-
-        //- Helper: reconstruct and write mesh points
-        //  (note: should be moved to something like processorMeshes class)
-        void reconstructPoints();
 };
 
 
@@ -188,7 +219,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-#   include "parFvFieldReconstructorFields.C"
+#   include "parFvFieldDistributorTemplates.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/applications/utilities/parallelProcessing/redistributePar/parFvFieldDistributorFields.C b/applications/utilities/parallelProcessing/redistributePar/parFvFieldDistributorFields.C
new file mode 100644
index 0000000000000000000000000000000000000000..3a0ae73d048082c12958aec7a2a2f8d9b19a2578
--- /dev/null
+++ b/applications/utilities/parallelProcessing/redistributePar/parFvFieldDistributorFields.C
@@ -0,0 +1,62 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2022 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "parFvFieldDistributor.H"
+#include "volFields.H"
+#include "surfaceFields.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::parFvFieldDistributor::distributeAllFields
+(
+    const IOobjectList& objects,
+    const wordRes& selectedFields
+) const
+{
+    do
+    {
+        #undef  doLocalCode
+        #define doLocalCode(Method)                                           \
+        {                                                                     \
+            this->Method <scalar> (objects, selectedFields);                  \
+            this->Method <vector> (objects, selectedFields);                  \
+            this->Method <sphericalTensor> (objects, selectedFields);         \
+            this->Method <symmTensor> (objects, selectedFields);              \
+            this->Method <tensor> (objects, selectedFields);                  \
+        }
+
+        doLocalCode(distributeInternalFields);
+        doLocalCode(distributeVolumeFields);
+        doLocalCode(distributeSurfaceFields);
+
+        #undef doLocalCode
+    }
+    while (false);
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/parallelProcessing/redistributePar/parFvFieldReconstructorFields.C b/applications/utilities/parallelProcessing/redistributePar/parFvFieldDistributorTemplates.C
similarity index 53%
rename from applications/utilities/parallelProcessing/redistributePar/parFvFieldReconstructorFields.C
rename to applications/utilities/parallelProcessing/redistributePar/parFvFieldDistributorTemplates.C
index 4a314017641e36b2853cbfe9b3670c9fe7e37896..7bbdf59c648639d8680e23421a08fb831666f82a 100644
--- a/applications/utilities/parallelProcessing/redistributePar/parFvFieldReconstructorFields.C
+++ b/applications/utilities/parallelProcessing/redistributePar/parFvFieldDistributorTemplates.C
@@ -26,7 +26,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "parFvFieldReconstructor.H"
+#include "parFvFieldDistributor.H"
 #include "Time.H"
 #include "PtrList.H"
 #include "fvPatchFields.H"
@@ -44,36 +44,33 @@ License
 
 template<class Type>
 Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
-Foam::parFvFieldReconstructor::reconstructFvVolumeInternalField
+Foam::parFvFieldDistributor::distributeField
 (
     const DimensionedField<Type, volMesh>& fld
 ) const
 {
+    // Create internalField by remote mapping
+
     distributedFieldMapper mapper
     (
         labelUList::null(),
         distMap_.cellMap()
     );
 
-    Field<Type> internalField(fld, mapper);
-
-    // Construct a volField
-    IOobject baseIO
-    (
-        fld.name(),
-        baseMesh_.time().timeName(),
-        fld.local(),
-        baseMesh_,
-        IOobject::NO_READ,
-        IOobject::NO_WRITE
-    );
-
     auto tfield = tmp<DimensionedField<Type, volMesh>>::New
     (
-        baseIO,
-        baseMesh_,
+        IOobject
+        (
+            fld.name(),
+            tgtMesh_.time().timeName(),
+            fld.local(),
+            tgtMesh_,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        tgtMesh_,
         fld.dimensions(),
-        internalField
+        Field<Type>(fld, mapper)
     );
 
     tfield.ref().oriented() = fld.oriented();
@@ -82,98 +79,86 @@ Foam::parFvFieldReconstructor::reconstructFvVolumeInternalField
 }
 
 
-template<class Type>
-Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
-Foam::parFvFieldReconstructor::reconstructFvVolumeInternalField
-(
-    const IOobject& fieldIoObject
-) const
-{
-    // Read the field
-    DimensionedField<Type, volMesh> fld
-    (
-        fieldIoObject,
-        procMesh_
-    );
-
-    // Distribute onto baseMesh
-    return reconstructFvVolumeInternalField(fld);
-}
-
-
-// Reconstruct a field onto the baseMesh
 template<class Type>
 Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
-Foam::parFvFieldReconstructor::reconstructFvVolumeField
+Foam::parFvFieldDistributor::distributeField
 (
     const GeometricField<Type, fvPatchField, volMesh>& fld
 ) const
 {
-    // Create the internalField by remote mapping
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+    // Create internalField by remote mapping
     distributedFieldMapper mapper
     (
         labelUList::null(),
         distMap_.cellMap()
     );
 
-    Field<Type> internalField(fld.internalField(), mapper);
+    DimensionedField<Type, volMesh> internalField
+    (
+        IOobject
+        (
+            fld.name(),
+            tgtMesh_.time().timeName(),
+            fld.local(),
+            tgtMesh_,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        tgtMesh_,
+        fld.dimensions(),
+        Field<Type>(fld.internalField(), mapper)
+    );
 
+    internalField.oriented() = fld.oriented();
 
 
-    // Create the patchFields by remote mapping
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    // Note: patchFields still on mesh, not baseMesh
+    // Create patchFields by remote mapping
+    // Note: patchFields still on source mesh, not target mesh
 
-    PtrList<fvPatchField<Type>> patchFields(fld.mesh().boundary().size());
+    PtrList<fvPatchField<Type>> oldPatchFields(fld.mesh().boundary().size());
 
     const auto& bfld = fld.boundaryField();
 
-    forAll(bfld, patchI)
+    forAll(bfld, patchi)
     {
-        if (patchFaceMaps_.set(patchI))
+        if (patchFaceMaps_.set(patchi))
         {
             // Clone local patch field
-            patchFields.set(patchI, bfld[patchI].clone());
+            oldPatchFields.set(patchi, bfld[patchi].clone());
 
             distributedFvPatchFieldMapper mapper
             (
                 labelUList::null(),
-                patchFaceMaps_[patchI]
+                patchFaceMaps_[patchi]
             );
 
             // Map into local copy
-            patchFields[patchI].autoMap(mapper);
+            oldPatchFields[patchi].autoMap(mapper);
         }
     }
 
 
-    PtrList<fvPatchField<Type>> basePatchFields
-    (
-        baseMesh_.boundary().size()
-    );
-
-    // Clone the patchFields onto the base patches. This is just to reset
+    // Clone the oldPatchFields onto the target patches. This is just to reset
     // the reference to the patch, size and content stay the same.
-    forAll(patchFields, patchI)
+
+    PtrList<fvPatchField<Type>> newPatchFields(tgtMesh_.boundary().size());
+
+    forAll(oldPatchFields, patchi)
     {
-        if (patchFields.set(patchI))
+        if (oldPatchFields.set(patchi))
         {
-            const fvPatch& basePatch = baseMesh_.boundary()[patchI];
-
-            const fvPatchField<Type>& pfld = patchFields[patchI];
+            const auto& pfld = oldPatchFields[patchi];
 
             labelList dummyMap(identity(pfld.size()));
             directFvPatchFieldMapper dummyMapper(dummyMap);
 
-            basePatchFields.set
+            newPatchFields.set
             (
-                patchI,
+                patchi,
                 fvPatchField<Type>::New
                 (
                     pfld,
-                    basePatch,
+                    tgtMesh_.boundary()[patchi],
                     DimensionedField<Type, volMesh>::null(),
                     dummyMapper
                 )
@@ -181,162 +166,143 @@ Foam::parFvFieldReconstructor::reconstructFvVolumeField
         }
     }
 
-    // Add some empty patches on remaining patches (tbd.probably processor
-    // patches)
-    forAll(basePatchFields, patchI)
+    // Add some empty patches on remaining patches
+    // (... probably processor patches)
+
+    forAll(newPatchFields, patchi)
     {
-        if (patchI >= patchFields.size() || !patchFields.set(patchI))
+        if (!newPatchFields.set(patchi))
         {
-            basePatchFields.set
+            newPatchFields.set
             (
-                patchI,
+                patchi,
                 fvPatchField<Type>::New
                 (
                     emptyFvPatchField<Type>::typeName,
-                    baseMesh_.boundary()[patchI],
+                    tgtMesh_.boundary()[patchi],
                     DimensionedField<Type, volMesh>::null()
                 )
             );
         }
     }
 
-    // Construct a volField
-    IOobject baseIO
-    (
-        fld.name(),
-        baseMesh_.time().timeName(),
-        fld.local(),
-        baseMesh_,
-        IOobject::NO_READ,
-        IOobject::NO_WRITE
-    );
+    // Return geometric field
 
-    auto tfield = tmp<GeometricField<Type, fvPatchField, volMesh>>::New
+    return tmp<GeometricField<Type, fvPatchField, volMesh>>::New
     (
-        baseIO,
-        baseMesh_,
-        fld.dimensions(),
-        internalField,
-        basePatchFields
+        std::move(internalField),
+        newPatchFields
     );
-
-    tfield.ref().oriented()= fld.oriented();
-
-    return tfield;
-}
-
-
-template<class Type>
-Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
-Foam::parFvFieldReconstructor::reconstructFvVolumeField
-(
-    const IOobject& fieldIoObject
-) const
-{
-    // Read the field
-    GeometricField<Type, fvPatchField, volMesh> fld
-    (
-        fieldIoObject,
-        procMesh_
-    );
-
-    // Distribute onto baseMesh
-    return reconstructFvVolumeField(fld);
 }
 
 
 template<class Type>
 Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh>>
-Foam::parFvFieldReconstructor::reconstructFvSurfaceField
+Foam::parFvFieldDistributor::distributeField
 (
     const GeometricField<Type, fvsPatchField, surfaceMesh>& fld
 ) const
 {
-    // Create the internalField by remote mapping
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+    // Create internalField by remote mapping
     distributedFieldMapper mapper
     (
         labelUList::null(),
         distMap_.faceMap()
     );
 
-    // Create flat field of internalField + all patch fields
-    Field<Type> flatFld(fld.mesh().nFaces(), Type(Zero));
-    SubList<Type>(flatFld, fld.internalField().size()) = fld.internalField();
-    forAll(fld.boundaryField(), patchI)
+
+    Field<Type> primitiveField;
     {
-        const fvsPatchField<Type>& fvp = fld.boundaryField()[patchI];
+        // Create flat field of internalField + all patch fields
+        Field<Type> flatFld(fld.mesh().nFaces(), Type(Zero));
+        SubList<Type>(flatFld, fld.internalField().size())
+            = fld.internalField();
+
+        for (const fvsPatchField<Type>& fvp : fld.boundaryField())
+        {
+            SubList<Type>(flatFld, fvp.size(), fvp.patch().start()) = fvp;
+        }
+
+        // Map all faces
+        primitiveField = Field<Type>(flatFld, mapper, fld.oriented()());
 
-        SubList<Type>(flatFld, fvp.size(), fvp.patch().start()) = fvp;
+        // Trim to internal faces (note: could also have special mapper)
+        primitiveField.resize
+        (
+            min
+            (
+                primitiveField.size(),
+                tgtMesh_.nInternalFaces()
+            )
+        );
     }
 
-    // Map all faces
-    Field<Type> internalField(flatFld, mapper, fld.oriented()());
 
-    // Trim to internal faces (note: could also have special mapper)
-    internalField.setSize
+    DimensionedField<Type, surfaceMesh> internalField
     (
-        min
+        IOobject
         (
-            internalField.size(),
-            baseMesh_.nInternalFaces()
-        )
+            fld.name(),
+            tgtMesh_.time().timeName(),
+            fld.local(),
+            tgtMesh_,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        tgtMesh_,
+        fld.dimensions(),
+        std::move(primitiveField)
     );
 
+    internalField.oriented() = fld.oriented();
+
 
-    // Create the patchFields by remote mapping
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    // Note: patchFields still on mesh, not baseMesh
+    // Create patchFields by remote mapping
+    // Note: patchFields still on source mesh, not target mesh
 
-    PtrList<fvsPatchField<Type>> patchFields(fld.mesh().boundary().size());
+    PtrList<fvsPatchField<Type>> oldPatchFields(fld.mesh().boundary().size());
 
     const auto& bfld = fld.boundaryField();
 
-    forAll(bfld, patchI)
+    forAll(bfld, patchi)
     {
-        if (patchFaceMaps_.set(patchI))
+        if (patchFaceMaps_.set(patchi))
         {
             // Clone local patch field
-            patchFields.set(patchI, bfld[patchI].clone());
+            oldPatchFields.set(patchi, bfld[patchi].clone());
 
             distributedFvPatchFieldMapper mapper
             (
                 labelUList::null(),
-                patchFaceMaps_[patchI]
+                patchFaceMaps_[patchi]
             );
 
             // Map into local copy
-            patchFields[patchI].autoMap(mapper);
+            oldPatchFields[patchi].autoMap(mapper);
         }
     }
 
 
-    PtrList<fvsPatchField<Type>> basePatchFields
-    (
-        baseMesh_.boundary().size()
-    );
+    PtrList<fvsPatchField<Type>> newPatchFields(tgtMesh_.boundary().size());
 
     // Clone the patchFields onto the base patches. This is just to reset
     // the reference to the patch, size and content stay the same.
-    forAll(patchFields, patchI)
+    forAll(oldPatchFields, patchi)
     {
-        if (patchFields.set(patchI))
+        if (oldPatchFields.set(patchi))
         {
-            const fvPatch& basePatch = baseMesh_.boundary()[patchI];
-
-            const fvsPatchField<Type>& pfld = patchFields[patchI];
+            const fvsPatchField<Type>& pfld = oldPatchFields[patchi];
 
             labelList dummyMap(identity(pfld.size()));
             directFvPatchFieldMapper dummyMapper(dummyMap);
 
-            basePatchFields.set
+            newPatchFields.set
             (
-                patchI,
+                patchi,
                 fvsPatchField<Type>::New
                 (
                     pfld,
-                    basePatch,
+                    tgtMesh_.boundary()[patchi],
                     DimensionedField<Type, surfaceMesh>::null(),
                     dummyMapper
                 )
@@ -344,71 +310,94 @@ Foam::parFvFieldReconstructor::reconstructFvSurfaceField
         }
     }
 
-    // Add some empty patches on remaining patches (tbd.probably processor
-    // patches)
-    forAll(basePatchFields, patchI)
+    // Add some empty patches on remaining patches
+    // (... probably processor patches)
+    forAll(newPatchFields, patchi)
     {
-        if (patchI >= patchFields.size() || !patchFields.set(patchI))
+        if (!newPatchFields.set(patchi))
         {
-            basePatchFields.set
+            newPatchFields.set
             (
-                patchI,
+                patchi,
                 fvsPatchField<Type>::New
                 (
                     emptyFvsPatchField<Type>::typeName,
-                    baseMesh_.boundary()[patchI],
+                    tgtMesh_.boundary()[patchi],
                     DimensionedField<Type, surfaceMesh>::null()
                 )
             );
         }
     }
 
-    // Construct a volField
-    IOobject baseIO
+
+    // Return geometric field
+    return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>::New
     (
-        fld.name(),
-        baseMesh_.time().timeName(),
-        fld.local(),
-        baseMesh_,
-        IOobject::NO_READ,
-        IOobject::NO_WRITE
+        std::move(internalField),
+        newPatchFields
     );
+}
+
 
-    auto tfield = tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>::New
+template<class Type>
+Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
+Foam::parFvFieldDistributor::distributeInternalField
+(
+    const IOobject& fieldObject
+) const
+{
+    // Read field
+    DimensionedField<Type, volMesh> fld
     (
-        baseIO,
-        baseMesh_,
-        fld.dimensions(),
-        internalField,
-        basePatchFields
+        fieldObject,
+        srcMesh_
     );
 
-    tfield.ref().oriented() = fld.oriented();
+    // Distribute
+    return distributeField(fld);
+}
 
-    return tfield;
+
+template<class Type>
+Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
+Foam::parFvFieldDistributor::distributeVolumeField
+(
+    const IOobject& fieldObject
+) const
+{
+    // Read field
+    GeometricField<Type, fvPatchField, volMesh> fld
+    (
+        fieldObject,
+        srcMesh_
+    );
+
+    // Distribute
+    return distributeField(fld);
 }
 
 
 template<class Type>
 Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh>>
-Foam::parFvFieldReconstructor::reconstructFvSurfaceField
+Foam::parFvFieldDistributor::distributeSurfaceField
 (
-    const IOobject& fieldIoObject
+    const IOobject& fieldObject
 ) const
 {
-    // Read the field
+    // Read field
     GeometricField<Type, fvsPatchField, surfaceMesh> fld
     (
-        fieldIoObject,
-        procMesh_
+        fieldObject,
+        srcMesh_
     );
 
-    return reconstructFvSurfaceField(fld);
+    // Distribute
+    return distributeField(fld);
 }
 
 
 template<class Type>
-Foam::label Foam::parFvFieldReconstructor::reconstructFvVolumeInternalFields
+Foam::label Foam::parFvFieldDistributor::distributeInternalFields
 (
     const IOobjectList& objects,
     const wordRes& selectedFields
@@ -427,17 +416,25 @@ Foam::label Foam::parFvFieldReconstructor::reconstructFvVolumeInternalFields
     label nFields = 0;
     for (const word& fieldName : fieldNames)
     {
-        if (!nFields++)
+        if ("cellDist" == fieldName)
         {
-            Info<< "    Reconstructing "
-                << fieldType::typeName << "s\n" << nl;
+            // There is an odd chance this is an internal field
+            continue;
         }
-
-        Info<< "        " << fieldName << nl;
+        if (verbose_)
+        {
+            if (!nFields)
+            {
+                Info<< "    Reconstructing "
+                    << fieldType::typeName << "s\n" << nl;
+            }
+            Info<< "        " << fieldName << nl;
+        }
+        ++nFields;
 
         tmp<fieldType> tfld
         (
-            reconstructFvVolumeInternalField<Type>(*(objects[fieldName]))
+            distributeInternalField<Type>(*(objects[fieldName]))
         );
         if (isWriteProc_)
         {
@@ -445,13 +442,13 @@ Foam::label Foam::parFvFieldReconstructor::reconstructFvVolumeInternalFields
         }
     }
 
-    if (nFields) Info<< endl;
+    if (nFields && verbose_) Info<< endl;
     return nFields;
 }
 
 
 template<class Type>
-Foam::label Foam::parFvFieldReconstructor::reconstructFvVolumeFields
+Foam::label Foam::parFvFieldDistributor::distributeVolumeFields
 (
     const IOobjectList& objects,
     const wordRes& selectedFields
@@ -474,16 +471,20 @@ Foam::label Foam::parFvFieldReconstructor::reconstructFvVolumeFields
         {
             continue;
         }
-        if (!nFields++)
+        if (verbose_)
         {
-            Info<< "    Reconstructing "
-                << fieldType::typeName << "s\n" << nl;
+            if (!nFields)
+            {
+                Info<< "    Reconstructing "
+                    << fieldType::typeName << "s\n" << nl;
+            }
+            Info<< "        " << fieldName << nl;
         }
-        Info<< "        " << fieldName << nl;
+        ++nFields;
 
         tmp<fieldType> tfld
         (
-            reconstructFvVolumeField<Type>(*(objects[fieldName]))
+            distributeVolumeField<Type>(*(objects[fieldName]))
         );
         if (isWriteProc_)
         {
@@ -491,13 +492,13 @@ Foam::label Foam::parFvFieldReconstructor::reconstructFvVolumeFields
         }
     }
 
-    if (nFields) Info<< endl;
+    if (nFields && verbose_) Info<< endl;
     return nFields;
 }
 
 
 template<class Type>
-Foam::label Foam::parFvFieldReconstructor::reconstructFvSurfaceFields
+Foam::label Foam::parFvFieldDistributor::distributeSurfaceFields
 (
     const IOobjectList& objects,
     const wordRes& selectedFields
@@ -516,16 +517,20 @@ Foam::label Foam::parFvFieldReconstructor::reconstructFvSurfaceFields
     label nFields = 0;
     for (const word& fieldName : fieldNames)
     {
-        if (!nFields++)
+        if (verbose_)
         {
-            Info<< "    Reconstructing "
-                << fieldType::typeName << "s\n" << nl;
+            if (!nFields)
+            {
+                Info<< "    Reconstructing "
+                    << fieldType::typeName << "s\n" << nl;
+            }
+            Info<< "        " << fieldName << nl;
         }
-        Info<< "        " << fieldName << nl;
+        ++nFields;
 
         tmp<fieldType> tfld
         (
-            reconstructFvSurfaceField<Type>(*(objects[fieldName]))
+            distributeSurfaceField<Type>(*(objects[fieldName]))
         );
         if (isWriteProc_)
         {
@@ -533,7 +538,7 @@ Foam::label Foam::parFvFieldReconstructor::reconstructFvSurfaceFields
         }
     }
 
-    if (nFields) Info<< endl;
+    if (nFields && verbose_) Info<< endl;
     return nFields;
 }
 
diff --git a/applications/utilities/parallelProcessing/redistributePar/parLagrangianRedistributor.C b/applications/utilities/parallelProcessing/redistributePar/parLagrangianDistributor.C
similarity index 96%
rename from applications/utilities/parallelProcessing/redistributePar/parLagrangianRedistributor.C
rename to applications/utilities/parallelProcessing/redistributePar/parLagrangianDistributor.C
index d0be2c50bb67ed35434d0b5a08228c2984fbdc03..2d8bb57a2d58ff5be88f7a4b374b48aed2dae5e0 100644
--- a/applications/utilities/parallelProcessing/redistributePar/parLagrangianRedistributor.C
+++ b/applications/utilities/parallelProcessing/redistributePar/parLagrangianDistributor.C
@@ -27,12 +27,12 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "ListOps.H"
-#include "parLagrangianRedistributor.H"
+#include "parLagrangianDistributor.H"
 #include "passivePositionParticleCloud.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::parLagrangianRedistributor::parLagrangianRedistributor
+Foam::parLagrangianDistributor::parLagrangianDistributor
 (
     const fvMesh& srcMesh,
     const fvMesh& tgtMesh,
@@ -59,7 +59,7 @@ Foam::parLagrangianRedistributor::parLagrangianRedistributor
 
 // Find all clouds (on all processors) and for each cloud all the objects.
 // Result will be synchronised on all processors
-void Foam::parLagrangianRedistributor::findClouds
+void Foam::parLagrangianDistributor::findClouds
 (
     const fvMesh& mesh,
     wordList& cloudNames,
@@ -129,7 +129,7 @@ void Foam::parLagrangianRedistributor::findClouds
 
 
 Foam::autoPtr<Foam::mapDistributeBase>
-Foam::parLagrangianRedistributor::redistributeLagrangianPositions
+Foam::parLagrangianDistributor::distributeLagrangianPositions
 (
     passivePositionParticleCloud& lpi
 ) const
@@ -314,7 +314,7 @@ Foam::parLagrangianRedistributor::redistributeLagrangianPositions
 
 
 Foam::autoPtr<Foam::mapDistributeBase>
-Foam::parLagrangianRedistributor::redistributeLagrangianPositions
+Foam::parLagrangianDistributor::distributeLagrangianPositions
 (
     const word& cloudName
 ) const
@@ -322,7 +322,7 @@ Foam::parLagrangianRedistributor::redistributeLagrangianPositions
     // Load cloud and send particle
     passivePositionParticleCloud lpi(srcMesh_, cloudName, false);
 
-    return redistributeLagrangianPositions(lpi);
+    return distributeLagrangianPositions(lpi);
 }
 
 
diff --git a/applications/utilities/parallelProcessing/redistributePar/parLagrangianRedistributor.H b/applications/utilities/parallelProcessing/redistributePar/parLagrangianDistributor.H
similarity index 69%
rename from applications/utilities/parallelProcessing/redistributePar/parLagrangianRedistributor.H
rename to applications/utilities/parallelProcessing/redistributePar/parLagrangianDistributor.H
index 5d66468efaa48fceb5d22cc26306ea835e804cc4..344c323a04fa1c8818204163a33e74d215b95d27 100644
--- a/applications/utilities/parallelProcessing/redistributePar/parLagrangianRedistributor.H
+++ b/applications/utilities/parallelProcessing/redistributePar/parLagrangianDistributor.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2015 OpenFOAM Foundation
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2022 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,7 +25,7 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::parLagrangianRedistributor
+    Foam::parLagrangianDistributor
 
 Description
     Lagrangian field redistributor.
@@ -33,13 +33,14 @@ Description
     Runs in parallel. Redistributes from fromMesh to toMesh.
 
 SourceFiles
-    parLagrangianRedistributor.C
-    parLagrangianRedistributorFields.C
+    parLagrangianDistributor.C
+    parLagrangianDistributorFields.C
+    parLagrangianDistributorTemplates.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef parLagrangianRedistributor_H
-#define parLagrangianRedistributor_H
+#ifndef Foam_parLagrangianDistributor_H
+#define Foam_parLagrangianDistributor_H
 
 #include "PtrList.H"
 #include "fvMesh.H"
@@ -49,19 +50,19 @@ SourceFiles
 namespace Foam
 {
 
-// Forward declarations
+// Forward Declarations
 class mapDistributePolyMesh;
 class mapDistributeBase;
 class IOobjectList;
 class passivePositionParticleCloud;
 
 /*---------------------------------------------------------------------------*\
-                    Class parLagrangianRedistributor Declaration
+                    Class parLagrangianDistributor Declaration
 \*---------------------------------------------------------------------------*/
 
-class parLagrangianRedistributor
+class parLagrangianDistributor
 {
-    // Private data
+    // Private Data
 
         //- Source mesh reference
         const fvMesh& srcMesh_;
@@ -82,10 +83,10 @@ class parLagrangianRedistributor
     // Private Member Functions
 
         //- No copy construct
-        parLagrangianRedistributor(const parLagrangianRedistributor&) = delete;
+        parLagrangianDistributor(const parLagrangianDistributor&) = delete;
 
         //- No copy assignment
-        void operator=(const parLagrangianRedistributor&) = delete;
+        void operator=(const parLagrangianDistributor&) = delete;
 
 
 public:
@@ -93,7 +94,7 @@ public:
     // Constructors
 
         //- Construct from components
-        parLagrangianRedistributor
+        parLagrangianDistributor
         (
             const fvMesh& srcMesh,
             const fvMesh& tgtMesh,
@@ -102,10 +103,10 @@ public:
         );
 
 
-    // Member Functions
+    // Static Functions
 
         //- Find all clouds (on all processors) and for each cloud all
-        //  the objects. Result will be synchronised on all processors
+        //- the objects. Result will be synchronised on all processors
         static void findClouds
         (
             const fvMesh&,
@@ -113,29 +114,74 @@ public:
             List<wordList>& objectNames
         );
 
+        //- Pick up any fields of a given type
+        template<class Type>
+        static wordList filterObjects
+        (
+            const IOobjectList& objects,
+            const wordRes& selectedFields = wordRes()
+        );
+
+        //- Read and store all fields of a cloud
+        template<class Container>
+        static label readFields
+        (
+            const passivePositionParticleCloud& cloud,
+            const IOobjectList& objects,
+            const wordRes& selectedFields = wordRes()
+        );
+
+        //- Read and store all fields for known cloud field types
+        static label readAllFields
+        (
+            const passivePositionParticleCloud& cloud,
+            const IOobjectList& objects,
+            const wordRes& selectedFields = wordRes()
+        );
+
+        //- Read and store all fields for known cloud field types
+        //  Uses the current cloud instance to obtain the IOobjectList
+        static label readAllFields
+        (
+            const passivePositionParticleCloud& cloud,
+            const wordRes& selectedFields = wordRes()
+        );
+
+
+    // Member Functions
+
         //- Redistribute and write lagrangian positions
-        autoPtr<mapDistributeBase> redistributeLagrangianPositions
+        autoPtr<mapDistributeBase> distributeLagrangianPositions
         (
             passivePositionParticleCloud& cloud
         ) const;
 
         //- Read, redistribute and write lagrangian positions
-        autoPtr<mapDistributeBase> redistributeLagrangianPositions
+        autoPtr<mapDistributeBase> distributeLagrangianPositions
         (
             const word& cloudName
         ) const;
 
-        //- Pick up any fields of a given type
-        template<class Type>
-        static wordList filterObjects
+        //- Redistribute all fields for known cloud field types
+        label distributeAllFields
         (
-            const IOobjectList& objects,
-            const wordRes& selectedFields = wordRes()
-        );
+            const mapDistributeBase& lagrangianMap,
+            const word& cloudName,
+            const IOobjectList& cloudObjs,
+            const wordRes& selectedFields
+        ) const;
+
+        //- Redistribute and write all stored lagrangian fields
+        label distributeAllStoredFields
+        (
+            const mapDistributeBase& lagrangianMap,
+            passivePositionParticleCloud& cloud
+        ) const;
+
 
         //- Read, redistribute and write all/selected lagrangian fields
         template<class Type>
-        label redistributeFields
+        label distributeFields
         (
             const mapDistributeBase& map,
             const word& cloudName,
@@ -145,7 +191,7 @@ public:
 
         //- Read, redistribute and write all/selected lagrangian fieldFields
         template<class Type>
-        label redistributeFieldFields
+        label distributeFieldFields
         (
             const mapDistributeBase& map,
             const word& cloudName,
@@ -153,23 +199,13 @@ public:
             const wordRes& selectedFields = wordRes()
         ) const;
 
-        //- Read and store all fields of a cloud
-        template<class Container>
-        static label readFields
-        (
-            const passivePositionParticleCloud& cloud,
-            const IOobjectList& objects,
-            const wordRes& selectedFields = wordRes()
-        );
-
         //- Redistribute and write stored lagrangian fields
         template<class Container>
-        label redistributeStoredFields
+        label distributeStoredFields
         (
             const mapDistributeBase& map,
             passivePositionParticleCloud& cloud
         ) const;
-
 };
 
 
@@ -180,7 +216,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-#   include "parLagrangianRedistributorFields.C"
+#   include "parLagrangianDistributorTemplates.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/applications/utilities/parallelProcessing/redistributePar/parLagrangianDistributorFields.C b/applications/utilities/parallelProcessing/redistributePar/parLagrangianDistributorFields.C
new file mode 100644
index 0000000000000000000000000000000000000000..730c3fcc1bbfcc40169129c96d001e0338226ef6
--- /dev/null
+++ b/applications/utilities/parallelProcessing/redistributePar/parLagrangianDistributorFields.C
@@ -0,0 +1,195 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2022 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "parLagrangianDistributor.H"
+#include "unmappedPassivePositionParticleCloud.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::label Foam::parLagrangianDistributor::readAllFields
+(
+    const passivePositionParticleCloud& cloud,
+    const IOobjectList& cloudObjs,
+    const wordRes& selectedFields
+)
+{
+    label nTotal = 0;
+
+    do
+    {
+        #undef  doLocalCode
+        #define doLocalCode(Type)                                             \
+        {                                                                     \
+            nTotal += parLagrangianDistributor::readFields                    \
+            <IOField<Type>>                                                   \
+            (                                                                 \
+                cloud,                                                        \
+                cloudObjs,                                                    \
+                selectedFields                                                \
+            );                                                                \
+                                                                              \
+            nTotal += parLagrangianDistributor::readFields                    \
+            <IOField<Field<Type>>>                                            \
+            (                                                                 \
+                cloud,                                                        \
+                cloudObjs,                                                    \
+                selectedFields                                                \
+            );                                                                \
+                                                                              \
+            nTotal += parLagrangianDistributor::readFields                    \
+            <CompactIOField<Field<Type>, Type>>                               \
+            (                                                                 \
+                cloud,                                                        \
+                cloudObjs,                                                    \
+                selectedFields                                                \
+            );                                                                \
+        }
+
+        doLocalCode(label);
+        doLocalCode(scalar);
+        doLocalCode(vector);
+        doLocalCode(sphericalTensor);
+        doLocalCode(symmTensor);
+        doLocalCode(tensor);
+
+        #undef doLocalCode
+    }
+    while (false);
+
+    return nTotal;
+}
+
+
+Foam::label Foam::parLagrangianDistributor::readAllFields
+(
+    const passivePositionParticleCloud& cloud,
+    const wordRes& selectedFields
+)
+{
+    IOobjectList cloudObjs(cloud, cloud.time().timeName());
+    return readAllFields(cloud, cloudObjs, selectedFields);
+}
+
+
+Foam::label Foam::parLagrangianDistributor::distributeAllFields
+(
+    const mapDistributeBase& lagrangianMap,
+    const word& cloudName,
+    const IOobjectList& cloudObjs,
+    const wordRes& selectedFields
+) const
+{
+    label nTotal = 0;
+
+    do
+    {
+        #undef  doLocalCode
+        #define doLocalCode(Type)                                             \
+        {                                                                     \
+            nTotal += this->distributeFields<Type>                            \
+            (                                                                 \
+                lagrangianMap,                                                \
+                cloudName,                                                    \
+                cloudObjs,                                                    \
+                selectedFields                                                \
+            );                                                                \
+                                                                              \
+            nTotal += this->distributeFieldFields<Type>                       \
+            (                                                                 \
+                lagrangianMap,                                                \
+                cloudName,                                                    \
+                cloudObjs,                                                    \
+                selectedFields                                                \
+            );                                                                \
+        }
+
+        doLocalCode(label);
+        doLocalCode(scalar);
+        doLocalCode(vector);
+        doLocalCode(sphericalTensor);
+        doLocalCode(symmTensor);
+        doLocalCode(tensor);
+
+        #undef doLocalCode
+    }
+    while (false);
+
+    return nTotal;
+}
+
+
+Foam::label Foam::parLagrangianDistributor::distributeAllStoredFields
+(
+    const mapDistributeBase& lagrangianMap,
+    passivePositionParticleCloud& cloud
+) const
+{
+    label nTotal = 0;
+
+    do
+    {
+        #undef  doLocalCode
+        #define doLocalCode(Type)                                             \
+        {                                                                     \
+            nTotal += this->distributeStoredFields                            \
+            <IOField<Type>>                                                   \
+            (                                                                 \
+                lagrangianMap,                                                \
+                cloud                                                         \
+            );                                                                \
+                                                                              \
+            nTotal += this->distributeStoredFields                            \
+            <IOField<Field<Type>>>                                            \
+            (                                                                 \
+                lagrangianMap,                                                \
+                cloud                                                         \
+            );                                                                \
+                                                                              \
+            nTotal += this->distributeStoredFields                            \
+            <CompactIOField<Field<Type>, Type>>                               \
+            (                                                                 \
+                lagrangianMap,                                                \
+                cloud                                                         \
+            );                                                                \
+        }
+
+        doLocalCode(label);
+        doLocalCode(scalar);
+        doLocalCode(vector);
+        doLocalCode(sphericalTensor);
+        doLocalCode(symmTensor);
+        doLocalCode(tensor);
+
+        #undef doLocalCode
+    }
+    while (false);
+
+    return nTotal;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/parallelProcessing/redistributePar/parLagrangianRedistributorFields.C b/applications/utilities/parallelProcessing/redistributePar/parLagrangianDistributorTemplates.C
similarity index 79%
rename from applications/utilities/parallelProcessing/redistributePar/parLagrangianRedistributorFields.C
rename to applications/utilities/parallelProcessing/redistributePar/parLagrangianDistributorTemplates.C
index 0bbf52f8ff89f13bd72b156082199041a48c8001..c30fd6f7b6eaeca5fb214a794bf341d3895ed78c 100644
--- a/applications/utilities/parallelProcessing/redistributePar/parLagrangianRedistributorFields.C
+++ b/applications/utilities/parallelProcessing/redistributePar/parLagrangianDistributorTemplates.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2015 OpenFOAM Foundation
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2022 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,18 +26,19 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "parLagrangianRedistributor.H"
+#include "parLagrangianDistributor.H"
 #include "Time.H"
 #include "IOobjectList.H"
 #include "mapDistributePolyMesh.H"
 #include "cloud.H"
 #include "CompactIOField.H"
+#include "DynamicList.H"
 #include "passivePositionParticleCloud.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Container>
-Foam::wordList Foam::parLagrangianRedistributor::filterObjects
+Foam::wordList Foam::parLagrangianDistributor::filterObjects
 (
     const IOobjectList& objects,
     const wordRes& selectedFields
@@ -64,7 +65,7 @@ Foam::wordList Foam::parLagrangianRedistributor::filterObjects
 
 
 template<class Type>
-Foam::label Foam::parLagrangianRedistributor::redistributeFields
+Foam::label Foam::parLagrangianDistributor::distributeFields
 (
     const mapDistributeBase& map,
     const word& cloudName,
@@ -76,7 +77,7 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFields
 
     const wordList fieldNames
     (
-        filterObjects<IOField<Type>>
+        filterObjects<fieldType>
         (
             objects,
             selectedFields
@@ -88,7 +89,7 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFields
     {
         if (!nFields)
         {
-            Info<< "    Redistributing lagrangian "
+            Info<< "    Distributing lagrangian "
                 << fieldType::typeName << "s\n" << endl;
         }
         Info<< "        " <<  objectName << endl;
@@ -125,11 +126,7 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFields
 
         if (field.size())
         {
-            IOField<Type>
-            (
-                fieldIO,
-                std::move(field)
-            ).write();
+            IOField<Type>(fieldIO, std::move(field)).write();
         }
         else
         {
@@ -146,7 +143,7 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFields
 
 
 template<class Type>
-Foam::label Foam::parLagrangianRedistributor::redistributeFieldFields
+Foam::label Foam::parLagrangianDistributor::distributeFieldFields
 (
     const mapDistributeBase& map,
     const word& cloudName,
@@ -156,7 +153,9 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFieldFields
 {
     typedef CompactIOField<Field<Type>, Type> fieldType;
 
-    wordList fieldNames
+    DynamicList<word> fieldNames;
+
+    fieldNames.append
     (
         filterObjects<fieldType>
         (
@@ -166,27 +165,30 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFieldFields
     );
 
     // Append IOField Field names
-    {
-        wordList ioFieldNames
+    fieldNames.append
+    (
+        filterObjects<IOField<Field<Type>>>
         (
-            filterObjects<IOField<Field<Type>>>
-            (
-                objects,
-                selectedFields
-            )
-        );
-        fieldNames.append(ioFieldNames);
-    }
+            objects,
+            selectedFields
+        )
+    );
+
+    const bool verbose_ = true;
 
     label nFields = 0;
     for (const word& objectName : fieldNames)
     {
-        if (!nFields++)
+        if (verbose_)
         {
-            Info<< "    Redistributing lagrangian "
-                << fieldType::typeName << "s\n" << nl;
+            if (!nFields)
+            {
+                Info<< "    Distributing lagrangian "
+                    << fieldType::typeName << "s\n" << nl;
+            }
+            Info<< "        " <<  objectName << nl;
         }
-        Info<< "        " <<  objectName << nl;
+        ++nFields;
 
         // Read if present
         CompactIOField<Field<Type>, Type> field
@@ -237,13 +239,13 @@ Foam::label Foam::parLagrangianRedistributor::redistributeFieldFields
         }
     }
 
-    if (nFields) Info<< endl;
+    if (nFields && verbose_) Info<< endl;
     return nFields;
 }
 
 
 template<class Container>
-Foam::label Foam::parLagrangianRedistributor::readFields
+Foam::label Foam::parLagrangianDistributor::readFields
 (
     const passivePositionParticleCloud& cloud,
     const IOobjectList& objects,
@@ -261,15 +263,21 @@ Foam::label Foam::parLagrangianRedistributor::readFields
         )
     );
 
+    const bool verbose_ = true;
+
     label nFields = 0;
     for (const word& objectName : fieldNames)
     {
-        if (!nFields++)
+        if (verbose_)
         {
-            Info<< "    Reading lagrangian "
-                << Container::typeName << "s\n" << nl;
+            if (!nFields)
+            {
+                Info<< "    Reading lagrangian "
+                    << Container::typeName << "s\n" << nl;
+            }
+            Info<< "        " <<  objectName << nl;
         }
-        Info<< "        " <<  objectName << nl;
+        ++nFields;
 
         // Read if present
         Container* fieldPtr = new Container
@@ -288,12 +296,13 @@ Foam::label Foam::parLagrangianRedistributor::readFields
         fieldPtr->store();
     }
 
+    if (nFields && verbose_) Info<< endl;
     return nFields;
 }
 
 
 template<class Container>
-Foam::label Foam::parLagrangianRedistributor::redistributeStoredFields
+Foam::label Foam::parLagrangianDistributor::distributeStoredFields
 (
     const mapDistributeBase& map,
     passivePositionParticleCloud& cloud
@@ -304,17 +313,23 @@ Foam::label Foam::parLagrangianRedistributor::redistributeStoredFields
         cloud.lookupClass<Container>()
     );
 
+    const bool verbose_ = true;
+
     label nFields = 0;
     forAllIters(fields, iter)
     {
         Container& field = *(iter.val());
 
-        if (!nFields++)
+        if (verbose_)
         {
-            Info<< "    Redistributing lagrangian "
-                << Container::typeName << "s\n" << endl;
+            if (!nFields)
+            {
+                Info<< "    Distributing lagrangian "
+                    << Container::typeName << "s\n" << endl;
+            }
+            Info<< "        " <<  field.name() << endl;
         }
-        Info<< "        " <<  field.name() << endl;
+        ++nFields;
 
         map.distribute(field);
 
@@ -331,11 +346,7 @@ Foam::label Foam::parLagrangianRedistributor::redistributeStoredFields
 
         if (field.size())
         {
-            Container
-            (
-                fieldIO,
-                std::move(field)
-            ).write();
+            Container(fieldIO, std::move(field)).write();
         }
         else
         {
@@ -347,6 +358,7 @@ Foam::label Foam::parLagrangianRedistributor::redistributeStoredFields
         }
     }
 
+    if (nFields && verbose_) Info<< endl;
     return nFields;
 }
 
diff --git a/applications/utilities/parallelProcessing/redistributePar/redistributeLagrangian.H b/applications/utilities/parallelProcessing/redistributePar/redistributeLagrangian.H
new file mode 100644
index 0000000000000000000000000000000000000000..99f08b3c299b6eb5096aaf5d193e28809dd258a2
--- /dev/null
+++ b/applications/utilities/parallelProcessing/redistributePar/redistributeLagrangian.H
@@ -0,0 +1,230 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2011-2017 OpenFOAM Foundation
+    Copyright (C) 2015-2022 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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/>.
+
+Description
+    Reading, reconstruct, redistribution of lagrangian fields.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef Foam_redistributeLagrangian_H
+#define Foam_redistributeLagrangian_H
+
+#include "parLagrangianDistributor.H"
+#include "unmappedPassivePositionParticleCloud.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// Read clouds (note: might not be present on all processors)
+PtrList<unmappedPassivePositionParticleCloud>
+readLagrangian
+(
+    const fvMesh& mesh,
+    const wordList& cloudNames,
+    const wordRes& selectedFields
+)
+{
+    PtrList<unmappedPassivePositionParticleCloud> clouds(cloudNames.size());
+
+    if (!cloudNames.empty())
+    {
+        (void)mesh.tetBasePtIs();
+    }
+
+    // Setup clouds
+    forAll(cloudNames, i)
+    {
+        //Pout<< "Loading cloud " << cloudNames[i] << endl;
+        clouds.set
+        (
+            i,
+            new unmappedPassivePositionParticleCloud(mesh, cloudNames[i], false)
+        );
+
+        //for (passivePositionParticle& p : clouds[i]))
+        //{
+        //    Pout<< "Particle position:" << p.position()
+        //        << " cell:" << p.cell()
+        //        << " with cc:" << mesh.cellCentres()[p.cell()]
+        //        << endl;
+        //}
+
+        IOobjectList cloudObjs(clouds[i], clouds[i].time().timeName());
+
+        //Pout<< "Found cloud objects:" << cloudObjs.names() << endl;
+
+        parLagrangianDistributor::readAllFields
+        (
+            clouds[i],
+            cloudObjs,
+            selectedFields
+        );
+    }
+
+    return clouds;
+}
+
+
+// Read clouds (note: might not be present on all processors)
+PtrList<unmappedPassivePositionParticleCloud>
+readLagrangian
+(
+    const fvMesh& mesh,
+    const wordRes& selectedFields
+)
+{
+    wordList cloudNames;
+    List<wordList> fieldNames;
+    // Find all cloudNames on all processors
+    parLagrangianDistributor::findClouds(mesh, cloudNames, fieldNames);
+
+    return readLagrangian(mesh, cloudNames, selectedFields);
+}
+
+
+void reconstructLagrangian
+(
+    autoPtr<parLagrangianDistributor>& distributorPtr,
+    const fvMesh& baseMesh,
+    const fvMesh& mesh,
+    const mapDistributePolyMesh& distMap,
+    const wordRes& selectedFields
+)
+{
+    // Clouds (note: might not be present on all processors)
+
+    wordList cloudNames;
+    List<wordList> fieldNames;
+    // Find all cloudNames on all processors
+    parLagrangianDistributor::findClouds(mesh, cloudNames, fieldNames);
+
+    if (cloudNames.empty())
+    {
+        // Nothing to do
+        return;
+    }
+
+    // Use existing or create distributor
+    if (!distributorPtr)
+    {
+        distributorPtr.reset
+        (
+            new parLagrangianDistributor
+            (
+                mesh,
+                baseMesh,
+                mesh.nCells(),      // range of cell indices in clouds
+                distMap
+            )
+        );
+    }
+    const auto& distributor = *distributorPtr;
+
+    for (const word& cloudName : cloudNames)
+    {
+        Info<< "Reconstructing lagrangian fields for cloud "
+            << cloudName << nl << endl;
+
+        IOobjectList cloudObjs
+        (
+            mesh,
+            mesh.time().timeName(),
+            cloud::prefix/cloudName
+        );
+
+        autoPtr<mapDistributeBase> lagrangianMapPtr =
+            distributor.distributeLagrangianPositions
+            (
+                cloudName
+            );
+
+        distributor.distributeAllFields
+        (
+            lagrangianMapPtr(),
+            cloudName,
+            cloudObjs,
+            selectedFields
+        );
+    }
+}
+
+
+void redistributeLagrangian
+(
+    autoPtr<parLagrangianDistributor>& distributorPtr,
+    const fvMesh& mesh,
+    const label nOldCells,
+    const mapDistributePolyMesh& distMap,
+    PtrList<unmappedPassivePositionParticleCloud>& clouds
+)
+{
+    if (clouds.empty())
+    {
+        // Nothing to do
+        return;
+    }
+
+    // Use existing or create distributor
+    if (!distributorPtr)
+    {
+        distributorPtr.reset
+        (
+            new parLagrangianDistributor
+            (
+                mesh,
+                mesh,
+                nOldCells,  // range of cell indices in clouds
+                distMap
+            )
+        );
+    }
+    const auto& distributor = *distributorPtr;
+
+    for (auto& cloud : clouds)
+    {
+        autoPtr<mapDistributeBase> lagrangianMapPtr =
+            distributor.distributeLagrangianPositions(cloud);
+
+        distributor.distributeAllStoredFields
+        (
+            lagrangianMapPtr(),
+            cloud
+        );
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
index c148c3d9e8ccb927e26d44133a517e30c8ea270c..f4d5a4cda4382584d5f6c0e46e1c0221a4e90a5e 100644
--- a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
+++ b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
@@ -94,14 +94,15 @@ Usage
 #include "topoSet.H"
 #include "regionProperties.H"
 
-#include "parFvFieldReconstructor.H"
+#include "parFvFieldDistributor.H"
 #include "parPointFieldDistributor.H"
-#include "parLagrangianRedistributor.H"
-#include "unmappedPassivePositionParticleCloud.H"
 #include "hexRef8Data.H"
 #include "meshRefinement.H"
 #include "pointFields.H"
 
+#include "readDistributedFields.H"
+#include "redistributeLagrangian.H"
+
 #include "cyclicACMIFvPatch.H"
 #include "masterUncollatedFileOperation.H"
 #include "uncollatedFileOperation.H"
@@ -498,7 +499,7 @@ void determineDecomposition
 
     if (Pstream::master() && decompose)
     {
-        Info<< "Restoring caseName to " << proc0CaseName << endl;
+        Info<< "Restoring caseName" << endl;
         tm.caseName() = proc0CaseName;
         tm.processorCase(oldProcCase);
     }
@@ -519,7 +520,7 @@ void determineDecomposition
                 tm.caseName() = baseRunTime.caseName();
                 tm.processorCase(false);
                 writeDecomposition("cellDist", mesh, decomp);
-                Info<< "Restoring caseName to " << proc0CaseName << endl;
+                Info<< "Restoring caseName" << endl;
                 tm.caseName() = proc0CaseName;
                 tm.processorCase(oldProcCase);
 
@@ -539,14 +540,8 @@ void determineDecomposition
 template<class CoupledPatchType, class GeoField>
 void correctCoupledBoundaryConditions(fvMesh& mesh)
 {
-    HashTable<GeoField*> flds
-    (
-        mesh.objectRegistry::lookupClass<GeoField>()
-    );
-
-    for (const word& fldName : flds.sortedToc())
+    for (GeoField& fld : mesh.sorted<GeoField>())
     {
-        GeoField& fld = *(flds[fldName]);
         fld.boundaryFieldRef().template evaluateCoupled<CoupledPatchType>();
     }
 }
@@ -755,7 +750,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
     fvMeshDistribute distributor(mesh);
 
     // Do all the distribution of mesh and fields
-    autoPtr<mapDistributePolyMesh> rawMap = distributor.distribute(decomp);
+    autoPtr<mapDistributePolyMesh> distMap = distributor.distribute(decomp);
 
     // Print some statistics
     Info<< "After distribution:" << endl;
@@ -786,7 +781,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
         // Construct new pointMesh from distributed mesh
         const pointMesh& newPointMesh = pointMesh::New(mesh);
 
-        pointDistributor.resetTarget(newPointMesh, rawMap());
+        pointDistributor.resetTarget(newPointMesh, distMap());
 
         pointDistributor.distributeAndStore(pointScalarFields);
         pointDistributor.distributeAndStore(pointVectorFields);
@@ -811,19 +806,20 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
     }
 
 
-    IOmapDistributePolyMesh map
+    // Register mapDistributePolyMesh for automatic writing...
+    IOmapDistributePolyMeshRef distMapRef
     (
         IOobject
         (
             "procAddressing",
             mesh.facesInstance(),
             polyMesh::meshSubDir,
-            mesh,
+            mesh.thisDb(),
             IOobject::NO_READ,
             IOobject::AUTO_WRITE
-        )
+        ),
+        distMap()
     );
-    map.transfer(rawMap());
 
 
     if (reconstruct)
@@ -839,7 +835,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
             topoSet::removeFiles(mesh);
 
             // Now we've written all. Reset caseName on master
-            Info<< "Restoring caseName to " << proc0CaseName << endl;
+            Info<< "Restoring caseName" << endl;
             runTime.caseName() = proc0CaseName;
             runTime.processorCase(oldProcCase);
         }
@@ -860,8 +856,8 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
         }
         topoSet::removeFiles(mesh);
     }
-    Info<< "Written redistributed mesh to " << mesh.facesInstance() << nl
-        << endl;
+    Info<< "Written redistributed mesh to "
+        << mesh.facesInstance() << nl << endl;
 
 
     if (decompose || reconstruct)
@@ -871,7 +867,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
         fvMeshTools::writeProcAddressing
         (
             mesh,
-            map,
+            distMap(),
             decompose,
             std::move(writeHandler)
         );
@@ -917,7 +913,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
         refData.sync(io);
 
         // Distribute
-        refData.distribute(map);
+        refData.distribute(distMap());
 
 
         // Now we've read refinement data we can remove it
@@ -937,7 +933,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
                 refData.write();
 
                 // Now we've written all. Reset caseName on master
-                Info<< "Restoring caseName to " << proc0CaseName << endl;
+                Info<< "Restoring caseName" << endl;
                 runTime.caseName() = proc0CaseName;
                 runTime.processorCase(oldProcCase);
 
@@ -971,7 +967,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
     //
     //    forAll(cellSets, i)
     //    {
-    //        cellSets[i].distribute(map);
+    //        cellSets[i].distribute(distMap());
     //    }
     //
     //    if (reconstruct)
@@ -985,11 +981,11 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
     //
     //            forAll(cellSets, i)
     //            {
-    //                cellSets[i].distribute(map);
+    //                cellSets[i].distribute(distMap());
     //            }
     //
     //            // Now we've written all. Reset caseName on master
-    //            Info<< "Restoring caseName to " << proc0CaseName << endl;
+    //            Info<< "Restoring caseName" << endl;
     //            runTime.caseName() = proc0CaseName;
     //            runTime.processorCase(oldProcCase);
     //        }
@@ -998,592 +994,19 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
     //    {
     //        forAll(cellSets, i)
     //        {
-    //            cellSets[i].distribute(map);
+    //            cellSets[i].distribute(distMap());
     //        }
     //    }
     //}
 
 
-    return autoPtr<mapDistributePolyMesh>::New(std::move(map));
-}
-
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Field Mapping
-//
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-void reconstructMeshFields
-(
-    const parFvFieldReconstructor& fvReconstructor,
-    const IOobjectList& objects,
-    const wordRes& selectedFields
-)
-{
-    // Dimensioned fields
-
-    fvReconstructor.reconstructFvVolumeInternalFields<scalar>
-    (
-        objects,
-        selectedFields
-    );
-    fvReconstructor.reconstructFvVolumeInternalFields<vector>
-    (
-        objects,
-        selectedFields
-    );
-    fvReconstructor.reconstructFvVolumeInternalFields<sphericalTensor>
-    (
-        objects,
-        selectedFields
-    );
-    fvReconstructor.reconstructFvVolumeInternalFields<symmTensor>
-    (
-        objects,
-        selectedFields
-    );
-    fvReconstructor.reconstructFvVolumeInternalFields<tensor>
-    (
-        objects,
-        selectedFields
-    );
-
-
-    // volFields
-
-    fvReconstructor.reconstructFvVolumeFields<scalar>
-    (
-        objects,
-        selectedFields
-    );
-    fvReconstructor.reconstructFvVolumeFields<vector>
-    (
-        objects,
-        selectedFields
-    );
-    fvReconstructor.reconstructFvVolumeFields<sphericalTensor>
-    (
-        objects,
-        selectedFields
-    );
-    fvReconstructor.reconstructFvVolumeFields<symmTensor>
-    (
-        objects,
-        selectedFields
-    );
-    fvReconstructor.reconstructFvVolumeFields<tensor>
-    (
-        objects,
-        selectedFields
-    );
-
-
-    // surfaceFields
-
-    fvReconstructor.reconstructFvSurfaceFields<scalar>
-    (
-        objects,
-        selectedFields
-    );
-    fvReconstructor.reconstructFvSurfaceFields<vector>
-    (
-        objects,
-        selectedFields
-    );
-    fvReconstructor.reconstructFvSurfaceFields<sphericalTensor>
-    (
-        objects,
-        selectedFields
-    );
-    fvReconstructor.reconstructFvSurfaceFields<symmTensor>
-    (
-        objects,
-        selectedFields
-    );
-    fvReconstructor.reconstructFvSurfaceFields<tensor>
-    (
-        objects,
-        selectedFields
-    );
-}
-
-
-void reconstructLagrangian
-(
-    autoPtr<parLagrangianRedistributor>& lagrangianReconstructorPtr,
-    const fvMesh& baseMesh,
-    const fvMesh& mesh,
-    const mapDistributePolyMesh& distMap,
-    const wordRes& selectedLagrangianFields
-)
-{
-    // Clouds (note: might not be present on all processors)
-
-    wordList cloudNames;
-    List<wordList> fieldNames;
-    // Find all cloudNames on all processors
-    parLagrangianRedistributor::findClouds(mesh, cloudNames, fieldNames);
-
-    if (cloudNames.size())
-    {
-        if (!lagrangianReconstructorPtr)
-        {
-            lagrangianReconstructorPtr.reset
-            (
-                new parLagrangianRedistributor
-                (
-                    mesh,
-                    baseMesh,
-                    mesh.nCells(),      // range of cell indices in clouds
-                    distMap
-                )
-            );
-        }
-        const parLagrangianRedistributor& lagrangianReconstructor =
-            *lagrangianReconstructorPtr;
-
-        for (const word& cloudName : cloudNames)
-        {
-            Info<< "Reconstructing lagrangian fields for cloud "
-                << cloudName << nl << endl;
-
-            autoPtr<mapDistributeBase> lagrangianMapPtr =
-                lagrangianReconstructor.redistributeLagrangianPositions
-                (
-                    cloudName
-                );
-
-            const mapDistributeBase& lagrangianMap = *lagrangianMapPtr;
-
-            IOobjectList cloudObjs
-            (
-                mesh,
-                mesh.time().timeName(),
-                cloud::prefix/cloudName
-            );
-
-            lagrangianReconstructor.redistributeFields<label>
-            (
-                lagrangianMap,
-                cloudName,
-                cloudObjs,
-                selectedLagrangianFields
-            );
-            lagrangianReconstructor.redistributeFieldFields<label>
-            (
-                lagrangianMap,
-                cloudName,
-                cloudObjs,
-                selectedLagrangianFields
-            );
-            lagrangianReconstructor.redistributeFields<scalar>
-            (
-                lagrangianMap,
-                cloudName,
-                cloudObjs,
-                selectedLagrangianFields
-            );
-            lagrangianReconstructor.redistributeFieldFields<scalar>
-            (
-                lagrangianMap,
-                cloudName,
-                cloudObjs,
-                selectedLagrangianFields
-            );
-            lagrangianReconstructor.redistributeFields<vector>
-            (
-                lagrangianMap,
-                cloudName,
-                cloudObjs,
-                selectedLagrangianFields
-            );
-            lagrangianReconstructor.redistributeFieldFields<vector>
-            (
-                lagrangianMap,
-                cloudName,
-                cloudObjs,
-                selectedLagrangianFields
-            );
-            lagrangianReconstructor.redistributeFields
-            <sphericalTensor>
-            (
-                lagrangianMap,
-                cloudName,
-                cloudObjs,
-                selectedLagrangianFields
-            );
-            lagrangianReconstructor.redistributeFieldFields
-            <sphericalTensor>
-            (
-                lagrangianMap,
-                cloudName,
-                cloudObjs,
-                selectedLagrangianFields
-            );
-            lagrangianReconstructor.redistributeFields<symmTensor>
-            (
-                lagrangianMap,
-                cloudName,
-                cloudObjs,
-                selectedLagrangianFields
-            );
-            lagrangianReconstructor.redistributeFieldFields
-            <symmTensor>
-            (
-                lagrangianMap,
-                cloudName,
-                cloudObjs,
-                selectedLagrangianFields
-            );
-            lagrangianReconstructor.redistributeFields<tensor>
-            (
-                lagrangianMap,
-                cloudName,
-                cloudObjs,
-                selectedLagrangianFields
-            );
-            lagrangianReconstructor.redistributeFieldFields<tensor>
-            (
-                lagrangianMap,
-                cloudName,
-                cloudObjs,
-                selectedLagrangianFields
-            );
-        }
-    }
-}
-
-
-// Read clouds (note: might not be present on all processors)
-void readLagrangian
-(
-    const fvMesh& mesh,
-    const wordList& cloudNames,
-    const wordRes& selectedLagrangianFields,
-    PtrList<unmappedPassivePositionParticleCloud>& clouds
-)
-{
-    (void)mesh.tetBasePtIs();
-
-    forAll(cloudNames, i)
-    {
-        //Pout<< "Loading cloud " << cloudNames[i] << endl;
-        clouds.set
-        (
-            i,
-            new unmappedPassivePositionParticleCloud(mesh, cloudNames[i], false)
-        );
-
-
-        //for (passivePositionParticle& p : clouds[i]))
-        //{
-        //    Pout<< "Particle position:" << p.position()
-        //        << " cell:" << p.cell()
-        //        << " with cc:" << mesh.cellCentres()[p.cell()]
-        //        << endl;
-        //}
-
-
-        IOobjectList cloudObjs(clouds[i], clouds[i].time().timeName());
-
-        //Pout<< "Found clould objects:" << cloudObjs.names() << endl;
-
-        parLagrangianRedistributor::readFields
-        <IOField<label>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-        parLagrangianRedistributor::readFields
-        <IOField<Field<label>>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-        parLagrangianRedistributor::readFields
-        <CompactIOField<Field<label>, label>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-
-
-        parLagrangianRedistributor::readFields
-        <IOField<scalar>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-        parLagrangianRedistributor::readFields
-        <IOField<Field<scalar>>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-        parLagrangianRedistributor::readFields
-        <CompactIOField<Field<scalar>, scalar>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-
-
-        parLagrangianRedistributor::readFields
-        <IOField<vector>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-        parLagrangianRedistributor::readFields
-        <IOField<Field<vector>>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-        parLagrangianRedistributor::readFields
-        <CompactIOField<Field<vector>, vector>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-
-
-        parLagrangianRedistributor::readFields
-        <IOField<sphericalTensor>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-        parLagrangianRedistributor::readFields
-        <IOField<Field<sphericalTensor>>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-        parLagrangianRedistributor::readFields
-        <CompactIOField<Field<sphericalTensor>, sphericalTensor>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-
-
-        parLagrangianRedistributor::readFields
-        <IOField<symmTensor>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-        parLagrangianRedistributor::readFields
-        <IOField<Field<symmTensor>>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-        parLagrangianRedistributor::readFields
-        <CompactIOField<Field<symmTensor>, symmTensor>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-
-
-        parLagrangianRedistributor::readFields
-        <IOField<tensor>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-        parLagrangianRedistributor::readFields
-        <IOField<Field<tensor>>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-        parLagrangianRedistributor::readFields
-        <CompactIOField<Field<tensor>, tensor>>
-        (
-            clouds[i],
-            cloudObjs,
-            selectedLagrangianFields
-        );
-    }
+    return distMap;
 }
 
 
-void redistributeLagrangian
-(
-    autoPtr<parLagrangianRedistributor>& lagrangianReconstructorPtr,
-    const fvMesh& mesh,
-    const label nOldCells,
-    const mapDistributePolyMesh& distMap,
-    PtrList<unmappedPassivePositionParticleCloud>& clouds
-)
-{
-    if (clouds.size())
-    {
-        if (!lagrangianReconstructorPtr)
-        {
-            lagrangianReconstructorPtr.reset
-            (
-                new parLagrangianRedistributor
-                (
-                    mesh,
-                    mesh,
-                    nOldCells,  // range of cell indices in clouds
-                    distMap
-                )
-            );
-        }
-        const parLagrangianRedistributor& distributor =
-            lagrangianReconstructorPtr();
-
-        forAll(clouds, i)
-        {
-            autoPtr<mapDistributeBase> lagrangianMapPtr =
-                distributor.redistributeLagrangianPositions(clouds[i]);
-            const mapDistributeBase& lagrangianMap = *lagrangianMapPtr;
-
-            distributor.redistributeStoredFields
-            <IOField<label>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-            distributor.redistributeStoredFields
-            <IOField<Field<label>>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-            distributor.redistributeStoredFields
-            <CompactIOField<Field<label>, label>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-
-
-            distributor.redistributeStoredFields
-            <IOField<scalar>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-            distributor.redistributeStoredFields
-            <IOField<Field<scalar>>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-            distributor.redistributeStoredFields
-            <CompactIOField<Field<scalar>, scalar>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-
-
-            distributor.redistributeStoredFields
-            <IOField<vector>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-            distributor.redistributeStoredFields
-            <IOField<Field<vector>>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-            distributor.redistributeStoredFields
-            <CompactIOField<Field<vector>, vector>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-
-
-            distributor.redistributeStoredFields
-            <IOField<sphericalTensor>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-            distributor.redistributeStoredFields
-            <IOField<Field<sphericalTensor>>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-            distributor.redistributeStoredFields
-            <CompactIOField<Field<sphericalTensor>, sphericalTensor>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-
-
-            distributor.redistributeStoredFields
-            <IOField<symmTensor>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-            distributor.redistributeStoredFields
-            <IOField<Field<symmTensor>>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-            distributor.redistributeStoredFields
-            <CompactIOField<Field<symmTensor>, symmTensor>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-
-
-            distributor.redistributeStoredFields
-            <IOField<tensor>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-            distributor.redistributeStoredFields
-            <IOField<Field<tensor>>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-            distributor.redistributeStoredFields
-            <CompactIOField<Field<tensor>, tensor>>
-            (
-                lagrangianMap,
-                clouds[i]
-            );
-        }
-    }
-}
-
+/*---------------------------------------------------------------------------*\
+                                     main
+\*---------------------------------------------------------------------------*/
 
 int main(int argc, char *argv[])
 {
@@ -1623,6 +1046,10 @@ int main(int argc, char *argv[])
         "newTimes",
         "Only reconstruct new times (i.e. that do not exist already)"
     );
+    argList::addVerboseOption
+    (
+        "Additional verbosity. (Can be used multiple times)"
+    );
 
 
     // Handle arguments
@@ -1675,16 +1102,17 @@ int main(int argc, char *argv[])
     const bool writeCellDist = args.found("cellDist");
     const bool dryrun = args.dryRun();
     const bool newTimes = args.found("newTimes");
+    const int optVerbose = args.verbose();
 
-    if (args.verbose())
+    bool decompose = args.found("decompose");
+    bool overwrite = args.found("overwrite");
+
+    if (optVerbose)
     {
         // Report on output
         parPointFieldDistributor::verbose_ = 1;
     }
 
-    bool decompose = args.found("decompose");
-    bool overwrite = args.found("overwrite");
-
     // Disable NaN setting and floating point error trapping. This is to avoid
     // any issues inside the field redistribution inside fvMeshDistribute
     // which temporarily moves processor faces into existing patches. These
@@ -1821,7 +1249,7 @@ int main(int argc, char *argv[])
     }
 
 
-    Info<< "Create undecomposed database"<< nl << endl;
+    Info<< "Create undecomposed database" << nl << endl;
     Time baseRunTime
     (
         runTime.controlDict(),
@@ -1858,7 +1286,7 @@ int main(int argc, char *argv[])
 
 
     // Demand driven lagrangian mapper
-    autoPtr<parLagrangianRedistributor> lagrangianReconstructorPtr;
+    autoPtr<parLagrangianDistributor> lagrangianDistributorPtr;
 
 
     if (reconstruct)
@@ -1881,8 +1309,7 @@ int main(int argc, char *argv[])
 
 
         Info<< nl
-            << "Pass1 : reconstructing mesh and addressing" << nl << endl;
-
+            << "Reconstructing mesh and addressing" << nl << endl;
 
         forAll(regionNames, regioni)
         {
@@ -1893,7 +1320,8 @@ int main(int argc, char *argv[])
             );
             const fileName meshSubDir(regionDir/polyMesh::meshSubDir);
 
-            Info<< "\n\nReconstructing mesh " << regionName << nl << endl;
+            Info<< nl << nl
+                << "Reconstructing mesh " << regionName << nl << endl;
 
             // Loop over all times
             forAll(timeDirs, timeI)
@@ -2071,7 +1499,7 @@ int main(int argc, char *argv[])
             // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
             Info<< nl
-                << "Pass2 : reconstructing fields" << nl << endl;
+                << "Reconstructing fields" << nl << endl;
 
             runTime.setTime(timeDirs[0], 0);
             baseRunTime.setTime(timeDirs[0], 0);
@@ -2128,13 +1556,13 @@ int main(int argc, char *argv[])
             distMap = fvMeshTools::readProcAddressing(mesh, baseMeshPtr);
 
             // Construct field mapper
-            auto fvReconstructorPtr =
-                autoPtr<parFvFieldReconstructor>::New
+            auto fvDistributorPtr =
+                autoPtr<parFvFieldDistributor>::New
                 (
-                    baseMeshPtr(),
-                    mesh,
+                    mesh,            // source
+                    baseMeshPtr(),   // target
                     distMap(),
-                    Pstream::master()       // do I need to write?
+                    UPstream::master()  // Write reconstructed on master
                 );
 
             // Construct point field mapper
@@ -2161,7 +1589,7 @@ int main(int argc, char *argv[])
                 Info<< "    Detected initial mesh motion;"
                     << " reconstructing points" << nl
                     << endl;
-                fvReconstructorPtr().reconstructPoints();
+                fvDistributorPtr().reconstructPoints();
             }
 
 
@@ -2183,18 +1611,18 @@ int main(int argc, char *argv[])
 
 
                 // Check if any new meshes need to be read.
-                fvMesh::readUpdateState procStat = mesh.readUpdate();
+                polyMesh::readUpdateState procStat = mesh.readUpdate();
 
-                if (procStat == fvMesh::POINTS_MOVED)
+                if (procStat == polyMesh::POINTS_MOVED)
                 {
-                    Info<< "    Dected mesh motion; reconstructing points" << nl
-                        << endl;
-                    fvReconstructorPtr().reconstructPoints();
+                    Info<< "    Detected mesh motion; reconstructing points"
+                        << nl << endl;
+                    fvDistributorPtr().reconstructPoints();
                 }
                 else if
                 (
-                    procStat == fvMesh::TOPO_CHANGE
-                 || procStat == fvMesh::TOPO_PATCH_CHANGE
+                    procStat == polyMesh::TOPO_CHANGE
+                 || procStat == polyMesh::TOPO_PATCH_CHANGE
                 )
                 {
                     Info<< "    Detected topology change;"
@@ -2225,14 +1653,14 @@ int main(int argc, char *argv[])
 
                     // Reset field mappers
 
-                    fvReconstructorPtr.reset
+                    fvDistributorPtr.reset
                     (
-                        new parFvFieldReconstructor
+                        new parFvFieldDistributor
                         (
-                            baseMeshPtr(),
-                            mesh,
+                            mesh,           // source
+                            baseMeshPtr(),  // target
                             distMap(),
-                            Pstream::master()
+                            UPstream::master()  // Write reconstruct on master
                         )
                     );
 
@@ -2252,7 +1680,7 @@ int main(int argc, char *argv[])
                         )
                     );
 
-                    lagrangianReconstructorPtr.clear();
+                    lagrangianDistributorPtr.reset();
                 }
 
 
@@ -2261,12 +1689,8 @@ int main(int argc, char *argv[])
 
 
                 // Mesh fields (vol, surface, volInternal)
-                reconstructMeshFields
-                (
-                    fvReconstructorPtr(),
-                    objects,
-                    selectedFields
-                );
+                fvDistributorPtr()
+                    .distributeAllFields(objects, selectedFields);
 
                 // pointfields
                 // - distribute and write (verbose)
@@ -2277,7 +1701,7 @@ int main(int argc, char *argv[])
                 // Clouds (note: might not be present on all processors)
                 reconstructLagrangian
                 (
-                    lagrangianReconstructorPtr,
+                    lagrangianDistributorPtr,
                     baseMeshPtr(),
                     mesh,
                     distMap(),
@@ -2393,7 +1817,7 @@ int main(int argc, char *argv[])
 
                 if (decompose)
                 {
-                    Info<< "Restoring caseName to " << proc0CaseName << endl;
+                    Info<< "Restoring caseName" << endl;
                     runTime.caseName() = proc0CaseName;
                     runTime.processorCase(oldProcCase);
                 }
@@ -2491,7 +1915,7 @@ int main(int argc, char *argv[])
 
             if (Pstream::master() && decompose)
             {
-                Info<< "Restoring caseName to " << proc0CaseName << endl;
+                Info<< "Restoring caseName" << endl;
                 runTime.caseName() = proc0CaseName;
                 runTime.processorCase(oldProcCase);
             }
@@ -2533,43 +1957,31 @@ int main(int argc, char *argv[])
             }
 
 
-
-            wordList cloudNames;
-            List<wordList> fieldNames;
-
             // Detect lagrangian fields
             if (Pstream::master() && decompose)
             {
                 runTime.caseName() = baseRunTime.caseName();
                 runTime.processorCase(false);
             }
-            parLagrangianRedistributor::findClouds
-            (
-                mesh,
-                cloudNames,
-                fieldNames
-            );
 
             // Read lagrangian fields and store on cloud (objectRegistry)
             PtrList<unmappedPassivePositionParticleCloud> clouds
             (
-                cloudNames.size()
-            );
-            readLagrangian
-            (
-                mesh,
-                cloudNames,
-                selectedLagrangianFields,
-                clouds
+                readLagrangian
+                (
+                    mesh,
+                    selectedLagrangianFields
+                )
             );
+
             if (Pstream::master() && decompose)
             {
                 runTime.caseName() = proc0CaseName;
                 runTime.processorCase(oldProcCase);
             }
 
-            // Load fields, do all distribution (mesh and fields - but not
-            // lagrangian fields; these are done later)
+            // Load fields, do all distribution (mesh and fields)
+            // - but not lagrangian fields; these are done later
             autoPtr<mapDistributePolyMesh> distMap = redistributeAndWrite
             (
                 std::move(writeHandler),
@@ -2591,7 +2003,7 @@ int main(int argc, char *argv[])
             // Redistribute any clouds
             redistributeLagrangian
             (
-                lagrangianReconstructorPtr,
+                lagrangianDistributorPtr,
                 mesh,
                 nOldCells,
                 distMap(),