diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/PV3FoamReader_SM.xml b/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/PV3FoamReader_SM.xml
index d522660cc4110cd70c04cb5e66cb088f2b7366d5..9a0e8d26bfd36f7583a3b4bf521f27162d6d6ffe 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/PV3FoamReader_SM.xml
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/PV3FoamReader_SM.xml
@@ -12,7 +12,7 @@
       animateable="0">
       <FileListDomain name="files"/>
       <Documentation>
-          Specifies the filename for the OpenFOAM Reader
+        Specifies the filename for the OpenFOAM Reader
       </Documentation>
     </StringVectorProperty>
 
@@ -32,25 +32,25 @@
       <TimeRangeInformationHelper/>
     </DoubleVectorProperty>
 
-    <!-- Available Region array -->
+    <!-- Available Parts (volume, patches, lagrangian) array -->
     <StringVectorProperty
-      name="RegionArrayInfo"
+      name="PartArrayInfo"
       information_only="1">
-      <ArraySelectionInformationHelper attribute_name="Region"/>
+      <ArraySelectionInformationHelper attribute_name="Part"/>
     </StringVectorProperty>
     <StringVectorProperty
-      name="RegionStatus"
+      name="PartStatus"
       label="Mesh Parts"
-      command="SetRegionArrayStatus"
+      command="SetPartArrayStatus"
       number_of_elements="0"
       repeat_command="1"
       number_of_elements_per_command="2"
       element_types="2 0"
-      information_property="RegionArrayInfo"
+      information_property="PartArrayInfo"
       animateable="0">
       <ArraySelectionDomain name="array_list">
         <RequiredProperties>
-          <Property name="RegionArrayInfo" function="ArrayList"/>
+          <Property name="PartArrayInfo" function="ArrayList"/>
         </RequiredProperties>
       </ArraySelectionDomain>
     </StringVectorProperty>
@@ -132,6 +132,9 @@
       default_values="0"
       animateable="0">
       <BooleanDomain name="bool"/>
+      <Documentation>
+        Extrapolate internalField to wall and empty patches
+      </Documentation>
     </IntVectorProperty>
 
     <!-- Include Sets check-box -->
@@ -141,6 +144,9 @@
       number_of_elements="1"
       default_values="0"
       animateable="0">
+      <Documentation>
+        Searches the polyMesh/sets/ directory
+      </Documentation>
       <BooleanDomain name="bool"/>
     </IntVectorProperty>
 
@@ -151,6 +157,10 @@
       number_of_elements="1"
       default_values="0"
       animateable="0">
+      <Documentation>
+        ZoneMesh information is used to find {cell,face,point}Zones.
+        The polyMesh/ directory is only checked on startup.
+      </Documentation>
       <BooleanDomain name="bool"/>
     </IntVectorProperty>
 
@@ -162,6 +172,9 @@
       default_values="0"
       animateable="0">
       <BooleanDomain name="bool"/>
+      <Documentation>
+        Show patch names in render window.
+      </Documentation>
     </IntVectorProperty>
 
     <!-- Cache Mesh check-box -->
@@ -172,6 +185,9 @@
       default_values="1"
       animateable="0">
       <BooleanDomain name="bool"/>
+      <Documentation>
+        Cache the fvMesh in memory.
+      </Documentation>
     </IntVectorProperty>
 
     <!-- Update GUI check box -->
@@ -182,6 +198,9 @@
       default_values="0"
       animateable="0">
       <BooleanDomain name="bool"/>
+      <Documentation>
+        A simple way cause a reader GUI modification.
+      </Documentation>
     </IntVectorProperty>
 
   </SourceProxy>
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx b/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx
index 2ad4f68cb01494fe722f034872b39e7a4137d2c0..70a6230bfe17dcf99d5085b866c3d3a25dc05f2e 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx
@@ -71,7 +71,7 @@ vtkPV3FoamReader::vtkPV3FoamReader()
 
     UpdateGUI = 0;
 
-    RegionSelection = vtkDataArraySelection::New();
+    PartSelection = vtkDataArraySelection::New();
     VolFieldSelection = vtkDataArraySelection::New();
     PointFieldSelection = vtkDataArraySelection::New();
     LagrangianFieldSelection = vtkDataArraySelection::New();
@@ -85,7 +85,7 @@ vtkPV3FoamReader::vtkPV3FoamReader()
     );
     SelectionObserver->SetClientData(this);
 
-    RegionSelection->AddObserver
+    PartSelection->AddObserver
     (
         vtkCommand::ModifiedEvent,
         this->SelectionObserver
@@ -128,14 +128,14 @@ vtkPV3FoamReader::~vtkPV3FoamReader()
     }
 
 
-    RegionSelection->RemoveObserver(this->SelectionObserver);
+    PartSelection->RemoveObserver(this->SelectionObserver);
     VolFieldSelection->RemoveObserver(this->SelectionObserver);
     PointFieldSelection->RemoveObserver(this->SelectionObserver);
     LagrangianFieldSelection->RemoveObserver(this->SelectionObserver);
 
     SelectionObserver->Delete();
 
-    RegionSelection->Delete();
+    PartSelection->Delete();
     VolFieldSelection->Delete();
     PointFieldSelection->Delete();
     LagrangianFieldSelection->Delete();
@@ -427,46 +427,46 @@ int vtkPV3FoamReader::GetTimeStep()
 
 
 // ----------------------------------------------------------------------
-// Region selection list control
+// Parts selection list control
 
-vtkDataArraySelection* vtkPV3FoamReader::GetRegionSelection()
+vtkDataArraySelection* vtkPV3FoamReader::GetPartSelection()
 {
-    vtkDebugMacro(<<"GetRegionSelection");
-    return RegionSelection;
+    vtkDebugMacro(<<"GetPartSelection");
+    return PartSelection;
 }
 
 
-int vtkPV3FoamReader::GetNumberOfRegionArrays()
+int vtkPV3FoamReader::GetNumberOfPartArrays()
 {
-    vtkDebugMacro(<<"GetNumberOfRegionArrays");
-    return RegionSelection->GetNumberOfArrays();
+    vtkDebugMacro(<<"GetNumberOfPartArrays");
+    return PartSelection->GetNumberOfArrays();
 }
 
 
-const char* vtkPV3FoamReader::GetRegionArrayName(int index)
+const char* vtkPV3FoamReader::GetPartArrayName(int index)
 {
-    vtkDebugMacro(<<"GetRegionArrayName");
-    return RegionSelection->GetArrayName(index);
+    vtkDebugMacro(<<"GetPartArrayName");
+    return PartSelection->GetArrayName(index);
 }
 
 
-int vtkPV3FoamReader::GetRegionArrayStatus(const char* name)
+int vtkPV3FoamReader::GetPartArrayStatus(const char* name)
 {
-    vtkDebugMacro(<<"GetRegionArrayStatus");
-    return RegionSelection->ArrayIsEnabled(name);
+    vtkDebugMacro(<<"GetPartArrayStatus");
+    return PartSelection->ArrayIsEnabled(name);
 }
 
 
-void vtkPV3FoamReader::SetRegionArrayStatus(const char* name, int status)
+void vtkPV3FoamReader::SetPartArrayStatus(const char* name, int status)
 {
-    vtkDebugMacro(<<"SetRegionArrayStatus");
+    vtkDebugMacro(<<"SetPartArrayStatus");
     if (status)
     {
-        RegionSelection->EnableArray(name);
+        PartSelection->EnableArray(name);
     }
     else
     {
-        RegionSelection->DisableArray(name);
+        PartSelection->DisableArray(name);
     }
 }
 
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.h b/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.h
index 88fbae9b313ae429e534c9411227fbbd71bb8451..fde87527de29c134526ee73c72909d1bd0fed8d9 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.h
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.h
@@ -88,12 +88,12 @@ public:
     int  GetTimeStep();
 
     // Description:
-    // Region selection list control
-    vtkDataArraySelection* GetRegionSelection();
-    int  GetNumberOfRegionArrays();
-    int  GetRegionArrayStatus(const char* name);
-    void SetRegionArrayStatus(const char* name, int status);
-    const char* GetRegionArrayName(int index);
+    // Parts selection list control
+    vtkDataArraySelection* GetPartSelection();
+    int  GetNumberOfPartArrays();
+    int  GetPartArrayStatus(const char* name);
+    void SetPartArrayStatus(const char* name, int status);
+    const char* GetPartArrayName(int index);
 
     // Description:
     // volField selection list control
@@ -191,7 +191,7 @@ private:
     //- Dummy variable/switch for invoke a reader update
     int UpdateGUI;
 
-    vtkDataArraySelection* RegionSelection;
+    vtkDataArraySelection* PartSelection;
     vtkDataArraySelection* VolFieldSelection;
     vtkDataArraySelection* PointFieldSelection;
     vtkDataArraySelection* LagrangianFieldSelection;
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/Make/files b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/Make/files
index 4bb4f69970e1898d90a3c0ddf209d73f75e27abf..9699e3c71ebe3c4159b36ee2f5abb09d9730ab2e 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/Make/files
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/Make/files
@@ -7,5 +7,6 @@ vtkPV3FoamMeshSet.C
 vtkPV3FoamMeshVolume.C
 vtkPV3FoamMeshZone.C
 vtkPV3FoamUpdateInfo.C
+vtkPV3FoamUtilities.C
 
 LIB = $(FOAM_LIBBIN)/libvtkPV3Foam
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C
index 9595e37ff7a9c9ecd2a259f9974f0d783ebd1ee8..11a28847b3b85e254038ba4d5a8de5eead1f3264 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C
@@ -31,20 +31,13 @@ License
 #include "fvMesh.H"
 #include "Time.H"
 #include "patchZones.H"
-#include "IFstream.H"
 
 // VTK includes
-#include "vtkCharArray.h"
 #include "vtkDataArraySelection.h"
-#include "vtkDataSet.h"
-#include "vtkFieldData.h"
 #include "vtkMultiBlockDataSet.h"
 #include "vtkRenderer.h"
 #include "vtkTextActor.h"
 #include "vtkTextProperty.h"
-#include "vtkPolyData.h"
-#include "vtkUnstructuredGrid.h"
-#include "vtkInformation.h"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -55,120 +48,40 @@ defineTypeNameAndDebug(Foam::vtkPV3Foam, 0);
 #include "vtkPV3FoamAddToSelection.H"
 #include "vtkPV3FoamUpdateInfoFields.H"
 
-void Foam::vtkPV3Foam::AddToBlock
-(
-    vtkMultiBlockDataSet* output,
-    const selectionInfo& selector,
-    const label datasetNo,
-    vtkDataSet* dataset,
-    const string& blockName
-)
+void Foam::vtkPV3Foam::resetCounters()
 {
-    const int blockNo = selector.block();
-
-    vtkDataObject* blockDO = output->GetBlock(blockNo);
-    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
-    if (blockDO && !block)
-    {
-        FatalErrorIn("Foam::vtkPV3Foam::AddToBlock")
-            << "Block already has a vtkDataSet assigned to it" << nl << endl;
-        return;
-    }
-
-    if (!block)
-    {
-        block = vtkMultiBlockDataSet::New();
-        output->SetBlock(blockNo, block);
-        block->Delete();
-    }
-
-    if (block)
-    {
-        if (debug)
-        {
-            Info<< "block[" << blockNo << "] has "
-                << block->GetNumberOfBlocks()
-                <<  " datasets prior to adding set " << datasetNo
-                <<  " with name: " << blockName << endl;
-        }
-
-        // when assigning dataset 0, also name the parent block
-        if (!datasetNo && selector.name())
-        {
-            output->GetMetaData(blockNo)->Set
-            (
-                vtkCompositeDataSet::NAME(),
-                selector.name()
-            );
-        }
-    }
-
-
-    block->SetBlock(datasetNo, dataset);
-
-    if (blockName.size())
-    {
-        block->GetMetaData(datasetNo)->Set
-        (
-            vtkCompositeDataSet::NAME(), blockName.c_str()
-        );
-    }
-
+    // Reset mesh part ids and sizes
+    partInfoVolume_.reset();
+    partInfoPatches_.reset();
+    partInfoLagrangian_.reset();
+    partInfoCellZones_.reset();
+    partInfoFaceZones_.reset();
+    partInfoPointZones_.reset();
+    partInfoCellSets_.reset();
+    partInfoFaceSets_.reset();
+    partInfoPointSets_.reset();
 }
 
 
-vtkDataSet* Foam::vtkPV3Foam::GetDataSetFromBlock
-(
-    vtkMultiBlockDataSet* output,
-    const selectionInfo& selector,
-    const label datasetNo
-)
+void Foam::vtkPV3Foam::reduceMemory()
 {
-    const int blockNo = selector.block();
-
-    vtkDataObject* blockDO = output->GetBlock(blockNo);
-    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
-    if (block)
+    forAll(regionPolyDecomp_, i)
     {
-        return vtkDataSet::SafeDownCast(block->GetBlock(datasetNo));
+        regionPolyDecomp_[i].clear();
     }
 
-    return 0;
-}
-
-
-Foam::label Foam::vtkPV3Foam::GetNumberOfDataSets
-(
-    vtkMultiBlockDataSet* output,
-    const selectionInfo& selector
-)
-{
-    const int blockNo = selector.block();
-
-    vtkDataObject* blockDO = output->GetBlock(blockNo);
-    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
-    if (block)
+    forAll(zonePolyDecomp_, i)
     {
-        return block->GetNumberOfBlocks();
+        zonePolyDecomp_[i].clear();
     }
 
-    return 0;
+    forAll(csetPolyDecomp_, i)
+    {
+        csetPolyDecomp_[i].clear();
+    }
 }
 
 
-void Foam::vtkPV3Foam::resetCounters()
-{
-    // Reset region ids and sizes
-    regionInfoVolume_.reset();
-    regionInfoPatches_.reset();
-    regionInfoLagrangian_.reset();
-    regionInfoCellZones_.reset();
-    regionInfoFaceZones_.reset();
-    regionInfoPointZones_.reset();
-    regionInfoCellSets_.reset();
-    regionInfoFaceSets_.reset();
-    regionInfoPointSets_.reset();
-}
 
 
 int Foam::vtkPV3Foam::setTime(const double& requestedTime)
@@ -231,242 +144,51 @@ int Foam::vtkPV3Foam::setTime(const double& requestedTime)
 }
 
 
