From fa0b03433813daaf3981126b1806716bab1a317e Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@Germany>
Date: Fri, 1 Aug 2008 20:04:38 +0200
Subject: [PATCH] PV3FoamReader - neater multiblocks and dual output ports

  - normal mesh data on port0
  - Lagrangian data on port1
  - no fixed block numbers for dividing internalMesh, patches, zones etc.
    This helps avoid ugly gaps in the multiblock output
  - avoid segfault if Lagrangian fields are converted without positions

  TODO:
  - can we label the output ports?
  - the selection of Lagrangian data and fields is wonky.
---
 .../PV3FoamReader/vtkPV3FoamReader.cxx        | 218 ++++++++++--------
 .../PV3FoamReader/vtkPV3FoamReader.h          |   9 +-
 .../PV3FoamReader/vtkPV3Foam/Make/files       |   2 +-
 .../PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C     | 178 +++++++-------
 .../PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H     |  91 +++++---
 ...FoamUpdate.C => vtkPV3FoamConvertFields.C} |  82 +------
 .../vtkPV3FoamConvertLagrangianFields.H       |  54 +++--
 .../vtkPV3Foam/vtkPV3FoamConvertMesh.C        | 162 ++++++++++---
 .../vtkPV3Foam/vtkPV3FoamConvertPointFields.H | 138 ++++++-----
 .../vtkPV3Foam/vtkPV3FoamConvertVolFields.H   | 145 ++++++------
 .../vtkPV3Foam/vtkPV3FoamUpdateInformation.C  |  10 +-
 .../vtkPV3FoamUpdateInformationFields.H       |  11 +-
 12 files changed, 626 insertions(+), 474 deletions(-)
 rename applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/{vtkPV3FoamUpdate.C => vtkPV3FoamConvertFields.C} (75%)

diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx b/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx
index 81885deee70..fc12c30b8ac 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx
@@ -36,6 +36,7 @@
 vtkCxxRevisionMacro(vtkPV3FoamReader, "$Revision: 1.5$");
 vtkStandardNewMacro(vtkPV3FoamReader);
 
+#undef EXPERIMENTAL_TIME_CACHING
 
 vtkPV3FoamReader::vtkPV3FoamReader()
 {
@@ -47,7 +48,16 @@ vtkPV3FoamReader::vtkPV3FoamReader()
     FileName  = NULL;
     foamData_ = NULL;
 
-    output1_ = NULL;
+    output0_  = NULL;
+
+    // Add second output for the Lagrangian
+    this->SetNumberOfOutputPorts(2);
+    vtkMultiBlockDataSet *lagrangian;
+    lagrangian = vtkMultiBlockDataSet::New();
+    lagrangian->ReleaseData();
+
+    this->GetExecutive()->SetOutputData(1, lagrangian);
+    lagrangian->Delete();
 
     TimeStep = 0;
     TimeStepRange[0] = 0;
@@ -60,8 +70,7 @@ vtkPV3FoamReader::vtkPV3FoamReader()
     IncludeZones = 0;
     ShowPatchNames = 0;
 
-    UpdateGUI = 1;
-    UpdateGUIOld = 1;
+    UpdateGUI = 0;
 
     RegionSelection = vtkDataArraySelection::New();
     VolFieldSelection = vtkDataArraySelection::New();
@@ -114,6 +123,12 @@ vtkPV3FoamReader::~vtkPV3FoamReader()
         delete [] FileName;
     }
 
+    if (output0_)
+    {
+        output0_->Delete();
+    }
+
+
     RegionSelection->RemoveObserver(this->SelectionObserver);
     VolFieldSelection->RemoveObserver(this->SelectionObserver);
     PointFieldSelection->RemoveObserver(this->SelectionObserver);
@@ -149,22 +164,19 @@ int vtkPV3FoamReader::RequestInformation
         return 0;
     }
 
-    vtkInformation *outInfo = outputVector->GetInformationObject(0);
+    int nInfo = outputVector->GetNumberOfInformationObjects();
 
-    if (!foamData_)
+    if (Foam::vtkPV3Foam::debug)
     {
-        vtkDebugMacro("RequestInformation: creating foamData_");
-        vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast
-        (
-            outInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT())
-        );
-
-        if (Foam::vtkPV3Foam::debug)
+        cout<<"RequestInformation with " << nInfo << " item(s)\n";
+        for (int infoI = 0; infoI < nInfo; ++infoI)
         {
-            cout<< "constructed vtkPV3Foam with output: ";
-            output->Print(cout);
+            outputVector->GetInformationObject(infoI)->Print(cout);
         }
+    }
 
+    if (!foamData_)
+    {
         foamData_ = new Foam::vtkPV3Foam(FileName, this);
     }
     else
@@ -175,12 +187,17 @@ int vtkPV3FoamReader::RequestInformation
     int nTimeSteps = 0;
     double* timeSteps = foamData_->findTimes(nTimeSteps);
 
-    outInfo->Set
-    (
-        vtkStreamingDemandDrivenPipeline::TIME_STEPS(),
-        timeSteps,
-        nTimeSteps
-    );
+
+    // set identical time steps for all ports
+    for (int infoI = 0; infoI < nInfo; ++infoI)
+    {
+        outputVector->GetInformationObject(infoI)->Set
+        (
+            vtkStreamingDemandDrivenPipeline::TIME_STEPS(),
+            timeSteps,
+            nTimeSteps
+        );
+    }
 
     double timeRange[2];
     if (nTimeSteps)
@@ -190,21 +207,25 @@ int vtkPV3FoamReader::RequestInformation
 
         if (Foam::vtkPV3Foam::debug > 1)
         {
-            cout<<"nTimeSteps " << nTimeSteps << "\n";
-            cout<<"timeRange " << timeRange[0] << " to " << timeRange[1] << "\n";
+            cout<<"nTimeSteps " << nTimeSteps << "\n"
+                <<"timeRange " << timeRange[0] << " to " << timeRange[1]
+                << "\n";
 
-            for (int i = 0; i < nTimeSteps; ++i)
+            for (int timeI = 0; timeI < nTimeSteps; ++timeI)
             {
-                cout<< "step[" << i << "] = " << timeSteps[i] << "\n";
+                cout<< "step[" << timeI << "] = " << timeSteps[timeI] << "\n";
             }
         }
 
-        outInfo->Set
-        (
-            vtkStreamingDemandDrivenPipeline::TIME_RANGE(),
-            timeRange,
-            2
-        );
+        for (int infoI = 0; infoI < nInfo; ++infoI)
+        {
+            outputVector->GetInformationObject(infoI)->Set
+            (
+                vtkStreamingDemandDrivenPipeline::TIME_RANGE(),
+                timeRange,
+                2
+            );
+        }
     }
 
     delete timeSteps;
@@ -229,75 +250,41 @@ int vtkPV3FoamReader::RequestData
         return 0;
     }
 
+    int nInfo = outputVector->GetNumberOfInformationObjects();
+
     if (Foam::vtkPV3Foam::debug)
     {
-        int nInfo = outputVector->GetNumberOfInformationObjects();
-        cout<<"requestData with " << nInfo << " items\n";
-
-        for (int i = 0; i < nInfo; ++i)
+        cout<<"RequestData with " << nInfo << " item(s)\n";
+        for (int infoI = 0; infoI < nInfo; ++infoI)
         {
-            vtkInformation *info = outputVector->GetInformationObject(i);
-            info->Print(cout);
+            outputVector->GetInformationObject(infoI)->Print(cout);
         }
     }
 
-    vtkInformation* outInfo = outputVector->GetInformationObject(0);
+    // take port0 as the lead for other outputs
+    vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
     vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast
     (
-        outInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT())
-    );
-
-    if (Foam::vtkPV3Foam::debug)
-    {
-        vtkInformation* outputInfo = this->GetOutputPortInformation(0);
-        outputInfo->Print(cout);
-
-        vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast
+        outInfo->Get
         (
-            outputInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT())
-        );
-        if (output)
-        {
-            output->Print(cout);
-        }
-        else
-        {
-            cout<< "no output\n";
-        }
-
-        vtkInformation* execInfo = this->GetExecutive()->GetOutputInformation(0);
-        execInfo->Print(cout);
+            vtkMultiBlockDataSet::DATA_OBJECT()
+        )
+    );
 
