Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/IO/ExodusIIMeshReader.hpp
4 : : \copyright 2012-2015 J. Bakosi,
5 : : 2016-2018 Los Alamos National Security, LLC.,
6 : : 2019-2021 Triad National Security, LLC.,
7 : : 2022-2024 J. Bakosi
8 : : All rights reserved. See the LICENSE file for details.
9 : : \brief ExodusII mesh reader
10 : : \details ExodusII mesh reader class declaration.
11 : : */
12 : : // *****************************************************************************
13 : : #ifndef ExodusIIMeshReader_h
14 : : #define ExodusIIMeshReader_h
15 : :
16 : : #include <cstddef>
17 : : #include <iosfwd>
18 : : #include <vector>
19 : : #include <array>
20 : : #include <map>
21 : : #include <unordered_map>
22 : :
23 : : #include "NoWarning/exodusII.hpp"
24 : :
25 : : #include "Types.hpp"
26 : : #include "Exception.hpp"
27 : : #include "UnsMesh.hpp"
28 : :
29 : : namespace tk {
30 : :
31 : : //! Supported ExodusII mesh cell types
32 : : //! \see ExodusIIMeshReader::readElemBlockIDs()
33 : : enum class ExoElemType : int { TET = 0, TRI = 1 };
34 : :
35 : : //! ExodusII mesh cell number of nodes
36 : : //! \details List of number of nodes per element for different element types
37 : : //! supported in the order of tk::ExoElemType
38 : : const std::array< std::size_t, 2 > ExoNnpe {{ 4, 3 }};
39 : :
40 : : //! ExodusII face-node numbering for tetrahedron side sets
41 : : //! \see ExodusII manual figure on "Sideset side Numbering"
42 : : const std::array< std::array< std::size_t, 3 >, 4 >
43 : : expofa{{ {{0,1,3}}, {{1,2,3}}, {{0,3,2}}, {{0,2,1}} }};
44 : :
45 : : //! ExodusII mesh-based data reader
46 : : //! \details Mesh reader class facilitating reading from mesh-based field data
47 : : //! a file in ExodusII format.
48 : : //! \see https://github.com/trilinos/Trilinos/tree/master/packages/seacas
49 : : class ExodusIIMeshReader {
50 : :
51 : : public:
52 : : //! Constructor
53 : : explicit ExodusIIMeshReader( const std::string& filename,
54 : : int cpuwordsize = sizeof(double),
55 : : int iowordsize = sizeof(double) );
56 : :
57 : : //! Destructor
58 : : ~ExodusIIMeshReader() noexcept;
59 : :
60 : : //! Read ExodusII mesh from file
61 : : void readMesh( UnsMesh& mesh );
62 : :
63 : : //! Return total number of mesh points in mesh file
64 : 243 : std::size_t npoin() { return readHeader(); }
65 : :
66 : : //! Read part of the mesh (graph and coords) from file
67 : : //! \details Total number of PEs defaults to 1 for a single-CPU read, this
68 : : //! PE defaults to 0 for a single-CPU read.
69 : : void readMeshPart( std::vector< std::size_t >& ginpoel,
70 : : std::vector< std::size_t >& inpoel,
71 : : std::vector< std::size_t >& triinp,
72 : : std::unordered_map< std::size_t, std::size_t >& lid,
73 : : tk::UnsMesh::Coords& coord,
74 : : int numpes=1, int mype=0 );
75 : :
76 : : //! Read coordinates of a number of mesh nodes from ExodusII file
77 : : std::array< std::vector< tk::real >, 3 >
78 : : readCoords( const std::vector< std::size_t >& gid ) const;
79 : :
80 : : //! Read face list of all side sets from ExodusII file
81 : : void
82 : : readSidesetFaces( std::map< int, std::vector< std::size_t > >& bface,
83 : : std::map< int, std::vector< std::size_t > >& faces );
84 : :
85 : : //! Read face connectivity of a number boundary faces from file
86 : : void readFaces( std::vector< std::size_t >& conn ) const;
87 : :
88 : : //! Read node list of all side sets from ExodusII file
89 : : std::map< int, std::vector< std::size_t > > readSidesetNodes();
90 : :
91 : : //! Read coordinates of a single mesh node from ExodusII file
92 : : void readNode( std::size_t fid,
93 : : std::size_t mid,
94 : : std::vector< tk::real >& x,
95 : : std::vector< tk::real >& y,
96 : : std::vector< tk::real >& z ) const;
97 : :
98 : : //! Read coordinates of a single mesh node from ExodusII file
99 : : void readNode( std::size_t id, std::array< tk::real, 3 >& coord ) const;
100 : :
101 : : //! Read coordinates of a number of mesh nodes from ExodusII file
102 : : std::array< std::vector< tk::real >, 3 >
103 : : readNodes( const std::vector< std::size_t >& gid ) const;
104 : :
105 : : //! Read element block IDs from file
106 : : std::size_t readElemBlockIDs();
107 : :
108 : : //! Read element connectivity of a number of mesh cells from file
109 : : void readElements( const std::array< std::size_t, 2 >& ext,
110 : : tk::ExoElemType elemtype,
111 : : std::vector< std::size_t >& conn ) const;
112 : :
113 : : //! Read local to global node-ID map
114 : : std::vector< std::size_t > readNodemap();
115 : :
116 : : //! Generate triangle face connectivity for side sets
117 : : std::vector< std::size_t > triinpoel(
118 : : std::map< int, std::vector< std::size_t > >& belem,
119 : : const std::map< int, std::vector< std::size_t > >& faces,
120 : : const std::vector< std::size_t >& ginpoel,
121 : : const std::vector< std::size_t >& triinp ) const;
122 : :
123 : : //! Read the names of nodal output variables from ExodusII file
124 : : void readNodeVarNames( std::vector< std::string >& nv ) const;
125 : :
126 : : //! Read time values from ExodusII file
127 : : void readTimeValues( std::vector< tk::real >& tv ) const;
128 : :
129 : : //! Read node scalar fields from ExodusII file
130 : : void readNodeScalars(
131 : : std::size_t ntime,
132 : : std::size_t nvar,
133 : : std::vector< std::vector< std::vector< tk::real > > >& var ) const;
134 : :
135 : : //! Return number of elements in a mesh block in the ExodusII file
136 : : std::size_t nelem( tk::ExoElemType elemtype ) const;
137 : :
138 : : //! Copy assignment
139 : : // cppcheck-suppress operatorEqVarError
140 : : // cppcheck-suppress operatorEqMissingReturnStatement
141 : : ExodusIIMeshReader& operator=( const ExodusIIMeshReader& x ) {
142 : : m_filename = x.m_filename;
143 : : m_cpuwordsize = x.m_cpuwordsize;
144 : : m_iowordsize = x.m_iowordsize;
145 : : float version;
146 : : m_inFile = ex_open( m_filename.c_str(), EX_READ, &m_cpuwordsize,
147 : : &m_iowordsize, &version );
148 : : ErrChk( m_inFile > 0, "Failed to open ExodusII file: " + m_filename );
149 : : m_nnode = x.m_nnode;
150 : : m_neblk = x.m_neblk;
151 : : m_neset = x.m_neset;
152 : : m_from = x.m_from;
153 : : m_till = x.m_till;
154 : : m_blockid = x.m_blockid;
155 : : m_blockid_by_type = x.m_blockid_by_type;
156 : : m_nel = x.m_nel;
157 : : m_elemblocks = x.m_elemblocks;
158 : : m_tri = x.m_tri;
159 : : return *this;
160 : : }
161 : :
162 : : //! Copy constructor: in terms of copy assignment
163 : : // cppcheck-suppress uninitMemberVar
164 : : ExodusIIMeshReader( const ExodusIIMeshReader& x ) { operator=(x); }
165 : :
166 : : //! Move assignment
167 : : // cppcheck-suppress operatorEqMissingReturnStatement
168 : : // cppcheck-suppress operatorEqVarError
169 : : ExodusIIMeshReader& operator=( ExodusIIMeshReader&& x ) {
170 : : m_filename = x.m_filename;
171 : : m_cpuwordsize = x.m_cpuwordsize;
172 : : m_iowordsize = x.m_iowordsize;
173 : : float version;
174 : : m_inFile = ex_open( m_filename.c_str(), EX_READ, &m_cpuwordsize,
175 : : &m_iowordsize, &version );
176 : : ErrChk( m_inFile > 0, "Failed to open ExodusII file: " + m_filename );
177 : : m_nnode = x.m_nnode;
178 : : m_neblk = x.m_neblk;
179 : : m_neset = x.m_neset;
180 : : m_from = x.m_from;
181 : : m_till = x.m_till;
182 : : m_blockid = x.m_blockid;
183 : : m_blockid_by_type = x.m_blockid_by_type;
184 : : m_nel = x.m_nel;
185 : : m_elemblocks = x.m_elemblocks;
186 : : m_tri = x.m_tri;
187 : : x.m_cpuwordsize = sizeof(double);
188 : : x.m_iowordsize = sizeof(double);
189 : : x.m_inFile = ex_open( m_filename.c_str(), EX_READ, &x.m_cpuwordsize,
190 : : &x.m_iowordsize, &version );
191 : : ErrChk( x.m_inFile > 0, "Failed to open ExodusII file: " + m_filename );
192 : : x.m_nnode = 0;
193 : : x.m_neblk = 0;
194 : : x.m_neset = 0;
195 : : x.m_from = 0;
196 : : x.m_till = 0;
197 : : x.m_blockid.clear();
198 : : x.m_blockid_by_type.resize( ExoNnpe.size() );
199 : : x.m_nel.resize( ExoNnpe.size() );
200 : : x.m_elemblocks.clear();
201 : : x.m_tri.clear();
202 : : return *this;
203 : : }
204 : :
205 : : //! Move constructor: in terms of move assignment
206 : : ExodusIIMeshReader( ExodusIIMeshReader&& x ) :
207 : : m_filename(),
208 : : m_cpuwordsize( 0 ),
209 : : m_iowordsize( 0 ),
210 : : m_inFile( 0 ),
211 : : m_nnode( 0 ),
212 : : m_neblk( 0 ),
213 : : m_neset( 0 ),
214 : : m_from( 0 ),
215 : : m_till( 0 ),
216 : : m_blockid(),
217 : : m_blockid_by_type(),
218 : : m_nel(),
219 : : m_elemblocks(),
220 : : m_tri()
221 : : { *this = std::move(x); }
222 : :
223 : : private:
224 : : std::string m_filename; //!< Input file name
225 : : int m_cpuwordsize; //!< CPU word size for ExodusII
226 : : int m_iowordsize; //!< I/O word size for ExodusII
227 : : int m_inFile; //!< ExodusII file handle
228 : : std::size_t m_nnode; //!< Number of nodes in file
229 : : std::size_t m_neblk; //!< Number of element blocks in file
230 : : std::size_t m_neset; //!< Number of element sets in file
231 : : std::size_t m_from; //!< Lower bound of tet ids on this PE
232 : : std::size_t m_till; //!< Upper bound of tet ids on this PE
233 : : //! Element block IDs in the order as in the file
234 : : std::vector< int > m_blockid;
235 : : //! Element block IDs for each elem type
236 : : std::vector< std::vector< int > > m_blockid_by_type;
237 : : //! Number of elements in blocks for each elem type
238 : : std::vector< std::vector< std::size_t > > m_nel;
239 : : //! Cell type and number of elements in blocks in the order as in the file
240 : : std::vector< std::pair< ExoElemType, std::size_t > > m_elemblocks;
241 : : //! Global->local triangle element ids on this PE
242 : : std::unordered_map< std::size_t, std::size_t > m_tri;
243 : :
244 : : //! Read ExodusII header without setting mesh size
245 : : std::size_t readHeader();
246 : :
247 : : //! Read ExodusII header with setting mesh size
248 : : void readHeader( UnsMesh& mesh );
249 : :
250 : : //! Read coordinates of a single mesh node from file
251 : : void readNode( std::size_t id, tk::real& x, tk::real& y, tk::real& z )
252 : : const;
253 : :
254 : : //! Read all node coordinates from ExodusII file
255 : : void readAllNodes( UnsMesh& mesh ) const;
256 : :
257 : : //! Read all element blocks and mesh connectivity from ExodusII file
258 : : void readAllElements( UnsMesh& mesh );
259 : :
260 : : //! Compute element-block-relative element id and element type
261 : : std::pair< tk::ExoElemType, std::size_t >
262 : : blkRelElemId( std::size_t id ) const;
263 : : };
264 : :
265 : : } // tk::
266 : :
267 : : #endif // ExodusIIMeshReader_h
|