-void Foam::vtkPV3Foam::updateRegionStatus()
+void Foam::vtkPV3Foam::updateMeshPartsStatus()
 {
     if (debug)
     {
-        Info<< "<beg> Foam::vtkPV3Foam::updateRegionStatus" << endl;
+        Info<< "<beg> Foam::vtkPV3Foam::updateMeshPartsStatus" << endl;
     }
 
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
-    const label nSelect = regionSelection->GetNumberOfArrays();
-    if (regionStatus_.size() != nSelect)
+    vtkDataArraySelection* selection = reader_->GetPartSelection();
+    label nElem = selection->GetNumberOfArrays();
+
+    if (partStatus_.size() != nElem)
     {
-        regionStatus_.setSize(nSelect);
-        regionStatus_ = false;
+        partStatus_.setSize(nElem);
+        partStatus_ = false;
         meshChanged_ = true;
     }
 
     // this needs fixing if we wish to re-use the datasets
-    regionDataset_.setSize(nSelect);
-    regionDataset_ = -1;
+    partDataset_.setSize(nElem);
+    partDataset_ = -1;
 
-    // Read the selected cell regions, zones, patches and add to region list
-    forAll(regionStatus_, regionId)
+    // Read the selected mesh parts (zones, patches ...) and add to list
+    forAll(partStatus_, partId)
     {
-        int setting = regionSelection->GetArraySetting(regionId);
+        const int setting = selection->GetArraySetting(partId);
 
-        if (regionStatus_[regionId] != setting)
+        if (partStatus_[partId] != setting)
         {
-            regionStatus_[regionId] = setting;
+            partStatus_[partId] = setting;
             meshChanged_ = true;
         }
 
         if (debug)
         {
-            Info<< "  region[" << regionId << "] = "
-                << regionStatus_[regionId]
-                << " : " << regionSelection->GetArrayName(regionId) << endl;
-        }
-    }
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::updateRegionStatus" << endl;
-    }
-}
-
-Foam::wordHashSet Foam::vtkPV3Foam::getSelected
-(
-    vtkDataArraySelection* select
-)
-{
-    int nElem = select->GetNumberOfArrays();
-    wordHashSet selections(2*nElem);
-
-    for (int elemI=0; elemI < nElem; ++elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            word name(getFirstWord(select->GetArrayName(elemI)));
-            selections.insert(name);
-        }
-    }
-
-    return selections;
-}
-
-
-Foam::stringList Foam::vtkPV3Foam::getSelectedArrayEntries
-(
-    vtkDataArraySelection* select,
-    const bool firstWord
-)
-{
-    stringList selections(select->GetNumberOfArrays());
-    label nElem = 0;
-
-    if (debug)
-    {
-        Info<< "available(";
-        forAll(selections, elemI)
-        {
-            Info<< " \"" << select->GetArrayName(elemI) << "\"";
-        }
-        Info<< " )\n"
-            << "selected(";
-    }
-
-    forAll(selections, elemI)
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            if (firstWord)
-            {
-                selections[nElem] = getFirstWord
-                (
-                    select->GetArrayName(elemI)
-                );
-            }
-            else
-            {
-                selections[nElem] = select->GetArrayName(elemI);
-            }
-
-            if (debug)
-            {
-                Info<< " " << selections[nElem];
-            }
-
-            ++nElem;
-        }
-    }
-
-    if (debug)
-    {
-        Info<< " )" << endl;
-    }
-
-    selections.setSize(nElem);
-    return selections;
-}
-
-
-Foam::stringList Foam::vtkPV3Foam::getSelectedArrayEntries
-(
-    vtkDataArraySelection* select,
-    const selectionInfo& selector,
-    const bool firstWord
-)
-{
-    stringList selections(selector.size());
-    label nElem = 0;
-
-    if (debug)
-    {
-        Info<< "available(";
-        for
-        (
-            int elemI = selector.start();
-            elemI < selector.end();
-            ++elemI
-        )
-        {
-            Info<< " \"" << select->GetArrayName(elemI) << "\"";
-        }
-
-        Info<< " )\n"
-            << "selected(";
-    }
-
-    for
-    (
-        int elemI = selector.start();
-        elemI < selector.end();
-        ++elemI
-    )
-    {
-        if (select->GetArraySetting(elemI))
-        {
-            if (firstWord)
-            {
-                selections[nElem] = getFirstWord
-                (
-                    select->GetArrayName(elemI)
-                );
-            }
-            else
-            {
-                selections[nElem] = select->GetArrayName(elemI);
-            }
-
-            if (debug)
-            {
-                Info<< " " << selections[nElem];
-            }
-
-            ++nElem;
+            Info<< "  part[" << partId << "] = "
+                << partStatus_[partId]
+                << " : " << selection->GetArrayName(partId) << endl;
         }
     }
-
     if (debug)
     {
-        Info<< " )" << endl;
+        Info<< "<end> Foam::vtkPV3Foam::updateMeshPartsStatus" << endl;
     }
-
-    selections.setSize(nElem);
-    return selections;
 }
 
-
-void Foam::vtkPV3Foam::setSelectedArrayEntries
-(
-    vtkDataArraySelection* select,
-    const stringList& selections
-)
-{
-    if (debug > 1)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::setSelectedArrayEntries" << endl;
-    }
-    const label nEntries = select->GetNumberOfArrays();
-
-    // Reset all current entries to 'not selected'
-    select->DisableAllArrays();
-
-    // Loop through entries, setting values from selectedEntries
-    forAll(selections, elemI)
-    {
-        if (debug > 1)
-        {
-            Info<< "selections[" << elemI << "] = " << selections[elemI]
-                << endl;
-        }
-
-        for (label i=0; i<nEntries; i++)
-        {
-            string arrayName = select->GetArrayName(i);
-
-            if (arrayName == selections[elemI])
-            {
-                if (debug > 1)
-                {
-                    Info<< "enabling array: " << arrayName << " Index = "
-                        << i
-                        << endl;
-                }
-
-                select->EnableArray(arrayName.c_str());
-                break;
-            }
-        }
-    }
-    if (debug > 1)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::setSelectedArrayEntries" << endl;
-    }
-}
-
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::vtkPV3Foam::vtkPV3Foam
@@ -482,15 +204,15 @@ Foam::vtkPV3Foam::vtkPV3Foam
     timeIndex_(-1),
     meshChanged_(true),
     fieldsChanged_(true),
-    regionInfoVolume_("unzoned"),
-    regionInfoPatches_("patches"),
-    regionInfoLagrangian_("lagrangian"),
-    regionInfoCellZones_("cellZone"),
-    regionInfoFaceZones_("faceZone"),
-    regionInfoPointZones_("pointZone"),
-    regionInfoCellSets_("cellSet"),
-    regionInfoFaceSets_("faceSet"),
-    regionInfoPointSets_("pointSet")
+    partInfoVolume_("unzoned"),
+    partInfoPatches_("patches"),
+    partInfoLagrangian_("lagrangian"),
+    partInfoCellZones_("cellZone"),
+    partInfoFaceZones_("faceZone"),
+    partInfoPointZones_("pointZone"),
+    partInfoCellSets_("cellSet"),
+    partInfoFaceSets_("faceSet"),
+    partInfoPointSets_("pointSet")
 {
     if (debug)
     {
@@ -569,29 +291,25 @@ void Foam::vtkPV3Foam::updateInfo()
 
     resetCounters();
 
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
+    vtkDataArraySelection* partSelection = reader_->GetPartSelection();
 
-    stringList selectedEntries;
     // enable 'internalMesh' on the first call
-    if (regionSelection->GetNumberOfArrays() == 0 && !meshPtr_)
+    // or preserve the enabled selections
+    stringList enabledEntries;
+    if (!partSelection->GetNumberOfArrays() && !meshPtr_)
     {
-        selectedEntries.setSize(1);
-        selectedEntries[0] = "internalMesh";
+        enabledEntries.setSize(1);
+        enabledEntries[0] = "internalMesh";
     }
     else
     {
-        // preserve the enabled selections
-        selectedEntries = getSelectedArrayEntries
-        (
-            regionSelection,
-            false
-        );
+        enabledEntries = getSelectedArrayEntries(partSelection);
     }
 
-    // Clear current region list/array
-    regionSelection->RemoveAllArrays();
+    // Clear current mesh parts list
+    partSelection->RemoveAllArrays();
 
-    // Update region array - add Lagrangian at the bottom
+    // Update mesh parts list - add Lagrangian at the bottom
     updateInfoInternalMesh();
     updateInfoPatches();
     updateInfoSets();
@@ -599,11 +317,7 @@ void Foam::vtkPV3Foam::updateInfo()
     updateInfoLagrangian();
 
     // restore the enabled selections
-    setSelectedArrayEntries
-    (
-        regionSelection,
-        selectedEntries
-    );
+    setSelectedArrayEntries(partSelection, enabledEntries);
 
     if (meshChanged_)
     {
@@ -696,14 +410,14 @@ void Foam::vtkPV3Foam::Update
     }
     reader_->UpdateProgress(0.1);
 
-    // Set up region selection(s)
-    updateRegionStatus();
+    // Set up mesh parts selection(s)
+    updateMeshPartsStatus();
 
     // Update the Foam mesh
     updateFoamMesh();
     reader_->UpdateProgress(0.2);
 
-    // Convert meshes
+    // Convert meshes - start port0 at block=0
     int blockNo = 0;
 
     convertMeshVolume(output, blockNo);
@@ -724,6 +438,7 @@ void Foam::vtkPV3Foam::Update
         convertMeshPointSets(output, blockNo);
     }
 
+    // restart port1 at block=0
     blockNo = 0;
     convertMeshLagrangian(lagrangianOutput, blockNo);
 
@@ -733,6 +448,10 @@ void Foam::vtkPV3Foam::Update
     convertVolFields(output);
     convertPointFields(output);
     convertLagrangianFields(lagrangianOutput);
+    reader_->UpdateProgress(0.95);
+
+    // reclaim some memory
+    reduceMemory();
     reader_->UpdateProgress(1.0);
 
     meshChanged_ = fieldsChanged_ = false;
@@ -789,11 +508,10 @@ void Foam::vtkPV3Foam::addPatchNames(vtkRenderer* renderer)
     removePatchNames(renderer);
 
     // get the display patches, strip off any suffix
-    const stringList selectedPatches = getSelectedArrayEntries
+    wordHashSet selectedPatches = getSelected
     (
-        reader_->GetRegionSelection(),
-        regionInfoPatches_,
-        true
+        reader_->GetPartSelection(),
+        partInfoPatches_
     );
 
     if (!selectedPatches.size())
@@ -828,68 +546,60 @@ void Foam::vtkPV3Foam::addPatchNames(vtkRenderer* renderer)
         const polyPatch& pp = pbMesh[patchI];
 
         // Only include the patch if it is selected
-        bool isSelected = false;
-        forAll(selectedPatches, elemI)
+        if (!selectedPatches.found(pp.name()))
         {
-            if (pp.name() == selectedPatches[elemI])
-            {
-                isSelected = true;
-                break;
-            }
+            continue;
         }
 
-        if (isSelected)
-        {
-            const labelListList& edgeFaces = pp.edgeFaces();
-            const vectorField& n = pp.faceNormals();
+        const labelListList& edgeFaces = pp.edgeFaces();
+        const vectorField& n = pp.faceNormals();
+
+        boolList featEdge(pp.nEdges(), false);
 
-            boolList featEdge(pp.nEdges(), false);
+        forAll(edgeFaces, edgeI)
+        {
+            const labelList& eFaces = edgeFaces[edgeI];
 
-            forAll(edgeFaces, edgeI)
+            if (eFaces.size() != 2)
             {
-                const labelList& eFaces = edgeFaces[edgeI];
-
-                if (eFaces.size() != 2)
-                {
-                    featEdge[edgeI] = true;
-                }
-                else if (mag(n[eFaces[0]] & n[eFaces[1]]) < 0.5)
-                {
-                    featEdge[edgeI] = true;
-                }
+                featEdge[edgeI] = true;
             }
+            else if (mag(n[eFaces[0]] & n[eFaces[1]]) < 0.5)
+            {
+                featEdge[edgeI] = true;
+            }
+        }
 
-            // Do topological analysis of patch. Determine disconnected regions
-            patchZones pZones(pp, featEdge);
-
-            nZones[patchI] = pZones.nZones();
+        // Do topological analysis of patch, find disconnected regions
+        patchZones pZones(pp, featEdge);
 
-            labelList zoneNFaces(pZones.nZones(), 0);
+        nZones[patchI] = pZones.nZones();
 
-            // Save start of information for current patch
-            label patchStart = zoneCentre.size();
+        labelList zoneNFaces(pZones.nZones(), 0);
 
-            // Create storage for additional zone centres
-            forAll(zoneNFaces, zoneI)
-            {
-                zoneCentre.append(vector::zero);
-            }
+        // Save start of information for current patch
+        label patchStart = zoneCentre.size();
 
-            // Do averaging per individual zone
+        // Create storage for additional zone centres
+        forAll(zoneNFaces, zoneI)
+        {
+            zoneCentre.append(vector::zero);
+        }
 
-            forAll(pp, faceI)
-            {
-                label zoneI = pZones[faceI];
-                zoneCentre[patchStart+zoneI] += pp[faceI].centre(pp.points());
-                zoneNFaces[zoneI]++;
-            }
+        // Do averaging per individual zone
+        forAll(pp, faceI)
+        {
+            label zoneI = pZones[faceI];
+            zoneCentre[patchStart+zoneI] += pp[faceI].centre(pp.points());
+            zoneNFaces[zoneI]++;
+        }
 
-            for (label i=0; i<nZones[patchI]; i++)
-            {
-                zoneCentre[patchStart + i] /= zoneNFaces[i];
-            }
+        for (label i=0; i<nZones[patchI]; i++)
+        {
+            zoneCentre[patchStart + i] /= zoneNFaces[i];
         }
     }
+
     zoneCentre.shrink();
 
     if (debug)
@@ -990,46 +700,4 @@ void Foam::vtkPV3Foam::PrintSelf(ostream& os, vtkIndent indent) const
         << (dbPtr_.valid() ? dbPtr_().times().size() : 0) << endl;
 }
 
-
-// parse these bits of info from /proc/meminfo (Linux)
-//
-// MemTotal:      2062660 kB
-// MemFree:       1124400 kB
-//
-// used = MemTotal - MemFree is what the free(1) uses.
-//
-void Foam::vtkPV3Foam::printMemory()
-{
-    const char* meminfo = "/proc/meminfo";
-
-    if (exists(meminfo))
-    {
-        IFstream is(meminfo);
-        label memTotal = 0;
-        label memFree = 0;
-
-        string line;
-
-        while (is.getLine(line).good())
-        {
-            char tag[32];
-            int value;
-
-            if (sscanf(line.c_str(), "%30s %d", tag, &value) == 2)
-            {
-                if (!strcmp(tag, "MemTotal:"))
-                {
-                    memTotal = value;
-                }
-                else if (!strcmp(tag, "MemFree:"))
-                {
-                    memFree = value;
-                }
-            }
-        }
-
-        Info << "memUsed: " << (memTotal - memFree) << " kB\n";
-    }
-}
-
 // ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H
index 3907348cc0348feb70f53f0c6e85b92d58b19f09..ada85c137322fc457c615792384664c938e1f850 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H
@@ -46,6 +46,7 @@ SourceFiles
     vtkPV3FoamPoints.H
     vtkPV3FoamUpdateInfo.C
     vtkPV3FoamUpdateInfoFields.H
+    vtkPV3FoamUtilities.C
     vtkPV3FoamVolFields.H
     vtkPV3FoamAddToSelection.H
 
