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