Chi-Tech
unpartmesh_01f_readfromexodus.cc
Go to the documentation of this file.
2
4
5#include "utils/chi_utils.h"
6
7#include <vtkSmartPointer.h>
8#include <vtkUnstructuredGrid.h>
9#include <vtkExodusIIReader.h>
10#include <vtkMultiBlockDataSet.h>
11
12#include <vtkInformation.h>
13
14#include "chi_runtime.h"
15#include "chi_log.h"
16
17#define ErrorReadingFile(fname) \
18std::runtime_error("Failed to open file: " + options.file_name + \
19" in call to " + #fname + ".")
20
21//###################################################################
22/**Reads an Exodus unstructured mesh.*/
25{
26 Chi::log.Log() << "Reading Exodus file: " << options.file_name << ".";
27
28 //======================================== Attempt to open file
29 std::ifstream file;
30 file.open(options.file_name);
31 if (!file.is_open()) throw ErrorReadingFile(ReadFromExodus);
32 file.close();
33
34 //======================================== Read the file
35 mesh_options_ = options;
37 reader->SetFileName(options.file_name.c_str());
38
39 if (not reader->CanReadFile(options.file_name.c_str()))
40 throw std::logic_error("Unable to read file-type with this routine");
41
42 reader->UpdateInformation();
43 //Exodus ships boundary-ids via SideSets and NodeSets. This allows
44 //it to be read from the file. Here we have to enable the reader
45 //to process this because it does not do it by default.
46 reader->SetAllArrayStatus(reader->NODE_SET, 1);
47 reader->SetAllArrayStatus(reader->NODE_SET_CONN, 1);
48 reader->SetAllArrayStatus(reader->SIDE_SET, 1);
49 reader->SetAllArrayStatus(reader->SIDE_SET_CONN, 1);
50
51 //The exodusII file format ships blocks of elements
52 //together with their points/vertices as self-contained (localized)
53 //unstructured meshes. To relate these localized blocks to the original
54 //mesh, where are the blocks formed a whole, we need to know the mapping
55 //from block-local ids to the original ids. This information can
56 //be derived from the GlobalNodeID arrays loaded onto point-data and
57 //cell-data. Again, this information is not read by default so we have to
58 //turn this on.
59 reader->SetGenerateGlobalNodeIdArray(true);
60 reader->SetGenerateGlobalElementIdArray(true);
61 reader->Update();
62
63 //======================================== Get all the grid blocks
64 // This part was quite difficult. I eventually found how to do
65 // this from this post:
66 // https://public.kitware.com/pipermail/vtkusers/2010-December/064921.html
67 // It indicated that all exodus formats are read with a single
68 // top level vtkMultiBlockDataSet (Level 1). Each of the blocks in
69 // level 2 is also of type vtkMultiBlockDataSet. The level 2 block that has
70 // the actual elements is also split into blocks but these, level 3,
71 // blocks each contain a structure castable to vtkUnstructuredGrid.
72 auto multiblock = reader->GetOutput();
73
74 std::vector<vtkUGridPtrAndName> grid_blocks;
75 auto iter_a = multiblock->NewIterator();
76 iter_a->GoToFirstItem();
77 while (not iter_a->IsDoneWithTraversal())
78 {
79 auto block_a = iter_a->GetCurrentDataObject();
80
81 const std::string block_name = chi::StringTrim(
82 iter_a->GetCurrentMetaData()->Get(vtkCompositeDataSet::NAME()));
83
84 if (block_a->GetDataObjectType() == VTK_UNSTRUCTURED_GRID)
85 {
86 grid_blocks.emplace_back(
87 vtkUnstructuredGrid::SafeDownCast(block_a),block_name);
88
90 << "Reading block " << block_name
91 << " Number of cells: " << grid_blocks.back().first->GetNumberOfCells()
92 << " Number of points: " << grid_blocks.back().first->GetNumberOfPoints();
93 }
94
95 iter_a->GoToNextItem();
96 }
97
98 //======================================== Get the main + bndry blocks
99 const int max_dimension = chi_mesh::FindHighestDimension(grid_blocks);
100 Chi::log.Log0Verbose1() << "Maximum dimension : " << max_dimension << "\n";
101 std::vector<vtkUGridPtrAndName> domain_grid_blocks =
102 chi_mesh::GetBlocksOfDesiredDimension(grid_blocks, max_dimension);
103 std::vector<vtkUGridPtrAndName> bndry_grid_blocks =
104 chi_mesh::GetBlocksOfDesiredDimension(grid_blocks, max_dimension-1);
105
106 //======================================== Process blocks
107 chi_mesh::SetBlockIDArrays(domain_grid_blocks);
108 auto ugrid = chi_mesh::ConsolidateGridBlocks(domain_grid_blocks);
109
110 //======================================== Copy Data
111 // Material-IDs will get set form block-id arrays
112 CopyUGridCellsAndPoints(*ugrid, options.scale, max_dimension);
113
114 //======================================== Always do this
115 chi_mesh::MeshAttributes dimension = NONE;
116 switch (max_dimension)
117 {
118 case 1: dimension = DIMENSION_1; break;
119 case 2: dimension = DIMENSION_2; break;
120 case 3: dimension = DIMENSION_3; break;
121 default: break;
122 }
123
124 attributes_ = dimension | UNSTRUCTURED;
125
128
129 //======================================== Set boundary ids
130 SetBoundaryIDsFromBlocks(bndry_grid_blocks);
131
132 Chi::log.Log() << "Done reading Exodus file: "
133 << options.file_name << ".";
134}
static chi::ChiLog & log
Definition: chi_runtime.h:81
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
LogStream Log0Verbose1()
Definition: chi_log.h:234
void ReadFromExodus(const Options &options)
void CopyUGridCellsAndPoints(vtkUnstructuredGrid &ugrid, double scale, int dimension_to_copy)
void SetBoundaryIDsFromBlocks(std::vector< vtkUGridPtrAndName > &bndry_grid_blocks)
vtkUGridPtr ConsolidateGridBlocks(std::vector< vtkUGridPtrAndName > &ugrid_blocks, const std::string &block_id_array_name="BlockID")
MeshAttributes
Definition: chi_mesh.h:70
@ UNSTRUCTURED
Definition: chi_mesh.h:77
@ DIMENSION_1
Definition: chi_mesh.h:72
@ DIMENSION_2
Definition: chi_mesh.h:73
@ NONE
Definition: chi_mesh.h:71
@ DIMENSION_3
Definition: chi_mesh.h:74
void SetBlockIDArrays(std::vector< vtkUGridPtrAndName > &ugrid_blocks)
int FindHighestDimension(std::vector< vtkUGridPtrAndName > &ugrid_blocks)
std::vector< vtkUGridPtrAndName > GetBlocksOfDesiredDimension(std::vector< vtkUGridPtrAndName > &ugrid_blocks, int desired_dimension)
std::string StringTrim(const std::string &s)
#define ErrorReadingFile(fname)