-        outInfo->Print(cout);
 
-        vtkMultiBlockDataSet* dobj = vtkMultiBlockDataSet::SafeDownCast
+    vtkMultiBlockDataSet* lagrangianOutput = vtkMultiBlockDataSet::SafeDownCast
+    (
+        outputVector->GetInformationObject(1)->Get
         (
-            outInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT())
-        );
-        if (dobj)
-        {
-            dobj->Print(cout);
-
-            vtkInformation* dobjInfo = dobj->GetInformation();
-            dobjInfo->Print(cout);
-        }
-        else
-        {
-            cout<< "no data_object\n";
-        }
-    }
+            vtkMultiBlockDataSet::DATA_OBJECT()
+        )
+    );
 
     if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()))
     {
-        if (Foam::vtkPV3Foam::debug)
-        {
-            cout<<"Has UPDATE_TIME_STEPS\n";
-            cout<<"output->GetNumberOfBlocks() = "
-                << output->GetNumberOfBlocks() << "\n";
-        }
-
         // Get the requested time step.
-        // We only supprt requests of a single time step
+        // We only support requests for a single time step
         int nRequestedTimeSteps = outInfo->Length
         (
             vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()
@@ -313,24 +300,56 @@ int vtkPV3FoamReader::RequestData
         }
     }
 
-    if
-    (
-        (UpdateGUIOld == GetUpdateGUI())
-     || (output->GetNumberOfBlocks() == 0)
-    )
+    if (Foam::vtkPV3Foam::debug)
+    {
+        cout<< "update output with "
+            << output->GetNumberOfBlocks() << " blocks\n";
+    }
+
+#ifdef EXPERIMENTAL_TIME_CACHING
+    bool needsUpdate = false;
+
+    if (!output0_)
+    {
+        output0_ = vtkMultiBlockDataSet::New();
+        needsUpdate = true;
+    }
+
+    // This experimental bit of code seems to work for the geometry,
+    // but trashes the fields and still triggers the GeometryFilter
+    if (needsUpdate)
     {
         foamData_->Update(output);
+        output0_->ShallowCopy(output);
+    }
+    else
+    {
+        output->ShallowCopy(output0_);
+    }
 
-        if (ShowPatchNames == 1)
+    if (Foam::vtkPV3Foam::debug)
+    {
+        if (needsUpdate)
         {
-            addPatchNamesToView();
+            cout<< "full UPDATE ---------\n";
         }
         else
         {
-            removePatchNamesFromView();
+            cout<< "cached UPDATE ---------\n";
         }
+
+        cout<< "UPDATED output: ";
+        output->Print(cout);
+
+        cout<< "UPDATED output0_: ";
+        output0_->Print(cout);
     }
-    UpdateGUIOld = GetUpdateGUI();
+
+#else
+
+    foamData_->Update(output, lagrangianOutput);
+
+#endif
 
     return 1;
 }
@@ -597,4 +616,19 @@ void vtkPV3FoamReader::SelectionModified()
     Modified();
 }
 
+
+int vtkPV3FoamReader::FillOutputPortInformation
+(
+    int port,
+    vtkInformation* info
+)
+{
+    if (port == 0)
+    {
+        return this->Superclass::FillOutputPortInformation(port, info);
+    }
+    info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMultiBlockDataSet");
+    return 1;
+}
+
 // ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.h b/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.h
index 8611884b519..77985be2125 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.h
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.h
@@ -157,11 +157,12 @@ protected:
         vtkInformationVector*
     );
 
+    virtual int FillOutputPortInformation(int, vtkInformation*);
+
     // The observer to modify this object when the array selections
     // are modified
     vtkCallbackCommand* SelectionObserver;
 
-
 private:
 
     vtkPV3FoamReader(const vtkPV3FoamReader&);  // Not implemented.
@@ -183,16 +184,16 @@ private:
     int IncludeZones;
     int ShowPatchNames;
 
+    //- Dummy variable/switch for provoking a reader update
     int UpdateGUI;
-    int UpdateGUIOld;
 
     vtkDataArraySelection* RegionSelection;
     vtkDataArraySelection* VolFieldSelection;
     vtkDataArraySelection* PointFieldSelection;
     vtkDataArraySelection* LagrangianFieldSelection;
 
-    //- Access to the output port1
-    vtkMultiBlockDataSet* output1_;
+    //- Cached data for output port0
+    vtkMultiBlockDataSet* output0_;
 
     //BTX
     Foam::vtkPV3Foam* foamData_;
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/Make/files b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/Make/files
index 0a5e64ddf14..8fb98bc9adf 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/Make/files
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/Make/files
@@ -4,8 +4,8 @@ vtkPV3FoamAddLagrangianMesh.C
 vtkPV3FoamAddPatchMesh.C
 vtkPV3FoamAddZoneMesh.C
 vtkPV3FoamAddSetMesh.C
-vtkPV3FoamUpdate.C
 vtkPV3FoamUpdateInformation.C
 vtkPV3FoamConvertMesh.C
+vtkPV3FoamConvertFields.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 8af700450c0..2d6e5756ce9 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C
@@ -213,6 +213,8 @@ bool Foam::vtkPV3Foam::setTime(const double& requestedTime)
             if (meshPtr_->readUpdate() != polyMesh::UNCHANGED)
             {
                 meshChanged_ = true;
+                reader_->UpdateProgress(0.05);
+
                 // patches, zones etc might have changed
                 UpdateInformation();
             }
@@ -464,15 +466,15 @@ Foam::vtkPV3Foam::vtkPV3Foam
     reader_(reader),
     dbPtr_(NULL),
     meshPtr_(NULL),
-    selectInfoVolume_(VOLUME, "unzoned"),
-    selectInfoPatches_(PATCHES, "patches"),
-    selectInfoLagrangian_(LAGRANGIAN, "lagrangian"),
-    selectInfoCellZones_(CELLZONE, "cellZone"),
-    selectInfoFaceZones_(FACEZONE, "faceZone"),
-    selectInfoPointZones_(POINTZONE, "pointZone"),
-    selectInfoCellSets_(CELLSET, "cellSet"),
-    selectInfoFaceSets_(FACESET, "faceSet"),
-    selectInfoPointSets_(POINTSET, "pointSet"),
+    selectInfoVolume_("unzoned"),
+    selectInfoPatches_("patches"),
+    selectInfoLagrangian_("lagrangian"),
+    selectInfoCellZones_("cellZone"),
+    selectInfoFaceZones_("faceZone"),
+    selectInfoPointZones_("pointZone"),
+    selectInfoCellSets_("cellSet"),
+    selectInfoFaceSets_("faceSet"),
+    selectInfoPointSets_("pointSet"),
     patchTextActorsPtrs_(0),
     nMesh_(0),
     timeIndex_(-1),
@@ -543,11 +545,7 @@ Foam::vtkPV3Foam::~vtkPV3Foam()
         Info<< "<end> Foam::vtkPV3Foam::~vtkPV3Foam" << endl;
     }
 
-    if (meshPtr_)
-    {
-        delete meshPtr_;
-        meshPtr_ = NULL;
-    }
+    delete meshPtr_;
 }
 
 
@@ -575,10 +573,11 @@ void Foam::vtkPV3Foam::UpdateInformation()
     }
     else
     {
-        // preserve the currently selected values
+        // preserve the enabled selections
         selectedEntries = getSelectedArrayEntries
         (
-            arraySelection
+            arraySelection,
+            false
         );
     }
 
@@ -600,7 +599,7 @@ void Foam::vtkPV3Foam::UpdateInformation()
         updateInformationZones();
     }
 