@@ -103,58 +104,10 @@ class List;
 
 class vtkPV3Foam
 {
-    // Private data
-
-        //- Access to the controlling vtkPV3FoamReader
-        vtkPV3FoamReader* reader_;
-
-        //- Foam time control
-        autoPtr<Time> dbPtr_;
-
-        //- Foam mesh
-        fvMesh* meshPtr_;
-
-        //- Number of meshes
-        // TODO - for info only - only set up to process ONE mesh
-        int nMesh_;
-
-        //- The time index
-        int timeIndex_;
-
-        //- Track changes in mesh geometry
-        bool meshChanged_;
-
-        //- Track changes in fields
-        bool fieldsChanged_;
-
-        //- Cell-centre labels used as additional points for decomposed cells
-        labelList addPointCellLabels_;
-
-        //- Label of original cell for decomposed cells (internal mesh)
-        labelList superCells_;
-
-        //- Label of original cell for decomposed cells (cellZone meshes)
-        List<labelList> zoneSuperCells_;
-
-        //- Label of original cell for decomposed cells (cellSet meshes)
-        List<labelList> csetSuperCells_;
-
-        //- List of patch names
-        List<vtkTextActor*> patchTextActorsPtrs_;
-
-
-        //- Selected geometrical pieces
-        //  [0] = internal mesh, patches, zones, sets, lagrangian
-        boolList regionStatus_;
-
-        //- Selected regions indices in each respective block
-        labelList regionDataset_;
-
-
     // Private classes
 
-        //- bookkeeping for the GUI checklists and the multi-block organization
-        class selectionInfo
+        //- Bookkeeping for GUI checklists and the multi-block organization
+        class partInfo
         {
             const char *name_;
             int block_;
@@ -163,7 +116,7 @@ class vtkPV3Foam
 
         public:
 
-            selectionInfo(const char *name, const int blockNo=0)
+            partInfo(const char *name, const int blockNo=0)
             :
                 name_(name),
                 block_(blockNo),
@@ -224,19 +177,121 @@ class vtkPV3Foam
             }
         };
 
-    // Private data
+        //- bookkeeping for polyhedral cell decomposition
+        //  hide in extra pointMap (cellSet/cellZone) for now
+        class polyDecomp
+        {
+            labelList superCells_;
+            labelList addPointCellLabels_;
+            labelList pointMap_;
 
-        //- First instance and size of various regions
-        selectionInfo regionInfoVolume_;
-        selectionInfo regionInfoPatches_;
-        selectionInfo regionInfoLagrangian_;
-        selectionInfo regionInfoCellZones_;
-        selectionInfo regionInfoFaceZones_;
-        selectionInfo regionInfoPointZones_;
-        selectionInfo regionInfoCellSets_;
-        selectionInfo regionInfoFaceSets_;
-        selectionInfo regionInfoPointSets_;
+        public:
 
+            polyDecomp()
+            {}
+
+            //- Label of original cell for decomposed cells
+            labelList& superCells()
+            {
+                return superCells_;
+            }
+
+            //- Label of original cell for decomposed cells
+            const labelList& superCells() const
+            {
+                return superCells_;
+            }
+
+            //- Cell-centre labels for additional points of decomposed cells
+            labelList& addPointCellLabels()
+            {
+                return addPointCellLabels_;
+            }
+
+            //- Cell-centre labels for additional points of decomposed cells
+            const labelList& addPointCellLabels() const
+            {
+                return addPointCellLabels_;
+            }
+
+            //- Point labels for subsetted meshes
+            labelList& pointMap()
+            {
+                return pointMap_;
+            }
+
+            //- Point labels for subsetted meshes
+            const labelList& pointMap() const
+            {
+                return pointMap_;
+            }
+
+
+            //- Clear
+            void clear()
+            {
+                superCells_.clear();
+                addPointCellLabels_.clear();
+                pointMap_.clear();
+            }
+        };
+
+
+    // Private Data
+
+        //- Access to the controlling vtkPV3FoamReader
+        vtkPV3FoamReader* reader_;
+
+        //- Foam time control
+        autoPtr<Time> dbPtr_;
+
+        //- Foam mesh
+        fvMesh* meshPtr_;
+
+        //- Number of meshes
+        // TODO - for info only - only set up to process ONE mesh
+        int nMesh_;
+
+        //- The time index
+        int timeIndex_;
+
+        //- Track changes in mesh geometry
+        bool meshChanged_;
+
+        //- Track changes in fields
+        bool fieldsChanged_;
+
+        //- Selected geometrical parts (internalMesh, patches, ...)
+        boolList partStatus_;
+
+        //- Datasets corresponding to selected geometrical pieces
+        //  a negative number indicates that no vtkmesh exists for this piece
+        labelList partDataset_;
+
+        //- First instance and size of various mesh parts
+        //  used to index into partStatus_ and partDataset_
+        partInfo partInfoVolume_;
+        partInfo partInfoPatches_;
+        partInfo partInfoLagrangian_;
+        partInfo partInfoCellZones_;
+        partInfo partInfoFaceZones_;
+        partInfo partInfoPointZones_;
+        partInfo partInfoCellSets_;
+        partInfo partInfoFaceSets_;
+        partInfo partInfoPointSets_;
+
+        //- Decomposed cells information (mesh regions)
+        //  TODO: regions
+        List<polyDecomp> regionPolyDecomp_;
+
+        //- Decomposed cells information (cellZone meshes)
+        List<polyDecomp> zonePolyDecomp_;
+
+        //- Decomposed cells information (cellSet meshes)
+        List<polyDecomp> csetPolyDecomp_;
+
+        //- List of patch names for rendering to window
+        List<vtkTextActor*> patchTextActorsPtrs_;
 
     // Private Member Functions
 
@@ -245,10 +300,10 @@ class vtkPV3Foam
         static void AddToBlock
         (
             vtkMultiBlockDataSet* output,
-            const selectionInfo&,
-            const label datasetNo,
             vtkDataSet* dataset,
-            const string& blockName=string::null
+            const partInfo&,
+            const label datasetNo,
+            const string& datasetName
         );
 
         // Convenience method use to convert the readers from VTK 5
@@ -256,7 +311,7 @@ class vtkPV3Foam
         static vtkDataSet* GetDataSetFromBlock
         (
             vtkMultiBlockDataSet* output,
-            const selectionInfo&,
+            const partInfo&,
             const label datasetNo
         );
 
@@ -265,7 +320,7 @@ class vtkPV3Foam
         static label GetNumberOfDataSets
         (
             vtkMultiBlockDataSet* output,
-            const selectionInfo&
+            const partInfo&
         );
 
         //- Reset data counters
@@ -273,8 +328,8 @@ class vtkPV3Foam
 
         // Update information helper functions
 
-            //- Update the regions selected in the GUI
-            void updateRegionStatus();
+            //- Update the mesh parts selected in the GUI
+            void updateMeshPartsStatus();
 
             //- Internal mesh info
             void updateInfoInternalMesh();
@@ -294,7 +349,7 @@ class vtkPV3Foam
             //- Read zone names for zoneType from file
             wordList readZoneNames(const word& zoneType);
 
-            //- Add to paraview array selection
+            //- Add objects of Type to paraview array selection
             template<class Type>
             label addToSelection
             (
@@ -316,6 +371,9 @@ class vtkPV3Foam
             //- Foam mesh
             void updateFoamMesh();
 
+            //- Reduce memory footprint after conversion
+            void reduceMemory();
+
             //- Volume fields
             void updateVolFields(vtkMultiBlockDataSet*);
 
@@ -359,11 +417,7 @@ class vtkPV3Foam
         // Add mesh functions
 
             //- Add internal mesh/cell set meshes
-            vtkUnstructuredGrid* volumeVTKMesh
-            (
-                const fvMesh&,
-                labelList& superCells
-            );
+            vtkUnstructuredGrid* volumeVTKMesh(const fvMesh&, polyDecomp&);
 
             //- Add Lagrangian mesh
             vtkPolyData* lagrangianVTKMesh
@@ -439,15 +493,26 @@ class vtkPV3Foam
                 vtkMultiBlockDataSet* output
             );
 
+            //- Volume field - all selected parts
+            template<class Type>
+            void convertVolFieldBlock
+            (
+                const GeometricField<Type, fvPatchField, volMesh>&,
+                const GeometricField<Type, pointPatchField, pointMesh>&,
+                vtkMultiBlockDataSet* output,
+                const partInfo& selector,
+                const List<polyDecomp>& decompLst
+            );
+
             //- Volume field
             template<class Type>
             void convertVolField
             (
                 const GeometricField<Type, fvPatchField, volMesh>&,
                 vtkMultiBlockDataSet* output,
-                const selectionInfo&,
+                const partInfo&,
                 const label datasetNo,
-                labelList& superCells
+                const polyDecomp&
             );
 
             //- Patch field
@@ -457,7 +522,7 @@ class vtkPV3Foam
                 const word& name,
                 const Field<Type>&,
                 vtkMultiBlockDataSet* output,
-                const selectionInfo&,
+                const partInfo&,
                 const label datasetNo
             );
 
@@ -467,7 +532,7 @@ class vtkPV3Foam
             (
                 const GeometricField<Type, fvPatchField, volMesh>&,
                 vtkMultiBlockDataSet* output,
-                const selectionInfo&,
+                const partInfo&,
                 const label datasetNo,
                 const fvMesh&,
                 const labelList& faceLabels
@@ -479,7 +544,7 @@ class vtkPV3Foam
             (
                 const GeometricField<Type, fvPatchField, volMesh>&,
                 vtkMultiBlockDataSet* output,
-                const selectionInfo&,
+                const partInfo&,
                 const label datasetNo,
                 const fvMesh&,
                 const faceSet&
@@ -500,7 +565,7 @@ class vtkPV3Foam
             (
                 const IOField<Type>&,
                 vtkMultiBlockDataSet* output,
-                const selectionInfo&,
+                const partInfo&,
                 const label datasetNo
             );
 
@@ -514,6 +579,16 @@ class vtkPV3Foam
                 vtkMultiBlockDataSet* output
             );
 
+            //- Point field - all selected parts
+            template<class Type>
+            void convertPointFieldBlock
+            (
+                const GeometricField<Type, pointPatchField, pointMesh>&,
+                vtkMultiBlockDataSet* output,
+                const partInfo& selector,
+                const List<polyDecomp>&
+            );
+
             //- Point fields
             template<class Type>
             void convertPointField
@@ -521,8 +596,9 @@ class vtkPV3Foam
                 const GeometricField<Type, pointPatchField, pointMesh>&,
                 const GeometricField<Type, fvPatchField, volMesh>&,
                 vtkMultiBlockDataSet* output,
-                const selectionInfo&,
-                const label datasetNo
+                const partInfo&,
+                const label datasetNo,
+                const polyDecomp&
             );
 
             //- Patch point field
@@ -532,7 +608,7 @@ class vtkPV3Foam
                 const word& name,
                 const Field<Type>&,
                 vtkMultiBlockDataSet* output,
-                const selectionInfo&,
+                const partInfo&,
                 const label datasetNo
             );
 
@@ -542,29 +618,31 @@ class vtkPV3Foam
             //- Extract up to the first non-word characters
             inline static word getFirstWord(const char*);
 
-            //- Subset an IOobjectList based on a hashSet
-            static void subsetObjectList
+            //- Only keep what is listed in hashSet
+            static void pruneObjectList
             (
                 IOobjectList&,
                 const wordHashSet&
             );
 
-            //- Store the current selection(s)
+            //- Retrieve the current selections
             static wordHashSet getSelected(vtkDataArraySelection*);
 
-            //- Store the current selection(s)
-            static stringList getSelectedArrayEntries
+            //- Retrieve a sub-list of the current selections
+            static wordHashSet getSelected
             (
                 vtkDataArraySelection*,
-                const bool firstWord=false
+                const partInfo&
             );
 
-            //- Store the current selection(s) for a sub-selection
+            //- Retrieve the current selections
+            static stringList getSelectedArrayEntries(vtkDataArraySelection*);
+
+            //- Retrieve a sub-list of the current selections
             static stringList getSelectedArrayEntries
             (
                 vtkDataArraySelection*,
-                const selectionInfo&,
-                const bool firstWord=false
+                const partInfo&
             );
 
             //- Set selection(s)
@@ -574,6 +652,9 @@ class vtkPV3Foam
                 const stringList&
             );
 
+            //- Get the first word from the mesh parts selection
+            word getPartName(int);
+
 
         //- Disallow default bitwise copy construct
         vtkPV3Foam(const vtkPV3Foam&);
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamAddToSelection.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamAddToSelection.H
index 7b9b0113acb5096bca3800c045b43c47e21c8115..5648889ff0ae4380531aa28e01bc2ea80cd11482 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamAddToSelection.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamAddToSelection.H
@@ -44,46 +44,21 @@ Foam::label Foam::vtkPV3Foam::addToSelection
     const string& suffix
 )
 {
-    IOobjectList objects(objectLst.lookupClass(Type::typeName));
+    SortableList<word> names(objectLst.names(Type::typeName));
 
-    SortableList<word> objectNames(objects.size());
-
-    label count = 0;
-    forAllConstIter(IOobjectList, objects, iter)
-    {
-        objectNames[count++] = iter()->name();
-    }
-
-    if (count)
+    forAll(names, nameI)
     {
-        objectNames.sort();
-
-        forAll(objectNames, objI)
+        if (suffix.size())
         {
-            if (debug)
-            {
-                Info<<"    addToSelection<" << Type::typeName << "> to GUI "
-                    << ":" << objectNames[objI] << endl;
-            }
-
-            if (suffix.size())
-            {
-                select->AddArray
-                (
-                    (objectNames[objI] + suffix).c_str()
-                );
-            }
-            else
-            {
-                select->AddArray
-                (
-                    objectNames[objI].c_str()
-                );
-            }
+            select->AddArray((names[nameI] + suffix).c_str());
+        }
+        else
+        {
+            select->AddArray(names[nameI].c_str());
         }
     }
 
-    return count;
+    return names.size();
 }
 
 
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFaceField.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFaceField.H
index 7ab511a5215d5cd306d1a3de87c2877f78e414c2..b3fdcacf329f0339e9ec8defe08f2a3d3310cc87 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFaceField.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFaceField.H
@@ -42,19 +42,13 @@ void Foam::vtkPV3Foam::convertFaceField
 (
     const GeometricField<Type, fvPatchField, volMesh>& tf,
     vtkMultiBlockDataSet* output,
-    const selectionInfo& selector,
+    const partInfo& selector,
     const label datasetNo,
     const fvMesh& mesh,
     const labelList& faceLabels
 )
 {
     const label nComp = pTraits<Type>::nComponents;
-
-    vtkPolyData* vtkmesh = vtkPolyData::SafeDownCast
-    (
-        GetDataSetFromBlock(output, selector, datasetNo)
-    );
-
     const label nInternalFaces = mesh.nInternalFaces();
     const labelList& faceOwner = mesh.faceOwner();
     const labelList& faceNeigh = mesh.faceNeighbour();
@@ -102,7 +96,13 @@ void Foam::vtkPV3Foam::convertFaceField
         cellData->InsertTuple(faceI, vec);
     }
 
