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