-    // restore the currently enabled values
+    // restore the enabled selections
     setSelectedArrayEntries
     (
         arraySelection,
@@ -635,23 +634,72 @@ void Foam::vtkPV3Foam::UpdateInformation()
 }
 
 
+void Foam::vtkPV3Foam::updateFoamMesh()
+{
+    if (debug)
+    {
+        Info<< "<beg> Foam::vtkPV3Foam::updateFoamMesh" << endl;
+        printMemory();
+    }
+
+    if (!reader_->GetCacheMesh())
+    {
+        delete meshPtr_;
+        meshPtr_ = NULL;
+    }
+
+    // Check to see if the FOAM mesh has been created
+    if (!meshPtr_)
+    {
+        if (debug)
+        {
+            Info<< "Creating Foam mesh" << endl;
+        }
+        meshPtr_ = new fvMesh
+        (
+            IOobject
+            (
+                fvMesh::defaultRegion,
+                dbPtr_().timeName(),
+                dbPtr_()
+            )
+        );
+
+        meshChanged_ = true;
+    }
+    else
+    {
+        if (debug)
+        {
+            Info<< "Using existing Foam mesh" << endl;
+        }
+    }
+
+    if (debug)
+    {
+        Info<< "<end> Foam::vtkPV3Foam::updateFoamMesh" << endl;
+        printMemory();
+    }
+}
+
+
 void Foam::vtkPV3Foam::Update
 (
-    vtkMultiBlockDataSet* output
+    vtkMultiBlockDataSet* output,
+    vtkMultiBlockDataSet* lagrangianOutput
 )
 {
     if (debug)
     {
-        cout<< "<beg> Foam::vtkPV3Foam::Update" << nl
-            <<"Update\n";
-        output->Print(cout);
+        cout<< "<beg> Foam::vtkPV3Foam::Update - output with "
+            << output->GetNumberOfBlocks() << " and "
+            << lagrangianOutput->GetNumberOfBlocks() << " blocks\n";
 
-        cout<<"Internally:\n";
         output->Print(cout);
-
-        cout<< " has " << output->GetNumberOfBlocks() << " blocks\n";
+        lagrangianOutput->Print(cout);
         printMemory();
     }
+    reader_->UpdateProgress(0.1);
 
     // Set up region selection(s)
     updateSelectedRegions();
@@ -661,65 +709,37 @@ void Foam::vtkPV3Foam::Update
     reader_->UpdateProgress(0.2);
 
     // Convert meshes
-    convertMeshVolume(output);
-    convertMeshLagrangian(output);
-    convertMeshPatches(output);
+    int blockNo = 0;
+
+    convertMeshVolume(output, blockNo);
+    convertMeshPatches(output, blockNo);
     reader_->UpdateProgress(0.4);
 
     if (reader_->GetIncludeZones())
     {
-        convertMeshCellZones(output);
-        convertMeshFaceZones(output);
-        convertMeshPointZones(output);
+        convertMeshCellZones(output, blockNo);
+        convertMeshFaceZones(output, blockNo);
+        convertMeshPointZones(output, blockNo);
     }
 
     if (reader_->GetIncludeSets())
     {
-        convertMeshCellSets(output);
-        convertMeshFaceSets(output);
-        convertMeshPointSets(output);
+        convertMeshCellSets(output, blockNo);
+        convertMeshFaceSets(output, blockNo);
+        convertMeshPointSets(output, blockNo);
     }
+
+    blockNo = 0;
+    convertMeshLagrangian(lagrangianOutput, blockNo);
+
     reader_->UpdateProgress(0.8);
 
     // Update fields
-    updateVolFields(output);
-    updatePointFields(output);
-    updateLagrangianFields(output);
+    convertVolFields(output);
+    convertPointFields(output);
+    convertLagrangianFields(lagrangianOutput);
     reader_->UpdateProgress(1.0);
 
-    if (debug)
-    {
-        Info<< "Number of data sets after update" << nl
-            << "  VOLUME = "
-            << GetNumberOfDataSets(output, selectInfoVolume_) << nl
-            << "  PATCHES = "
-            << GetNumberOfDataSets(output, selectInfoPatches_) << nl
-            << "  LAGRANGIAN = "
-            << GetNumberOfDataSets(output, selectInfoLagrangian_) << nl
-            << "  CELLZONE = "
-            << GetNumberOfDataSets(output, selectInfoCellZones_) << nl
-            << "  FACEZONE = "
-            << GetNumberOfDataSets(output, selectInfoFaceZones_) << nl
-            << "  POINTZONE = "
-            << GetNumberOfDataSets(output, selectInfoPointZones_) << nl
-            << "  CELLSET = "
-            << GetNumberOfDataSets(output, selectInfoCellSets_) << nl
-            << "  FACESET = "
-            << GetNumberOfDataSets(output, selectInfoFaceSets_) << nl
-            << "  POINTSET = "
-            << GetNumberOfDataSets(output, selectInfoPointSets_) << nl;
-
-        // traverse blocks:
-        cout<< "nBlocks = " << output->GetNumberOfBlocks() << "\n";
-        cout<< "done Update\n";
-        output->Print(cout);
-        cout<< " has " << output->GetNumberOfBlocks() << " blocks\n";
-        output->GetInformation()->Print(cout);
-
-        cout<<"ShouldIReleaseData :" << output->ShouldIReleaseData() << "\n";
-        printMemory();
-    }
-
     meshChanged_ = fieldsChanged_ = false;
 }
 
@@ -778,15 +798,11 @@ void Foam::vtkPV3Foam::addPatchNames(vtkRenderer* renderer)
         Info<< "<beg> Foam::vtkPV3Foam::addPatchNames" << endl;
     }
 
-    const polyBoundaryMesh& pbMesh = meshPtr_->boundaryMesh();
-
-    const selectionInfo& selector = selectInfoPatches_;
-
-    // the currently selected patches, strip off any suffix
+    // get the display patches, strip off any suffix
     const stringList selectedPatches = getSelectedArrayEntries
     (
         reader_->GetRegionSelection(),
-        selector,
+        selectInfoPatches_,
         true
     );
 
@@ -795,9 +811,15 @@ void Foam::vtkPV3Foam::addPatchNames(vtkRenderer* renderer)
         Info<<"... add patches: " << selectedPatches << endl;
     }
 
+    if (!selectedPatches.size())
+    {
+        return;
+    }
+
+    const polyBoundaryMesh& pbMesh = meshPtr_->boundaryMesh();
+
     // Find the total number of zones
     // Each zone will take the patch name
-
     // Number of zones per patch ... zero zones should be skipped
     labelList nZones(pbMesh.size(), 0);
 
@@ -948,7 +970,7 @@ void Foam::vtkPV3Foam::addPatchNames(vtkRenderer* renderer)
 
     if (debug)
     {
-        Info<< "<end> Foam::vtkPV3Foam::addPatchNames)" << endl;
+        Info<< "<end> Foam::vtkPV3Foam::addPatchNames" << endl;
     }
 }
 
@@ -965,7 +987,7 @@ void Foam::vtkPV3Foam::removePatchNames(vtkRenderer* renderer)
         renderer->RemoveViewProp(patchTextActorsPtrs_[patchI]);
         patchTextActorsPtrs_[patchI]->Delete();
     }
-    patchTextActorsPtrs_.setSize(0);
+    patchTextActorsPtrs_.clear();
 }
 
 
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H
index 0fbed64bfac..f78ba346b4b 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.H
@@ -38,6 +38,7 @@ SourceFiles
     vtkPV3FoamAddToSelection.H
     vtkPV3FoamAddVolumeMesh.C
     vtkPV3FoamAddZoneMesh.C
+    vtkPV3FoamConvertFields.C
     vtkPV3FoamConvertFaceField.H
     vtkPV3FoamConvertLagrangianFields.H
     vtkPV3FoamConvertMesh.C
