Commit 12231112 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: improve internal bookkeeping in paraview readers

- has the selected values directly and use these lookup names to store
  directly into a hash. This replaces several parallel lists of
  decomp information etc and makes it easier.
parent 01a04e6e
......@@ -47,6 +47,20 @@ License
namespace Foam
{
defineTypeNameAndDebug(vtkPVFoam, 0);
// file-scope
static word updateStateName(polyMesh::readUpdateState state)
{
switch (state)
{
case polyMesh::UNCHANGED: return "UNCHANGED";
case polyMesh::POINTS_MOVED: return "POINTS_MOVED";
case polyMesh::TOPO_CHANGE: return "TOPO_CHANGE";
case polyMesh::TOPO_PATCH_CHANGE: return "TOPO_PATCH_CHANGE";
};
return "UNKNOWN";
}
}
......@@ -138,27 +152,15 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
<< ", nearestIndex = " << nearestIndex << endl;
}
// see what has changed
// See what has changed
if (timeIndex_ != nearestIndex)
{
timeIndex_ = nearestIndex;
runTime.setTime(Times[nearestIndex], nearestIndex);
// the fields change each time
// When the changes, so do the fields
fieldsChanged_ = true;
if (meshPtr_)
{
if (meshPtr_->readUpdate() != polyMesh::UNCHANGED)
{
meshChanged_ = true;
}
}
else
{
meshChanged_ = true;
}
meshState_ = meshPtr_ ? meshPtr_->readUpdate() : polyMesh::TOPO_CHANGE;
reader_->UpdateProgress(0.05);
......@@ -171,7 +173,7 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
Info<< "<end> setTime() - selectedTime="
<< Times[nearestIndex].name() << " index=" << timeIndex_
<< "/" << Times.size()
<< " meshChanged=" << Switch(meshChanged_)
<< " meshUpdateState=" << updateStateName(meshState_)
<< " fieldsChanged=" << Switch(fieldsChanged_) << endl;
}
......@@ -179,7 +181,20 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
}
Foam::word Foam::vtkPVFoam::getPartName(const int partId)
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));
}
......@@ -199,7 +214,7 @@ Foam::vtkPVFoam::vtkPVFoam
meshRegion_(polyMesh::defaultRegion),
meshDir_(polyMesh::meshSubDir),
timeIndex_(-1),
meshChanged_(true),
meshState_(polyMesh::TOPO_CHANGE),
fieldsChanged_(true),
rangeVolume_("unzoned"),
rangePatches_("patch"),
......@@ -334,7 +349,7 @@ void Foam::vtkPVFoam::updateInfo()
// time of the vtkDataArraySelection, but the qt/paraview proxy
// layer doesn't care about that anyhow.
stringList enabledEntries;
HashSet<string> enabledEntries;
if (!partSelection->GetNumberOfArrays() && !meshPtr_)
{
// enable 'internalMesh' on the first call
......@@ -356,10 +371,10 @@ void Foam::vtkPVFoam::updateInfo()
updateInfoZones(partSelection);
updateInfoLagrangian(partSelection);
// restore the enabled selections
// Adjust/restore the enabled selections
setSelectedArrayEntries(partSelection, enabledEntries);
if (meshChanged_)
if (meshState_ != polyMesh::UNCHANGED)
{
fieldsChanged_ = true;
}
......@@ -408,37 +423,48 @@ void Foam::vtkPVFoam::Update
}
vtkDataArraySelection* selection = reader_->GetPartSelection();
label nElem = selection->GetNumberOfArrays();
const int n = selection->GetNumberOfArrays();
if (partStatus_.size() != nElem)
// All previously selected (enabled) names
HashSet<string> original;
forAllConstIters(selectedPartIds_, iter)
{
partStatus_.setSize(nElem);
partStatus_ = false;
meshChanged_ = true;
original.insert(iter.object());
}
// this needs fixing if we wish to re-use the datasets
partDataset_.setSize(nElem);
partDataset_ = -1;
selectedPartIds_.clear();
// Read the selected mesh parts (zones, patches ...) and add to list
forAll(partStatus_, partId)
for (int id=0; id < n; ++id)
{
const int setting = selection->GetArraySetting(partId);
string str(selection->GetArrayName(id));
bool status = selection->GetArraySetting(id);
if (partStatus_[partId] != setting)
if (status)
{
partStatus_[partId] = setting;
meshChanged_ = true;
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;
}
}
if (debug > 1)
{
Info<< " part[" << partId << "] = "
<< partStatus_[partId]
<< " : " << selection->GetArrayName(partId) << endl;
Info<< " part[" << id << "] = " << status
<< " : " << str << nl;
}
}
if (debug)
{
Info<< "<end> updateMeshPartsStatus" << endl;
......@@ -467,8 +493,7 @@ void Foam::vtkPVFoam::Update
if (debug)
{
Info<< "Creating OpenFOAM mesh for region " << meshRegion_
<< " at time=" << dbPtr_().timeName()
<< endl;
<< " at time=" << dbPtr_().timeName() << endl;
}
......@@ -483,7 +508,7 @@ void Foam::vtkPVFoam::Update
)
);
meshChanged_ = true;
meshState_ = polyMesh::TOPO_CHANGE; // New mesh
}
else
{
......@@ -502,6 +527,20 @@ void Foam::vtkPVFoam::Update
reader_->UpdateProgress(0.4);
// Update cached, saved, unneed values:
HashSet<string> nowActive;
forAllConstIters(selectedPartIds_, iter)
{
nowActive.insert(iter.object());
}
// Dispose of unneeded components
cachedVtp_.retain(nowActive);
cachedVtu_.retain(nowActive);
// Reset (expire) dataset ids
partDataset_.clear();
// Convert meshes - start port0 at block=0
int blockNo = 0;
......@@ -549,21 +588,12 @@ void Foam::vtkPVFoam::Update
}
reader_->UpdateProgress(0.95);
meshChanged_ = fieldsChanged_ = false;
fieldsChanged_ = false;
meshState_ = polyMesh::UNCHANGED;
// Standard memory cleanup
forAll(regionVtus_, i)
{
regionVtus_[i].clear();
}
forAll(zoneVtus_, i)
{
zoneVtus_[i].clear();
}
forAll(csetVtus_, i)
{
csetVtus_[i].clear();
}
cachedVtp_.clear();
cachedVtu_.clear();
}
......
......@@ -160,7 +160,17 @@ class vtkPVFoam
}
};
typedef polyDecomp foamVtuData;
//- Bookkeeping for vtkPolyData
class foamVtpData
{
};
//- Bookkeeping for vtkUnstructuredGrid
class foamVtuData
:
public polyDecomp
{
};
// Private Data
......@@ -184,20 +194,26 @@ class vtkPVFoam
int timeIndex_;
//- Track changes in mesh geometry
bool meshChanged_;
enum polyMesh::readUpdateState meshState_;
//- Track changes in fields
bool fieldsChanged_;
//- Selected geometrical parts (internalMesh, patches, ...)
boolList partStatus_;
//- The index of selected parts mapped to their names
Map<string> selectedPartIds_;
//- Datasets corresponding to selected geometrical pieces
// a negative number indicates that no vtkmesh exists for this piece
labelList partDataset_;
Map<label> partDataset_;
//- Any information for 2D (VTP) geometries
HashTable<foamVtpData, string> cachedVtp_;
//- Cell maps and other information for 3D (VTU) geometries
HashTable<foamVtuData, string> cachedVtu_;
//- First instance and size of various mesh parts
// used to index into partStatus_ and partDataset_
// used to index into selectedPartIds and thus indirectly into
// cachedVtp, cachedVtu and partDataset
arrayRange rangeVolume_;
arrayRange rangePatches_;
arrayRange rangeLagrangian_;
......@@ -208,16 +224,6 @@ class vtkPVFoam
arrayRange rangeFaceSets_;
arrayRange rangePointSets_;
//- Decomposed cells information (mesh regions)
// TODO: regions
List<foamVtuData> regionVtus_;
//- Decomposed cells information (cellZone meshes)
List<foamVtuData> zoneVtus_;
//- Decomposed cells information (cellSet meshes)
List<foamVtuData> csetVtus_;
//- List of patch names for rendering to window
List<vtkSmartPointer<vtkTextActor>> patchTextActors_;
......@@ -230,19 +236,24 @@ class vtkPVFoam
// Update information helper functions
//- Internal mesh info
void updateInfoInternalMesh(vtkDataArraySelection*);
void updateInfoInternalMesh(vtkDataArraySelection* select);
//- Lagrangian info
void updateInfoLagrangian(vtkDataArraySelection*);
void updateInfoLagrangian(vtkDataArraySelection* select);
//- Patch info
void updateInfoPatches(vtkDataArraySelection*, stringList&);
//- Patch info, modifies enabledEntries
void updateInfoPatches
(
vtkDataArraySelection* select,
HashSet<string>& enabledEntries
);
//- Set info
void updateInfoSets(vtkDataArraySelection*);
void updateInfoSets(vtkDataArraySelection* select);
//- Zone info
void updateInfoZones(vtkDataArraySelection*);
void updateInfoZones(vtkDataArraySelection* select);
//- Get non-empty zone names for zoneType from file
wordList getZoneNames(const word& zoneType) const;
......@@ -395,8 +406,7 @@ class vtkPVFoam
const GeometricField<Type, fvPatchField, volMesh>& fld,
autoPtr<GeometricField<Type, pointPatchField, pointMesh>>& ptfPtr,
vtkMultiBlockDataSet* output,
const arrayRange& range,
const List<foamVtuData>& vtuDataList
const arrayRange& range
);
//- Lagrangian fields - all types
......@@ -423,8 +433,7 @@ class vtkPVFoam
(
const GeometricField<Type, pointPatchField, pointMesh>& pfld,
vtkMultiBlockDataSet* output,
const arrayRange& range,
const List<foamVtuData>& vtuDataList
const arrayRange& range
);
//- Point field
......@@ -447,8 +456,12 @@ class vtkPVFoam
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 getPartName(const int partId);
word getReaderPartName(const int partId) const;
// Constructors
......
......@@ -84,8 +84,7 @@ void Foam::vtkPVFoam::convertVolField
fld,
ptfPtr,
output,
rangeVolume_,
regionVtus_
rangeVolume_
);
// Convert activated cellZones
......@@ -94,8 +93,7 @@ void Foam::vtkPVFoam::convertVolField
fld,
ptfPtr,
output,
rangeCellZones_,
zoneVtus_
rangeCellZones_
);
// Convert activated cellSets
......@@ -104,21 +102,30 @@ void Foam::vtkPVFoam::convertVolField
fld,
ptfPtr,
output,
rangeCellSets_,
csetVtus_
rangeCellSets_
);
//
// Convert patches - if activated
// - skip field conversion for groups
//
for (auto partId : rangePatches_)
{
if
(
!selectedPartIds_.found(partId)
|| selectedPartIds_[partId].startsWith("group/")
)
{
continue;
}
const word patchName = getPartName(partId);
const label datasetNo = partDataset_[partId];
const label datasetNo = partDataset_.lookup(partId, -1);
const label patchId = patches.findPatchID(patchName);
if (!partStatus_[partId] || patchId < 0)
if (patchId < 0)
{
continue;
}
......@@ -199,10 +206,15 @@ void Foam::vtkPVFoam::convertVolField
//
for (auto partId : rangeFaceZones_)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const word zoneName = getPartName(partId);
const label datasetNo = partDataset_[partId];
const label datasetNo = partDataset_.lookup(partId, -1);
if (!partStatus_[partId] || datasetNo < 0)
if (datasetNo < 0)
{
continue;
}
......@@ -239,14 +251,14 @@ void Foam::vtkPVFoam::convertVolField
//
for (auto partId : rangeFaceSets_)
{
const word selectName = getPartName(partId);
const label datasetNo = partDataset_[partId];
if (!partStatus_[partId])
if (!selectedPartIds_.found(partId))
{
continue;
}
const word selectName = getPartName(partId);
const label datasetNo = partDataset_.lookup(partId, -1);
vtkPolyData* vtkmesh = getDataFromBlock<vtkPolyData>
(
output, rangeFaceSets_, datasetNo
......@@ -373,23 +385,23 @@ void Foam::vtkPVFoam::convertVolFieldBlock
const GeometricField<Type, fvPatchField, volMesh>& fld,
autoPtr<GeometricField<Type, pointPatchField, pointMesh>>& ptfPtr,
vtkMultiBlockDataSet* output,
const arrayRange& range,
const List<foamVtuData>& vtuDataList
const arrayRange& range
)
{
for (auto partId : range)
{
const label datasetNo = partDataset_[partId];
if (!partStatus_[partId])
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
const label datasetNo = partDataset_.lookup(partId, -1);
vtkUnstructuredGrid* vtkmesh =
getDataFromBlock<vtkUnstructuredGrid>(output, range, datasetNo);
if (!vtkmesh)
if (!vtkmesh || !cachedVtu_.found(longName))
{
continue;
}
......@@ -397,13 +409,17 @@ void Foam::vtkPVFoam::convertVolFieldBlock
vtkSmartPointer<vtkFloatArray> cdata = convertVolFieldToVTK
(
fld,
vtuDataList[datasetNo]
cachedVtu_[longName]
);
vtkmesh->GetCellData()->AddArray(cdata);
if (ptfPtr.valid())
{
convertPointField(vtkmesh, ptfPtr(), fld, vtuDataList[datasetNo]);
convertPointField
(
vtkmesh, ptfPtr(), fld,
cachedVtu_[longName]
);
}
}
}
......@@ -446,44 +462,53 @@ void Foam::vtkPVFoam::convertPointFields
GeometricField<Type, pointPatchField, pointMesh> pfld(*iter(), pMesh);
// Convert activated internalMesh regions
// Convert internalMesh (if selected)
convertPointFieldBlock
(
pfld,
output,
rangeVolume_,
regionVtus_
rangeVolume_
);
// Convert activated cellZones
// Convert (selected) cellZones
convertPointFieldBlock
(
pfld,
output,
rangeCellZones_,
zoneVtus_
rangeCellZones_
);
// Convert activated cellSets
// Convert (selected) cellSets
convertPointFieldBlock
(
pfld,
output,
rangeCellSets_,
csetVtus_
rangeCellSets_
);
//
// Convert patches - if activated
// Convert patches (if selected)
//
for (auto partId : rangePatches_)
{
if (!selectedPartIds_.found(partId))
{
continue;
}
const auto& longName = selectedPartIds_[partId];
if (longName.startsWith("group/"))
{
// Skip patch-groups
continue;
}
const word patchName = getPartName(partId);
const label datasetNo = partDataset_[partId];
const label datasetNo = partDataset_.lookup(partId, -1);
const label patchId = patches.findPatchID(patchName);
if (!partStatus_[partId] || patchId < 0)
if (patchId < 0)
{
continue;
}
......@@ -506,15 +531,20 @@ void Foam::vtkPVFoam::convertPointFields
}
//