-    vtkmesh->GetCellData()->AddArray(cellData);
+
+    vtkPolyData::SafeDownCast
+    (
+        GetDataSetFromBlock(output, selector, datasetNo)
+    )   ->GetCellData()
+        ->AddArray(cellData);
+
     cellData->Delete();
 }
 
@@ -112,19 +112,13 @@ void Foam::vtkPV3Foam::convertFaceField
 (
     const GeometricField<Type, fvPatchField, volMesh>& tf,
     vtkMultiBlockDataSet* output,
-    const selectionInfo& selector,
+    const partInfo& selector,
     const label datasetNo,
     const fvMesh& mesh,
     const faceSet& fSet
 )
 {
     const label nComp = pTraits<Type>::nComponents;
-
-    vtkPolyData* vtkmesh = vtkPolyData::SafeDownCast
-    (
-        GetDataSetFromBlock(output, selector, datasetNo)
-    );
-
     const label nInternalFaces = mesh.nInternalFaces();
     const labelList& faceOwner = mesh.faceOwner();
     const labelList& faceNeigh = mesh.faceNeighbour();
@@ -175,7 +169,13 @@ void Foam::vtkPV3Foam::convertFaceField
         ++faceI;
     }
 
-    vtkmesh->GetCellData()->AddArray(cellData);
+
+    vtkPolyData::SafeDownCast
+    (
+        GetDataSetFromBlock(output, selector, datasetNo)
+    )   ->GetCellData()
+        ->AddArray(cellData);
+
     cellData->Delete();
 }
 
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFields.C b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFields.C
index bff8d615291b0af7a10c2dd6907cdae2812043d0..bf5742e3a8671751db6527f789283ee78f00f65f 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFields.C
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamFields.C
@@ -44,7 +44,7 @@ Description
 #include "vtkPV3FoamLagrangianFields.H"
 
 
-void Foam::vtkPV3Foam::subsetObjectList
+void Foam::vtkPV3Foam::pruneObjectList
 (
     IOobjectList& objects,
     const wordHashSet& selected
@@ -83,10 +83,9 @@ void Foam::vtkPV3Foam::convertVolFields
     }
 
     const fvMesh& mesh = *meshPtr_;
-
     // Get objects (fields) for this time - only keep selected fields
     IOobjectList objects(mesh, dbPtr_().timeName());
-    subsetObjectList(objects, selectedFields);
+    pruneObjectList(objects, selectedFields);
 
     if (!objects.size())
     {
@@ -170,11 +169,9 @@ void Foam::vtkPV3Foam::convertPointFields
     }
 
     const fvMesh& mesh = *meshPtr_;
-
     // Get objects (fields) for this time - only keep selected fields
     IOobjectList objects(mesh, dbPtr_().timeName());