@@ -46,7 +47,6 @@ SourceFiles
     vtkPV3FoamConvertPointFields.H
     vtkPV3FoamConvertVolFields.H
     vtkPV3FoamInsertNextPoint.H
-    vtkPV3FoamUpdate.C
     vtkPV3FoamUpdateInformation.C
     vtkPV3FoamUpdateInformationFields.H
 
@@ -111,17 +111,17 @@ public:
         //- bookkeeping for the GUI checklists and the multi-block organization
         class selectionInfo
         {
-            int block_;
             const char *name_;
+            int block_;
             int start_;
             int size_;
 
         public:
 
-            selectionInfo(const int blockNo, const char *name)
+            selectionInfo(const char *name, const int blockNo=0)
             :
-                block_(blockNo),
                 name_(name),
+                block_(blockNo),
                 start_(-1),
                 size_(0)
             {}
@@ -132,6 +132,13 @@ public:
                 return block_;
             }
 
+            int block(int blockNo)
+            {
+                int prev = block_;
+                block_ = blockNo;
+                return prev;
+            }
+
             const char* name() const
             {
                 return name_;
@@ -170,6 +177,15 @@ public:
             {
                 size_ += n;
             }
+
+            friend Ostream& operator<<(Ostream& os, const selectionInfo& s)
+            {
+                os  << "selector: " << s.name_
+                    << " (block " << s.block_ << ") "
+                    << " = " << s.start_ << " + " << s.size_;
+                return os;
+            }
+
         };
 
 
@@ -177,22 +193,6 @@ private:
 
     // Private data
 
-        //BTX
-        //- Indices for datasets in vtkMultiBlockDataSet
-        enum
-        {
-            VOLUME      = 0, // internal mesh
-            PATCHES     = 1, // patches
-            LAGRANGIAN  = 2,
-            CELLZONE    = 3,
-            FACEZONE    = 4,
-            POINTZONE   = 5,
-            CELLSET     = 6,
-            FACESET     = 7,
-            POINTSET    = 8
-        };
-        //ETX
-
         //- Access to the controlling vtkPV3FoamReader
         vtkPV3FoamReader* reader_;
 
@@ -270,7 +270,7 @@ private:
             const selectionInfo&,
             const label datasetNo,
             vtkDataSet* dataset,
-            const string& blockName = string::null
+            const string& blockName=string::null
         );
 
         // Convenience method use to convert the readers from VTK 5
@@ -322,7 +322,7 @@ private:
             (
                 vtkDataArraySelection *arraySelection,
                 const IOobjectList&,
-                const string& suffix = ""
+                const string& suffix=string::null
             );
 
             //- Field info
@@ -342,43 +342,43 @@ private:
             void updateFoamMesh();
 
             //- Volume fields
-            void updateVolFields(vtkMultiBlockDataSet* output);
+            void updateVolFields(vtkMultiBlockDataSet*);
 
             //- Point fields
-            void updatePointFields(vtkMultiBlockDataSet* output);
+            void updatePointFields(vtkMultiBlockDataSet*);
 
             //- Lagrangian fields
-            void updateLagrangianFields(vtkMultiBlockDataSet* output);
+            void updateLagrangianFields(vtkMultiBlockDataSet*);
 
 
         // Mesh conversion functions
 
             //- Volume mesh
-            void convertMeshVolume(vtkMultiBlockDataSet* output);
+            void convertMeshVolume(vtkMultiBlockDataSet*, int& blockNo);
 
             //- Lagrangian mesh
-            void convertMeshLagrangian(vtkMultiBlockDataSet* output);
+            void convertMeshLagrangian(vtkMultiBlockDataSet*, int& blockNo);
 
             //- Patch meshes
-            void convertMeshPatches(vtkMultiBlockDataSet* output);
+            void convertMeshPatches(vtkMultiBlockDataSet*, int& blockNo);
 
             //- Cell zone meshes
-            void convertMeshCellZones(vtkMultiBlockDataSet* output);
+            void convertMeshCellZones(vtkMultiBlockDataSet*, int& blockNo);
 
             //- Face zone meshes
-            void convertMeshFaceZones(vtkMultiBlockDataSet* output);
+            void convertMeshFaceZones(vtkMultiBlockDataSet*, int& blockNo);
 
             //- Point zone meshes
-            void convertMeshPointZones(vtkMultiBlockDataSet* output);
+            void convertMeshPointZones(vtkMultiBlockDataSet*, int& blockNo);
 
             //- Cell set meshes
-            void convertMeshCellSets(vtkMultiBlockDataSet* output);
+            void convertMeshCellSets(vtkMultiBlockDataSet*, int& blockNo);
 
             //- Face set meshes
-            void convertMeshFaceSets(vtkMultiBlockDataSet* output);
+            void convertMeshFaceSets(vtkMultiBlockDataSet*, int& blockNo);
 
             //- Point set meshes
-            void convertMeshPointSets(vtkMultiBlockDataSet* output);
+            void convertMeshPointSets(vtkMultiBlockDataSet*, int& blockNo);
 
 
         // Add mesh functions
@@ -444,6 +444,17 @@ private:
                 vtkPolyData*
             );
 
+        // Field conversion functions
+
+            //- Convert volume fields
+            void convertVolFields(vtkMultiBlockDataSet*);
+
+            //- Convert point fields
+            void convertPointFields(vtkMultiBlockDataSet*);
+
+            //- Convert Lagrangian fields
+            void convertLagrangianFields(vtkMultiBlockDataSet*);
+
 
         //- Add the fields in the selected time directory to the selection
         //  lists
@@ -452,7 +463,7 @@ private:
         (
             vtkDataArraySelection* fieldSelection,
             const IOobjectList& objects,
-            const string& suffix = string::null
+            const string& suffix=string::null
         );
 
 
@@ -578,7 +589,7 @@ private:
             static stringList getSelectedArrayEntries
             (
                 vtkDataArraySelection* arraySelection,
-                const bool firstWord = false
+                const bool firstWord=false
             );
 
             //- Store the current selection(s) for a sub-selection
@@ -586,7 +597,7 @@ private:
             (
                 vtkDataArraySelection* arraySelection,
                 const selectionInfo&,
-                const bool firstWord = false
+                const bool firstWord=false
             );
 
             //- Set selection(s)
@@ -631,7 +642,11 @@ public:
         //- Update
         void UpdateInformation();
 
-        void Update(vtkMultiBlockDataSet* output);
+        void Update
+        (
+            vtkMultiBlockDataSet* output,
+            vtkMultiBlockDataSet* lagrangianOutput
+        );
 
         //- Allocate and return a list of selected times
         //  returns the count via the parameter
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdate.C b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertFields.C
similarity index 75%
rename from applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdate.C
rename to applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertFields.C
index 8f4a83c43f3..543fc63eb0b 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdate.C
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertFields.C
@@ -43,63 +43,15 @@ Description
 #include "vtkPV3FoamConvertPointFields.H"
 #include "vtkPV3FoamConvertLagrangianFields.H"
 
-void Foam::vtkPV3Foam::updateFoamMesh()
-{
-    if (debug)
-    {
-        Info<< "<beg> Foam::vtkPV3Foam::updateFoamMesh" << endl;
-        printMemory();
-    }
-
-    if (!reader_->GetCacheMesh())
-    {
-        delete meshPtr_;
-        meshPtr_ = NULL;
-    }
 
-    // Check to see if the FOAM mesh has been created
-    if (!meshPtr_)
-    {
-        if (debug)
-        {
-            Info<< "Creating Foam mesh" << endl;
-        }
-        meshPtr_ = new fvMesh
-        (
-            IOobject
-            (
-                fvMesh::defaultRegion,
-                dbPtr_().timeName(),
-                dbPtr_()
-            )
-        );
-
-        meshChanged_ = true;
-    }
-    else
-    {
-        if (debug)
-        {
-            Info<< "Using existing Foam mesh" << endl;
-        }
-    }
-
-    if (debug)
-    {
-        Info<< "<end> Foam::vtkPV3Foam::updateFoamMesh" << endl;
-        printMemory();
-    }
-}
-
-
-void Foam::vtkPV3Foam::updateVolFields
+void Foam::vtkPV3Foam::convertVolFields
 (
     vtkMultiBlockDataSet* output
 )
 {
     if (debug)
     {
-        Info<< "<beg> Foam::vtkPV3Foam::updateVolFields" << endl;
+        Info<< "<beg> Foam::vtkPV3Foam::convertVolFields" << endl;
         printMemory();
     }
 
@@ -135,12 +87,7 @@ void Foam::vtkPV3Foam::updateVolFields
             )
         );
     }
