Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/IO/ExodusIIMeshWriter.cpp
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-based data writer
9 : : \details ExodusII mesh-based data writer class definition.
10 : : */
11 : : // *****************************************************************************
12 : :
13 : : #include <numeric>
14 : :
15 : : #include "NoWarning/exodusII.hpp"
16 : :
17 : : #include "ExodusIIMeshWriter.hpp"
18 : : #include "Exception.hpp"
19 : : #include "UnsMesh.hpp"
20 : :
21 : : using tk::ExodusIIMeshWriter;
22 : :
23 : 8405 : ExodusIIMeshWriter::ExodusIIMeshWriter( const std::string& filename,
24 : : ExoWriter mode,
25 : : int cpuwordsize,
26 : 8405 : int iowordsize ) :
27 : 8405 : m_filename( filename ), m_outFile( 0 )
28 : : // *****************************************************************************
29 : : // Constructor: create/open Exodus II file
30 : : //! \param[in] filename File to open as ExodusII file
31 : : //! \param[in] mode ExodusII writer constructor mode: ExoWriter::CREATE for
32 : : //! creating a new file, ExoWriter::OPEN for opening an existing file for
33 : : //! appending
34 : : //! \param[in] cpuwordsize Set CPU word size, see ExodusII documentation
35 : : //! \param[in] iowordsize Set I/O word size, see ExodusII documentation
36 : : // *****************************************************************************
37 : : {
38 : : // Increase verbosity from ExodusII library in debug mode
39 : : #ifndef NDEBUG
40 : : ex_opts( EX_DEBUG | EX_VERBOSE );
41 : : #endif
42 : :
43 [ + + ]: 8405 : if (mode == ExoWriter::CREATE) {
44 : :
45 [ + - ]: 1687 : m_outFile = ex_create( filename.c_str(),
46 : : EX_CLOBBER | EX_LARGE_MODEL,
47 : : &cpuwordsize,
48 : : &iowordsize );
49 : :
50 [ + - ]: 6718 : } else if (mode == ExoWriter::OPEN) {
51 : :
52 : : float version;
53 [ + - ]: 6718 : m_outFile = ex_open( filename.c_str(),
54 : : EX_WRITE,
55 : : &cpuwordsize,
56 : : &iowordsize,
57 : : &version );
58 : :
59 [ - - ][ - - ]: 0 : } else Throw( "Unknown ExodusII writer constructor mode" );
[ - - ][ - - ]
[ - - ][ - - ]
60 : :
61 [ - + ][ - - ]: 8405 : ErrChk( m_outFile > 0, "Failed to create/open ExodusII file: " + filename );
[ - - ][ - - ]
[ - - ][ - - ]
62 : 8405 : }
63 : :
64 : 16810 : ExodusIIMeshWriter::~ExodusIIMeshWriter() noexcept
65 : : // *****************************************************************************
66 : : // Destructor
67 : : // *****************************************************************************
68 : : {
69 [ - + ]: 8405 : if ( ex_close(m_outFile) < 0 )
70 : 0 : printf( ">>> WARNING: Failed to close ExodusII file: %s\n",
71 : : m_filename.c_str() );
72 : 8405 : }
73 : :
74 : : void
75 : 1687 : ExodusIIMeshWriter::writeMesh( const UnsMesh& mesh ) const
76 : : // *****************************************************************************
77 : : // Write ExodusII mesh file taking a tk::UnsMesh object
78 : : //! \param[in] mesh Unstructured mesh object
79 : : // *****************************************************************************
80 : : {
81 : 1687 : writeHeader( mesh );
82 : 1687 : writeNodes( mesh );
83 : 1687 : writeElements( mesh );
84 : 1687 : writeSidesets( mesh );
85 : 1687 : writeNodesets( mesh );
86 : 1687 : writeTimeValues( mesh.vartimes() );
87 : 1687 : writeNodeVarNames( mesh.nodevarnames() );
88 : 1687 : writeNodeScalars( mesh.nodevars() );
89 : 1687 : }
90 : :
91 : : void
92 : 59 : ExodusIIMeshWriter::writeMesh(
93 : : const std::vector< std::size_t >& tetinp,
94 : : const UnsMesh::Coords& coord,
95 : : const std::map< int, std::vector< std::size_t > >& bface,
96 : : const std::vector< std::size_t >& triinp ) const
97 : : // *****************************************************************************
98 : : // Write ExodusII mesh file taking inputs to a tk::UnsMesh object
99 : : //! \param[in] tetinp Tetrahedron element connectivity
100 : : //! \param[in] coord Node coordinates
101 : : //! \param[in] bface Boundary face ids for each side set
102 : : //! \param[in] triinp Triangle face connectivity (for all faces in bface)
103 : : // *****************************************************************************
104 : : {
105 : : // Fill element-relative face ids (0,1,2,3) for all side sets with 0 (will
106 : : // use triangles as face elements for side sets)
107 : : std::map< int, std::vector< std::size_t > > faceid;
108 [ + + ][ + - ]: 306 : for (const auto& s : bface) faceid[s.first].resize( s.second.size(), 0 );
[ + - ]
109 : :
110 : : // Generate file-internal Exodus (triangle face) element ids for all faces of
111 : : // all side sets. bface_exo:: face ids for each side set, triinpoel: triangle
112 : : // face connectivity for all side sets.
113 : : std::map< int, std::vector< std::size_t > > bface_exo;
114 [ + - ]: 59 : std::vector< std::size_t > triinpoel( triinp.size() );
115 : : // Generate/start exodus-file-face ids from max number of tetrahedra because
116 : : // tet elem blocks will be written out first
117 : 59 : std::size_t exo_faceid = tetinp.size() / 4;
118 [ + + ]: 306 : for (const auto& s : bface) {
119 [ + - ]: 247 : auto& b = bface_exo[ s.first ];
120 [ + - ]: 247 : b.resize( s.second.size() );
121 : : std::size_t j = 0; // side-set-relative face id
122 [ + + ]: 93589 : for (auto f : s.second) { // for all faces on side set s.first
123 : 93342 : b[ j++ ] = exo_faceid; // generate exo-file face id
124 : 93342 : auto k = exo_faceid - tetinp.size()/4;
125 : : // copy over triangle connectivity in order
126 : 93342 : triinpoel[ k*3+0 ] = triinp[ f*3+0 ];
127 : 93342 : triinpoel[ k*3+1 ] = triinp[ f*3+1 ];
128 : 93342 : triinpoel[ k*3+2 ] = triinp[ f*3+2 ];
129 : 93342 : ++exo_faceid;
130 : : }
131 : : }
132 : :
133 : : // Write mesh
134 [ + - ][ + - ]: 59 : writeMesh( tk::UnsMesh( tetinp, coord, bface_exo, triinpoel, faceid ) );
[ + - ][ - - ]
135 : 59 : }
136 : :
137 : : void
138 : 70 : ExodusIIMeshWriter::writeMesh(
139 : : const std::vector< std::size_t >& tetinp,
140 : : const UnsMesh::Coords& coord,
141 : : const std::map< int, std::vector< std::size_t > >& bnode ) const
142 : : // *****************************************************************************
143 : : // Write ExodusII mesh file taking inputs to a tk::UnsMesh object
144 : : //! \param[in] tetinp Tetrahedron element connectivity
145 : : //! \param[in] coord Node coordinates
146 : : //! \param[in] bnode Boundary node ids for each side set
147 : : // *****************************************************************************
148 : : {
149 [ + - ]: 70 : writeMesh( tk::UnsMesh( tetinp, coord, bnode ) );
150 : 70 : }
151 : :
152 : : void
153 : 1687 : ExodusIIMeshWriter::writeHeader( const UnsMesh& mesh ) const
154 : : // *****************************************************************************
155 : : // Write ExodusII header
156 : : //! \param[in] mesh Unstructured mesh object
157 : : // *****************************************************************************
158 : : {
159 [ - + ][ - - ]: 1687 : ErrChk(
[ - - ][ - - ]
[ - - ][ - - ]
160 : : ex_put_init( m_outFile,
161 : : "Written by Quinoa",
162 : : 3, // number of dimensions
163 : : static_cast< int64_t >( mesh.nnode() ),
164 : : static_cast< int64_t >( mesh.triinpoel().size()/3 +
165 : : mesh.tetinpoel().size()/4 ),
166 : : static_cast< int64_t >( mesh.neblk() ),
167 : : static_cast< int64_t >( mesh.bnode().size() ),
168 : : static_cast< int64_t >( mesh.bface().size() )
169 : : ) == 0,
170 : : "Failed to write header to file: " + m_filename );
171 : 1687 : }
172 : :
173 : : void
174 : 0 : ExodusIIMeshWriter::writeHeader( const char* title,
175 : : int64_t ndim,
176 : : int64_t nnodes,
177 : : int64_t nelem,
178 : : int64_t nblk,
179 : : int64_t node_set,
180 : : int64_t side_set ) const
181 : : // *****************************************************************************
182 : : // Write ExodusII header
183 : : //! \param[in] title ExodusII file header 'title'
184 : : //! \param[in] ndim Number of spatial dimensions in ExodusII file
185 : : //! \param[in] nnodes Number of mesh nodes in ExodusII file
186 : : //! \param[in] nelem Number of mesh elements in ExodusII file
187 : : //! \param[in] nblk Number of mesh element blocks in ExodusII file
188 : : //! \param[in] node_set Number of node sets in ExodusII file
189 : : //! \param[in] side_set Number of side sets in ExodusII file
190 : : // *****************************************************************************
191 : : {
192 [ - - ][ - - ]: 0 : ErrChk(
[ - - ][ - - ]
[ - - ][ - - ]
193 : : ex_put_init( m_outFile, title, ndim, nnodes, nelem, nblk,
194 : : node_set, side_set) == 0,
195 : : "Failed to write header to file: " + m_filename );
196 : 0 : }
197 : :
198 : : void
199 : 1687 : ExodusIIMeshWriter::writeNodes( const UnsMesh& mesh ) const
200 : : // *****************************************************************************
201 : : // Write node coordinates to ExodusII file
202 : : //! \param[in] mesh Unstructured mesh object
203 : : // *****************************************************************************
204 : : {
205 [ - + ][ - - ]: 1687 : ErrChk( ex_put_coord( m_outFile, mesh.x().data(), mesh.y().data(),
[ - - ][ - - ]
[ - - ][ - - ]
206 : : mesh.z().data() ) == 0,
207 : : "Failed to write coordinates to ExodusII file: " + m_filename );
208 : 1687 : }
209 : :
210 : : void
211 : 0 : ExodusIIMeshWriter::writeNodes( const std::vector< tk::real >& x,
212 : : const std::vector< tk::real >& y,
213 : : const std::vector< tk::real >& z ) const
214 : : // *****************************************************************************
215 : : // Write node coordinates to ExodusII file without Mesh
216 : : //! \param[in] x coordinates of mesh nodes
217 : : //! \param[in] y coordinates of mesh nodes
218 : : //! \param[in] z coordinates of mesh nodes
219 : : // *****************************************************************************
220 : : {
221 [ - - ][ - - ]: 0 : ErrChk( ex_put_coord( m_outFile, x.data(), y.data(), z.data() ) == 0,
[ - - ][ - - ]
[ - - ][ - - ]
222 : : "Failed to write coordinates to ExodusII file: " + m_filename );
223 : 0 : }
224 : :
225 : : void
226 : 1687 : ExodusIIMeshWriter::writeElements( const UnsMesh& mesh ) const
227 : : // *****************************************************************************
228 : : // Write element connectivity to ExodusII file
229 : : //! \param[in] mesh Unstructured mesh object
230 : : // *****************************************************************************
231 : : {
232 [ + - ]: 1687 : int elclass = 0;
233 : :
234 : : // For meshes that have no triangle element block (only tetrahedra), keeping
235 : : // the order as tets first followed by triangles allows keeping the tet ids
236 : : // associated to side sets the same when adding the missing triangle elements
237 : : // by meshconv. Hence this order should be kept as tets first triangles next.
238 : :
239 [ + - ][ + - ]: 3374 : writeElemBlock( elclass, 4, "TETRAHEDRA", mesh.tetinpoel() );
[ + - ]
240 [ + - ][ + - ]: 1687 : writeElemBlock( elclass, 3, "TRIANGLES", mesh.triinpoel() );
241 : 1687 : }
242 : :
243 : : void
244 [ + + ]: 3374 : ExodusIIMeshWriter::writeElemBlock( int& elclass,
245 : : int64_t nnpe,
246 : : const std::string& eltype,
247 : : const std::vector< std::size_t >& inpoel )
248 : : const
249 : : // *****************************************************************************
250 : : // Write element block to ExodusII file
251 : : //! \param[inout] elclass Count element class ids in file
252 : : //! \param[in] nnpe Number of nodes per element for block
253 : : //! \param[in] eltype String describing element type
254 : : //! \param[in] inpoel Element connectivity
255 : : // *****************************************************************************
256 : : {
257 [ + + ]: 3374 : if (inpoel.empty()) return;
258 : :
259 : : // increase number of element classes in file
260 : 1755 : ++elclass;
261 : :
262 : : // Compute number of edges and number of faces for triangles and tetrahedra
263 : : int nedge = 0, nface = 0;
264 [ + + ]: 1755 : if (nnpe == 4) {
265 : : nedge = 6;
266 : : nface = 4;
267 [ - + ]: 137 : } else if (nnpe == 3) {
268 : : nedge = 3;
269 : : nface = 1;
270 [ - - ][ - - ]: 0 : } else Throw( "Write ExodusII element block does not support elements with "
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
271 : : + std::to_string(nnpe) + " nodes" );
272 : :
273 : : // Write element block information
274 [ - + ][ - - ]: 1755 : ErrChk(
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
275 : : ex_put_block( m_outFile, // exo file handle
276 : : EX_ELEM_BLOCK, // block type: elem block
277 : : elclass, // element class id
278 : : eltype.c_str(), // element block description
279 : : static_cast< int64_t >( inpoel.size() ) / nnpe, // nof cells
280 : : nnpe, // number of nodes per element
281 : : nedge,// number of edges per element
282 : : nface,// number of faces per element
283 : : 0 // number of attributes per element
284 : : ) == 0,
285 : : "Failed to write " + eltype + " element block to ExodusII file: " +
286 : : m_filename );
287 : :
288 : : // Write element connectivity with 1-based node ids
289 : 1755 : std::vector< int > inp( inpoel.size() );
290 : : std::size_t i = 0;
291 [ + + ]: 8593360 : for (auto p : inpoel) inp[ i++ ] = static_cast< int >( p+1 );
292 [ + - ][ - + ]: 1755 : ErrChk( ex_put_conn( m_outFile, EX_ELEM_BLOCK, elclass, inp.data(),
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
293 : : nullptr, nullptr ) == 0,
294 : : "Failed to write " + eltype + " element connectivity to ExodusII "
295 : : "file: " + m_filename );
296 : : }
297 : :
298 : : void
299 : 1687 : ExodusIIMeshWriter::writeSidesets( const UnsMesh& mesh ) const
300 : : // *****************************************************************************
301 : : // Write side sets and their face connectivity to ExodusII file
302 : : //! \param[in] mesh Unstructured mesh object
303 : : // *****************************************************************************
304 : : {
305 : : // Write all side sets face list and connectivity in mesh
306 [ + + ]: 1939 : for (const auto& s : mesh.bface()) {
307 : : // Write side set parameters
308 [ + - ][ - + ]: 252 : ErrChk( ex_put_set_param( m_outFile, EX_SIDE_SET, s.first,
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
309 : : static_cast<int64_t>(s.second.size()), 0 ) == 0,
310 : : "Failed to write side set parameters to ExodusII file: " + m_filename );
311 : :
312 : : // ExodusII wants 32-bit integers as IDs of element ids
313 [ + - ]: 252 : std::vector< int > bface( s.second.size() );
314 : : std::size_t i = 0;
315 [ + + ]: 100876 : for (auto f : s.second) bface[ i++ ] = static_cast<int>(f)+1;
316 : : // ExodusII wants 32-bit integers as element-relative face IDs
317 : : const auto& fi = tk::cref_find( mesh.faceid(), s.first );
318 [ + - ][ - - ]: 252 : std::vector< int > faceid( fi.size() );
319 : : i = 0;
320 [ + + ]: 100876 : for (auto f : fi) faceid[ i++ ] = static_cast<int>(f)+1;
321 : :
322 : : // Write side set data: ExodusII-file internal element ids adjacent to side
323 : : // set and face id relative to element indicating which face is aligned with
324 : : // the side set.
325 [ + - ][ - + ]: 252 : ErrChk( ex_put_set( m_outFile, EX_SIDE_SET, s.first, bface.data(),
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
326 : : faceid.data() ) == 0,
327 : : "Failed to write side set face list to ExodusII file: " + m_filename );
328 : : }
329 : 1687 : }
330 : :
331 : : void
332 : 1687 : ExodusIIMeshWriter::writeNodesets( const UnsMesh& mesh ) const
333 : : // *****************************************************************************
334 : : // Write side sets and their node list to ExodusII file
335 : : //! \param[in] mesh Unstructured mesh object
336 : : // *****************************************************************************
337 : : {
338 : : // Write all side set node lists in mesh
339 [ + + ]: 1859 : for (const auto& s : mesh.bnode()) {
340 : : // Write side set parameters
341 [ + - ][ - + ]: 172 : ErrChk( ex_put_set_param( m_outFile, EX_NODE_SET, s.first,
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
342 : : static_cast<int64_t>(s.second.size()), 0 ) == 0,
343 : : "Failed to write side set parameters to ExodusII file: " + m_filename );
344 : :
345 : : // ExodusII wants 32-bit integers as IDs of node ids
346 [ + - ]: 172 : std::vector< int > bnode( s.second.size() );
347 : : std::size_t i = 0;
348 [ + + ]: 31499 : for (auto n : s.second) bnode[ i++ ] = static_cast<int>(n)+1;
349 : :
350 : : // Write side set data
351 [ + - ][ - + ]: 172 : ErrChk( ex_put_set( m_outFile, EX_NODE_SET, s.first, bnode.data(),
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
352 : : nullptr ) == 0,
353 : : "Failed to write side set node list to ExodusII file: " + m_filename );
354 : : }
355 : 1687 : }
356 : :
357 : : void
358 : 6718 : ExodusIIMeshWriter::writeTimeStamp( uint64_t it, tk::real time ) const
359 : : // *****************************************************************************
360 : : // Write time stamp to ExodusII file
361 : : //! \param[in] it Iteration number
362 : : //! \param[in] time Time
363 : : // *****************************************************************************
364 : : {
365 [ - + ][ - - ]: 6718 : ErrChk( ex_put_time( m_outFile, static_cast<int>(it), &time ) == 0,
[ - - ][ - - ]
[ - - ][ - - ]
366 : : "Failed to write time stamp to ExodusII file: " + m_filename );
367 : 6718 : }
368 : :
369 : : void
370 : 1687 : ExodusIIMeshWriter::writeTimeValues( const std::vector< tk::real >& tv ) const
371 : : // *****************************************************************************
372 : : // Write time values to ExodusII file
373 : : //! \param[in] tv Time values for all time steps
374 : : // *****************************************************************************
375 : : {
376 : : int i = 0;
377 [ + + ]: 1690 : for (const auto& v : tv) {
378 [ - + ][ - - ]: 3 : ErrChk( ex_put_time( m_outFile, ++i, &v ) == 0,
[ - - ][ - - ]
[ - - ][ - - ]
379 : : "Failed to write time value for a time step to ExodusII file: " +
380 : : m_filename );
381 : : }
382 : 1687 : }
383 : :
384 : : void
385 [ + + ]: 3364 : ExodusIIMeshWriter::writeNodeVarNames( const std::vector< std::string >& nv )
386 : : const
387 : : // *****************************************************************************
388 : : // Write the names of nodal output variables to ExodusII file
389 : : //! \param[in] nv Nodal variable names
390 : : // *****************************************************************************
391 : : {
392 [ + + ]: 3364 : if (!nv.empty()) {
393 : :
394 : : #if defined(__clang__)
395 : : #pragma clang diagnostic push
396 : : #pragma clang diagnostic ignored "-Wvla"
397 : : #pragma clang diagnostic ignored "-Wvla-extension"
398 : : #elif defined(STRICT_GNUC)
399 : : #pragma GCC diagnostic push
400 : : #pragma GCC diagnostic ignored "-Wvla"
401 : : #endif
402 : :
403 [ - + ][ - - ]: 861 : ErrChk(
[ - - ][ - - ]
[ - - ][ - - ]
404 : : ex_put_variable_param( m_outFile, EX_NODE_BLOCK,
405 : : static_cast< int >( nv.size() ) ) == 0,
406 : : "Failed to write nodal output variable parameters to ExodusII file: " +
407 : : m_filename );
408 : :
409 : 861 : char* names[ nv.size() ];
410 : : std::size_t i = 0;
411 [ + + ]: 6344 : for (const auto& n : nv) names[ i++ ] = const_cast< char* >( n.c_str() );
412 : :
413 [ - + ][ - - ]: 861 : ErrChk( ex_put_variable_names( m_outFile,
[ - - ][ - - ]
[ - - ][ - - ]
414 : : EX_NODE_BLOCK,
415 : : static_cast< int >( nv.size() ),
416 : : names ) == 0,
417 : : "Failed to write nodal output variable names to ExodusII file: " +
418 : : m_filename );
419 : :
420 : : #if defined(__clang__)
421 : : #pragma clang diagnostic pop
422 : : #elif defined(STRICT_GNUC)
423 : 861 : #pragma GCC diagnostic pop
424 : : #endif
425 : : }
426 : 3364 : }
427 : :
428 : : void
429 [ + + ]: 1609 : ExodusIIMeshWriter::writeElemVarNames( const std::vector< std::string >& ev )
430 : : const
431 : : // *****************************************************************************
432 : : // Write the names of element output variables to ExodusII file
433 : : //! \param[in] ev Elem variable names
434 : : // *****************************************************************************
435 : : {
436 [ + + ]: 1609 : if (!ev.empty()) {
437 : :
438 : : #if defined(__clang__)
439 : : #pragma clang diagnostic push
440 : : #pragma clang diagnostic ignored "-Wvla"
441 : : #pragma clang diagnostic ignored "-Wvla-extension"
442 : : #elif defined(STRICT_GNUC)
443 : : #pragma GCC diagnostic push
444 : : #pragma GCC diagnostic ignored "-Wvla"
445 : : #endif
446 : :
447 [ - + ][ - - ]: 1335 : ErrChk(
[ - - ][ - - ]
[ - - ][ - - ]
448 : : ex_put_variable_param( m_outFile, EX_ELEM_BLOCK,
449 : : static_cast< int >( ev.size() ) ) == 0,
450 : : "Failed to write element output variable parameters to ExodusII file: " +
451 : : m_filename );
452 : :
453 : 1335 : char* names[ ev.size() ];
454 : : std::size_t i = 0;
455 [ + + ]: 7389 : for (const auto& n : ev) names[ i++ ] = const_cast< char* >( n.c_str() );
456 : :
457 [ - + ][ - - ]: 1335 : ErrChk( ex_put_variable_names( m_outFile,
[ - - ][ - - ]
[ - - ][ - - ]
458 : : EX_ELEM_BLOCK,
459 : : static_cast< int >( ev.size() ),
460 : : names ) == 0,
461 : : "Failed to write element output variable names to ExodusII file: " +
462 : : m_filename );
463 : :
464 : : #if defined(__clang__)
465 : : #pragma clang diagnostic pop
466 : : #elif defined(STRICT_GNUC)
467 : 1335 : #pragma GCC diagnostic pop
468 : : #endif
469 : : }
470 : 1609 : }
471 : :
472 : : void
473 : 1687 : ExodusIIMeshWriter::writeNodeScalars(
474 : : const std::vector< std::vector< std::vector< tk::real > > >& var ) const
475 : : // *****************************************************************************
476 : : // Write multiple node scalar fields to ExodusII file at multiple time steps
477 : : //! \param[in] var Vector of nodal variables to read to: inner vector: nodes,
478 : : //! middle vector: (physics) variable, outer vector: time step
479 : : // *****************************************************************************
480 : : {
481 : : uint64_t time = 0;
482 : : int varid = 0;
483 : :
484 [ + + ]: 1690 : for (const auto& t : var) { // for all times
485 : 3 : ++time;
486 [ + + ]: 21 : for (const auto& v : t) { // for all variables
487 : 18 : writeNodeScalar( time, ++varid, v );
488 : : }
489 : : varid = 0;
490 : : }
491 : 1687 : }
492 : :
493 : : void
494 [ + - ]: 31479 : ExodusIIMeshWriter::writeNodeScalar( uint64_t it,
495 : : int varid,
496 : : const std::vector< tk::real >& var ) const
497 : : // *****************************************************************************
498 : : // Write node scalar field to ExodusII file
499 : : //! \param[in] it Iteration number
500 : : //! \param[in] varid Variable id
501 : : //! \param[in] var Vector of variable to output
502 : : // *****************************************************************************
503 : : {
504 [ + - ]: 31479 : if (!var.empty()) {
505 [ - + ][ - - ]: 31479 : ErrChk( ex_put_var( m_outFile,
[ - - ][ - - ]
[ - - ][ - - ]
506 : : static_cast< int >( it ),
507 : : EX_NODE_BLOCK,
508 : : varid,
509 : : 1,
510 : : static_cast< int64_t >( var.size() ),
511 : : var.data() ) == 0,
512 : : "Failed to write node scalar to ExodusII file: " + m_filename );
513 : : }
514 : 31479 : }
515 : :
516 : : void
517 [ + - ]: 23905 : ExodusIIMeshWriter::writeElemScalar( uint64_t it,
518 : : int varid,
519 : : const std::vector< tk::real >& var ) const
520 : : // *****************************************************************************
521 : : // Write elem scalar field to ExodusII file
522 : : //! \param[in] it Iteration number
523 : : //! \param[in] varid Variable id
524 : : //! \param[in] var Vector of variable to output
525 : : // *****************************************************************************
526 : : {
527 [ + - ]: 23905 : if (!var.empty()) {
528 [ - + ][ - - ]: 23905 : ErrChk( ex_put_var( m_outFile,
[ - - ][ - - ]
[ - - ][ - - ]
529 : : static_cast< int >( it ),
530 : : EX_ELEM_BLOCK,
531 : : varid,
532 : : 1,
533 : : static_cast< int64_t >( var.size() ),
534 : : var.data() ) == 0,
535 : : "Failed to write elem scalar to ExodusII file: " + m_filename );
536 : : }
537 : 23905 : }
|