-
-    subsetObjectList(objects, selectedFields);
+    pruneObjectList(objects, selectedFields);
 
     if (!objects.size())
     {
@@ -231,6 +228,9 @@ void Foam::vtkPV3Foam::convertLagrangianFields
     vtkMultiBlockDataSet* output
 )
 {
+    partInfo& selector = partInfoLagrangian_;
+    const fvMesh& mesh = *meshPtr_;
+
     wordHashSet selectedFields = getSelected
     (
         reader_->GetLagrangianFieldSelection()
@@ -241,35 +241,22 @@ void Foam::vtkPV3Foam::convertLagrangianFields
         return;
     }
 
-    const fvMesh& mesh = *meshPtr_;
-    selectionInfo& selector = regionInfoLagrangian_;
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
-
     if (debug)
     {
         Info<< "<beg> Foam::vtkPV3Foam::convertLagrangianFields" << endl;
         printMemory();
     }
 
-    for
-    (
-        int regionId = selector.start();
-        regionId < selector.end();
-        ++regionId
-    )
+    for (int partId = selector.start(); partId < selector.end(); ++partId)
     {
-        const label datasetNo = regionDataset_[regionId];
+        const word  cloudName = getPartName(partId);
+        const label datasetNo = partDataset_[partId];
 
-        if (!regionStatus_[regionId] || datasetNo < 0)
+        if (!partStatus_[partId] || datasetNo < 0)
         {
             continue;
         }
 
-        word cloudName = getFirstWord
-        (
-            regionSelection->GetArrayName(regionId)
-        );
-
         // Get the Lagrangian fields for this time and this cloud
         // but only keep selected fields
         IOobjectList objects
@@ -278,7 +265,7 @@ void Foam::vtkPV3Foam::convertLagrangianFields
             dbPtr_().timeName(),
             "lagrangian"/cloudName
         );
-        subsetObjectList(objects, selectedFields);
+        pruneObjectList(objects, selectedFields);
 
         if (!objects.size())
         {
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamLagrangianFields.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamLagrangianFields.H
index 6a6056086bea5c9ff155bc4f201b3298665f49b4..c0bc91e82fa56fc0dbf70f9ddadde9a426eacd88 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamLagrangianFields.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamLagrangianFields.H
@@ -40,21 +40,16 @@ void Foam::vtkPV3Foam::convertLagrangianFields
     const label datasetNo
 )
 {
-    const selectionInfo& selector = regionInfoLagrangian_;
+    const partInfo& selector = partInfoLagrangian_;
 
-    // field subset based on type
-    IOobjectList fieldObjects
-    (
-        objects.lookupClass
-        (
-            IOField<Type>::typeName
-        )
-    );
-
-    forAllIter(IOobjectList, fieldObjects, iter)
+    forAllConstIter(IOobjectList, objects, iter)
     {
-        IOField<Type> tf(*iter());
-        convertLagrangianField(tf, output, selector, datasetNo);
+        // restrict to this IOField<Type>
+        if (iter()->headerClassName() == IOField<Type>::typeName)
+        {
+            IOField<Type> tf(*iter());
+            convertLagrangianField(tf, output, selector, datasetNo);
+        }
     }
 }
 
@@ -64,17 +59,12 @@ void Foam::vtkPV3Foam::convertLagrangianField
 (
     const IOField<Type>& tf,
     vtkMultiBlockDataSet* output,
-    const selectionInfo& selector,
+    const partInfo& selector,
     const label datasetNo
 )
 {
     const label nComp = pTraits<Type>::nComponents;
 
-    vtkPolyData* vtkmesh = vtkPolyData::SafeDownCast
-    (
-        GetDataSetFromBlock(output, selector, datasetNo)
-    );
-
     vtkFloatArray *pointData = vtkFloatArray::New();
     pointData->SetNumberOfTuples( tf.size() );
     pointData->SetNumberOfComponents( nComp );
@@ -102,11 +92,16 @@ void Foam::vtkPV3Foam::convertLagrangianField
         pointData->InsertTuple(i, vec);
     }
 
-    vtkmesh->GetPointData()->AddArray(pointData);
+
+    vtkPolyData::SafeDownCast
+    (
+        GetDataSetFromBlock(output, selector, datasetNo)
+    )   ->GetPointData()
+        ->AddArray(pointData);
+
     pointData->Delete();
 }
 
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #endif
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMesh.C b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMesh.C
index 3c5cc6fa933b154c84f0a046e833f5435ba2d9f0..8539bca001ce85a70819c92cdefb85cfeaad790b 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMesh.C
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMesh.C
@@ -49,54 +49,47 @@ void Foam::vtkPV3Foam::convertMeshVolume
     int& blockNo
 )
 {
+    partInfo& selector = partInfoVolume_;
+    selector.block(blockNo);   // set output block
+    label datasetNo = 0;       // restart at dataset 0
+    const fvMesh& mesh = *meshPtr_;
+
+    // resize for decomposed polyhedra
+    regionPolyDecomp_.setSize(selector.size());
+
     if (debug)
     {
         Info<< "<beg> Foam::vtkPV3Foam::convertMeshVolume" << endl;
         printMemory();
     }
 
-    const fvMesh& mesh = *meshPtr_;
-    selectionInfo& selector = regionInfoVolume_;
-
-    // set output block, restart at dataset 0
-    selector.block(blockNo);
-    label datasetNo = 0;
-
-    // Create the internalMesh
-    // TODO: multiple regions
-    for
-    (
-        int regionId = selector.start();
-        regionId < selector.end();
-        ++regionId
-    )
-    {
-        if (!regionStatus_[regionId])
-        {
-            continue;
-        }
+    // Convert the internalMesh
+    // TODO: multiple mesh regions
+    for (int partId = selector.start(); partId < selector.end(); ++partId)
+    {
+        const word partName = "internalMesh";
 
-        if (debug)
+        if (!partStatus_[partId])
         {
-            Info<< "Creating VTK internalMesh" << endl;
+            continue;
         }
 
         vtkUnstructuredGrid* vtkmesh = volumeVTKMesh
         (
             mesh,
-            superCells_
+            regionPolyDecomp_[datasetNo]
         );
 
         if (vtkmesh)
         {
-            AddToBlock(output, selector, datasetNo, vtkmesh, "internalMesh");
+            AddToBlock(output, vtkmesh, selector, datasetNo, partName);
             vtkmesh->Delete();
 
-            regionDataset_[regionId] = datasetNo++;
+            partDataset_[partId] = datasetNo++;
         }
     }
 
-    // was anything added?
+    // anything added?
     if (datasetNo)
     {
         ++blockNo;
@@ -116,49 +109,38 @@ void Foam::vtkPV3Foam::convertMeshLagrangian
     int& blockNo
 )
 {
+    partInfo& selector = partInfoLagrangian_;
+    selector.block(blockNo);   // set output block
+    label datasetNo = 0;       // restart at dataset 0
+    const fvMesh& mesh = *meshPtr_;
+
     if (debug)
     {
         Info<< "<beg> Foam::vtkPV3Foam::convertMeshLagrangian" << endl;
         printMemory();
     }
 
-    const fvMesh& mesh = *meshPtr_;
-    selectionInfo& selector = regionInfoLagrangian_;
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
-
-    // set output block, restart at dataset 0
-    selector.block(blockNo);
-    label datasetNo = 0;
-
-    // Create Lagrangian meshes
-    for
-    (
-        int regionId = selector.start();
-        regionId < selector.end();
-        ++regionId
-    )
-    {
-        if (!regionStatus_[regionId])
+    for (int partId = selector.start(); partId < selector.end(); ++partId)
+    {
+        const word cloudName = getPartName(partId);
+
+        if (!partStatus_[partId])
         {
             continue;
         }
 
-        word cloudName = getFirstWord
-        (
-            regionSelection->GetArrayName(regionId)
-        );
-
         vtkPolyData* vtkmesh = lagrangianVTKMesh(mesh, cloudName);
+
         if (vtkmesh)
         {
-            AddToBlock(output, selector, datasetNo, vtkmesh, cloudName);
+            AddToBlock(output, vtkmesh, selector, datasetNo, cloudName);
             vtkmesh->Delete();
 
-            regionDataset_[regionId] = datasetNo++;
+            partDataset_[partId] = datasetNo++;
         }
     }
 
-    // was anything added?
+    // anything added?
     if (datasetNo)
     {
         ++blockNo;
@@ -178,61 +160,46 @@ void Foam::vtkPV3Foam::convertMeshPatches
     int& blockNo
 )
 {
+    partInfo& selector = partInfoPatches_;
+    selector.block(blockNo);   // set output block
+    label datasetNo = 0;       // restart at dataset 0
+    const fvMesh& mesh = *meshPtr_;
+    const polyBoundaryMesh& patches = mesh.boundaryMesh();
+
     if (debug)
     {
         Info<< "<beg> Foam::vtkPV3Foam::convertMeshPatches" << endl;
         printMemory();
     }
 
-    const fvMesh& mesh = *meshPtr_;
-    selectionInfo& selector = regionInfoPatches_;
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
-
-    // set output block, restart at dataset 0
-    selector.block(blockNo);
-    label datasetNo = 0;
-
-    if (selector.size())
+    for (int partId = selector.start(); partId < selector.end(); ++partId)
     {
-        const polyBoundaryMesh& patches = mesh.boundaryMesh();
+        const word patchName = getPartName(partId);
+        const label  patchId = patches.findPatchID(patchName);
 
-        for
-        (
-            int regionId = selector.start();
-            regionId < selector.end();
-            ++regionId
-        )
+        if (!partStatus_[partId] || patchId < 0)
         {
-            word patchName = getFirstWord
-            (
-                regionSelection->GetArrayName(regionId)
-            );
-
-            label patchId = patches.findPatchID(patchName);
+            continue;
+        }
 
-            if (!regionStatus_[regionId] || patchId < 0)
-            {
-                continue;
-            }
+        if (debug)
+        {
+            Info<< "Creating VTK mesh for patch[" << patchId <<"] "
+                << patchName  << endl;
+        }
 
-            if (debug)
-            {
-                Info<< "Creating VTK mesh for patch: " << patchName
-                    << " patch index: " << patchId << endl;
-            }
+        vtkPolyData* vtkmesh = patchVTKMesh(patches[patchId]);
 
-            vtkPolyData* vtkmesh = patchVTKMesh(patches[patchId]);
-            if (vtkmesh)
-            {
-                AddToBlock(output, selector, datasetNo, vtkmesh, patchName);
-                vtkmesh->Delete();
+        if (vtkmesh)
+        {
+            AddToBlock(output, vtkmesh, selector, datasetNo, patchName);
+            vtkmesh->Delete();
 
-                regionDataset_[regionId] = datasetNo++;
-            }
+            partDataset_[partId] = datasetNo++;
         }
     }
 
-    // was anything added?
+    // anything added?
     if (datasetNo)
     {
         ++blockNo;
@@ -252,80 +219,77 @@ void Foam::vtkPV3Foam::convertMeshCellZones
     int& blockNo
 )
 {
+    partInfo& selector = partInfoCellZones_;
+    selector.block(blockNo);   // set output block
+    label datasetNo = 0;       // restart at dataset 0
+    const fvMesh& mesh = *meshPtr_;
+
+    // resize for decomposed polyhedra
+    zonePolyDecomp_.setSize(selector.size());
+
+    if (!selector.size())
+    {
+        return;
+    }
+
     if (debug)
     {
         Info<< "<beg> Foam::vtkPV3Foam::convertMeshCellZones" << endl;
         printMemory();
     }
 
-    const fvMesh& mesh = *meshPtr_;
-    selectionInfo& selector = regionInfoCellZones_;
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
-
-    // set output block, restart at dataset 0
-    selector.block(blockNo);
-    label datasetNo = 0;
+    const cellZoneMesh& zMesh = mesh.cellZones();
 
-    if (selector.size())
+    for (int partId = selector.start(); partId < selector.end(); ++partId)
     {
-        const cellZoneMesh& zMesh = mesh.cellZones();
+        const word zoneName = getPartName(partId);
+        const label  zoneId = zMesh.findZoneID(zoneName);
 
-        for
-        (
-            int regionId = selector.start();
-            regionId < selector.end();
-            ++regionId
-        )
+        if (!partStatus_[partId] || zoneId < 0)
         {
-            word zoneName = getFirstWord
-            (
-                regionSelection->GetArrayName(regionId)
-            );
+            continue;
+        }
 
-            label zoneId = zMesh.findZoneID(zoneName);
+        if (debug)
+        {
+            Info<< "Creating VTK mesh for cellZone[" << zoneId << "] "
+                << zoneName << endl;
+        }
 
-            if (!regionStatus_[regionId] || zoneId < 0)
-            {
-                continue;
-            }
+        fvMeshSubset subsetter(mesh);
+        subsetter.setLargeCellSubset(zMesh[zoneId]);
 
-            if (debug)
-            {
-                Info<< "Creating VTK mesh for cellZone: "
-                    << zoneId << endl;
-            }
-
-            fvMeshSubset subsetter(mesh);
-            subsetter.setLargeCellSubset(zMesh[zoneId]);
+        vtkUnstructuredGrid* vtkmesh = volumeVTKMesh
+        (
+            subsetter.subMesh(),
+            zonePolyDecomp_[datasetNo]
+        );
 
-            vtkUnstructuredGrid* vtkmesh = volumeVTKMesh
+        if (vtkmesh)
+        {
+            // superCells + addPointCellLabels must contain global cell ids
+            inplaceRenumber
             (
-                subsetter.subMesh(),
-                zoneSuperCells_[datasetNo]
+                subsetter.cellMap(),
+                zonePolyDecomp_[datasetNo].superCells()
+            );
+            inplaceRenumber
+            (
+                subsetter.cellMap(),
+                zonePolyDecomp_[datasetNo].addPointCellLabels()
             );
 
-            if (vtkmesh)
-            {
-                // renumber - superCells must contain global cell ids
-                inplaceRenumber
-                (
-                    subsetter.cellMap(),
-                    zoneSuperCells_[datasetNo]
-                );
-
-                AddToBlock
-                (
-                    output, selector, datasetNo, vtkmesh,
-                    zMesh[zoneId].name() + ":cellZone"
-                );
-                vtkmesh->Delete();
+            // copy pointMap as well, otherwise pointFields fail
+            zonePolyDecomp_[datasetNo].pointMap() = subsetter.pointMap();
 
-                regionDataset_[regionId] = datasetNo++;
-            }
+            AddToBlock(output, vtkmesh, selector, datasetNo, zoneName);
+            vtkmesh->Delete();
+
+            partDataset_[partId] = datasetNo++;
         }
     }
 
-    // was anything added?
+    // anything added?
     if (datasetNo)
     {
         ++blockNo;
@@ -345,77 +309,69 @@ void Foam::vtkPV3Foam::convertMeshCellSets
     int& blockNo
 )
 {
+    partInfo& selector = partInfoCellSets_;
+    selector.block(blockNo);   // set output block
+    label datasetNo = 0;       // restart at dataset 0
+    const fvMesh& mesh = *meshPtr_;
+
+    // resize for decomposed polyhedra
+    csetPolyDecomp_.setSize(selector.size());
+
     if (debug)
     {
         Info<< "<beg> Foam::vtkPV3Foam::convertMeshCellSets" << endl;
         printMemory();
     }
 
-    const fvMesh& mesh = *meshPtr_;
-    selectionInfo& selector = regionInfoCellSets_;
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
-
-    // set output block, restart at dataset 0
-    selector.block(blockNo);
-    label datasetNo = 0;
-
-    // Create the cell sets and add as dataset
-    if (selector.size())
+    for (int partId = selector.start(); partId < selector.end(); ++partId)
     {
-        for
-        (
-            int regionId = selector.start();
-            regionId < selector.end();
-            ++regionId)
+        const word partName = getPartName(partId);
+
+        if (!partStatus_[partId])
         {
-            if (!regionStatus_[regionId])
-            {
-                continue;
-            }
+            continue;
+        }
 
-            word selectedName = getFirstWord
-            (
-                regionSelection->GetArrayName(regionId)
-            );
+        if (debug)
+        {
+            Info<< "Creating VTK mesh for cellSet=" << partName << endl;
+        }
 
-            if (debug)
-            {
-                Info<< "Creating VTK mesh for cellSet: " << selectedName
-                    << " region index: " << regionId << endl;
-            }
+        const cellSet cSet(mesh, partName);
+        fvMeshSubset subsetter(mesh);
+        subsetter.setLargeCellSubset(cSet);
 
-            const cellSet cSet(mesh, selectedName);
-            fvMeshSubset subsetter(mesh);
-            subsetter.setLargeCellSubset(cSet);
+        vtkUnstructuredGrid* vtkmesh = volumeVTKMesh
+        (
+            subsetter.subMesh(),
+            csetPolyDecomp_[datasetNo]
+        );
 
-            vtkUnstructuredGrid* vtkmesh = volumeVTKMesh
+        if (vtkmesh)
+        {
+            // superCells + addPointCellLabels must contain global cell ids
+            inplaceRenumber
+            (
+                subsetter.cellMap(),
+                csetPolyDecomp_[datasetNo].superCells()
+            );
+            inplaceRenumber
             (
-                subsetter.subMesh(),
-                csetSuperCells_[datasetNo]
+                subsetter.cellMap(),
+                csetPolyDecomp_[datasetNo].addPointCellLabels()
             );
 
-            if (vtkmesh)
-            {
-                // renumber - superCells must contain global cell ids
-                inplaceRenumber
-                (
-                    subsetter.cellMap(),
-                    csetSuperCells_[datasetNo]
-                );
-
-                AddToBlock
-                (
-                    output, selector, datasetNo, vtkmesh,
-                    selectedName + ":cellSet"
-                );
-                vtkmesh->Delete();
+            // copy pointMap as well, otherwise pointFields fail
+            csetPolyDecomp_[datasetNo].pointMap() = subsetter.pointMap();
 
-                regionDataset_[regionId] = datasetNo++;
-            }
+            AddToBlock(output, vtkmesh, selector, datasetNo, partName);
+            vtkmesh->Delete();
+
+            partDataset_[partId] = datasetNo++;
         }
     }
 
-    // was anything added?
+    // anything added?
     if (datasetNo)
     {
         ++blockNo;
@@ -435,71 +391,51 @@ void Foam::vtkPV3Foam::convertMeshFaceZones
     int& blockNo
 )
 {
+    partInfo& selector = partInfoFaceZones_;
+    selector.block(blockNo);   // set output block
+    label datasetNo = 0;       // restart at dataset 0
+    const fvMesh& mesh = *meshPtr_;
+
+    if (!selector.size())
+    {
+        return;
+    }
+
     if (debug)
     {
         Info<< "<beg> Foam::vtkPV3Foam::convertMeshFaceZones" << endl;
         printMemory();
     }
 
-    const fvMesh& mesh = *meshPtr_;
-    selectionInfo& selector = regionInfoFaceZones_;
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
-
-    // set output block, restart at dataset 0
-    selector.block(blockNo);
-    label datasetNo = 0;
+    const faceZoneMesh& zMesh = mesh.faceZones();
 
-    // Create the cell zone(s)
-    if (selector.size())
+    for (int partId = selector.start(); partId < selector.end(); ++partId)
     {
-        const faceZoneMesh& zMesh = mesh.faceZones();
+        const word zoneName = getPartName(partId);
+        const label  zoneId = zMesh.findZoneID(zoneName);
 
-        for
-        (
-            int regionId = selector.start();
-            regionId < selector.end();
-            ++regionId
-        )
+        if (!partStatus_[partId] || zoneId < 0)
         {
-            word zoneName = getFirstWord
-            (
-                regionSelection->GetArrayName(regionId)
-            );
-
-            const label zoneId = zMesh.findZoneID(zoneName);
-
-            if (!regionStatus_[regionId] || zoneId < 0)
-            {
-                continue;
-            }
-
-            if (debug)
-            {
-                Info<< "Creating VTK mesh for faceZone[" << zoneId
-                    << "] " << zoneName << endl;
-            }
+            continue;
+        }
 
-            vtkPolyData* vtkmesh = faceZoneVTKMesh
-            (
-                mesh,
-                zMesh[zoneId]
-            );
+        if (debug)
+        {
+            Info<< "Creating VTKmesh for faceZone[" << zoneId << "] "
+                << zoneName << endl;
+        }
 
-            if (vtkmesh)
-            {
-                AddToBlock
-                (
-                    output, selector, datasetNo, vtkmesh,
-                    zMesh[zoneId].name() + ":faceZone"
-                );
-                vtkmesh->Delete();
+        vtkPolyData* vtkmesh = faceZoneVTKMesh(mesh, zMesh[zoneId]);
+        if (vtkmesh)
+        {
+            AddToBlock(output, vtkmesh, selector, datasetNo, zoneName);
+            vtkmesh->Delete();
 
-                regionDataset_[regionId] = datasetNo++;
-            }
+            partDataset_[partId] = datasetNo++;
         }
     }
 
-    // was anything added?
+    // anything added?
     if (datasetNo)
     {
         ++blockNo;
@@ -519,69 +455,44 @@ void Foam::vtkPV3Foam::convertMeshFaceSets
     int& blockNo
 )
 {
+    partInfo& selector = partInfoFaceSets_;
+    selector.block(blockNo);   // set output block
+    label datasetNo = 0;       // restart at dataset 0
+    const fvMesh& mesh = *meshPtr_;
+
     if (debug)
     {
         Info<< "<beg> Foam::vtkPV3Foam::convertMeshFaceSets" << endl;
         printMemory();
     }
 
-    const fvMesh& mesh = *meshPtr_;
-    selectionInfo& selector = regionInfoFaceSets_;
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
-
-    // set output block, restart at dataset 0
-    selector.block(blockNo);
-    label datasetNo = 0;
-
-    // Create the face sets and add as dataset
-    if (selector.size())
+    for (int partId = selector.start(); partId < selector.end(); ++partId)
     {
-        for
-        (
-            int regionId = selector.start();
-            regionId < selector.end();
-            ++regionId
-        )
-        {
-            if (!regionStatus_[regionId])
-            {
-                continue;
-            }
-
-            word selectedName = getFirstWord
-            (
-                regionSelection->GetArrayName(regionId)
-            );
+        const word partName = getPartName(partId);
 
-            if (debug)
-            {
-                Info<< "Creating VTK mesh for faceSet: " << selectedName
-                    << " region index: " << regionId << endl;
-            }
+        if (!partStatus_[partId])
+        {
+            continue;
+        }
 
-            const faceSet fSet(mesh, selectedName);
+        if (debug)
+        {
+            Info<< "Creating VTK mesh for faceSet=" << partName << endl;
+        }
 
-            vtkPolyData* vtkmesh = faceSetVTKMesh
-            (
-                mesh,
-                fSet
-            );
+        const faceSet fSet(mesh, partName);
 
-            if (vtkmesh)
-            {
-                AddToBlock
-                (
-                    output, selector, datasetNo, vtkmesh,
-                    selectedName + ":faceSet"
-                );
-                vtkmesh->Delete();
+        vtkPolyData* vtkmesh = faceSetVTKMesh(mesh, fSet);
+        if (vtkmesh)
+        {
+            AddToBlock(output, vtkmesh, selector, datasetNo, partName);
+            vtkmesh->Delete();
 
-                regionDataset_[regionId] = datasetNo++;
-            }
+            partDataset_[partId] = datasetNo++;
         }
     }
 
-    // was anything added?
+    // anything added?
     if (datasetNo)
     {
         ++blockNo;
@@ -601,6 +512,10 @@ void Foam::vtkPV3Foam::convertMeshPointZones
     int& blockNo
 )
 {
+    partInfo& selector = partInfoPointZones_;
+    selector.block(blockNo);   // set output block
+    label datasetNo = 0;       // restart at dataset 0
+
     if (debug)
     {
         Info<< "<beg> Foam::vtkPV3Foam::convertMeshPointZones" << endl;
@@ -608,53 +523,33 @@ void Foam::vtkPV3Foam::convertMeshPointZones
     }
 
     const fvMesh& mesh = *meshPtr_;
-    selectionInfo& selector = regionInfoPointZones_;
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
-
-    // set output block, restart at dataset 0
-    selector.block(blockNo);
-    label datasetNo = 0;
 
     if (selector.size())
     {
         const pointZoneMesh& zMesh = mesh.pointZones();
 
-        for
-        (
-            int regionId = selector.start();
-            regionId < selector.end();
-            ++regionId
-        )
+        for (int partId = selector.start(); partId < selector.end(); ++partId)
         {
-            word zoneName = getFirstWord
-            (
-                regionSelection->GetArrayName(regionId)
-            );
-
+            word zoneName = getPartName(partId);
             label zoneId = zMesh.findZoneID(zoneName);
 
-            if (!regionStatus_[regionId] || zoneId < 0)
+            if (!partStatus_[partId] || zoneId < 0)
             {
                 continue;
             }
 
             vtkPolyData* vtkmesh = pointZoneVTKMesh(mesh, zMesh[zoneId]);
-
             if (vtkmesh)
             {
-                AddToBlock
-                (
-                    output, selector, datasetNo, vtkmesh,
-                    zMesh[zoneId].name() + ":pointZone"
-                );
+                AddToBlock(output, vtkmesh, selector, datasetNo, zoneName);
                 vtkmesh->Delete();
 
-                regionDataset_[regionId] = datasetNo++;
+                partDataset_[partId] = datasetNo++;
             }
         }
     }
 
-    // was anything added?
+    // anything added?
     if (datasetNo)
     {
         ++blockNo;
@@ -675,63 +570,44 @@ void Foam::vtkPV3Foam::convertMeshPointSets
     int& blockNo
 )
 {
+    partInfo& selector = partInfoPointSets_;
+    selector.block(blockNo);   // set output block
+    label datasetNo = 0;       // restart at dataset 0
+    const fvMesh& mesh = *meshPtr_;
+
     if (debug)
     {
         Info<< "<beg> Foam::vtkPV3Foam::convertMeshPointSets" << endl;
         printMemory();
     }
 
-    const fvMesh& mesh = *meshPtr_;
-    selectionInfo& selector = regionInfoPointSets_;
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
-
-    // set output block, restart at dataset 0
-    selector.block(blockNo);
-    label datasetNo = 0;
-
-    if (selector.size())
+    for (int partId = selector.start(); partId < selector.end(); ++partId)
     {
-        for
-        (
-            int regionId = selector.start();
-            regionId < selector.end();
-            ++regionId
-        )
-        {
-            if (!regionStatus_[regionId])
-            {
-                continue;
-            }
+        word partName = getPartName(partId);
 
-            word selectedName = getFirstWord
-            (
-                regionSelection->GetArrayName(regionId)
-            );
+        if (!partStatus_[partId])
+        {
+            continue;
+        }
 
-            if (debug)
-            {
-                Info<< "Creating VTK mesh for pointSet: " << selectedName
-                    << " region index: " << regionId << endl;
-            }
+        if (debug)
+        {
+            Info<< "Creating VTK mesh for pointSet=" << partName << endl;
+        }
 
-            const pointSet pSet(mesh, selectedName);
+        const pointSet pSet(mesh, partName);
 
-            vtkPolyData* vtkmesh = pointSetVTKMesh(mesh, pSet);
-            if (vtkmesh)
-            {
-                AddToBlock
-                (
-                    output, selector, datasetNo, vtkmesh,
-                    selectedName + ":pointSet"
-                );
-                vtkmesh->Delete();
+        vtkPolyData* vtkmesh = pointSetVTKMesh(mesh, pSet);
+        if (vtkmesh)
+        {
+            AddToBlock(output, vtkmesh, selector, datasetNo, partName);
+            vtkmesh->Delete();
 
-                regionDataset_[regionId] = datasetNo++;
-            }
+            partDataset_[partId] = datasetNo++;
         }
     }
 
-    // was anything added?
+    // anything added?
     if (datasetNo)
     {
         ++blockNo;
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshVolume.C b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshVolume.C
index 333a9dc1063a8d607e5cc9f1bf88db22f2708c3a..05e15827251e9873c9e1d8b0d02c1a34e71ab09f 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshVolume.C
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamMeshVolume.C
@@ -42,7 +42,7 @@ Description
 vtkUnstructuredGrid* Foam::vtkPV3Foam::volumeVTKMesh
 (
     const fvMesh& mesh,
-    labelList& superCells
+    polyDecomp& decompInfo
 )
 {
     vtkUnstructuredGrid* vtkmesh = vtkUnstructuredGrid::New();
@@ -59,6 +59,9 @@ vtkUnstructuredGrid* Foam::vtkPV3Foam::volumeVTKMesh
     // Number of additional cells generated by the decomposition of polyhedra
     label nAddCells = 0;
 
+    labelList& superCells = decompInfo.superCells();
+    labelList& addPointCellLabels = decompInfo.addPointCellLabels();
+
     const cellModel& tet = *(cellModeller::lookup("tet"));
     const cellModel& pyr = *(cellModeller::lookup("pyr"));
     const cellModel& prism = *(cellModeller::lookup("prism"));
@@ -112,7 +115,7 @@ vtkUnstructuredGrid* Foam::vtkPV3Foam::volumeVTKMesh
 
     // Set size of additional point addressing array
     // (from added point to original cell)
-    addPointCellLabels_.setSize(nAddPoints);
+    addPointCellLabels.setSize(nAddPoints);
 
     // Set size of additional cells mapping array
     // (from added cell to original cell)
@@ -260,7 +263,7 @@ vtkUnstructuredGrid* Foam::vtkPV3Foam::volumeVTKMesh
             // Polyhedral cell. Decompose into tets + prisms.
 
             // Mapping from additional point to cell
-            addPointCellLabels_[addPointI] = cellI;
+            addPointCellLabels[addPointI] = cellI;
 
             // Insert the new vertex from the cell-centre
             label newVertexLabel = mesh.nPoints() + addPointI;
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPatchField.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPatchField.H
index aa7fea32535e91868205711a5feda2bede0cc3fb..ee4d3b7dcb58ef376524eedce2581fd62ba68246 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPatchField.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPatchField.H
@@ -45,17 +45,12 @@ void Foam::vtkPV3Foam::convertPatchField
     const word& name,
     const Field<Type>& ptf,
     vtkMultiBlockDataSet* output,
-    const selectionInfo& selector,
+    const partInfo& selector,
     const label datasetNo
 )
 {
     const label nComp = pTraits<Type>::nComponents;
 
-    vtkPolyData* vtkmesh = vtkPolyData::SafeDownCast
-    (
-        GetDataSetFromBlock(output, selector, datasetNo)
-    );
-
     vtkFloatArray* cellData = vtkFloatArray::New();
     cellData->SetNumberOfTuples( ptf.size() );
     cellData->SetNumberOfComponents( nComp );
@@ -70,11 +65,15 @@ void Foam::vtkPV3Foam::convertPatchField
         {
             vec[d] = component(t, d);
         }
-
         cellData->InsertTuple(i, vec);
     }
 
-    vtkmesh->GetCellData()->AddArray(cellData);
+    vtkPolyData::SafeDownCast
+    (
+        GetDataSetFromBlock(output, selector, datasetNo)
+    )   ->GetCellData()
+        ->AddArray(cellData);
+
     cellData->Delete();
 }
 
@@ -86,17 +85,12 @@ void Foam::vtkPV3Foam::convertPatchPointField
     const word& name,
     const Field<Type>& pptf,
     vtkMultiBlockDataSet* output,
-    const selectionInfo& selector,
+    const partInfo& selector,
     const label datasetNo
 )
 {
     const label nComp = pTraits<Type>::nComponents;
 
-    vtkPolyData* vtkmesh = vtkPolyData::SafeDownCast
-    (
-        GetDataSetFromBlock(output, selector, datasetNo)
-    );
-
     vtkFloatArray *pointData = vtkFloatArray::New();
     pointData->SetNumberOfTuples( pptf.size() );
     pointData->SetNumberOfComponents( nComp );
@@ -115,7 +109,12 @@ void Foam::vtkPV3Foam::convertPatchPointField
         pointData->InsertTuple(i, vec);
     }
 
-    vtkmesh->GetPointData()->AddArray(pointData);
+    vtkPolyData::SafeDownCast
+    (
+        GetDataSetFromBlock(output, selector, datasetNo)
+    )   ->GetPointData()
+        ->AddArray(pointData);
+
     pointData->Delete();
 }
 
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPointFields.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPointFields.H
index eece2609d7b75453104cea4c5cab921f627b9c67..9493bce3210aa53e833d0181a54bae1e5655169b 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPointFields.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPointFields.H
@@ -44,21 +44,20 @@ void Foam::vtkPV3Foam::convertPointFields
     vtkMultiBlockDataSet* output
 )
 {
-    // field subset based on type
-    IOobjectList fieldObjects
-    (
-        objects.lookupClass
-        (
-            GeometricField<Type, pointPatchField, pointMesh>::typeName
-        )
-    );
-
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
 
-    forAllIter(IOobjectList, fieldObjects, iter)
+    forAllConstIter(IOobjectList, objects, iter)
     {
-        word fieldName = iter()->name();
+        const word& fieldName = iter()->name();
+        // restrict to this GeometricField<Type, ...>
+        if
+        (
+            iter()->headerClassName()
+         != GeometricField<Type, pointPatchField, pointMesh>::typeName
+        )
+        {
+            continue;
+        }
 
         if (debug)
         {
@@ -73,52 +72,49 @@ void Foam::vtkPV3Foam::convertPointFields
         );
 
 
-        //
-        // Convert internal mesh - if activated
-        //
-        for
+        // Convert activated internalMesh regions
+        convertPointFieldBlock
         (
-            int regionId = regionInfoVolume_.start();
-            regionId < regionInfoVolume_.end();
-            ++regionId
-        )
-        {
-            const label datasetNo = regionDataset_[regionId];
+            ptf,
+            output,
+            partInfoVolume_,
+            regionPolyDecomp_
+        );
 
-            if (!regionStatus_[regionId] || datasetNo < 0)
-            {
-                continue;
-            }
+        // Convert activated cellZones
+        convertPointFieldBlock
+        (
+            ptf,
+            output,
+            partInfoCellZones_,
+            zonePolyDecomp_
+        );
+
+        // Convert activated cellSets
+        convertPointFieldBlock
+        (
+            ptf,
+            output,
+            partInfoCellSets_,
+            csetPolyDecomp_
+        );
 
-            convertPointField
-            (
-                ptf,
-                GeometricField<Type, fvPatchField, volMesh>::null(),
-                output,
-                regionInfoVolume_,
-                datasetNo
-            );
-        }
 
         //
         // Convert patches - if activated
         //
         for
         (
-            int regionId = regionInfoPatches_.start();
-            regionId < regionInfoPatches_.end();
-            ++regionId
+            int partId = partInfoPatches_.start();
+            partId < partInfoPatches_.end();
+            ++partId
         )
         {
-            word patchName = getFirstWord
-            (
-                regionSelection->GetArrayName(regionId)
-            );
+            const word  patchName = getPartName(partId);
+            const label datasetNo = partDataset_[partId];
+            const label   patchId = patches.findPatchID(patchName);
 
-            const label datasetNo = regionDataset_[regionId];
-            const label patchId = patches.findPatchID(patchName);
-
-            if (!regionStatus_[regionId] || datasetNo < 0 || patchId < 0)
+            if (!partStatus_[partId] || datasetNo < 0 || patchId < 0)
             {
                 continue;
             }
@@ -128,7 +124,7 @@ void Foam::vtkPV3Foam::convertPointFields
                 fieldName,
                 ptf.boundaryField()[patchId].patchInternalField()(),
                 output,
-                regionInfoPatches_,
+                partInfoPatches_,
                 datasetNo
             );
         }
@@ -136,27 +132,67 @@ void Foam::vtkPV3Foam::convertPointFields
 }
 
 
+
+template<class Type>
+void Foam::vtkPV3Foam::convertPointFieldBlock
+(
+    const GeometricField<Type, pointPatchField, pointMesh>& ptf,
+    vtkMultiBlockDataSet* output,
+    const partInfo& selector,
+    const List<polyDecomp>& decompLst
+)
+{
+   for (int partId = selector.start(); partId < selector.end(); ++partId)
+   {
+       const label datasetNo = partDataset_[partId];
+
+       if (datasetNo >= 0 && partStatus_[partId])
+       {
+           convertPointField
+           (
+               ptf,
+               GeometricField<Type, fvPatchField, volMesh>::null(),
+               output,
+               selector,
+               datasetNo,
+               decompLst[datasetNo]
+           );
+       }
+   }
+}
+
+
+
 template<class Type>
 void Foam::vtkPV3Foam::convertPointField
 (
     const GeometricField<Type, pointPatchField, pointMesh>& ptf,
     const GeometricField<Type, fvPatchField, volMesh>& tf,
     vtkMultiBlockDataSet* output,
-    const selectionInfo& selector,
-    const label datasetNo
+    const partInfo& selector,
+    const label datasetNo,
+    const polyDecomp& decomp
 )
 {
     const label nComp = pTraits<Type>::nComponents;
+    const labelList& addPointCellLabels = decomp.addPointCellLabels();
+    const labelList& pointMap = decomp.pointMap();
 
-    vtkUnstructuredGrid* vtkmesh = vtkUnstructuredGrid::SafeDownCast
-    (
-        GetDataSetFromBlock(output, selector, datasetNo)
-    );
+    // use a pointMap or address directly into mesh
+    label nPoints;
+    if (pointMap.size())
+    {
+        nPoints = pointMap.size();
+    }
+    else
+    {
+        nPoints = ptf.size();
+    }
 
     vtkFloatArray *pointData = vtkFloatArray::New();
-    pointData->SetNumberOfTuples( ptf.size() + addPointCellLabels_.size() );
+    pointData->SetNumberOfTuples( nPoints + addPointCellLabels.size() );
     pointData->SetNumberOfComponents( nComp );
-    pointData->Allocate( nComp*(ptf.size() + addPointCellLabels_.size()) );
+    pointData->Allocate( nComp*(nPoints + addPointCellLabels.size()) );
     pointData->SetName( tf.name().c_str() );
 
 
@@ -164,56 +200,73 @@ void Foam::vtkPV3Foam::convertPointField
     {
         Info<< "convert convertPointField: "
             << tf.name()
-            << " size = " << ptf.size()
+            << " size = " << nPoints
             << " nComp=" << nComp
-            << " nTuples = " << (ptf.size() + addPointCellLabels_.size())
+            << " nTuples = " << (nPoints + addPointCellLabels.size())
             <<  endl;
     }
 
     float vec[nComp];
-    forAll(ptf, i)
+
+    if (pointMap.size())
+    {
+        forAll(pointMap, i)
+        {
+            const Type& t = ptf[pointMap[i]];
+            for (direction d=0; d<nComp; d++)
+            {
+                vec[d] = component(t, d);
+            }
+            pointData->InsertTuple(i, vec);
+        }
+    }
+    else
     {
-        const Type& t = ptf[i];
-        for (direction d=0; d<nComp; d++)
+        forAll(ptf, i)
         {
-            vec[d] = component(t, d);
+            const Type& t = ptf[i];
+            for (direction d=0; d<nComp; d++)
+            {
+                vec[d] = component(t, d);
+            }
+            pointData->InsertTuple(i, vec);
         }
-
-        pointData->InsertTuple(i, vec);
     }
 
     // continue insertion from here
-    label i = ptf.size();
+    label i = nPoints;
 
     if (&tf != &GeometricField<Type, fvPatchField, volMesh>::null())
     {
-        forAll(addPointCellLabels_, api)
+        forAll(addPointCellLabels, apI)
         {
-            const Type& t = tf[addPointCellLabels_[api]];
+            const Type& t = tf[addPointCellLabels[apI]];
             for (direction d=0; d<nComp; d++)
             {
                 vec[d] = component(t, d);
             }
-
             pointData->InsertTuple(i++, vec);
         }
     }
     else
     {
-        forAll(addPointCellLabels_, api)
+        forAll(addPointCellLabels, apI)
         {
-            Type t = interpolatePointToCell(ptf, addPointCellLabels_[api]);
-
+            Type t = interpolatePointToCell(ptf, addPointCellLabels[apI]);
             for (direction d=0; d<nComp; d++)
             {
                 vec[d] = component(t, d);
             }
-
             pointData->InsertTuple(i++, vec);
         }
     }
 
-    vtkmesh->GetPointData()->AddArray(pointData);
+    vtkUnstructuredGrid::SafeDownCast
+    (
+        GetDataSetFromBlock(output, selector, datasetNo)
+    )   ->GetPointData()
+        ->AddArray(pointData);
+
     pointData->Delete();
 }
 
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfo.C b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfo.C
index 4319a8b5195b4912fbc9a773174958271a0acae6..1c00a04a8573edf498772061a60d081b95e06a1c 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfo.C
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfo.C
@@ -124,22 +124,22 @@ void Foam::vtkPV3Foam::updateInfoInternalMesh()
         Info<< "<beg> Foam::vtkPV3Foam::updateInfoInternalMesh" << endl;
     }
 
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
+    vtkDataArraySelection* partSelection = reader_->GetPartSelection();
 
     // Determine number of meshes available
     HashTable<const fvMesh*> meshObjects = dbPtr_().lookupClass<const fvMesh>();
     nMesh_ = meshObjects.size();
 
-    // Determine regions (internal mesh and patches...)
+    // Determine mesh parts (internalMesh, patches...)
     //- Add internal mesh as first entry
-    regionInfoVolume_ = regionSelection->GetNumberOfArrays();
-    regionSelection->AddArray("internalMesh");
-    regionInfoVolume_ += 1;
+    partInfoVolume_ = partSelection->GetNumberOfArrays();
+    partSelection->AddArray("internalMesh");
+    partInfoVolume_ += 1;
 
     if (debug)
     {
         // just for debug info
-        getSelectedArrayEntries(regionSelection);
+        getSelectedArrayEntries(partSelection);
 
         Info<< "<end> Foam::vtkPV3Foam::updateInfoInternalMesh" << endl;
     }
@@ -161,14 +161,14 @@ void Foam::vtkPV3Foam::updateInfoLagrangian()
         readDir(dbPtr_->timePath()/"lagrangian", fileName::DIRECTORY)
     );
 
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
-    regionInfoLagrangian_ = regionSelection->GetNumberOfArrays();
+    vtkDataArraySelection* partSelection = reader_->GetPartSelection();
+    partInfoLagrangian_ = partSelection->GetNumberOfArrays();
 
     int nClouds = 0;
     forAll(cloudDirs, cloudI)
     {
         // Add cloud to GUI list
-        regionSelection->AddArray
+        partSelection->AddArray
         (
             (cloudDirs[cloudI] + " - lagrangian").c_str()
         );
@@ -176,12 +176,12 @@ void Foam::vtkPV3Foam::updateInfoLagrangian()
         ++nClouds;
     }
 
-    regionInfoLagrangian_ += nClouds;
+    partInfoLagrangian_ += nClouds;
 
     if (debug)
     {
         // just for debug info
-        getSelectedArrayEntries(regionSelection);
+        getSelectedArrayEntries(partSelection);
 
         Info<< "<end> Foam::vtkPV3Foam::updateInfoLagrangian" << endl;
     }
@@ -196,8 +196,8 @@ void Foam::vtkPV3Foam::updateInfoPatches()
             << " [meshPtr=" << (meshPtr_ ? "set" : "NULL") << "]" << endl;
     }
 
-    vtkDataArraySelection *regionSelection = reader_->GetRegionSelection();
-    regionInfoPatches_ = regionSelection->GetNumberOfArrays();
+    vtkDataArraySelection* partSelection = reader_->GetPartSelection();
+    partInfoPatches_ = partSelection->GetNumberOfArrays();
 
     int nPatches = 0;
     if (meshPtr_)
@@ -210,7 +210,7 @@ void Foam::vtkPV3Foam::updateInfoPatches()
             if (pp.size())
             {
                 // Add patch to GUI list
-                regionSelection->AddArray
+                partSelection->AddArray
                 (
                     (pp.name() + " - patch").c_str()
                 );
@@ -236,7 +236,7 @@ void Foam::vtkPV3Foam::updateInfoPatches()
             )
         );
 
-        // Start regions at patches
+        // Add (non-zero) patches to the list of mesh parts
         forAll(patchEntries, entryI)
         {
             label nFaces
@@ -248,7 +248,7 @@ void Foam::vtkPV3Foam::updateInfoPatches()
             if (nFaces)
             {
                 // Add patch to GUI list
-                regionSelection->AddArray
+                partSelection->AddArray
                 (
                     (patchEntries[entryI].keyword() + " - patch").c_str()
                 );
@@ -258,12 +258,12 @@ void Foam::vtkPV3Foam::updateInfoPatches()
         }
     }
 
-    regionInfoPatches_ += nPatches;
+    partInfoPatches_ += nPatches;
 
     if (debug)
     {
         // just for debug info
-        getSelectedArrayEntries(regionSelection);
+        getSelectedArrayEntries(partSelection);
 
         Info<< "<end> Foam::vtkPV3Foam::updateInfoPatches" << endl;
     }
@@ -283,8 +283,7 @@ void Foam::vtkPV3Foam::updateInfoZones()
             << " [meshPtr=" << (meshPtr_ ? "set" : "NULL") << "]" << endl;
     }
 
-    vtkDataArraySelection *regionSelection = reader_->GetRegionSelection();
-
+    vtkDataArraySelection* partSelection = reader_->GetPartSelection();
     wordList namesLst;
 
     //
@@ -299,13 +298,12 @@ void Foam::vtkPV3Foam::updateInfoZones()
         namesLst = readZoneNames("cellZones");
     }
 
-    regionInfoCellZones_ = regionSelection->GetNumberOfArrays();
+    partInfoCellZones_ = partSelection->GetNumberOfArrays();
     forAll(namesLst, elemI)
     {
-        regionSelection->AddArray((namesLst[elemI] + " - cellZone").c_str());
+        partSelection->AddArray((namesLst[elemI] + " - cellZone").c_str());
     }
-    regionInfoCellZones_ += namesLst.size();
-    zoneSuperCells_.setSize(regionInfoCellZones_.size());
+    partInfoCellZones_ += namesLst.size();
 
 
     //
@@ -320,15 +318,15 @@ void Foam::vtkPV3Foam::updateInfoZones()
         namesLst = readZoneNames("faceZones");
     }
 
-    regionInfoFaceZones_ = regionSelection->GetNumberOfArrays();
+    partInfoFaceZones_ = partSelection->GetNumberOfArrays();
     forAll(namesLst, elemI)
     {
-        regionSelection->AddArray
+        partSelection->AddArray
         (
             (namesLst[elemI] + " - faceZone").c_str()
         );
     }
-    regionInfoFaceZones_ += namesLst.size();
+    partInfoFaceZones_ += namesLst.size();
 
 
     //
@@ -343,21 +341,21 @@ void Foam::vtkPV3Foam::updateInfoZones()
         namesLst = readZoneNames("pointZones");
     }
 
-    regionInfoPointZones_ = regionSelection->GetNumberOfArrays();
+    partInfoPointZones_ = partSelection->GetNumberOfArrays();
     forAll(namesLst, elemI)
     {
-        regionSelection->AddArray
+        partSelection->AddArray
         (
             (namesLst[elemI] + " - pointZone").c_str()
         );
     }
-    regionInfoPointZones_ += namesLst.size();
+    partInfoPointZones_ += namesLst.size();
 
 
     if (debug)
     {
         // just for debug info
-        getSelectedArrayEntries(regionSelection);
+        getSelectedArrayEntries(partSelection);
 
         Info<< "<end> Foam::vtkPV3Foam::updateInfoZones" << endl;
     }
@@ -376,7 +374,7 @@ void Foam::vtkPV3Foam::updateInfoSets()
         Info<< "<beg> Foam::vtkPV3Foam::updateInfoSets" << endl;
     }
 