-/*
-    convertVolFields<Foam::label>
-    (
-        mesh, pInterp, objects, arraySelection, output
-    );
-*/
+
     convertVolFields<Foam::scalar>
     (
         mesh, pInterp, ppInterpList, objects, arraySelection, output
@@ -164,20 +111,20 @@ void Foam::vtkPV3Foam::updateVolFields
 
     if (debug)
     {
-        Info<< "<end> Foam::vtkPV3Foam::updateVolFields" << endl;
+        Info<< "<end> Foam::vtkPV3Foam::convertVolFields" << endl;
         printMemory();
     }
 }
 
 
-void Foam::vtkPV3Foam::updatePointFields
+void Foam::vtkPV3Foam::convertPointFields
 (
     vtkMultiBlockDataSet* output
 )
 {
     if (debug)
     {
-        Info<< "<beg> Foam::vtkPV3Foam::updatePointFields" << endl;
+        Info<< "<beg> Foam::vtkPV3Foam::convertPointFields" << endl;
         printMemory();
     }
 
@@ -188,12 +135,6 @@ void Foam::vtkPV3Foam::updatePointFields
 
     vtkDataArraySelection* arraySelection = reader_->GetPointFieldSelection();
 
-/*
-    convertPointFields<Foam::label>
-    (
-        mesh, objects, arraySelection, output
-    );
-*/
     convertPointFields<Foam::scalar>
     (
         mesh, objects, arraySelection, output
@@ -217,20 +158,20 @@ void Foam::vtkPV3Foam::updatePointFields
 
     if (debug)
     {
-        Info<< "<end> Foam::vtkPV3Foam::updatePointFields" << endl;
+        Info<< "<end> Foam::vtkPV3Foam::convertPointFields" << endl;
         printMemory();
     }
 }
 
 
-void Foam::vtkPV3Foam::updateLagrangianFields
+void Foam::vtkPV3Foam::convertLagrangianFields
 (
     vtkMultiBlockDataSet* output
 )
 {
     if (debug)
     {
-        Info<< "<beg> Foam::vtkPV3Foam::updateLagrangianFields" << endl;
+        Info<< "<beg> Foam::vtkPV3Foam::convertLagrangianFields" << endl;
         printMemory();
     }
 
@@ -251,7 +192,8 @@ void Foam::vtkPV3Foam::updateLagrangianFields
     // Convert Lagrangian fields
     if (debug)
     {
-        Info<< "converting Foam Lagrangian fields" << endl;
+        Info<< "converting Lagrangian fields - "
+            << selectInfoLagrangian_ << endl;
     }
 
     convertLagrangianFields<Foam::label>
@@ -282,7 +224,7 @@ void Foam::vtkPV3Foam::updateLagrangianFields
 
     if (debug)
     {
-        Info<< "<end> Foam::vtkPV3Foam::updateLagrangianFields" << endl;
+        Info<< "<end> Foam::vtkPV3Foam::convertLagrangianFields" << endl;
         printMemory();
     }
 }
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertLagrangianFields.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertLagrangianFields.H
index 0ccc3f81a04..b77fadaa9d5 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertLagrangianFields.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertLagrangianFields.H
@@ -42,12 +42,6 @@ void Foam::vtkPV3Foam::convertLagrangianFields
 )
 {
     const selectionInfo& selector = selectInfoLagrangian_;
-    const label datasetId = 0;
-
-    if (!selector.size())
-    {
-        return;
-    }
 
     IOobjectList fieldObjects
     (
@@ -58,28 +52,46 @@ void Foam::vtkPV3Foam::convertLagrangianFields
     );
 
     label nFields = fieldSelection->GetNumberOfArrays();
-
     for (label i=0; i<nFields; i++)
     {
-        if (fieldSelection->GetArraySetting(i))
+        const word fieldName = fieldSelection->GetArrayName(i);
+
+        if
+        (
+            !fieldSelection->GetArraySetting(i)
+         || !fieldObjects.found(fieldName))
         {
-            const word fieldName = fieldSelection->GetArrayName(i);
+            continue;
+        }
 
-            if (fieldObjects.found(fieldName))
+        IOField<Type> iotf
+        (
+            IOobject
+            (
+                fieldName,
+                mesh.time().timeName(),
+                "lagrangian"/cloudName_,
+                mesh,
+                IOobject::MUST_READ
+            )
+        );
+
+
+        // Convert Lagrangian points
+        for
+        (
+            int regionId = selector.start();
+            regionId < selector.end();
+            ++regionId
+        )
+        {
+            if (selectedRegions_[regionId])
             {
-                IOField<Type> iotf
+                convertLagrangianField
                 (
-                    IOobject
-                    (
-                        fieldName,
-                        mesh.time().timeName(),
-                        "lagrangian"/cloudName_,
-                        mesh,
-                        IOobject::MUST_READ
-                    )
+                    iotf, output, selector,
+                    selectedRegionDatasetIds_[regionId]
                 );
-
-                convertLagrangianField(iotf, output, selector, datasetId);
             }
         }
     }
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertMesh.C b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertMesh.C
index 33b5891f046..acd0ed5f038 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertMesh.C
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertMesh.C
@@ -45,7 +45,8 @@ Description
 
 void Foam::vtkPV3Foam::convertMeshVolume
 (
-    vtkMultiBlockDataSet* output
+    vtkMultiBlockDataSet* output,
+    int& blockNo
 )
 {
     if (debug)
@@ -54,8 +55,12 @@ void Foam::vtkPV3Foam::convertMeshVolume
         printMemory();
     }
 
-    const selectionInfo& selector = selectInfoVolume_;
     const fvMesh& mesh = *meshPtr_;
+    selectionInfo& selector = selectInfoVolume_;
+
+    // set output block and note if anything was added
+    selector.block(blockNo);
+    bool created = false;
 
     // Create the internal mesh and add as dataset 0
     for
@@ -88,6 +93,13 @@ void Foam::vtkPV3Foam::convertMeshVolume
         AddToBlock(output, selector, datasetId, vtkmesh, "internalMesh");
         selectedRegionDatasetIds_[regionId] = datasetId;
         vtkmesh->Delete();
+
+        created = true;
+    }
+
+    if (created)
+    {
+        ++blockNo;
     }
 
     if (debug)
@@ -100,7 +112,8 @@ void Foam::vtkPV3Foam::convertMeshVolume
 
 void Foam::vtkPV3Foam::convertMeshLagrangian
 (
-    vtkMultiBlockDataSet* output
+    vtkMultiBlockDataSet* output,
+    int& blockNo
 )
 {
     if (debug)
@@ -109,10 +122,14 @@ void Foam::vtkPV3Foam::convertMeshLagrangian
         printMemory();
     }
 
-    const selectionInfo& selector = selectInfoLagrangian_;
     const fvMesh& mesh = *meshPtr_;
+    selectionInfo& selector = selectInfoLagrangian_;
+
+    // set output block and note if anything was added
+    selector.block(blockNo);
+    bool created = false;
 
-    // Create the Lagrangian mesh and add as dataset 0
+    // Create a single Lagrangian mesh and add as dataset 0
     for
     (
         int regionId = selector.start();
@@ -138,7 +155,15 @@ void Foam::vtkPV3Foam::convertMeshLagrangian
         AddToBlock(output, selector, datasetId, vtkmesh, cloudName_);
         selectedRegionDatasetIds_[regionId] = datasetId;
         vtkmesh->Delete();
+
+        created = true;
     }
