diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/PVFoamReader_SM.xml b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/PVFoamReader_SM.xml
index e88e13b61d..7daa151df4 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/PVFoamReader_SM.xml
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/PVFoamReader_SM.xml
@@ -27,6 +27,8 @@
+
+
Rescan for updated times/fields.
-
-
- Search the polyMesh/sets/ directory
+ Search the polyMesh/sets/ directory for {cell,face,point} sets
- ZoneMesh information is used to find {cell,face,point}Zones.
+ ZoneMesh information is used to find {cell,face,point} zones.
The polyMesh/ directory is only checked on startup.
@@ -88,7 +90,7 @@
panel_visibility="default">
- Show patchGroups only.
+ Display patchGroups only instead of individual patches.
@@ -109,6 +111,7 @@
-
+
-
+
-
+
+
+
+
+
- Cache the fvMesh in memory.
+ Mesh caching styles.
+ Caching the OpenFOAM fvMesh reduces disk access.
+ Caching the VTK mesh reduces transcription overhead.
@@ -185,7 +195,7 @@
-
+
diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.cxx b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.cxx
index f501599397..3cc3b19577 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.cxx
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.cxx
@@ -26,6 +26,7 @@ License
#include "pqFoamReaderControls.h"
#include
+#include
#include
#include
#include
@@ -42,6 +43,17 @@ License
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+// file-scope
+// Add horizontal divider to layout
+static void addHline(QGridLayout* layout, int row, int nCols)
+{
+ QFrame* hline = new QFrame(layout->parentWidget());
+ hline->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+
+ layout->addWidget(hline, row, 0, 1, nCols);
+}
+
+
// file-scope
// Widget properties
static QWidget* setWidgetProperties
@@ -94,6 +106,66 @@ static QAbstractButton* setButtonProperties
}
+// file-scope
+// Fill combo-box from XML enumeration
+static QComboBox* setComboBoxContent
+(
+ QComboBox* b,
+ vtkSMIntVectorProperty* prop
+)
+{
+ vtkSMEnumerationDomain* propEnum =
+ vtkSMEnumerationDomain::SafeDownCast
+ (
+ prop->FindDomain("vtkSMEnumerationDomain")
+ );
+
+ if (propEnum)
+ {
+ unsigned int n = propEnum->GetNumberOfEntries();
+ for (unsigned int idx=0; idx < n; ++idx)
+ {
+ const int val = propEnum->GetEntryValue(idx);
+ const char* txt = propEnum->GetEntryText(idx);
+
+ b->insertItem(val, txt);
+ }
+
+ // Set default
+ const int val = prop->GetElement(0);
+ unsigned int idx = 0;
+ if (!propEnum->IsInDomain(val, idx))
+ {
+ idx = 0;
+ }
+ b->setCurrentIndex(idx);
+ }
+
+ return b;
+}
+
+
+// file-scope
+// Translate a combo-box index to a lookup value
+static int comboBoxValue(vtkSMIntVectorProperty* prop, int idx)
+{
+ vtkSMEnumerationDomain* propEnum =
+ vtkSMEnumerationDomain::SafeDownCast
+ (
+ prop->FindDomain("vtkSMEnumerationDomain")
+ );
+
+ if (propEnum)
+ {
+ return propEnum->GetEntryValue(idx);
+ }
+ else
+ {
+ return idx;
+ }
+}
+
+
static vtkSMIntVectorProperty* lookupIntProp
(
vtkSMPropertyGroup* group,
@@ -154,9 +226,9 @@ void pqFoamReaderControls::refreshPressed()
}
-void pqFoamReaderControls::cacheMesh(int val)
+void pqFoamReaderControls::cacheMesh(int idx)
{
- fireCommand(cacheMesh_, val);
+ fireCommand(meshCaching_, comboBoxValue(meshCaching_, idx));
}
@@ -210,12 +282,14 @@ pqFoamReaderControls::pqFoamReaderControls
showGroupsOnly_(lookupIntProp(group, "ShowGroupsOnly")),
includeSets_(lookupIntProp(group, "IncludeSets")),
includeZones_(lookupIntProp(group, "IncludeZones")),
- cacheMesh_(lookupIntProp(group, "CacheMesh"))
+ meshCaching_(lookupIntProp(group, "MeshCaching"))
{
typedef vtkSMIntVectorProperty intProp;
QGridLayout* form = new QGridLayout(this);
+ const int nCols = 3;
+
// ROW
// ~~~
int row = 0;
@@ -243,13 +317,7 @@ pqFoamReaderControls::pqFoamReaderControls
}
// LINE
- // ~~~~
- ++row;
- {
- QFrame* hline = new QFrame(this);
- hline->setFrameStyle(QFrame::HLine | QFrame::Sunken);
- form->addWidget(hline, row, 0, 1, 4);
- }
+ addHline(form, ++row, nCols);
// ROW
// ~~~
@@ -321,13 +389,7 @@ pqFoamReaderControls::pqFoamReaderControls
}
// LINE
- // ~~~~
- ++row;
- {
- QFrame* hline = new QFrame(this);
- hline->setFrameStyle(QFrame::HLine | QFrame::Sunken);
- form->addWidget(hline, row, 0, 1, 4);
- }
+ addHline(form, ++row, nCols);
// ROW
// ~~~
@@ -360,13 +422,7 @@ pqFoamReaderControls::pqFoamReaderControls
}
// LINE
- // ~~~~
- ++row;
- {
- QFrame* hline = new QFrame(this);
- hline->setFrameStyle(QFrame::HLine | QFrame::Sunken);
- form->addWidget(hline, row, 0, 1, 4);
- }
+ addHline(form, ++row, nCols);
// ROW
// ~~~
@@ -398,14 +454,22 @@ pqFoamReaderControls::pqFoamReaderControls
);
}
- if (cacheMesh_)
+ if (meshCaching_)
{
- QCheckBox* b = new QCheckBox(this);
- setButtonProperties(b, cacheMesh_);
+ QComboBox* b = new QComboBox(this);
form->addWidget(b, row, 2, Qt::AlignLeft);
+
+ setWidgetProperties(b, meshCaching_);
+ setComboBoxContent(b, meshCaching_);
+
+ addPropertyLink
+ (
+ b, "indexChanged", SIGNAL(currentIndexChanged(int)), meshCaching_
+ );
+
connect
(
- b, SIGNAL(toggled(bool)), this, SLOT(cacheMesh(bool))
+ b, SIGNAL(currentIndexChanged(int)), this, SLOT(cacheMesh(int))
);
}
}
diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.h b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.h
index d8656d894b..ba0a7a9f67 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.h
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/pqFoamReaderControls.h
@@ -69,8 +69,8 @@ class pqFoamReaderControls
//- IncludeZones (bool property)
vtkSMIntVectorProperty* includeZones_;
- //- CacheMesh (bool property)
- vtkSMIntVectorProperty* cacheMesh_;
+ //- MeshCaching (enum property)
+ vtkSMIntVectorProperty* meshCaching_;
// Private Member Functions
@@ -102,7 +102,7 @@ protected slots:
// Protected Member Functions
void refreshPressed();
- void cacheMesh(bool checked);
+ void cacheMesh(int idx);
void showPatchNames(bool checked);
void showGroupsOnly(bool checked);
void includeSets(bool checked);
diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.cxx b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.cxx
index 7da8452e31..c6ec1e676c 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.cxx
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.cxx
@@ -69,8 +69,7 @@ vtkPVFoamReader::vtkPVFoamReader()
// Add second output for the Lagrangian
this->SetNumberOfOutputPorts(2);
- vtkSmartPointer lagrangian =
- vtkSmartPointer::New();
+ auto lagrangian = vtkSmartPointer::New();
lagrangian->ReleaseData();
@@ -80,7 +79,7 @@ vtkPVFoamReader::vtkPVFoamReader()
TimeStepRange[0] = 0;
TimeStepRange[1] = 0;
- CacheMesh = true;
+ MeshCaching = 3; // fvMesh+vtk
SkipZeroTime = true;
ExtrapolatePatches = false;
diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.h b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.h
index be9d1db3f7..550c1167bb 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.h
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/PVFoamReader/vtkPVFoamReader.h
@@ -83,9 +83,9 @@ public:
virtual void PrintInfo();
// Description:
- // OpenFOAM mesh caching control
- vtkSetMacro(CacheMesh, bool);
- vtkGetMacro(CacheMesh, bool);
+ // Mesh caching control (0:none,1:fvMesh,3:fvMesh+vtk)
+ vtkSetMacro(MeshCaching, int);
+ vtkGetMacro(MeshCaching, int);
// Description:
// OpenFOAM refresh times/fields
@@ -232,7 +232,7 @@ private:
void updatePatchNamesView(const bool show);
int TimeStepRange[2];
- bool CacheMesh;
+ int MeshCaching;
bool SkipZeroTime;
bool ExtrapolatePatches;
diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C
index c2b9793dc1..67857bc0bf 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C
@@ -136,12 +136,12 @@ bool Foam::vtkPVFoam::addOutputBlock
if (selectedPartIds_.found(partId))
{
const auto& longName = selectedPartIds_[partId];
- const word shortName = getPartName(partId);
+ const word shortName = getFoamName(longName);
auto iter = cache.find(longName);
- if (iter.found() && (*iter).vtkmesh)
+ if (iter.found() && iter.object().dataset)
{
- auto dataset = (*iter).vtkmesh;
+ auto dataset = iter.object().dataset;
if (singleDataset)
{
@@ -224,7 +224,6 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
runTime.setTime(Times[nearestIndex], nearestIndex);
// When the changes, so do the fields
- fieldsChanged_ = true;
meshState_ = meshPtr_ ? meshPtr_->readUpdate() : polyMesh::TOPO_CHANGE;
reader_->UpdateProgress(0.05);
@@ -238,27 +237,13 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
Info<< " setTime() - selectedTime="
<< Times[nearestIndex].name() << " index=" << timeIndex_
<< "/" << Times.size()
- << " meshUpdateState=" << updateStateName(meshState_)
- << " fieldsChanged=" << Switch(fieldsChanged_) << endl;
+ << " meshUpdateState=" << updateStateName(meshState_) << endl;
}
return nearestIndex;
}
-Foam::word Foam::vtkPVFoam::getPartName(const int partId) const
-{
- if (selectedPartIds_.found(partId))
- {
- return getFoamName(selectedPartIds_[partId]);
- }
- else
- {
- return word::null;
- }
-}
-
-
Foam::word Foam::vtkPVFoam::getReaderPartName(const int partId) const
{
return getFoamName(reader_->GetPartArrayName(partId));
@@ -279,8 +264,8 @@ Foam::vtkPVFoam::vtkPVFoam
meshRegion_(polyMesh::defaultRegion),
meshDir_(polyMesh::meshSubDir),
timeIndex_(-1),
+ decomposePoly_(false),
meshState_(polyMesh::TOPO_CHANGE),
- fieldsChanged_(true),
rangeVolume_("unzoned"),
rangePatches_("patch"),
rangeLagrangian_("lagrangian"),
@@ -414,16 +399,16 @@ void Foam::vtkPVFoam::updateInfo()
// time of the vtkDataArraySelection, but the qt/paraview proxy
// layer doesn't care about that anyhow.
- HashSet enabledEntries;
+ HashSet enabled;
if (!partSelection->GetNumberOfArrays() && !meshPtr_)
{
- // enable 'internalMesh' on the first call
- enabledEntries = { "internalMesh" };
+ // Fake enable 'internalMesh' on the first call
+ enabled = { "internalMesh" };
}
else
{
// preserve the enabled selections
- enabledEntries = getSelectedArrayEntries(partSelection);
+ enabled = getSelectedArraySet(partSelection);
}
// Clear current mesh parts list
@@ -431,18 +416,13 @@ void Foam::vtkPVFoam::updateInfo()
// Update mesh parts list - add Lagrangian at the bottom
updateInfoInternalMesh(partSelection);
- updateInfoPatches(partSelection, enabledEntries);
+ updateInfoPatches(partSelection, enabled);
updateInfoSets(partSelection);
updateInfoZones(partSelection);
updateInfoLagrangian(partSelection);
// Adjust/restore the enabled selections
- setSelectedArrayEntries(partSelection, enabledEntries);
-
- if (meshState_ != polyMesh::UNCHANGED)
- {
- fieldsChanged_ = true;
- }
+ setSelectedArrayEntries(partSelection, enabled);
// Update volume, point and lagrangian fields
updateInfoFields
@@ -480,42 +460,28 @@ void Foam::vtkPVFoam::Update
}
reader_->UpdateProgress(0.1);
+ const int caching = reader_->GetMeshCaching();
+ const bool oldDecomp = decomposePoly_;
+ decomposePoly_ = !reader_->GetUseVTKPolyhedron();
+
// Set up mesh parts selection(s)
+ // Update cached, saved, unneed values.
{
vtkDataArraySelection* selection = reader_->GetPartSelection();
const int n = selection->GetNumberOfArrays();
- // All previously selected (enabled) names
- HashSet original;
- forAllConstIters(selectedPartIds_, iter)
- {
- original.insert(iter.object());
- }
-
selectedPartIds_.clear();
+ HashSet nowActive;
for (int id=0; id < n; ++id)
{
- string str(selection->GetArrayName(id));
- bool status = selection->GetArraySetting(id);
+ const string str(selection->GetArrayName(id));
+ const bool status = selection->GetArraySetting(id);
if (status)
{
selectedPartIds_.set(id, str); // id -> name
-
- if (!original.erase(str))
- {
- // New part, or newly enabled
- //? meshChanged_ = true;
- }
- }
- else
- {
- if (original.erase(str))
- {
- // Part disappeared, or newly disabled
- //? meshChanged_ = true;
- }
+ nowActive.set(str);
}
if (debug > 1)
@@ -524,6 +490,39 @@ void Foam::vtkPVFoam::Update
<< " : " << str << nl;
}
}
+
+ // Dispose of unneeded components
+ cachedVtp_.retain(nowActive);
+ cachedVtu_.retain(nowActive);
+
+ if
+ (
+ !caching
+ || meshState_ == polyMesh::TOPO_CHANGE
+ || meshState_ == polyMesh::TOPO_PATCH_CHANGE
+ )
+ {
+ // Eliminate cached values that would be unreliable
+ forAllIters(cachedVtp_, iter)
+ {
+ iter.object().clearGeom();
+ iter.object().clear();
+ }
+ forAllIters(cachedVtu_, iter)
+ {
+ iter.object().clearGeom();
+ iter.object().clear();
+ }
+ }
+ else if (oldDecomp != decomposePoly_)
+ {
+ // poly-decompose changed - dispose of cached values
+ forAllIters(cachedVtu_, iter)
+ {
+ iter.object().clearGeom();
+ iter.object().clear();
+ }
+ }
}
reader_->UpdateProgress(0.15);
@@ -536,7 +535,7 @@ void Foam::vtkPVFoam::Update
printMemory();
}
- if (!reader_->GetCacheMesh())
+ if (!caching)
{
delete meshPtr_;
meshPtr_ = nullptr;
@@ -549,7 +548,6 @@ void Foam::vtkPVFoam::Update
{
Info<< "Creating OpenFOAM mesh for region " << meshRegion_
<< " at time=" << dbPtr_().timeName() << endl;
-
}
meshPtr_ = new fvMesh
@@ -582,17 +580,6 @@ void Foam::vtkPVFoam::Update
reader_->UpdateProgress(0.4);
- // Update cached, saved, unneed values:
- HashSet nowActive;
- forAllConstIters(selectedPartIds_, iter)
- {
- nowActive.insert(iter.object());
- }
-
- // Dispose of unneeded components
- cachedVtp_.retain(nowActive);
- cachedVtu_.retain(nowActive);
-
convertMeshVolume();
convertMeshPatches();
reader_->UpdateProgress(0.6);
@@ -645,18 +632,28 @@ void Foam::vtkPVFoam::Update
}
reader_->UpdateProgress(0.95);
- fieldsChanged_ = false;
meshState_ = polyMesh::UNCHANGED;
- // Standard memory cleanup
- cachedVtp_.clear();
- cachedVtu_.clear();
+ if (caching & 2)
+ {
+ // Suppress caching of Lagrangian since it normally always changes.
+ cachedVtp_.filterKeys
+ (
+ [](const word& k){ return k.startsWith("lagrangian/"); },
+ true // prune
+ );
+ }
+ else
+ {
+ cachedVtp_.clear();
+ cachedVtu_.clear();
+ }
}
void Foam::vtkPVFoam::UpdateFinalize()
{
- if (!reader_->GetCacheMesh())
+ if (!reader_->GetMeshCaching())
{
delete meshPtr_;
meshPtr_ = nullptr;
diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.H b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.H
index 680fcb139d..55ec9d73e1 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.H
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.H
@@ -25,7 +25,25 @@ Class
Foam::vtkPVFoam
Description
- Provides a reader interface for OpenFOAM to VTK interaction.
+ The backend for the vtkPVFoamReader reader module -
+ providing a paraview reader interface for OpenFOAM meshes and fields.
+
+ Similar, and sometimes better, functionality may be provided by the
+ native VTK OpenFOAM reader. OpenCFD has recently (2017) been working
+ on improving the native VTK OpenFOAM reader for the benefit of everyone.
+
+ In some areas the reader module lacks compared to the native reader
+ (notably the ability to work on decomosed datasets), but provides
+ additional handling of sets,zones,groups. Some features have also since
+ been adapted to the native reader. Additionally, the reader module
+ provides a useful platform for testing new ideas.
+
+Note
+ The reader module allows two levels of caching. The OpenFOAM fvMesh
+ can be cached in memory, for faster loading of fields. Additionally,
+ the translated VTK geometries are held in a local cache. The cached
+ VTK geometries should incur no additional overhead since they use
+ the VTK reference counting for their storage management.
SourceFiles
vtkPVFoam.C
@@ -56,22 +74,22 @@ SourceFiles
#include "foamPvCore.H"
#include "foamVtkMeshMaps.H"
-#include "vtkSmartPointer.h"
+#include "vtkPoints.h"
#include "vtkPolyData.h"
+#include "vtkSmartPointer.h"
#include "vtkUnstructuredGrid.h"
// * * * * * * * * * * * * * Forward Declarations * * * * * * * * * * * * * //
+class vtkCellArray;
class vtkDataArraySelection;
class vtkDataSet;
class vtkFloatArray;
-class vtkPoints;
+class vtkIndent;
+class vtkMultiBlockDataSet;
class vtkPVFoamReader;
class vtkRenderer;
class vtkTextActor;
-class vtkMultiBlockDataSet;
-class vtkIndent;
-
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -104,20 +122,99 @@ class vtkPVFoam
// Private classes
- //- Bookkeeping for vtkPolyData
- class foamVtpData
+ //- Bookkeeping for internal caching.
+ // Retain an original copy of the geometry as well as a shallow copy
+ // with the output fields.
+ // The original copy is reused for different timestep
+ template
+ class foamVtkCaching
{
public:
- vtkSmartPointer vtkmesh;
+ typedef DataType dataType;
+
+ //- The geometry, without any cell/point data
+ vtkSmartPointer vtkgeom;
+
+ //- The shallow-copy of geometry, plus additional data
+ vtkSmartPointer dataset;
+
+ //- Number of points associated with geometry
+ inline uint64_t nPoints() const
+ {
+ return vtkgeom ? vtkgeom->GetNumberOfPoints() : 0;
+ }
+
+ //- Clear geometry and dataset
+ void clearGeom()
+ {
+ vtkgeom = nullptr;
+ dataset = nullptr;
+ }
+
+ //- Return a shallow copy of vtkgeom for manipulation
+ vtkSmartPointer getCopy() const
+ {
+ auto copy = vtkSmartPointer::New();
+ copy->ShallowCopy(vtkgeom);
+ return copy;
+ }
+
+ //- Make a shallow copy of vtkgeom into dataset
+ void reuse()
+ {
+ dataset = vtkSmartPointer::New();
+ dataset->ShallowCopy(vtkgeom);
+ }
+
+ //- Set the geometry and make a shallow copy to dataset
+ void set(vtkSmartPointer geom)
+ {
+ vtkgeom = geom;
+ reuse();
+ }
+
+ //- Report basic information to output
+ void PrintSelf(std::ostream& os) const
+ {
+ os << "geom" << nl;
+ if (vtkgeom)
+ {
+ vtkgeom->PrintSelf(std::cout, vtkIndent(2));
+ }
+ else
+ {
+ os << "nullptr";
+ }
+ os << nl;
+
+ os << "copy" << nl;
+ if (dataset)
+ {
+ dataset->PrintSelf(std::cout, vtkIndent(2));
+ }
+ else
+ {
+ os << "nullptr";
+ }
+ os << nl;
+ }
};
+ //- Bookkeeping for vtkPolyData
+ class foamVtpData
+ :
+ public foamVtkCaching,
+ public foamVtkMeshMaps
+ {};
+
+
//- Bookkeeping for vtkUnstructuredGrid
- class foamVtuData : public foamVtkMeshMaps
- {
- public:
- vtkSmartPointer vtkmesh;
- };
+ class foamVtuData
+ :
+ public foamVtkCaching,
+ public foamVtkMeshMaps
+ {};
// Private Data
@@ -140,12 +237,12 @@ class vtkPVFoam
//- The time index
int timeIndex_;
+ //- Previous/current decomposition request
+ bool decomposePoly_;
+
//- Track changes in mesh geometry
enum polyMesh::readUpdateState meshState_;
- //- Track changes in fields
- bool fieldsChanged_;
-
//- The index of selected parts mapped to their names
Map selectedPartIds_;
@@ -232,75 +329,143 @@ class vtkPVFoam
// Mesh conversion functions
- //- Convert volume mesh
+ //- Convert InternalMesh
void convertMeshVolume();
//- Convert Lagrangian points
void convertMeshLagrangian();
- //- Convert mesh patches
+ //- Convert mesh patches.
+ // The additionalIds (cached data) contain the patch Ids.
+ // There will be several for groups, but only one for regular patches.
void convertMeshPatches();
- //- Convert subsetted mesh
- void convertMeshSubset
- (
- const fvMeshSubset& subsetter,
- const string& longName
- );
-
//- Convert cell zones
void convertMeshCellZones();
- //- Convert face zones
- void convertMeshFaceZones();
-
- //- Convert point zones
- void convertMeshPointZones();
-
//- Convert cell sets
void convertMeshCellSets();
+ //- Convert face zones
+ void convertMeshFaceZones();
+
//- Convert face sets
+ // The cellMap (cached data) contains the face-labels.
void convertMeshFaceSets();
+ //- Convert point zones
+ // The pointMap (cached data) contains the point-labels.
+ void convertMeshPointZones();
+
//- Convert point sets
+ // The pointMap (cached data) contains the point-labels.
void convertMeshPointSets();
// Add mesh functions
- //- Volume meshes as vtkUnstructuredGrid
+ //- Generate vtk points for the current mesh points/decomposition
+ static vtkSmartPointer movePoints
+ (
+ const fvMesh& mesh,
+ const foamVtuData& vtuData
+ );
+
+ //- Generate vtk points for the current mesh points/decomposition,
+ // using the provided pointMap
+ static vtkSmartPointer movePoints
+ (
+ const fvMesh& mesh,
+ const foamVtuData& vtuData,
+ const labelUList& pointMap
+ );
+
+ //- Volume mesh as vtkUnstructuredGrid
+ static vtkSmartPointer volumeVTKMesh
+ (
+ const fvMesh& mesh,
+ foamVtuData& vtuData,
+ const bool decompPoly
+ );
+
+ //- Subsetted mesh as vtkUnstructuredGrid
+ static vtkSmartPointer volumeVTKSubsetMesh
+ (
+ const fvMeshSubset& subsetter,
+ foamVtuData& vtuData,
+ const bool decompPoly
+ );
+
+ //- Volume mesh as vtkUnstructuredGrid
vtkSmartPointer volumeVTKMesh
(
const fvMesh& mesh,
foamVtuData& vtuData
- );
+ ) const;
+
+ //- Subsetted mesh as vtkUnstructuredGrid
+ vtkSmartPointer volumeVTKSubsetMesh
+ (
+ const fvMeshSubset& subsetter,
+ foamVtuData& vtuData
+ ) const;
//- Lagrangian positions as vtkPolyData
vtkSmartPointer lagrangianVTKMesh
(
const polyMesh& mesh,
const word& cloudName
+ ) const;
+
+ //- Patch points
+ template
+ static vtkSmartPointer movePatchPoints
+ (
+ const PatchType& p
+ );
+
+ //- Patch faces as vtk-cells
+ template
+ static vtkSmartPointer patchFacesVTKCells
+ (
+ const PatchType& p
);
//- Patches (mesh or primitive) as vtkPolyData
template
- vtkSmartPointer patchVTKMesh
+ static vtkSmartPointer patchVTKMesh
(
- const string& name,
const PatchType& p
);
// Field conversion functions
- //- Convert Field to VTK field
+ //- Copy list to pre-allocated vtk array.
+ // \return number of input items copied
+ template
+ static label transcribeFloatData
+ (
+ vtkFloatArray* array,
+ const UList& input,
+ const label start = 0
+ );
+
+ //- Create named field initialized to zero
+ template
+ static vtkSmartPointer zeroVTKField
+ (
+ const word& name,
+ const label size
+ );
+
+ //- Convert float data to VTK field
template
vtkSmartPointer convertFieldToVTK
(
const word& name,
- const Field& fld
- );
+ const UList& fld
+ ) const;
//- Face set/zone field
template
@@ -308,7 +473,7 @@ class vtkPVFoam
(
const GeometricField& fld,
const labelUList& faceLabels
- );
+ ) const;
//- Volume field
template
@@ -316,7 +481,7 @@ class vtkPVFoam
(
const GeometricField& fld,
const foamVtuData& vtuData
- );
+ ) const;
//- Convert volume fields
@@ -392,9 +557,8 @@ class vtkPVFoam
//- Point field
template
- void convertPointField
+ vtkSmartPointer convertPointField
(
- vtkUnstructuredGrid* vtkmesh,
const GeometricField& pfld,
const GeometricField& vfld,
const foamVtuData& vtuData
@@ -403,17 +567,6 @@ class vtkPVFoam
// GUI selection helper functions
- //- Only retain specified fields
- static void pruneObjectList
- (
- IOobjectList& objects,
- const hashedWordList& retain
- );
-
-
- //- Get the first word from selectedPartIds_
- word getPartName(const int partId) const;
-
//- Get the first word from the reader 'parts' selection
word getReaderPartName(const int partId) const;
diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFieldTemplates.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFieldTemplates.C
index 3df2eb9925..fdab4abe23 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFieldTemplates.C
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFieldTemplates.C
@@ -30,6 +30,7 @@ InClass
#define vtkPVFoamFieldTemplates_C
// OpenFOAM includes
+#include "error.H"
#include "emptyFvPatchField.H"
#include "wallPolyPatch.H"
#include "faceSet.H"
@@ -81,92 +82,103 @@ void Foam::vtkPVFoam::convertVolField
convertVolFieldBlock(fld, ptfPtr, rangeCellZones_); // cellZones
convertVolFieldBlock(fld, ptfPtr, rangeCellSets_); // cellSets
-
- // Patches - skip field conversion for groups
+ // Patches - currently skip field conversion for groups
for (auto partId : rangePatches_)
{
- if
+ if (!selectedPartIds_.found(partId))
+ {
+ continue;
+ }
+ const auto& longName = selectedPartIds_[partId];
+
+ auto iter = cachedVtp_.find(longName);
+ if (!iter.found() || !iter.object().dataset)
+ {
+ // Should not happen, but for safety require a vtk geometry
+ continue;
+ }
+ foamVtpData& vtpData = iter.object();
+ auto dataset = vtpData.dataset;
+
+ const labelList& patchIds = vtpData.additionalIds();
+ if (patchIds.empty())
+ {
+ continue;
+ }
+
+ // This is slightly roundabout, but we deal with groups and with
+ // single patches.
+ // For groups (spanning several patches) it is fairly messy to
+ // get interpolated point fields. We would need to create a indirect
+ // patch each time to obtain the mesh points. We thus skip that.
+ //
+ // To improve code reuse, we allocate the CellData as a zeroed-field
+ // ahead of time.
+
+ vtkSmartPointer cdata = zeroVTKField
(
- !selectedPartIds_.found(partId)
- || selectedPartIds_[partId].startsWith("group/")
- )
+ fld.name(),
+ dataset->GetNumberOfPolys()
+ );
+
+ vtkSmartPointer pdata;
+ const bool allowPdata = (interpField && patchIds.size() == 1);
+
+ label coffset = 0; // the write offset into cell-data
+ for (label patchId : patchIds)
{
- continue;
- }
+ const fvPatchField& ptf = fld.boundaryField()[patchId];
- const word patchName = getPartName(partId);
- const label patchId = patches.findPatchID(patchName);
-
- if (patchId < 0)
- {
- continue;
- }
-
- auto iter = cachedVtp_.find(selectedPartIds_[partId]);
- if (!iter.found() || !(*iter).vtkmesh)
- {
- continue;
- }
- auto vtkmesh = (*iter).vtkmesh;
-
- const fvPatchField& ptf = fld.boundaryField()[patchId];
-
- if
- (
- isType>(ptf)
- ||
+ if
(
- extrapPatch
- && !polyPatch::constraintType(patches[patchId].type())
+ isType>(ptf)
+ ||
+ (
+ extrapPatch
+ && !polyPatch::constraintType(patches[patchId].type())
+ )
)
- )
- {
- fvPatch p(ptf.patch().patch(), mesh.boundary());
-
- tmp> tpptf
- (
- fvPatchField(p, fld).patchInternalField()
- );
-
- vtkSmartPointer cdata =
- convertFieldToVTK
- (
- fld.name(),
- tpptf()
- );
- vtkmesh->GetCellData()->AddArray(cdata);
-
- if (patchId < patchInterpList.size())
{
- vtkSmartPointer pdata = convertFieldToVTK
+ fvPatch p(ptf.patch().patch(), mesh.boundary());
+
+ tmp> tpptf
(
- fld.name(),
- patchInterpList[patchId].faceToPointInterpolate(tpptf)()
+ fvPatchField(p, fld).patchInternalField()
);
- vtkmesh->GetPointData()->AddArray(pdata);
+ coffset += transcribeFloatData(cdata, tpptf(), coffset);
+
+ if (allowPdata && patchId < patchInterpList.size())
+ {
+ pdata = convertFieldToVTK
+ (
+ fld.name(),
+ patchInterpList[patchId].faceToPointInterpolate(tpptf)()
+ );
+ }
+ }
+ else
+ {
+ coffset += transcribeFloatData(cdata, ptf, coffset);
+
+ if (allowPdata && patchId < patchInterpList.size())
+ {
+ pdata = convertFieldToVTK
+ (
+ fld.name(),
+ patchInterpList[patchId].faceToPointInterpolate(ptf)()
+ );
+ }
}
}
- else
+
+ if (cdata)
{
- vtkSmartPointer cdata =
- convertFieldToVTK
- (
- fld.name(),
- ptf
- );
- vtkmesh->GetCellData()->AddArray(cdata);
-
- if (patchId < patchInterpList.size())
- {
- vtkSmartPointer pdata = convertFieldToVTK
- (
- fld.name(),
- patchInterpList[patchId].faceToPointInterpolate(ptf)()
- );
-
- vtkmesh->GetPointData()->AddArray(pdata);
- }
+ dataset->GetCellData()->AddArray(cdata);
+ }
+ if (pdata)
+ {
+ dataset->GetPointData()->AddArray(pdata);
}
}
@@ -178,15 +190,18 @@ void Foam::vtkPVFoam::convertVolField
{
continue;
}
+ const auto& longName = selectedPartIds_[partId];
+ const word zoneName = getFoamName(longName);
- auto iter = cachedVtu_.find(selectedPartIds_[partId]);
- if (!iter.found() || !(*iter).vtkmesh)
+ auto iter = cachedVtp_.find(longName);
+ if (!iter.found() || !iter.object().dataset)
{
+ // Should not happen, but for safety require a vtk geometry
continue;
}
- auto vtkmesh = (*iter).vtkmesh;
+ foamVtpData& vtpData = iter.object();
+ auto dataset = vtpData.dataset;
- const word zoneName = getPartName(partId);
const faceZoneMesh& zMesh = mesh.faceZones();
const label zoneId = zMesh.findZoneID(zoneName);
@@ -195,15 +210,16 @@ void Foam::vtkPVFoam::convertVolField
continue;
}
- vtkSmartPointer cdata = convertFaceFieldToVTK
- (
- fld,
- zMesh[zoneId]
- );
+ vtkSmartPointer cdata =
+ convertFaceFieldToVTK
+ (
+ fld,
+ zMesh[zoneId]
+ );
- vtkmesh->GetCellData()->AddArray(cdata);
+ dataset->GetCellData()->AddArray(cdata);
- // TODO: points
+ // TODO: point data
}
@@ -214,26 +230,27 @@ void Foam::vtkPVFoam::convertVolField
{
continue;
}
+ const auto& longName = selectedPartIds_[partId];
+ const word selectName = getFoamName(longName);
- auto iter = cachedVtu_.find(selectedPartIds_[partId]);
- if (!iter.found() || !(*iter).vtkmesh)
+ auto iter = cachedVtp_.find(longName);
+ if (!iter.found() || !iter.object().dataset)
{
+ // Should not happen, but for safety require a vtk geometry
continue;
}
- auto vtkmesh = (*iter).vtkmesh;
-
- const word selectName = getPartName(partId);
- const faceSet fSet(mesh, selectName);
+ foamVtpData& vtpData = iter.object();
+ auto dataset = vtpData.dataset;
vtkSmartPointer cdata = convertFaceFieldToVTK
(
fld,
- fSet.sortedToc()
+ vtpData.cellMap()
);
- vtkmesh->GetCellData()->AddArray(cdata);
+ dataset->GetCellData()->AddArray(cdata);
- // TODO: points
+ // TODO: point data
}
}
@@ -246,27 +263,21 @@ void Foam::vtkPVFoam::convertVolFields
const IOobjectList& objects
)
{
+ typedef GeometricField FieldType;
+
forAllConstIters(objects, iter)
{
// Restrict to GeometricField
- if
- (
- iter()->headerClassName()
- != GeometricField::typeName
- )
+ const auto& ioobj = *(iter.object());
+
+ if (ioobj.headerClassName() == FieldType::typeName)
{
- continue;
+ // Load field
+ FieldType fld(ioobj, mesh);
+
+ // Convert
+ convertVolField(patchInterpList, fld);
}
-
- // Load field
- GeometricField fld
- (
- *iter(),
- mesh
- );
-
- // Convert
- convertVolField(patchInterpList, fld);
}
}
@@ -279,22 +290,21 @@ void Foam::vtkPVFoam::convertDimFields
const IOobjectList& objects
)
{
+ typedef DimensionedField FieldType;
typedef GeometricField VolFieldType;
forAllConstIters(objects, iter)
{
// Restrict to DimensionedField
- if
- (
- iter()->headerClassName()
- != DimensionedField::typeName
- )
+ const auto& ioobj = *(iter.object());
+
+ if (ioobj.headerClassName() != FieldType::typeName)
{
continue;
}
// Load field
- DimensionedField dimFld(*iter(), mesh);
+ FieldType dimFld(ioobj, mesh);
// Construct volField with zero-gradient patch fields
@@ -345,25 +355,33 @@ void Foam::vtkPVFoam::convertVolFieldBlock
{
continue;
}
+ const auto& longName = selectedPartIds_[partId];
- auto iter = cachedVtu_.find(selectedPartIds_[partId]);
- if (!iter.found() || !(*iter).vtkmesh)
+ auto iter = cachedVtu_.find(longName);
+ if (!iter.found() || !iter.object().dataset)
{
+ // Should not happen, but for safety require a vtk geometry
continue;
}
- auto vtuData = (*iter);
- auto vtkmesh = (*iter).vtkmesh;
+ foamVtuData& vtuData = iter.object();
+ auto dataset = vtuData.dataset;
vtkSmartPointer cdata = convertVolFieldToVTK
(
fld,
vtuData
);
- vtkmesh->GetCellData()->AddArray(cdata);
+ dataset->GetCellData()->AddArray(cdata);
if (ptfPtr.valid())
{
- convertPointField(vtkmesh, ptfPtr(), fld, vtuData);
+ vtkSmartPointer pdata = convertPointField
+ (
+ ptfPtr(),
+ fld,
+ vtuData
+ );
+ dataset->GetPointData()->AddArray(pdata);
}
}
}
@@ -382,17 +400,16 @@ void Foam::vtkPVFoam::convertPointFields
)
{
const polyMesh& mesh = pMesh.mesh();
- const polyBoundaryMesh& patches = mesh.boundaryMesh();
+
+ typedef GeometricField FieldType;
forAllConstIters(objects, iter)
{
- const word& fieldName = iter()->name();
// Restrict to this GeometricField
- if
- (
- iter()->headerClassName()
- != GeometricField::typeName
- )
+ const auto& ioobj = *(iter.object());
+
+ const word& fieldName = ioobj.name();
+ if (ioobj.headerClassName() != FieldType::typeName)
{
continue;
}
@@ -402,15 +419,13 @@ void Foam::vtkPVFoam::convertPointFields
Info<< "convertPointFields : " << fieldName << endl;
}
- GeometricField pfld(*iter(), pMesh);
-
+ FieldType pfld(ioobj, pMesh);
convertPointFieldBlock(pfld, rangeVolume_); // internalMesh
convertPointFieldBlock(pfld, rangeCellZones_); // cellZones
convertPointFieldBlock(pfld, rangeCellSets_); // cellSets
-
- // Patches)
+ // Patches - currently skip field conversion for groups
for (auto partId : rangePatches_)
{
if (!selectedPartIds_.found(partId))
@@ -419,26 +434,22 @@ void Foam::vtkPVFoam::convertPointFields
}
const auto& longName = selectedPartIds_[partId];
- if (longName.startsWith("group/"))
+ auto iter = cachedVtp_.find(longName);
+ if (!iter.found() || !iter.object().dataset)
{
- // Skip patch-groups
+ // Should not happen, but for safety require a vtk geometry
continue;
}
+ foamVtpData& vtpData = iter.object();
+ auto dataset = vtpData.dataset;
- const word patchName = getPartName(partId);
- const label patchId = patches.findPatchID(patchName);
-
- if (patchId < 0)
+ const labelList& patchIds = vtpData.additionalIds();
+ if (patchIds.size() != 1)
{
continue;
}
- auto iter = cachedVtp_.find(selectedPartIds_[partId]);
- if (!iter.found() || !(*iter).vtkmesh)
- {
- continue;
- }
- auto vtkmesh = (*iter).vtkmesh;
+ const label patchId = patchIds[0];
vtkSmartPointer pdata = convertFieldToVTK
(
@@ -446,27 +457,28 @@ void Foam::vtkPVFoam::convertPointFields
pfld.boundaryField()[patchId].patchInternalField()()
);
- vtkmesh->GetPointData()->AddArray(pdata);
+ dataset->GetPointData()->AddArray(pdata);
}
- //
- // Convert (selected) faceZones
- //
+ // Face Zones
for (auto partId : rangeFaceZones_)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
+ const auto& longName = selectedPartIds_[partId];
+ const word zoneName = getFoamName(longName);
- auto iter = cachedVtp_.find(selectedPartIds_[partId]);
- if (!iter.found() || !(*iter).vtkmesh)
+ auto iter = cachedVtp_.find(longName);
+ if (!iter.found() || !iter.object().dataset)
{
+ // Should not happen, but for safety require a vtk geometry
continue;
}
- auto vtkmesh = (*iter).vtkmesh;
+ foamVtpData& vtpData = iter.object();
+ auto dataset = vtpData.dataset;
- const word zoneName = getPartName(partId);
const label zoneId = mesh.faceZones().findZoneID(zoneName);
if (zoneId < 0)
@@ -488,7 +500,7 @@ void Foam::vtkPVFoam::convertPointFields
znfld
);
- vtkmesh->GetPointData()->AddArray(pdata);
+ dataset->GetPointData()->AddArray(pdata);
}
}
}
@@ -507,63 +519,58 @@ void Foam::vtkPVFoam::convertPointFieldBlock
{
continue;
}
+ const auto& longName = selectedPartIds_[partId];
- auto iter = cachedVtu_.find(selectedPartIds_[partId]);
- if (!iter.found() || ! (*iter).vtkmesh)
+ auto iter = cachedVtu_.find(longName);
+ if (!iter.found() || !iter.object().dataset)
{
+ // Should not happen, but for safety require a vtk geometry
continue;
}
- auto vtuData = (*iter);
- auto vtkmesh = (*iter).vtkmesh;
+ foamVtuData& vtuData = iter.object();
+ auto dataset = vtuData.dataset;
- convertPointField
+ vtkSmartPointer pdata = convertPointField
(
- vtkmesh,
pfld,
GeometricField::null(),
vtuData
);
+
+ dataset->GetPointData()->AddArray(pdata);
}
}
template
-void Foam::vtkPVFoam::convertPointField
+vtkSmartPointer Foam::vtkPVFoam::convertPointField
(
- vtkUnstructuredGrid* vtkmesh,
const GeometricField& pfld,
const GeometricField& vfld,
const foamVtuData& vtuData
)
{
- if (!vtkmesh)
- {
- return;
- }
-
- const label nComp = pTraits::nComponents;
+ const int nComp(pTraits::nComponents);
const labelUList& addPointCellLabels = vtuData.additionalIds();
const labelUList& pointMap = vtuData.pointMap();
// Use a pointMap or address directly into mesh
const label nPoints = (pointMap.size() ? pointMap.size() : pfld.size());
- vtkSmartPointer fldData =
- vtkSmartPointer::New();
-
- fldData->SetNumberOfComponents(nComp);
- fldData->SetNumberOfTuples(nPoints + addPointCellLabels.size());
+ auto data = vtkSmartPointer::New();
+ data->SetNumberOfComponents(nComp);
+ data->SetNumberOfTuples(nPoints + addPointCellLabels.size());
// Note: using the name of the original volField
// not the name generated by the interpolation "volPointInterpolate()"
- if (&vfld != &GeometricField::null())
+ if (notNull(vfld))
{
- fldData->SetName(vfld.name().c_str());
+ data->SetName(vfld.name().c_str());
}
else
{
- fldData->SetName(pfld.name().c_str());
+ data->SetName(pfld.name().c_str());
}
if (debug)
@@ -589,7 +596,7 @@ void Foam::vtkPVFoam::convertPointField
}
foamPvFields::remapTuple(vec);
- fldData->SetTuple(pointi++, vec);
+ data->SetTuple(pointi++, vec);
}
}
else
@@ -603,13 +610,13 @@ void Foam::vtkPVFoam::convertPointField
}
foamPvFields::remapTuple(vec);
- fldData->SetTuple(pointi++, vec);
+ data->SetTuple(pointi++, vec);
}
}
- // Continue additional points
+ // Continue with additional points
- if (&vfld != &GeometricField::null())
+ if (notNull(vfld))
{
forAll(addPointCellLabels, apI)
{
@@ -620,7 +627,7 @@ void Foam::vtkPVFoam::convertPointField
}
foamPvFields::remapTuple(vec);
- fldData->SetTuple(pointi++, vec);
+ data->SetTuple(pointi++, vec);
}
}
else
@@ -634,11 +641,11 @@ void Foam::vtkPVFoam::convertPointField
}
foamPvFields::remapTuple(vec);
- fldData->SetTuple(pointi++, vec);
+ data->SetTuple(pointi++, vec);
}
}
- vtkmesh->GetPointData()->AddArray(fldData);
+ return data;
}
@@ -656,19 +663,23 @@ void Foam::vtkPVFoam::convertLagrangianFields
{
forAllConstIters(objects, iter)
{
- // restrict to this IOField
- if (iter()->headerClassName() == IOField::typeName)
- {
- IOField fld(*iter());
+ // Restrict to IOField
+ const auto& ioobj = *(iter.object());
- vtkSmartPointer fldData =
+ if (ioobj.headerClassName() == IOField::typeName)
+ {
+ IOField fld(ioobj);
+
+ vtkSmartPointer data =
convertFieldToVTK
(
- fld.name(),
+ ioobj.name(),
fld
);
- vtkmesh->GetPointData()->AddArray(fldData);
+ // Provide identical data as cell and as point data
+ vtkmesh->GetCellData()->AddArray(data);
+ vtkmesh->GetPointData()->AddArray(data);
}
}
}
@@ -679,45 +690,116 @@ void Foam::vtkPVFoam::convertLagrangianFields
// low-level conversions
//
+template
+vtkSmartPointer
+Foam::vtkPVFoam::zeroVTKField
+(
+ const word& name,
+ const label size
+)
+{
+ auto data = vtkSmartPointer::New();
+
+ data->SetName(name.c_str());
+ data->SetNumberOfComponents(int(pTraits::nComponents));
+ data->SetNumberOfTuples(size);
+
+ data->Fill(0);
+
+ return data;
+}
+
+
+template
+Foam::label Foam::vtkPVFoam::transcribeFloatData
+(
+ vtkFloatArray* array,
+ const UList& input,
+ const label start
+)
+{
+ const int nComp(pTraits::nComponents);
+
+ if (array->GetNumberOfComponents() != nComp)
+ {
+ FatalErrorInFunction
+ << "vtk array '" << array->GetName()
+ << "' has mismatch in number of components for type '"
+ << pTraits::typeName
+ << "' : target array has " << array->GetNumberOfComponents()
+ << " components instead of " << nComp
+ << endl;
+ }
+
+ const vtkIdType maxSize = array->GetNumberOfTuples();
+ const vtkIdType endPos = vtkIdType(start) + vtkIdType(input.size());
+
+ if (start < 0 || vtkIdType(start) >= maxSize)
+ {
+ WarningInFunction
+ << "vtk array '" << array->GetName()
+ << "' copy with out-of-range (0-" << long(maxSize-1) << ")"
+ << " starting location"
+ << endl;
+
+ return 0;
+ }
+ else if (endPos > maxSize)
+ {
+ WarningInFunction
+ << "vtk array '" << array->GetName()
+ << "' copy ends out-of-range (" << long(maxSize) << ")"
+ << " using sizing (start,size) = ("
+ << start << "," << input.size() << ")"
+ << endl;
+
+ return 0;
+ }
+
+ float scratch[nComp];
+ forAll(input, idx)
+ {
+ const Type& t = input[idx];
+ for (direction d=0; d(scratch);
+
+ array->SetTuple(start+idx, scratch);
+ }
+
+ return input.size();
+}
+
+
template
vtkSmartPointer
Foam::vtkPVFoam::convertFieldToVTK
(
const word& name,
- const Field& fld
-)
+ const UList& fld
+) const
{
+ const int nComp(pTraits::nComponents);
+
if (debug)
{
- Info<< "convert Field<" << pTraits::typeName << "> "
+ Info<< "convert UList<" << pTraits::typeName << "> "
<< name
<< " size=" << fld.size()
- << " nComp=" << label(pTraits::nComponents) << endl;
+ << " nComp=" << nComp << endl;
}
- const label nComp = pTraits::nComponents;
+ auto data = vtkSmartPointer::New();
- vtkSmartPointer fldData =
- vtkSmartPointer::New();
+ data->SetName(name.c_str());
+ data->SetNumberOfComponents(nComp);
+ data->SetNumberOfTuples(fld.size());
- fldData->SetNumberOfComponents(nComp);
- fldData->SetNumberOfTuples(fld.size());
- fldData->SetName(name.c_str());
+ transcribeFloatData(data, fld);
- float vec[nComp];
- forAll(fld, idx)
- {
- const Type& t = fld[idx];
- for (direction d=0; d(vec);
-
- fldData->SetTuple(idx, vec);
- }
-
- return fldData;
+ return data;
}
@@ -727,34 +809,32 @@ Foam::vtkPVFoam::convertFaceFieldToVTK
(
const GeometricField& fld,
const labelUList& faceLabels
-)
+) const
{
if (debug)
{
Info<< "convert face field: "
<< fld.name()
<< " size=" << faceLabels.size()
- << " nComp=" << label(pTraits::nComponents) << endl;
+ << " nComp=" << int(pTraits::nComponents) << endl;
}
const fvMesh& mesh = fld.mesh();
- const label nComp = pTraits::nComponents;
+ const int nComp(pTraits::nComponents);
const label nInternalFaces = mesh.nInternalFaces();
const labelList& faceOwner = mesh.faceOwner();
const labelList& faceNeigh = mesh.faceNeighbour();
- vtkSmartPointer fldData =
- vtkSmartPointer::New();
+ auto data = vtkSmartPointer::New();
+ data->SetName(fld.name().c_str());
+ data->SetNumberOfComponents(nComp);
+ data->SetNumberOfTuples(faceLabels.size());
- fldData->SetNumberOfComponents(nComp);
- fldData->SetNumberOfTuples(faceLabels.size());
- fldData->SetName(fld.name().c_str());
+ float scratch[nComp];
- float vec[nComp];
-
- // for interior faces: average owner/neighbour
- // for boundary faces: owner
+ // Interior faces: average owner/neighbour
+ // Boundary faces: the owner value
forAll(faceLabels, idx)
{
const label faceNo = faceLabels[idx];
@@ -764,7 +844,7 @@ Foam::vtkPVFoam::convertFaceFieldToVTK
for (direction d=0; d(vec);
+ foamPvFields::remapTuple(scratch);
- fldData->SetTuple(idx, vec);
+ data->SetTuple(idx, scratch);
}
- return fldData;
+ return data;
}
@@ -790,17 +870,15 @@ Foam::vtkPVFoam::convertVolFieldToVTK
(
const GeometricField& fld,
const foamVtuData& vtuData
-)
+) const
{
- const label nComp = pTraits::nComponents;
- const labelList& cellMap = vtuData.cellMap();
+ const int nComp(pTraits::nComponents);
+ const labelUList& cellMap = vtuData.cellMap();
- vtkSmartPointer fldData =
- vtkSmartPointer::New();
-
- fldData->SetNumberOfComponents(nComp);
- fldData->SetNumberOfTuples(cellMap.size());
- fldData->SetName(fld.name().c_str());
+ auto data = vtkSmartPointer::New();
+ data->SetName(fld.name().c_str());
+ data->SetNumberOfComponents(nComp);
+ data->SetNumberOfTuples(cellMap.size());
if (debug)
{
@@ -812,20 +890,20 @@ Foam::vtkPVFoam::convertVolFieldToVTK
<< ") nComp=" << nComp << endl;
}
- float vec[nComp];
+ float scratch[nComp];
forAll(cellMap, idx)
{
const Type& t = fld[cellMap[idx]];
for (direction d=0; d(vec);
+ foamPvFields::remapTuple(scratch);
- fldData->SetTuple(idx, vec);
+ data->SetTuple(idx, scratch);
}
- return fldData;
+ return data;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFields.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFields.C
index 8f1ca82460..9da212916f 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFields.C
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamFields.C
@@ -40,28 +40,6 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
-void Foam::vtkPVFoam::pruneObjectList
-(
- IOobjectList& objects,
- const hashedWordList& retain
-)
-{
- if (retain.empty())
- {
- objects.clear();
- }
-
- // only retain specified fields
- forAllIters(objects, iter)
- {
- if (!retain.found(iter()->name()))
- {
- objects.erase(iter);
- }
- }
-}
-
-
void Foam::vtkPVFoam::convertVolFields()
{
const fvMesh& mesh = *meshPtr_;
@@ -80,7 +58,7 @@ void Foam::vtkPVFoam::convertVolFields()
// Get objects (fields) for this time - only keep selected fields
// the region name is already in the mesh db
IOobjectList objects(mesh, dbPtr_().timeName());
- pruneObjectList(objects, selectedFields);
+ objects.filterKeys(selectedFields);
if (objects.empty())
{
@@ -89,7 +67,7 @@ void Foam::vtkPVFoam::convertVolFields()
if (debug)
{
- Info<< " convert volume fields" << endl;
+ Info<< " " << FUNCTION_NAME << endl;
forAllConstIters(objects, iter)
{
Info<< " " << iter()->name()
@@ -132,7 +110,7 @@ void Foam::vtkPVFoam::convertVolFields()
if (debug)
{
- Info<< " convert volume fields" << endl;
+ Info<< " " << FUNCTION_NAME << endl;
printMemory();
}
}
@@ -159,7 +137,7 @@ void Foam::vtkPVFoam::convertPointFields()
// Get objects (fields) for this time - only keep selected fields
// the region name is already in the mesh db
IOobjectList objects(mesh, dbPtr_().timeName());
- pruneObjectList(objects, selectedFields);
+ objects.filterKeys(selectedFields);
if (objects.empty())
{
@@ -196,7 +174,7 @@ void Foam::vtkPVFoam::convertPointFields()
void Foam::vtkPVFoam::convertLagrangianFields()
{
- arrayRange& range = rangeLagrangian_;
+ const arrayRange& range = rangeLagrangian_;
const fvMesh& mesh = *meshPtr_;
hashedWordList selectedFields = getSelected
@@ -211,7 +189,7 @@ void Foam::vtkPVFoam::convertLagrangianFields()
if (debug)
{
- Info<< " convert Lagrangian fields" << endl;
+ Info<< " " << FUNCTION_NAME << endl;
printMemory();
}
@@ -222,14 +200,16 @@ void Foam::vtkPVFoam::convertLagrangianFields()
continue;
}
- const word cloudName = getPartName(partId);
- auto iter = cachedVtp_.find(selectedPartIds_[partId]);
+ const auto& longName = selectedPartIds_[partId];
+ const word cloudName = getFoamName(longName);
- if (!iter.found() || !(*iter).vtkmesh)
+ auto iter = cachedVtp_.find(longName);
+ if (!iter.found() || !iter.object().dataset)
{
+ // Should not happen, but for safety require a vtk geometry
continue;
}
- auto vtkmesh = (*iter).vtkmesh;
+ auto dataset = iter.object().dataset;
// Get the Lagrangian fields for this time and this cloud
// but only keep selected fields
@@ -240,7 +220,7 @@ void Foam::vtkPVFoam::convertLagrangianFields()
dbPtr_().timeName(),
cloud::prefix/cloudName
);
- pruneObjectList(objects, selectedFields);
+ objects.filterKeys(selectedFields);
if (objects.empty())
{
@@ -257,17 +237,17 @@ void Foam::vtkPVFoam::convertLagrangianFields()
}
}
- convertLagrangianFields