-    vtkDataArraySelection *regionSelection = reader_->GetRegionSelection();
+    vtkDataArraySelection* partSelection = reader_->GetPartSelection();
 
     // Add names of sets
     IOobjectList objects
@@ -387,27 +385,26 @@ void Foam::vtkPV3Foam::updateInfoSets()
     );
 
 
-    regionInfoCellSets_ = regionSelection->GetNumberOfArrays();
-    regionInfoCellSets_ += addToSelection<cellSet>
+    partInfoCellSets_ = partSelection->GetNumberOfArrays();
+    partInfoCellSets_ += addToSelection<cellSet>
     (
-        regionSelection,
+        partSelection,
         objects,
         " - cellSet"
     );
-    csetSuperCells_.setSize(regionInfoCellSets_.size());
 
-    regionInfoFaceSets_ = regionSelection->GetNumberOfArrays();
-    regionInfoFaceSets_ += addToSelection<faceSet>
+    partInfoFaceSets_ = partSelection->GetNumberOfArrays();
+    partInfoFaceSets_ += addToSelection<faceSet>
     (
-        regionSelection,
+        partSelection,
         objects,
         " - faceSet"
     );
 
-    regionInfoPointSets_ = regionSelection->GetNumberOfArrays();
-    regionInfoPointSets_ += addToSelection<pointSet>
+    partInfoPointSets_ = partSelection->GetNumberOfArrays();
+    partInfoPointSets_ += addToSelection<pointSet>
     (
-        regionSelection,
+        partSelection,
         objects,
         " - pointSet"
     );