+
+    if (created)
+    {
+        ++blockNo;
+    }
+
     if (debug)
     {
         Info<< "<end> Foam::vtkPV3Foam::convertMeshLagrangian" << endl;
@@ -149,7 +174,8 @@ void Foam::vtkPV3Foam::convertMeshLagrangian
 
 void Foam::vtkPV3Foam::convertMeshPatches
 (
-    vtkMultiBlockDataSet* output
+    vtkMultiBlockDataSet* output,
+    int& blockNo
 )
 {
     if (debug)
@@ -158,12 +184,16 @@ void Foam::vtkPV3Foam::convertMeshPatches
         printMemory();
     }
 
-    const selectionInfo& selector = selectInfoPatches_;
+    const fvMesh& mesh = *meshPtr_;
+    selectionInfo& selector = selectInfoPatches_;
     vtkDataArraySelection* arraySelection = reader_->GetRegionSelection();
 
+    // set output block and note if anything was added
+    selector.block(blockNo);
+    bool created = false;
+
     if (selector.size())
     {
-        const fvMesh& mesh = *meshPtr_;
         const polyBoundaryMesh& patches = mesh.boundaryMesh();
 
         // Create the patches and add as dataset ...
@@ -208,9 +238,18 @@ void Foam::vtkPV3Foam::convertMeshPatches
             );
             selectedRegionDatasetIds_[regionId] = datasetId;
             vtkmesh->Delete();
+
+            created = true;
         }
     }
 
+    if (created)
+    {
+        ++blockNo;
+    }
+
+
+
     if (debug)
     {
         Info<< "<end> Foam::vtkPV3Foam::convertMeshPatches" << endl;
@@ -221,7 +260,8 @@ void Foam::vtkPV3Foam::convertMeshPatches
 
 void Foam::vtkPV3Foam::convertMeshCellZones
 (
-    vtkMultiBlockDataSet* output
+    vtkMultiBlockDataSet* output,
+    int& blockNo
 )
 {
     if (debug)
@@ -230,8 +270,12 @@ void Foam::vtkPV3Foam::convertMeshCellZones
         printMemory();
     }
 
-    const selectionInfo& selector = selectInfoCellZones_;
     const fvMesh& mesh = *meshPtr_;
+    selectionInfo& selector = selectInfoCellZones_;
+
+    // set output block and note if anything was added
+    selector.block(blockNo);
+    bool created = false;
 
     // Create the cell zone(s) and add as DataSet(CELLZONE, 0..n)
     if (selector.size())
@@ -282,9 +326,16 @@ void Foam::vtkPV3Foam::convertMeshCellZones
             );
             selectedRegionDatasetIds_[regionId] = datasetId;
             vtkmesh->Delete();
+
+            created = true;
         }
     }
 
+    if (created)
+    {
+        ++blockNo;
+    }
+
     if (debug)
     {
         Info<< "<end> Foam::vtkPV3Foam::convertMeshCellZones" << endl;
@@ -295,7 +346,8 @@ void Foam::vtkPV3Foam::convertMeshCellZones
 
 void Foam::vtkPV3Foam::convertMeshCellSets
 (
-    vtkMultiBlockDataSet* output
+    vtkMultiBlockDataSet* output,
+    int& blockNo
 )
 {
     if (debug)
@@ -304,14 +356,17 @@ void Foam::vtkPV3Foam::convertMeshCellSets
         printMemory();
     }
 
-    const selectionInfo& selector = selectInfoCellSets_;
+    const fvMesh& mesh = *meshPtr_;
+    selectionInfo& selector = selectInfoCellSets_;
     vtkDataArraySelection* arraySelection = reader_->GetRegionSelection();
 
+    // set output block and note if anything was added
+    selector.block(blockNo);
+    bool created = false;
+
     // Create the cell sets and add as dataset
     if (selector.size())
     {
-        const fvMesh& mesh = *meshPtr_;
-
         for
         (
             int regionId = selector.start();
@@ -363,9 +418,16 @@ void Foam::vtkPV3Foam::convertMeshCellSets
             );
             selectedRegionDatasetIds_[regionId] = datasetId;
             vtkmesh->Delete();
+
+            created = true;
         }
     }
 
+    if (created)
+    {
+        ++blockNo;
+    }
+
     if (debug)
     {
         Info<< "<end> Foam::vtkPV3Foam::convertMeshCellSets" << endl;
@@ -376,7 +438,8 @@ void Foam::vtkPV3Foam::convertMeshCellSets
 
 void Foam::vtkPV3Foam::convertMeshFaceZones
 (
-    vtkMultiBlockDataSet* output
+    vtkMultiBlockDataSet* output,
+    int& blockNo
 )
 {
     if (debug)
@@ -385,8 +448,12 @@ void Foam::vtkPV3Foam::convertMeshFaceZones
         printMemory();
     }
 
-    const selectionInfo& selector = selectInfoFaceZones_;
     const fvMesh& mesh = *meshPtr_;
+    selectionInfo& selector = selectInfoFaceZones_;
+
+    // set output block and note if anything was added
+    selector.block(blockNo);
+    bool created = false;
 
     // Create the cell zone(s) and add as datasets
     if (selector.size())
@@ -427,9 +494,17 @@ void Foam::vtkPV3Foam::convertMeshFaceZones
             );
             selectedRegionDatasetIds_[regionId] = datasetId;
             vtkmesh->Delete();
+
+            created = true;
         }
     }
 
+
+    if (created)
+    {
+        ++blockNo;
+    }
+
     if (debug)
     {
         Info<< "<end> Foam::vtkPV3Foam::convertMeshFaceZones" << endl;
@@ -440,7 +515,8 @@ void Foam::vtkPV3Foam::convertMeshFaceZones
 
 void Foam::vtkPV3Foam::convertMeshFaceSets
 (
-    vtkMultiBlockDataSet* output
+    vtkMultiBlockDataSet* output,
+    int& blockNo
 )
 {
     if (debug)
@@ -449,14 +525,17 @@ void Foam::vtkPV3Foam::convertMeshFaceSets
         printMemory();
     }
 
-    const selectionInfo& selector = selectInfoFaceSets_;
+    const fvMesh& mesh = *meshPtr_;
+    selectionInfo& selector = selectInfoFaceSets_;
     vtkDataArraySelection* arraySelection = reader_->GetRegionSelection();
 
+    // set output block and note if anything was added
+    selector.block(blockNo);
+    bool created = false;
+
     // Create the face sets and add as dataset
     if (selector.size())
     {
-        const fvMesh& mesh = *meshPtr_;
-
         for
         (
             int regionId = selector.start();
@@ -499,9 +578,16 @@ void Foam::vtkPV3Foam::convertMeshFaceSets
             );
             selectedRegionDatasetIds_[regionId] = datasetId;
             vtkmesh->Delete();
+
+            created = true;
         }
     }
 
+    if (created)
+    {
+        ++blockNo;
+    }
+
     if (debug)
     {
         Info<< "<end> Foam::vtkPV3Foam::convertMeshFaceSets" << endl;
@@ -512,7 +598,8 @@ void Foam::vtkPV3Foam::convertMeshFaceSets
 
 void Foam::vtkPV3Foam::convertMeshPointZones
 (
-    vtkMultiBlockDataSet* output
+    vtkMultiBlockDataSet* output,
+    int& blockNo
 )
 {
     if (debug)
@@ -521,8 +608,12 @@ void Foam::vtkPV3Foam::convertMeshPointZones
         printMemory();
     }
 
-    const selectionInfo& selector = selectInfoPointZones_;
     const fvMesh& mesh = *meshPtr_;
+    selectionInfo& selector = selectInfoPointZones_;
+
+    // set output block and note if anything was added
+    selector.block(blockNo);
+    bool created = false;
 
     // Create the point sets and add as dataset
     if (selector.size())
@@ -563,9 +654,17 @@ void Foam::vtkPV3Foam::convertMeshPointZones
             );
             selectedRegionDatasetIds_[regionId] = datasetId;
             vtkmesh->Delete();
