VTK  9.7.1
vtkIOSSReaderInternal.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-FileCopyrightText: Copyright (c) Sandia Corporation
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #include "vtkIOSSReader.h" // For enums
6 #include "vtkIOSSUtilities.h" // For enums
7 
8 #include <vtk_ioss.h>
9 
10 // clang-format off
11 #include VTK_IOSS(Ionit_Initializer.h)
12 #include VTK_IOSS(Ioss_Assembly.h)
13 #include VTK_IOSS(Ioss_DatabaseIO.h)
14 #include VTK_IOSS(Ioss_EdgeBlock.h)
15 #include VTK_IOSS(Ioss_EdgeSet.h)
16 #include VTK_IOSS(Ioss_ElementBlock.h)
17 #include VTK_IOSS(Ioss_ElementSet.h)
18 #include VTK_IOSS(Ioss_ElementTopology.h)
19 #include VTK_IOSS(Ioss_FaceBlock.h)
20 #include VTK_IOSS(Ioss_FaceSet.h)
21 #include VTK_IOSS(Ioss_IOFactory.h)
22 #include VTK_IOSS(Ioss_NodeBlock.h)
23 #include VTK_IOSS(Ioss_NodeSet.h)
24 #include VTK_IOSS(Ioss_Region.h)
25 #include VTK_IOSS(Ioss_SideBlock.h)
26 #include VTK_IOSS(Ioss_SideSet.h)
27 #include VTK_IOSS(Ioss_StructuredBlock.h)
28 // clang-format on
29 
30 #include <algorithm>
31 #include <array>
32 #include <map>
33 #include <set>
34 #include <string>
35 #include <vector>
36 
37 VTK_ABI_NAMESPACE_BEGIN
38 
39 class vtkCellData;
40 class vtkDataArray;
41 class vtkDataAssembly;
43 class vtkFieldData;
44 class vtkIdTypeArray;
46 class vtkPointData;
47 class vtkPointSet;
48 class vtkStructuredGrid;
50 
52 {
53  int ProcessCount = 0;
54  std::set<int> Ranks;
55 
56  bool operator==(const DatabasePartitionInfo& other) const
57  {
58  return this->ProcessCount == other.ProcessCount && this->Ranks == other.Ranks;
59  }
60 };
61 
62 // Opaque handle used to identify a specific Region
63 using DatabaseHandle = std::pair<std::string, int>;
64 
75 {
76 protected:
77  // It's okay to instantiate this multiple times.
78  Ioss::Init::Initializer io;
79 
80  double DisplacementMagnitude = 1.;
81 
82  using DatabaseNamesType = std::map<std::string, DatabasePartitionInfo>;
86 
87  std::map<std::string, std::vector<std::pair<int, double>>> DatabaseTimes;
88  std::vector<double> TimestepValues;
90 
91  // a collection of names for blocks and sets in the file(s).
92  std::array<std::set<vtkIOSSUtilities::EntityNameType>, vtkIOSSReader::NUMBER_OF_ENTITY_TYPES>
95 
96  // Keeps track of idx of a partitioned dataset in the output.
97  std::map<std::pair<Ioss::EntityType, std::string>, unsigned int> DatasetIndexMap;
98 
99  std::map<DatabaseHandle, std::shared_ptr<Ioss::Region>> RegionMap;
100 
102 
105 
108 
109 public:
111 
113  : IOSSReader(reader)
114  {
115  }
116  virtual ~vtkIOSSReaderInternal() = default; // Force polymorphism
117 
118  Ioss::PropertyManager DatabaseProperties;
119  std::set<std::string> FileNames;
121 
122  std::set<std::string> Selectors;
123 
124  const std::vector<double>& GetTimeSteps() const { return this->TimestepValues; }
126 
127  void SetDisplacementMagnitude(double s) { this->DisplacementMagnitude = s; }
129 
131 
134  void ClearCache() { this->Cache.Clear(); }
135  void ResetCacheAccessCounts() { this->Cache.ResetAccessCounts(); }
136  void ClearCacheUnused() { this->Cache.ClearUnused(); }
138 
156 
172 
177  vtkIOSSReader* self, const std::vector<DatabaseHandle>& dbaseHandles);
178 
184 
188  bool UpdateAssembly(vtkIOSSReader* self, int* tag);
189 
190  vtkDataAssembly* GetAssembly() const;
191 
197 
202 
206  std::vector<vtkSmartPointer<vtkDataSet>> GetDataSets(const std::string& blockname,
207  vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle& handle, int timestep,
208  vtkIOSSReader* self);
209 
216  vtkSmartPointer<vtkDataSet> GetExodusEntityDataSet(const std::vector<std::string>& blockNames,
217  vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle& handle, int timestep,
218  vtkIOSSReader* self);
219 
223  bool GetQAAndInformationRecords(vtkFieldData* fd, const DatabaseHandle& handle);
224 
228  bool GetGlobalFields(vtkDataArraySelection* globalFieldSelection, vtkFieldData* fd,
229  const DatabaseHandle& handle, int timestep);
230 
234  bool HaveRestartFiles() const { return this->DatabaseTimes.size() > 1; }
235 
240  std::vector<DatabaseHandle> GetDatabaseHandles(int piece, int npieces, int timestep) const;
241 
245  std::string GetRawFileName(const DatabaseHandle& handle, bool shortname = false) const
246  {
247  auto iter = this->DatabaseNames.find(handle.first);
248  if (iter == this->DatabaseNames.end())
249  {
250  throw std::runtime_error("bad database handle!");
251  }
252 
253  const int& fileid = handle.second;
254  auto dbasename = shortname ? vtksys::SystemTools::GetFilenameName(handle.first) : handle.first;
255 
256  auto& dinfo = iter->second;
257  if (dinfo.ProcessCount > 0)
258  {
259  return Ioss::Utils::decode_filename(
260  dbasename, dinfo.ProcessCount, *std::next(dinfo.Ranks.begin(), fileid));
261  }
262  return dbasename;
263  }
264 
269  int GetFileProcessor(const DatabaseHandle& handle) const
270  {
271  auto iter = this->DatabaseNames.find(handle.first);
272  if (iter == this->DatabaseNames.end())
273  {
274  throw std::runtime_error("bad database handle!");
275  }
276  const int& fileid = handle.second;
277  auto& dinfo = iter->second;
278  if (dinfo.ProcessCount > 0)
279  {
280  return *std::next(dinfo.Ranks.begin(), fileid);
281  }
282 
283  // this is not a spatially partitioned file; just return 0.
284  return 0;
285  }
286 
290  bool HaveCreatedRegions(const std::vector<DatabaseHandle>& dbaseHandles)
291  {
292  if (this->RegionMap.empty())
293  {
294  return false;
295  }
296  const bool allHandlesAreNew =
297  std::all_of(dbaseHandles.begin(), dbaseHandles.end(), [&](const DatabaseHandle& handle)
298  { return this->RegionMap.find(handle) == this->RegionMap.end(); });
299  return !allHandlesAreNew;
300  }
301 
306  {
307  // RegionMap is where all the handles are kept. All we need to do is release
308  // them.
309  for (const auto& pair : this->RegionMap)
310  {
311  pair.second->get_database()->closeDatabase();
312  }
313  }
314 
320  void ReleaseRegions() { this->RegionMap.clear(); }
321 
325  void Reset()
326  {
327  this->Cache.Clear();
328  this->RegionMap.clear();
329  this->DatabaseNames.clear();
330  this->IOSSReader->RemoveAllSelections();
331  this->DatabaseNamesMTime = vtkTimeStamp();
332  this->SelectionsMTime = vtkTimeStamp();
333  this->TimestepValuesMTime = vtkTimeStamp();
334  }
335 
336  void ResetDatabaseNamesMTime() { this->DatabaseNamesMTime = vtkTimeStamp(); }
337 
338 protected:
339  std::vector<int> GetFileIds(const std::string& dbasename, int myrank, int numRanks) const;
340  Ioss::Region* GetRegion(
341  const std::string& dbasename, int fileid, Ioss::DatabaseUsage dbUsage = Ioss::READ_RESTART);
342  Ioss::Region* GetRegion(const DatabaseHandle& handle)
343  {
344  return this->GetRegion(handle.first, handle.second);
345  }
346 
348 
359  vtkSmartPointer<vtkAbstractArray> GetField(const std::string& fieldname, Ioss::Region* region,
360  const Ioss::GroupingEntity* group_entity, const DatabaseHandle& handle, int timestep,
361  vtkIdTypeArray* ids_to_extract = nullptr, const std::string& cache_key_suffix = std::string());
363 
375  std::vector<std::pair<int, vtkSmartPointer<vtkCellArray>>> GetTopology(
376  const std::string& blockname, vtkIOSSReader::EntityType vtk_entity_type,
377  const DatabaseHandle& handle);
378 
383  std::pair<vtkSmartPointer<vtkDataArray>, vtkSmartPointer<vtkCellArray>> CombineTopologies(
384  const std::vector<std::pair<int, vtkSmartPointer<vtkCellArray>>>& topologies);
385 
398  bool GetTopology(vtkUnstructuredGrid* grid, const std::string& blockname,
399  vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle& handle);
400 
414  const std::string& blockname, const DatabaseHandle& handle);
415 
428  bool GetGeometry(
429  vtkUnstructuredGrid* grid, const std::string& blockname, const DatabaseHandle& handle);
430 
434  bool GetGeometry(vtkStructuredGrid* grid, const Ioss::StructuredBlock* groupEntity);
435 
441  Ioss::GroupingEntity* GetNodeBlock(const Ioss::Region* region, const std::string& blockname);
442 
459  bool GetMesh(vtkUnstructuredGrid* grid, const std::string& blockname,
460  vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle& handle,
461  bool remove_unused_points);
462 
474  bool GetEntityMesh(vtkUnstructuredGrid* grid, const std::vector<std::string>& blockNames,
475  vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle& handle);
476 
484  bool GetMesh(vtkStructuredGrid* grid, const std::string& blockname,
485  vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle& handle);
486 
492  bool GenerateEntityIdArray(vtkCellData* cd, vtkIdType numberOfCells, const std::string& blockname,
493  vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle& handle);
494 
516  bool GetFields(vtkDataSetAttributes* dsa, vtkDataArraySelection* selection, Ioss::Region* region,
517  Ioss::GroupingEntity* group_entity, const DatabaseHandle& handle, int timestep,
518  bool read_ioss_ids, vtkIdTypeArray* ids_to_extract = nullptr,
519  const std::string& cache_key_suffix = std::string(), vtkFieldData* field_data = nullptr);
520 
529  Ioss::Region* region, Ioss::GroupingEntity* group_entity, const DatabaseHandle& handle,
530  int timestep, bool read_ioss_ids, bool mergeExodusEntityBlocks = false);
531 
536  bool ApplyDisplacements(vtkPointSet* grid, Ioss::Region* region,
537  Ioss::GroupingEntity* group_entity, const DatabaseHandle& handle, int timestep,
538  bool mergeExodusEntityBlocks = false);
539 
543  bool GenerateFileId(vtkDataSetAttributes* cellData, vtkIdType numberOfCells,
544  Ioss::GroupingEntity* group_entity, const DatabaseHandle& handle);
545 
551 
552  unsigned int GetDataSetIndexForEntity(const Ioss::GroupingEntity* entity) const
553  {
554  return this->DatasetIndexMap.at(std::make_pair(entity->type(), entity->name()));
555  }
556 
560  void GenerateElementAndSideIds(vtkDataSet* dataset, Ioss::SideSet* sideSet,
561  const DatabaseHandle& handle, const std::string& blockname,
562  vtkIOSSReader::EntityType vtk_entity_type);
563 
565 
569  std::vector<vtkSmartPointer<vtkDataSet>> GetExodusDataSets(const std::string& blockname,
570  vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle& handle, int timestep,
571  vtkIOSSReader* self);
572 
573  std::vector<vtkSmartPointer<vtkDataSet>> GetCGNSDataSets(const std::string& blockname,
574  vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle& handle, int timestep,
575  vtkIOSSReader* self);
577 
578  bool BuildAssembly(Ioss::Region* region, vtkDataAssembly* assembly, int root, bool add_leaves);
579 
585 };
586 
587 VTK_ABI_NAMESPACE_END
Ioss::Init::Initializer io
vtkDataAssembly * GetAssembly() const
bool UpdateTimeInformation(vtkIOSSReader *self)
Read Ioss databases to generate information about timesteps / times in the databases.
bool GetMesh(vtkUnstructuredGrid *grid, const std::string &blockname, vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle &handle, bool remove_unused_points)
Adds geometry (points) and topology (cell) information to the grid for the entity block or set chosen...
Ioss::Region * GetRegion(const std::string &dbasename, int fileid, Ioss::DatabaseUsage dbUsage=Ioss::READ_RESTART)
vtkSmartPointer< vtkAbstractArray > ConvertFieldForVTK(vtkAbstractArray *array)
Fields like "ids" have to be vtkIdTypeArray in VTK.
represent and manipulate point attribute data
Definition: vtkPointData.h:30
std::array< std::set< vtkIOSSUtilities::EntityNameType >, vtkIOSSReader::NUMBER_OF_ENTITY_TYPES > EntityNames
void Reset()
Clear all regions, databases etc.
abstract class to specify dataset behavior
Definition: vtkDataSet.h:56
std::vector< vtkSmartPointer< vtkDataSet > > GetDataSets(const std::string &blockname, vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle &handle, int timestep, vtkIOSSReader *self)
Reads datasets (meshes and fields) for the given block.
Abstract superclass for all arrays.
bool GenerateFileId(vtkDataSetAttributes *cellData, vtkIdType numberOfCells, Ioss::GroupingEntity *group_entity, const DatabaseHandle &handle)
Adds 'file_id' array to indicate which file the dataset was read from.
bool GetQAAndInformationRecords(vtkFieldData *fd, const DatabaseHandle &handle)
Read quality assurance and information data from the file.
bool ReadAssemblies(vtkPartitionedDataSetCollection *output, const DatabaseHandle &handle)
Fills up the vtkDataAssembly with ioss-assemblies, if present.
std::map< std::pair< Ioss::EntityType, std::string >, unsigned int > DatasetIndexMap
bool HaveCreatedRegions(const std::vector< DatabaseHandle > &dbaseHandles)
Returns if the given database handles have regions already created.
record modification and/or execution time
Definition: vtkTimeStamp.h:24
represent and manipulate cell attribute data
Definition: vtkCellData.h:31
bool GetEntityMesh(vtkUnstructuredGrid *grid, const std::vector< std::string > &blockNames, vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle &handle)
Adds geometry (points) and topology (cell) information to the grid for all the entity blocks or sets ...
std::string GetRawFileName(const DatabaseHandle &handle, bool shortname=false) const
Useful for printing error messages etc.
void ResetCacheAccessCounts()
Cache related API.
Ioss::GroupingEntity * GetNodeBlock(const Ioss::Region *region, const std::string &blockname)
Get IOSS NodeBlock blockname if it exists, otherwise get first Nodeblock in region.
void ReleaseHandles()
Releases any open file handles.
Internal methods and state for the IOSS reader.
const std::vector< double > & GetTimeSteps() const
bool GenerateOutput(vtkPartitionedDataSetCollection *output, vtkIOSSReader *self)
Fills up the output data-structure based on the entity blocks/sets chosen and those available...
std::map< std::string, std::vector< std::pair< int, double > > > DatabaseTimes
concrete class for storing a set of points
Definition: vtkPointSet.h:58
dynamic, self-adjusting array of vtkIdType
virtual ~vtkIOSSReaderInternal()=default
int vtkIdType
Definition: vtkType.h:363
std::vector< DatabaseHandle > GetDatabaseHandles(int piece, int npieces, int timestep) const
Returns the list of fileids, if any to be read for a given "piece" for the chosen timestep...
bool GenerateEntityIdArray(vtkCellData *cd, vtkIdType numberOfCells, const std::string &blockname, vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle &handle)
Add "id" array to the dataset using the id for the grouping entity, if any.
bool UpdateEntityAndFieldSelections(vtkIOSSReader *self)
Populates various vtkDataArraySelection objects on the vtkIOSSReader with names for entity-blocks...
std::map< std::string, DatabasePartitionInfo > DatabaseNamesType
bool HaveRestartFiles() const
Get if there are restart files available.
void GenerateElementAndSideIds(vtkDataSet *dataset, Ioss::SideSet *sideSet, const DatabaseHandle &handle, const std::string &blockname, vtkIOSSReader::EntityType vtk_entity_type)
Add field-data arrays holding side-set specifications (i.e., (cell-id, side-id) tuples) for use by th...
vtkSmartPointer< vtkAbstractArray > GetField(const std::string &fieldname, Ioss::Region *region, const Ioss::GroupingEntity *group_entity, const DatabaseHandle &handle, int timestep, vtkIdTypeArray *ids_to_extract=nullptr, const std::string &cache_key_suffix=std::string())
Reads a field with name fieldname from entity block or set with chosen name (blockname) and type (vtk...
std::pair< std::string, int > DatabaseHandle
DatabaseNamesType GenerateSubset(const DatabaseNamesType &databases, vtkIOSSReader *self)
Generate a subset based the readers current settings for FileRange and FileStride.
std::vector< vtkSmartPointer< vtkDataSet > > GetExodusDataSets(const std::string &blockname, vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle &handle, int timestep, vtkIOSSReader *self)
Called by GetDataSets to process each type of dataset.
Ioss::PropertyManager DatabaseProperties
std::vector< int > GetFileIds(const std::string &dbasename, int myrank, int numRanks) const
std::map< DatabaseHandle, std::shared_ptr< Ioss::Region > > RegionMap
void SetDisplacementMagnitude(double s)
bool GetNodeFields(vtkDataSetAttributes *dsa, vtkDataArraySelection *selection, Ioss::Region *region, Ioss::GroupingEntity *group_entity, const DatabaseHandle &handle, int timestep, bool read_ioss_ids, bool mergeExodusEntityBlocks=false)
This reads node fields for an entity block or set.
vtkIOSSUtilities::DatabaseFormatType Format
std::vector< std::pair< int, vtkSmartPointer< vtkCellArray > > > GetTopology(const std::string &blockname, vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle &handle)
Get a vector of cell arrays and their cell type for the entity block (or set) with the given name (bl...
DatabaseNamesType UnfilteredDatabaseNames
Store on/off settings for data arrays, etc.
bool operator==(const DatabasePartitionInfo &other) const
dataset represents arbitrary combinations of all possible cell types
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:44
vtkSmartPointer< vtkDataSet > GetExodusEntityDataSet(const std::vector< std::string > &blockNames, vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle &handle, int timestep, vtkIOSSReader *self)
Reads datasets (meshes and fields) for the given exodus entity.
vtkIOSSUtilities::Cache Cache
vtkIOSSReaderInternal(vtkIOSSReader *reader)
bool UpdateDatabaseNames(vtkIOSSReader *self)
Processes filenames to populate names for Ioss databases to read.
vtkSmartPointer< vtkPoints > GetGeometry(const std::string &blockname, const DatabaseHandle &handle)
Get with point coordinates aka geometry read from the block with the given name (blockname).
bool UpdateAssembly(vtkIOSSReader *self, int *tag)
Populates the vtkDataAssembly used for block/set selection.
DatabaseNamesType DatabaseNames
represent and manipulate attribute data in a dataset
void Clear()
Clears the cache.
int GetFileProcessor(const DatabaseHandle &handle) const
For spatially partitioned files, this returns the partition identifier for the file identified by the...
void ClearCacheUnused()
Cache related API.
std::set< std::string > FileNames
Ioss::Region * GetRegion(const DatabaseHandle &handle)
std::vector< double > TimestepValues
unsigned int GetDataSetIndexForEntity(const Ioss::GroupingEntity *entity) const
void ReleaseRegions()
Little more aggressive than ReleaseHandles but less intense than Reset, releases all IOSS regions and...
Reader for IOSS (Sierra IO System)
topologically regular array of data
hierarchical representation to use with vtkPartitionedDataSetCollection
bool ApplyDisplacements(vtkPointSet *grid, Ioss::Region *region, Ioss::GroupingEntity *group_entity, const DatabaseHandle &handle, int timestep, bool mergeExodusEntityBlocks=false)
Reads node block array with displacements and then transforms the points in the grid using those disp...
void ResetAccessCounts()
Call this to clear internal count for hits.
std::pair< vtkSmartPointer< vtkDataArray >, vtkSmartPointer< vtkCellArray > > CombineTopologies(const std::vector< std::pair< int, vtkSmartPointer< vtkCellArray >>> &topologies)
Combine a vector cell types, cell arrays pairs into a single vtkDataArray of cell types and a vtkCell...
std::set< std::string > Selectors
vtkIOSSUtilities::DatabaseFormatType GetFormat() const
void ClearCache()
Cache related API.
vtkSmartPointer< vtkDataAssembly > Assembly
bool BuildAssembly(Ioss::Region *region, vtkDataAssembly *assembly, int root, bool add_leaves)
bool GetFields(vtkDataSetAttributes *dsa, vtkDataArraySelection *selection, Ioss::Region *region, Ioss::GroupingEntity *group_entity, const DatabaseHandle &handle, int timestep, bool read_ioss_ids, vtkIdTypeArray *ids_to_extract=nullptr, const std::string &cache_key_suffix=std::string(), vtkFieldData *field_data=nullptr)
Reads selected field arrays for the given entity block or set.
void ClearUnused()
Removes all cached entries not accessed since most recent call to ResetAccessCounts.
bool GetGlobalFields(vtkDataArraySelection *globalFieldSelection, vtkFieldData *fd, const DatabaseHandle &handle, int timestep)
Read global fields.
Represents and manipulates a collection of data arrays.
Definition: vtkFieldData.h:51
std::vector< vtkSmartPointer< vtkDataSet > > GetCGNSDataSets(const std::string &blockname, vtkIOSSReader::EntityType vtk_entity_type, const DatabaseHandle &handle, int timestep, vtkIOSSReader *self)
Called by GetDataSets to process each type of dataset.
bool NeedToUpdateEntityAndFieldSelections(vtkIOSSReader *self, const std::vector< DatabaseHandle > &dbaseHandles)
Checks if the entity and field selections have changed.
void RemoveAllSelections()
Composite dataset that groups datasets as a collection.