@@ -415,7 +412,7 @@ void Foam::vtkPV3Foam::updateInfoSets()
     if (debug)
     {
         // just for debug info
-        getSelectedArrayEntries(regionSelection);
+        getSelectedArrayEntries(partSelection);
 
         Info<< "<end> Foam::vtkPV3Foam::updateInfoSets" << endl;
     }
@@ -433,35 +430,24 @@ void Foam::vtkPV3Foam::updateInfoLagrangianFields()
     vtkDataArraySelection *fieldSelection =
         reader_->GetLagrangianFieldSelection();
 
-    vtkDataArraySelection *regionSelection =
-        reader_->GetRegionSelection();
-
     // preserve the enabled selections
-    stringList selectedEntries = getSelectedArrayEntries
-    (
-        fieldSelection,
-        true
-    );
-
+    stringList enabledEntries = getSelectedArrayEntries(fieldSelection);
     fieldSelection->RemoveAllArrays();
 
-
-    //
-    // TODO - can currently only get fields from ONE cloud
     //
+    // TODO - currently only get fields from ONE cloud
+    // have to decide if the second set of fields get mixed in
+    // or dealt with separately
 
-    const selectionInfo& selector = regionInfoLagrangian_;
-    int regionId = selector.start();
+    const partInfo& selector = partInfoLagrangian_;
+    int partId = selector.start();
 
-    if (!selector.size() || regionId < 0)
+    if (!selector.size() || partId < 0)
     {
         return;
     }
 
-    word cloudName = getFirstWord
-    (
-        regionSelection->GetArrayName(regionId)
-    );
+    word cloudName = getPartName(partId);
 
     IOobjectList objects
     (
@@ -488,6 +474,7 @@ void Foam::vtkPV3Foam::updateInfoLagrangianFields()
     addToSelection<IOField<sphericalTensor> >
     (
         fieldSelection,
+
         objects
     );
     addToSelection<IOField<symmTensor> >
@@ -502,11 +489,7 @@ void Foam::vtkPV3Foam::updateInfoLagrangianFields()
     );
 
     // restore the enabled selections
-    setSelectedArrayEntries
-    (
-        fieldSelection,
-        selectedEntries
-    );
+    setSelectedArrayEntries(fieldSelection, enabledEntries);
 
     if (debug)
     {
@@ -517,5 +500,4 @@ void Foam::vtkPV3Foam::updateInfoLagrangianFields()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-
 // ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfoFields.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfoFields.H
index 540820907760d95f2bf902367dd1ebade5736749..bd18d66d944640a02ad8fdc30bad1333d7117b28 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfoFields.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInfoFields.H
@@ -43,18 +43,18 @@ void Foam::vtkPV3Foam::updateInfoFields
         Info<< "<beg> Foam::vtkPV3Foam::updateInfoFields" << endl;
     }
 
-    stringList selectedEntries;
+    stringList enabledEntries;
     // enable 'p' and 'U' on the first call
     if (select->GetNumberOfArrays() == 0 && !meshPtr_)
     {
-        selectedEntries.setSize(2);
-        selectedEntries[0] = "p";
-        selectedEntries[1] = "U";
+        enabledEntries.setSize(2);
+        enabledEntries[0] = "p";
+        enabledEntries[1] = "U";
     }
     else
     {
         // preserve the enabled selections
-        selectedEntries = getSelectedArrayEntries(select);
+        enabledEntries = getSelectedArrayEntries(select);
     }
 
     select->RemoveAllArrays();
@@ -90,11 +90,7 @@ void Foam::vtkPV3Foam::updateInfoFields
     );
 
     // restore the enabled selections