+
+            created = true;
         }
     }
 
+    if (created)
+    {
+        ++blockNo;
+    }
+
+
     if (debug)
     {
         Info<< "<end> Foam::vtkPV3Foam::convertMeshPointZones" << endl;
@@ -577,7 +676,8 @@ void Foam::vtkPV3Foam::convertMeshPointZones
 
 void Foam::vtkPV3Foam::convertMeshPointSets
 (
-    vtkMultiBlockDataSet* output
+    vtkMultiBlockDataSet* output,
+    int& blockNo
 )
 {
     if (debug)
@@ -586,14 +686,17 @@ void Foam::vtkPV3Foam::convertMeshPointSets
         printMemory();
     }
 
-    const selectionInfo& selector = selectInfoPointSets_;
+    const fvMesh& mesh = *meshPtr_;
+    selectionInfo& selector = selectInfoPointSets_;
     vtkDataArraySelection* arraySelection = reader_->GetRegionSelection();
 
+    // set output block and note if anything was added
+    selector.block(blockNo);
+    bool created = false;
+
     // Create the point sets and add as dataset
     if (selector.size())
     {
-        const fvMesh& mesh = *meshPtr_;
-
         for
         (
             int regionId = selector.start();
@@ -636,9 +739,16 @@ void Foam::vtkPV3Foam::convertMeshPointSets
             );
             selectedRegionDatasetIds_[regionId] = datasetId;
             vtkmesh->Delete();
+
+            created = true;
         }
     }
 
+    if (created)
+    {
+        ++blockNo;
+    }
+
     if (debug)
     {
         Info<< "<end> Foam::vtkPV3Foam::convertMeshPointSets" << endl;
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertPointFields.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertPointFields.H
index d26a0eb3658..dbbe22d6637 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertPointFields.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertPointFields.H
@@ -52,81 +52,93 @@ void Foam::vtkPV3Foam::convertPointFields
         )
     );
 
-    label nSelectedFields = fieldSelection->GetNumberOfArrays();
+    label nFields = fieldSelection->GetNumberOfArrays();
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
 
-    for (label i=0; i<nSelectedFields; i++)
+    for (label i=0; i<nFields; i++)
     {
-        if (fieldSelection->GetArraySetting(i))
+        const word fieldName = fieldSelection->GetArrayName(i);
+
+        if
+        (
+            !fieldSelection->GetArraySetting(i)
+         || !fieldObjects.found(fieldName))
         {
-            word fieldName = fieldSelection->GetArrayName(i);
+            continue;
+        }
 
-            if (fieldObjects.found(fieldName))
-            {
+        if (debug)
+        {
+            Info<< "Foam::vtkPV3Foam::convertPointFields : "
+                << fieldName << endl;
+        }
 
-                if (debug)
-                {
-                    Info<< "Foam::vtkPV3Foam::convertPointFields : " << fieldName
-                        << endl;
-                }
+        pointMesh pMesh(mesh);
 
-                pointMesh pMesh(mesh);
+        GeometricField<Type, pointPatchField, pointMesh> ptf
+        (
+            IOobject
+            (
+                fieldName,
+                mesh.time().timeName(),
+                mesh,
+                IOobject::MUST_READ
+            ),
+            pMesh
+        );
+
+
+        //
+        // Convert internal mesh - if activated
+        //
+        for
+        (
+            int regionId = selectInfoVolume_.start();
+            regionId < selectInfoVolume_.end();
+            ++regionId
+        )
+        {
+            const label datasetId = selectedRegionDatasetIds_[regionId];
 
-                GeometricField<Type, pointPatchField, pointMesh> ptf
-                (
-                    IOobject
-                    (
-                        fieldName,
-                        mesh.time().timeName(),
-                        mesh,
-                        IOobject::MUST_READ
-                    ),
-                    pMesh
-                );
-
-                // Convert internal mesh
-                for
-                (
-                    int regionId = selectInfoVolume_.start();
-                    regionId < selectInfoVolume_.end();
-                    ++regionId
-                )
-                {
-                    if (selectedRegions_[regionId])
-                    {
-                        convertPointField
-                        (
-                            ptf,
-                            GeometricField<Type, fvPatchField, volMesh>::null(),
-                            output,
-                            selectInfoVolume_,
-                            selectedRegionDatasetIds_[regionId]
-                        );
-                    }
-                }
+            if (!selectedRegions_[regionId] || datasetId < 0)
+            {
+                continue;
+            }
+
+            convertPointField
+            (
+                ptf,
+                GeometricField<Type, fvPatchField, volMesh>::null(),
+                output,
+                selectInfoVolume_,
+                datasetId
+            );
+        }
 
 
-                // Convert patches
-                label regionId = selectInfoPatches_.start();
-                forAll (patches, patchI)
+        //
+        // Convert patches - if activated
+        //
+        label regionId = selectInfoPatches_.start();
+        forAll (patches, patchI)
+        {
+            if (patches[patchI].size())
+            {
+                const label datasetId = selectedRegionDatasetIds_[regionId];
+
+                if (selectedRegions_[regionId] && datasetId >= 0)
                 {
-                    if (patches[patchI].size())
-                    {
-                        if (selectedRegions_[regionId])
-                        {
-                            convertPatchPointField
-                            (
-                                fieldName,
-                                ptf.boundaryField()[patchI]
-                                   .patchInternalField()(),
-                                output,
-                                selectInfoPatches_,
-                                selectedRegionDatasetIds_[regionId]
-                            );
-                        }
-                        regionId++;
-                    }
+
+                    convertPatchPointField
+                    (
+                        fieldName,
+                        ptf.boundaryField()[patchI].patchInternalField()(),
+                        output,
+                        selectInfoPatches_,
+                        datasetId
+                    );
                 }
+                regionId++;
             }
         }
     }
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertVolFields.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertVolFields.H
index 7543f58c9c9..7ed194bfa5b 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertVolFields.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamConvertVolFields.H
@@ -78,8 +78,7 @@ void Foam::vtkPV3Foam::convertVolFields
 
         if (debug)
         {
-            Info<< "converting Foam volume field: " << fieldName
-                << endl;
+            Info<< "converting volume field: " << fieldName << endl;
         }
 
         GeometricField<Type, fvPatchField, volMesh> tf
@@ -99,7 +98,10 @@ void Foam::vtkPV3Foam::convertVolFields
             pInterp.interpolate(tf)
         );
 
-        // Convert internal mesh
+
+        //
+        // Convert internal mesh - if activated
+        //
         for
         (
             int regionId = selectInfoVolume_.start();
@@ -107,29 +109,34 @@ void Foam::vtkPV3Foam::convertVolFields
             ++regionId
         )
         {
-            if (selectedRegions_[regionId])
+            const label datasetId = selectedRegionDatasetIds_[regionId];
+
+            if (!selectedRegions_[regionId] || datasetId < 0)
             {
-                convertVolField
-                (
-                    tf,
-                    output,
-                    selectInfoVolume_,
-                    selectedRegionDatasetIds_[regionId],
-                    superCells_
-                );
-                convertPointField
-                (
-                    tptf(),
-                    tf,
-                    output,
-                    selectInfoVolume_,
-                    selectedRegionDatasetIds_[regionId]
-                );
+                continue;
             }
-        }
 
+            convertVolField
+            (
+                tf,
+                output,
+                selectInfoVolume_,
+                datasetId,
+                superCells_
+            );
+            convertPointField
+            (
+                tptf(),
+                tf,
+                output,
+                selectInfoVolume_,
+                datasetId
+            );
+        }
 
-        // Convert patches
+        //
+        // Convert patches - if activated
+        //
         for
         (
             int regionId = selectInfoPatches_.start();
@@ -137,7 +144,9 @@ void Foam::vtkPV3Foam::convertVolFields
             ++regionId
         )
         {
-            if (!selectedRegions_[regionId])
+            const label datasetId = selectedRegionDatasetIds_[regionId];
+
+            if (!selectedRegions_[regionId] || datasetId < 0)
             {
                 continue;
             }
@@ -176,7 +185,7 @@ void Foam::vtkPV3Foam::convertVolFields
                     fvPatchField<Type>(p, tf).patchInternalField()(),
                     output,
                     selectInfoPatches_,
-                    selectedRegionDatasetIds_[regionId]
+                    datasetId
                 );
             }
             else
@@ -187,7 +196,7 @@ void Foam::vtkPV3Foam::convertVolFields
                     ptf,
                     output,
                     selectInfoPatches_,
-                    selectedRegionDatasetIds_[regionId]
+                    datasetId
                 );
             }
 
@@ -197,11 +206,13 @@ void Foam::vtkPV3Foam::convertVolFields
                 ppInterpList[patchId].faceToPointInterpolate(ptf)(),
                 output,
                 selectInfoPatches_,
-                selectedRegionDatasetIds_[regionId]
+                datasetId
             );
         }
 
-        // Convert cell zones
+        //
+        // Convert cell zones - if activated
+        //
         for
         (
             int regionId = selectInfoCellZones_.start();
@@ -209,37 +220,35 @@ void Foam::vtkPV3Foam::convertVolFields
             ++regionId
         )
         {
-            if (!selectedRegions_[regionId])
+            const label datasetId = selectedRegionDatasetIds_[regionId];
+
+            if (!selectedRegions_[regionId] || datasetId < 0)
             {
                 continue;
             }
 
             if (debug)
             {
-
-                word selectName = getFirstWord
-                (
-                    arraySelector->GetArrayName(regionId)
-                );
-
-                Info<< "wish to convert cellzone: " << selectName
+                Info<< "wish to convert cellzone: "
+                    << getFirstWord(arraySelector->GetArrayName(regionId))
                     << " regionId: " << regionId
                     << " volume field: " << fieldName
                     << endl;
             }
 
-            const label datasetId =
-                selectedRegionDatasetIds_[regionId];
-
             convertVolField
             (
                 tf,
-                output, selectInfoCellZones_, datasetId,
+                output,
+                selectInfoCellZones_,
+                datasetId,
                 zoneSuperCells_[datasetId]
             );
         }
 
-        // Convert cell sets
+        //
+        // Convert cell sets - if activated
+        //
         for
         (
             int regionId = selectInfoCellSets_.start();
@@ -247,36 +256,35 @@ void Foam::vtkPV3Foam::convertVolFields
             ++regionId
         )
         {
-            if (!selectedRegions_[regionId])
+            const label datasetId = selectedRegionDatasetIds_[regionId];
+
+            if (!selectedRegions_[regionId] || datasetId < 0)
             {
                 continue;
             }
 
             if (debug)
             {
-                word selectName = getFirstWord
-                (
-                    arraySelector->GetArrayName(regionId)
-                );
-
-                Info<< "wish to convert cellset: " << selectName
+                Info<< "wish to convert cellset: "
+                    << getFirstWord(arraySelector->GetArrayName(regionId))
                     << " regionId: " << regionId
                     << " volume field: " << fieldName
                     << endl;
             }
 
-            const label datasetId =
-                selectedRegionDatasetIds_[regionId];
-
             convertVolField
             (
                 tf,
-                output, selectInfoCellSets_, datasetId,
+                output,
+                selectInfoCellSets_,
+                datasetId,
                 csetSuperCells_[datasetId]
             );
         }
 
-        // Convert face zones
+        //
+        // Convert face zones - if activated
+        //
         for
         (
             int regionId = selectInfoFaceZones_.start();
@@ -284,19 +292,17 @@ void Foam::vtkPV3Foam::convertVolFields
             ++regionId
         )
         {
-            if (!selectedRegions_[regionId])
+            const label datasetId = selectedRegionDatasetIds_[regionId];
+
+            if (!selectedRegions_[regionId] || datasetId < 0)
             {
                 continue;
             }
 
             if (debug)
             {
-                word selectName = getFirstWord
-                (
-                    arraySelector->GetArrayName(regionId)
-                );
-
-                Info<< "wish to convert facezone: " << selectName
+                Info<< "wish to convert facezone: "
+                    << getFirstWord(arraySelector->GetArrayName(regionId))
                     << " regionId: " << regionId
                     << " volume field: " << fieldName
                     << endl;
@@ -305,19 +311,20 @@ void Foam::vtkPV3Foam::convertVolFields
             const faceZoneMesh& fzMesh = mesh.faceZones();
             const label zoneI = regionId - selectInfoFaceZones_.start();
 
-            const label datasetId =
-                selectedRegionDatasetIds_[regionId];
-
             convertFaceField
             (
                 tf,
-                output, selectInfoFaceZones_, datasetId,
+                output,
+                selectInfoFaceZones_,
+                datasetId,
                 mesh,
                 fzMesh[zoneI]
             );
         }
 
-        // Convert face sets
+        //
+        // Convert face sets - if activated
+        //
         for
         (
             int regionId = selectInfoFaceSets_.start();
@@ -325,7 +332,9 @@ void Foam::vtkPV3Foam::convertVolFields
             ++regionId
         )
         {
-            if (!selectedRegions_[regionId])
+            const label datasetId = selectedRegionDatasetIds_[regionId];
+
+            if (!selectedRegions_[regionId] || datasetId < 0)
             {
                 continue;
             }
@@ -345,13 +354,13 @@ void Foam::vtkPV3Foam::convertVolFields
 
             const faceSet fSet(mesh, selectName);
 
-            const label datasetId =
-                selectedRegionDatasetIds_[regionId];
 
             convertFaceField
             (
                 tf,
-                output, selectInfoFaceSets_, datasetId,
+                output,
+                selectInfoFaceSets_,
+                datasetId,
                 mesh,
                 fSet
             );
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInformation.C b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInformation.C
index 031d8aad58d..3f18047ced0 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInformation.C
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInformation.C
@@ -432,11 +432,13 @@ void Foam::vtkPV3Foam::updateInformationLagrangianFields()
     vtkDataArraySelection *arraySelection =
         reader_->GetLagrangianFieldSelection();
 
-    // preserve the currently selected values
-    const stringList selectedEntries = getSelectedArrayEntries
+    // preserve the enabled selections
+    stringList selectedEntries = getSelectedArrayEntries
     (
-        arraySelection
+        arraySelection,
+        true
     );
+
     arraySelection->RemoveAllArrays();
 
     // TODO - currently hard-coded to ONE cloud
@@ -478,7 +480,7 @@ void Foam::vtkPV3Foam::updateInformationLagrangianFields()
         objects
     );
 
-    // restore the currently enabled values
+    // restore the enabled selections
     setSelectedArrayEntries
     (
         arraySelection,
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInformationFields.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInformationFields.H
index b9d7df9fa55..601a7f5326d 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInformationFields.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamUpdateInformationFields.H
@@ -53,7 +53,7 @@ void Foam::vtkPV3Foam::updateInformationFields
     }
     else
     {
-        // preserve the currently selected values
+        // preserve the enabled selections
         selectedEntries = getSelectedArrayEntries
         (
             arraySelection
@@ -67,13 +67,6 @@ void Foam::vtkPV3Foam::updateInformationFields
     // Populate the GUI volume/point field arrays
 
     //- Add volume fields to GUI
-/*
-    addToSelection<GeometricField<label, patchType, meshType> >
-    (
-        arraySelection,
-        objects
-    );
-*/
     addToSelection<GeometricField<scalar, patchType, meshType> >
     (
         arraySelection,
@@ -100,7 +93,7 @@ void Foam::vtkPV3Foam::updateInformationFields
         objects
     );
 
-    // restore the currently enabled values
+    // restore the enabled selections
     setSelectedArrayEntries
     (
         arraySelection,
-- 
GitLab