-    setSelectedArrayEntries
-    (
-        select,
-        selectedEntries
-    );
+    setSelectedArrayEntries(select, enabledEntries);
 
     if (debug)
     {
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUtilities.C b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUtilities.C
new file mode 100644
index 0000000000000000000000000000000000000000..e09d83e5e2c7cb87293917d267b8255ffef70159
--- /dev/null
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUtilities.C
@@ -0,0 +1,341 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Description
+    Misc helper methods and utilities
+
+\*---------------------------------------------------------------------------*/
+
+#include "vtkPV3Foam.H"
+#include "vtkPV3FoamReader.h"
+
+// Foam includes
+#include "fvMesh.H"
+#include "Time.H"
+#include "IFstream.H"
+
+// VTK includes
+#include "vtkDataArraySelection.h"
+#include "vtkDataSet.h"
+#include "vtkMultiBlockDataSet.h"
+#include "vtkInformation.h"
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::vtkPV3Foam::AddToBlock
+(
+    vtkMultiBlockDataSet* output,
+    vtkDataSet* dataset,
+    const partInfo& selector,
+    const label datasetNo,
+    const string& datasetName
+)
+{
+    const int blockNo = selector.block();
+
+    vtkDataObject* blockDO = output->GetBlock(blockNo);
+    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
+
+    if (!block)
+    {
+        if (blockDO)
+        {
+            FatalErrorIn("Foam::vtkPV3Foam::AddToBlock")
+                << "Block already has a vtkDataSet assigned to it"
+                << endl;
+            return;
+        }
+
+        block = vtkMultiBlockDataSet::New();
+        output->SetBlock(blockNo, block);
+        block->Delete();
+    }
+
+    if (debug)
+    {
+        Info<< "block[" << blockNo << "] has "
+            << block->GetNumberOfBlocks()
+            <<  " datasets prior to adding set " << datasetNo
+            <<  " with name: " << datasetName << endl;
+    }
+
+    block->SetBlock(datasetNo, dataset);
+
+    // name the block when assigning dataset 0
+    if (datasetNo == 0)
+    {
+        output->GetMetaData(blockNo)->Set
+        (
+            vtkCompositeDataSet::NAME(),
+            selector.name()
+        );
+    }
+
+    if (datasetName.size())
+    {
+        block->GetMetaData(datasetNo)->Set
+        (
+            vtkCompositeDataSet::NAME(),
+            datasetName.c_str()
+        );
+    }
+}
+
+
+vtkDataSet* Foam::vtkPV3Foam::GetDataSetFromBlock
+(
+    vtkMultiBlockDataSet* output,
+    const partInfo& selector,
+    const label datasetNo
+)
+{
+    const int blockNo = selector.block();
+
+    vtkDataObject* blockDO = output->GetBlock(blockNo);
+    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
+
+    if (block)
+    {
+        return vtkDataSet::SafeDownCast(block->GetBlock(datasetNo));
+    }
+
+    return 0;
+}
+
+
+// ununsed at the moment
+Foam::label Foam::vtkPV3Foam::GetNumberOfDataSets
+(
+    vtkMultiBlockDataSet* output,
+    const partInfo& selector
+)
+{
+    const int blockNo = selector.block();
+
+    vtkDataObject* blockDO = output->GetBlock(blockNo);
+    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
+    if (block)
+    {
+        return block->GetNumberOfBlocks();
+    }
+
+    return 0;
+}
+
+
+Foam::word Foam::vtkPV3Foam::getPartName(int partId)
+{
+    return getFirstWord(reader_->GetPartArrayName(partId));
+}
+
+
+Foam::wordHashSet Foam::vtkPV3Foam::getSelected
+(
+    vtkDataArraySelection* select
+)
+{
+    int nElem = select->GetNumberOfArrays();
+    wordHashSet selections(2*nElem);
+
+    for (int elemI=0; elemI < nElem; ++elemI)
+    {
+        if (select->GetArraySetting(elemI))
+        {
+            selections.insert(getFirstWord(select->GetArrayName(elemI)));
+        }
+    }
+
+    return selections;
+}
+
+
+Foam::wordHashSet Foam::vtkPV3Foam::getSelected
+(
+    vtkDataArraySelection* select,
+    const partInfo& selector
+)
+{
+    int nElem = select->GetNumberOfArrays();
+    wordHashSet selections(2*nElem);
+
+    for (int elemI = selector.start(); elemI < selector.end(); ++elemI)
+    {
+        if (select->GetArraySetting(elemI))
+        {
+            selections.insert(getFirstWord(select->GetArrayName(elemI)));
+        }
+    }
+
+    return selections;
+}
+
+
+Foam::stringList Foam::vtkPV3Foam::getSelectedArrayEntries
+(
+    vtkDataArraySelection* select
+)
+{
+    stringList selections(select->GetNumberOfArrays());
+    label nElem = 0;
+
+    forAll(selections, elemI)
+    {
+        if (select->GetArraySetting(elemI))
+        {
+            selections[nElem++] = select->GetArrayName(elemI);
+        }
+    }
+    selections.setSize(nElem);
+
+
+    if (debug)
+    {
+        label nElem = select->GetNumberOfArrays();
+        Info<< "available(";
+        for (int elemI = 0; elemI < nElem; ++elemI)
+        {
+            Info<< " \"" << select->GetArrayName(elemI) << "\"";
+        }
+        Info<< " )\nselected(";
+
+        forAll(selections, elemI)
+        {
+            Info<< " " << selections[elemI];
+        }
+        Info<< " )\n";
+    }
+
+    return selections;
+}
+
+
+Foam::stringList Foam::vtkPV3Foam::getSelectedArrayEntries
+(
+    vtkDataArraySelection* select,
+    const partInfo& selector
+)
+{
+    stringList selections(selector.size());
+    label nElem = 0;
+
+    for (int elemI = selector.start(); elemI < selector.end(); ++elemI)
+    {
+        if (select->GetArraySetting(elemI))
+        {
+            selections[nElem++] = select->GetArrayName(elemI);
+        }
+    }
+    selections.setSize(nElem);
+
+
+    if (debug)
+    {
+        Info<< "available(";
+        for (int elemI = selector.start(); elemI < selector.end(); ++elemI)
+        {
+            Info<< " \"" << select->GetArrayName(elemI) << "\"";
+        }
+        Info<< " )\nselected(";
+
+        forAll(selections, elemI)
+        {
+            Info<< " " << selections[elemI];
+        }
+        Info<< " )\n";
+    }
+
+    return selections;
+}
+
+
+void Foam::vtkPV3Foam::setSelectedArrayEntries
+(
+    vtkDataArraySelection* select,
+    const stringList& selections
+)
+{
+    const int nElem = select->GetNumberOfArrays();
+    select->DisableAllArrays();
+
+    // Loop through entries, setting values from selectedEntries
+    for (int elemI=0; elemI < nElem; ++elemI)
+    {
+        string arrayName(select->GetArrayName(elemI));
+
+        forAll(selections, elemI)
+        {
+            if (selections[elemI] == arrayName)
+            {
+                select->EnableArray(arrayName.c_str());
+                break;
+            }
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+// parse these bits of info from /proc/meminfo (Linux)
+//
+// MemTotal:      2062660 kB
+// MemFree:       1124400 kB
+//
+// used = MemTotal - MemFree is what the free(1) uses.
+//
+void Foam::vtkPV3Foam::printMemory()
+{
+    const char* meminfo = "/proc/meminfo";
+
+    if (exists(meminfo))
+    {
+        IFstream is(meminfo);
+        label memTotal = 0;
+        label memFree = 0;
+
+        string line;
+
+        while (is.getLine(line).good())
+        {
+            char tag[32];
+            int value;
+
+            if (sscanf(line.c_str(), "%30s %d", tag, &value) == 2)
+            {
+                if (!strcmp(tag, "MemTotal:"))
+                {
+                    memTotal = value;
+                }
+                else if (!strcmp(tag, "MemFree:"))
+                {
+                    memFree = value;
+                }
+            }
+        }
+
+        Info << "memUsed: " << (memTotal - memFree) << " kB\n";
+    }
+}
+
+// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamVolFields.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamVolFields.H
index 6413852bffdd995c26f56579364205d729b7e5fb..a15b314706a24e48ffbbf73d7bd77a8492a7328c 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamVolFields.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamVolFields.H
@@ -49,21 +49,19 @@ void Foam::vtkPV3Foam::convertVolFields
     vtkMultiBlockDataSet* output
 )
 {
-    // field subset based on type
-    IOobjectList fieldObjects
-    (
-        objects.lookupClass
-        (
-            GeometricField<Type, fvPatchField, volMesh>::typeName
-        )
-    );
-
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
-    vtkDataArraySelection* regionSelection = reader_->GetRegionSelection();
 
-    forAllIter(IOobjectList, fieldObjects, iter)
+    forAllConstIter(IOobjectList, objects, iter)
     {
-        word fieldName = iter()->name();
+        // restrict to GeometricField<Type, ...>
+        if
+        (
+            iter()->headerClassName()
+         != GeometricField<Type, fvPatchField, volMesh>::typeName
+        )
+        {
+            continue;
+        }
 
         GeometricField<Type, fvPatchField, volMesh> tf
         (
@@ -77,60 +75,52 @@ void Foam::vtkPV3Foam::convertVolFields
         );
 
 
-        //
-        // Convert internal mesh - if activated
-        //
-        for
+        // Convert activated internalMesh regions
+        convertVolFieldBlock
         (
-            int regionId = regionInfoVolume_.start();
-            regionId < regionInfoVolume_.end();
-            ++regionId
-        )
-        {
-            const label datasetNo = regionDataset_[regionId];
+            tf,
+            tptf(),
+            output,
+            partInfoVolume_,
+            regionPolyDecomp_
+        );
 
-            if (!regionStatus_[regionId] || datasetNo < 0)
-            {
-                continue;
-            }
+        // Convert activated cellZones
+        convertVolFieldBlock
+        (
+            tf,
+            tptf(),
+            output,
+            partInfoCellZones_,
+            zonePolyDecomp_
+        );
+
+        // Convert activated cellSets
+        convertVolFieldBlock
+        (
+            tf,
+            tptf(),
+            output,
+            partInfoCellSets_,
+            csetPolyDecomp_
+        );
 
-            convertVolField
-            (
-                tf,
-                output,
-                regionInfoVolume_,
-                datasetNo,
-                superCells_
-            );
-            convertPointField
-            (
-                tptf(),
-                tf,
-                output,
-                regionInfoVolume_,
-                datasetNo
-            );
-        }
 
         //
         // Convert patches - if activated
         //
         for
         (
-            int regionId = regionInfoPatches_.start();
-            regionId < regionInfoPatches_.end();
-            ++regionId
+            int partId = partInfoPatches_.start();
+            partId < partInfoPatches_.end();
+            ++partId
         )
         {
-            word patchName = getFirstWord
-            (
-                regionSelection->GetArrayName(regionId)
-            );
-
-            const label datasetNo = regionDataset_[regionId];
+            const word patchName = getPartName(partId);
+            const label datasetNo = partDataset_[partId];
             const label patchId = patches.findPatchID(patchName);
 
-            if (!regionStatus_[regionId] || datasetNo < 0 || patchId < 0)
+            if (!partStatus_[partId] || datasetNo < 0 || patchId < 0)
             {
                 continue;
             }
@@ -147,18 +137,28 @@ void Foam::vtkPV3Foam::convertVolFields
                 )
             )
             {
-                fvPatch p
+                fvPatch p(ptf.patch().patch(), tf.mesh().boundary());
+
+                tmp<Field<Type> > tpptf
                 (
-                    ptf.patch().patch(),
-                    tf.mesh().boundary()
+                    fvPatchField<Type>(p, tf).patchInternalField()
                 );
 
                 convertPatchField
                 (
                     tf.name(),
-                    fvPatchField<Type>(p, tf).patchInternalField()(),
+                    tpptf(),
                     output,
-                    regionInfoPatches_,
+                    partInfoPatches_,
+                    datasetNo
+                );
+
+                convertPatchPointField
+                (
+                    tf.name(),
+                    ppInterpList[patchId].faceToPointInterpolate(tpptf)(),
+                    output,
+                    partInfoPatches_,
                     datasetNo
                 );
             }
@@ -169,91 +169,19 @@ void Foam::vtkPV3Foam::convertVolFields
                     tf.name(),
                     ptf,
                     output,
-                    regionInfoPatches_,
+                    partInfoPatches_,
                     datasetNo
                 );
-            }
-
-            convertPatchPointField
-            (
-                tf.name(),
-                ppInterpList[patchId].faceToPointInterpolate(ptf)(),
-                output,
-                regionInfoPatches_,
-                datasetNo
-            );
-        }
-
-        //
-        // Convert cell zones - if activated
-        //
-        for
-        (
-            int regionId = regionInfoCellZones_.start();
-            regionId < regionInfoCellZones_.end();
-            ++regionId
-        )
-        {
-            const label datasetNo = regionDataset_[regionId];
-
-            if (!regionStatus_[regionId] || datasetNo < 0)
-            {
-                continue;
-            }
-
-            if (debug)
-            {
-                Info<< "wish to convert cellzone: "
-                    << getFirstWord(regionSelection->GetArrayName(regionId))
-                    << " regionId: " << regionId
-                    << " volume field: " << fieldName
-                    << endl;
-            }
-
-            convertVolField
-            (
-                tf,
-                output,
-                regionInfoCellZones_,
-                datasetNo,
-                zoneSuperCells_[datasetNo]
-            );
-        }
 
-        //
-        // Convert cell sets - if activated
-        //
-        for
-        (
-            int regionId = regionInfoCellSets_.start();
-            regionId < regionInfoCellSets_.end();
-            ++regionId
-        )
-        {
-            const label datasetNo = regionDataset_[regionId];
-
-            if (!regionStatus_[regionId] || datasetNo < 0)
-            {
-                continue;
-            }
-
-            if (debug)
-            {
-                Info<< "wish to convert cellset: "
-                    << getFirstWord(regionSelection->GetArrayName(regionId))
-                    << " regionId: " << regionId
-                    << " volume field: " << fieldName
-                    << endl;
+                convertPatchPointField
+                (
+                    tf.name(),
+                    ppInterpList[patchId].faceToPointInterpolate(ptf)(),
+                    output,
+                    partInfoPatches_,
+                    datasetNo
+                );
             }
-
-            convertVolField
-            (
-                tf,
-                output,
-                regionInfoCellSets_,
-                datasetNo,
-                csetSuperCells_[datasetNo]
-            );
         }
 
         //
@@ -261,18 +189,15 @@ void Foam::vtkPV3Foam::convertVolFields
         //
         for
         (
-            int regionId = regionInfoFaceZones_.start();
-            regionId < regionInfoFaceZones_.end();
-            ++regionId
+            int partId = partInfoFaceZones_.start();
+            partId < partInfoFaceZones_.end();
+            ++partId
         )
         {
-            word zoneName = getFirstWord
-            (
-                regionSelection->GetArrayName(regionId)
-            );
-            const label datasetNo = regionDataset_[regionId];
+            const word zoneName = getPartName(partId);
+            const label datasetNo = partDataset_[partId];
 
-            if (!regionStatus_[regionId] || datasetNo < 0)
+            if (!partStatus_[partId] || datasetNo < 0)
             {
                 continue;
             }
@@ -285,24 +210,17 @@ void Foam::vtkPV3Foam::convertVolFields
                 continue;
             }
 
-            if (debug)
-            {
-                Info<< "wish to convert facezone: "
-                    << zoneName
-                    << " regionId: " << regionId
-                    << " volume field: " << fieldName
-                    << endl;
-            }
-
             convertFaceField
             (
                 tf,
                 output,
-                regionInfoFaceZones_,
+                partInfoFaceZones_,
                 datasetNo,
                 mesh,
                 zMesh[zoneId]
             );
+
+            // TODO: points
         }
 
         //
@@ -310,28 +228,17 @@ void Foam::vtkPV3Foam::convertVolFields
         //
         for
         (
-            int regionId = regionInfoFaceSets_.start();
-            regionId < regionInfoFaceSets_.end();
-            ++regionId
+            int partId = partInfoFaceSets_.start();
+            partId < partInfoFaceSets_.end();
+            ++partId
         )
         {
-            const label datasetNo = regionDataset_[regionId];
-            if (!regionStatus_[regionId] || datasetNo < 0)
-            {
-                continue;
-            }
-
-            word selectName = getFirstWord
-            (
-                regionSelection->GetArrayName(regionId)
-            );
+            const word selectName = getPartName(partId);
+            const label datasetNo = partDataset_[partId];
 
-            if (debug)
+            if (!partStatus_[partId] || datasetNo < 0)
             {
-                Info<< "wish to convert faceset: " << selectName
-                    << " regionId: " << regionId
-                    << " volume field: " << fieldName
-                    << endl;
+                continue;
             }
 
             const faceSet fSet(mesh, selectName);
@@ -340,32 +247,69 @@ void Foam::vtkPV3Foam::convertVolFields
             (
                 tf,
                 output,
-                regionInfoFaceSets_,
+                partInfoFaceSets_,
                 datasetNo,
                 mesh,
                 fSet
             );
+
+            // TODO: points
         }
     }
 }
 
+template<class Type>
+void Foam::vtkPV3Foam::convertVolFieldBlock
+(
+    const GeometricField<Type, fvPatchField, volMesh>& tf,
+    const GeometricField<Type, pointPatchField, pointMesh>& ptf,
+    vtkMultiBlockDataSet* output,
+    const partInfo& selector,
+    const List<polyDecomp>& decompLst
+)
+{
+   for (int partId = selector.start(); partId < selector.end(); ++partId)
+   {
+       const label datasetNo = partDataset_[partId];
+
+       if (datasetNo >= 0 && partStatus_[partId])
+       {
+           convertVolField
+           (
+               tf,
+               output,
+               selector,
+               datasetNo,
+               decompLst[datasetNo]
+           );
+
+           convertPointField
+           (
+               ptf,
+               tf,
+               output,
+               selector,
+               datasetNo,
+               decompLst[datasetNo]
+           );
+       }
+   }
+}
+
+
 
 template<class Type>
 void Foam::vtkPV3Foam::convertVolField
 (
     const GeometricField<Type, fvPatchField, volMesh>& tf,
     vtkMultiBlockDataSet* output,
-    const selectionInfo& selector,
+    const partInfo& selector,
     const label datasetNo,
-    labelList& superCells
+    const polyDecomp& decompInfo
 )
 {
     const label nComp = pTraits<Type>::nComponents;
-
-    vtkUnstructuredGrid* vtkmesh = vtkUnstructuredGrid::SafeDownCast
-    (
-        GetDataSetFromBlock(output, selector, datasetNo)
-    );
+    const labelList& superCells = decompInfo.superCells();
 
     vtkFloatArray* celldata = vtkFloatArray::New();
     celldata->SetNumberOfTuples( superCells.size() );
@@ -390,11 +334,15 @@ void Foam::vtkPV3Foam::convertVolField
         {
             vec[d] = component(t, d);
         }
-
         celldata->InsertTuple(i, vec);
     }
 
-    vtkmesh->GetCellData()->AddArray(celldata);
+    vtkUnstructuredGrid::SafeDownCast
+    (
+        GetDataSetFromBlock(output, selector, datasetNo)
+    )   ->GetCellData()
+        ->AddArray(celldata);
+
     celldata->Delete();
 }