Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/IO/HyperMeshReader.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 Hyper mesh reader class definition
9 : : \details Hyper mesh reader class definition. Only supports tetrahedra.
10 : : */
11 : : // *****************************************************************************
12 : :
13 : : #include <array>
14 : : #include <cstddef>
15 : : #include <vector>
16 : : #include <string>
17 : : #include <sstream>
18 : :
19 : : #include "NoWarning/pugixml.hpp"
20 : :
21 : : #include "Types.hpp"
22 : : #include "Exception.hpp"
23 : : #include "UnsMesh.hpp"
24 : : #include "HyperMeshReader.hpp"
25 : :
26 : : using tk::HyperMeshReader;
27 : :
28 : : void
29 : 1 : HyperMeshReader::readMesh( UnsMesh& mesh )
30 : : // *****************************************************************************
31 : : // Read Hyper mesh
32 : : //! \param[in] mesh Unstructured mesh object
33 : : // *****************************************************************************
34 : : {
35 [ + - ]: 2 : auto filenames = getFileNames();
36 : :
37 : : // Read nodes
38 [ + - ]: 1 : readNodes( filenames.first, mesh );
39 : : // Read elements
40 [ + - ]: 1 : readElements( filenames.second, mesh );
41 : 1 : }
42 : :
43 : :
44 : : std::pair< std::string, std::string >
45 : 1 : HyperMeshReader::getFileNames() const
46 : : // *****************************************************************************
47 : : // Read Hyper mesh metadata and extract filenames we need to read
48 : : //! \return Vector of strings containing the filenames
49 : : // *****************************************************************************
50 : : {
51 : : // Read XML file for metadata
52 [ + - ]: 2 : pugi::xml_document meta;
53 [ + - ]: 1 : auto res = meta.load_file( m_filename.c_str() );
54 [ + - ][ - + ]: 1 : ErrChk( res == true, "Could not parse XML attempting to read HyperMesh "
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
55 : : "metadata file '" + m_filename + "', at character position " +
56 : : std::to_string(res.offset) + " : " + res.description() );
57 : :
58 : : // Extract path from metadata filename
59 [ + - ]: 2 : std::string fn = m_filename;
60 [ + - ]: 2 : std::string path( fn.substr(0,fn.find_last_of("/")+1) );
61 : : // Prepend path to filenames to be extracted
62 [ + - ]: 1 : std::pair< std::string, std::string > filenames( path, path );
63 : :
64 [ + - ][ + - ]: 2 : for (const auto& child : meta.children("mesh"))
[ + + ][ + - ]
[ + - ]
65 [ + - ][ + - ]: 9 : for (const auto& group : child.children()) {
[ + + ][ + - ]
[ + - ]
66 : :
67 [ + - ][ + - ]: 8 : if (group.name() == std::string("coordinates")) {
[ + + ]
68 : :
69 [ + - ][ + - ]: 1 : filenames.first += group.attribute("file").value();
[ + - ]
70 : :
71 [ + - ][ + - ]: 7 : } else if (group.name() == std::string("element_set")) {
[ + + ]
72 : :
73 [ + - ][ + - ]: 1 : filenames.second += group.attribute("file").value();
[ + - ]
74 [ + - ][ + - ]: 1 : Assert( group.attribute("topology").value() ==
[ + - ][ - + ]
[ - - ][ - - ]
[ - - ]
75 : : std::string("four_node_tet"), "Only pure tetrahedron-element "
76 : : "meshes are supported" );
77 : : }
78 : : }
79 : :
80 : 2 : return filenames;
81 : : }
82 : :
83 : : void
84 : 1 : HyperMeshReader::readNodes( const std::string& filename, UnsMesh& mesh ) const
85 : : // *****************************************************************************
86 : : // Read nodes
87 : : //! \param[in] filename Filename to read nodes from
88 : : //! \param[in] mesh Unstructured mesh object to put nodes coordinates
89 : : //! \note We throw away the node ID, which means the nodes must be in order.
90 : : // *****************************************************************************
91 : : {
92 : : // Read in node coordinates: x-coord y-coord z-coord
93 [ + - ][ + - ]: 589 : for (auto& l : tk::Reader(filename).lines()) {
[ + + ]
94 [ + - ]: 1176 : std::stringstream ss(l);
95 : : int id;
96 : : tk::real x, y, z;
97 [ + - ][ + - ]: 588 : ss >> id >> x >> y >> z;
[ + - ][ + - ]
98 [ + - ]: 588 : mesh.x().push_back( x );
99 [ + - ]: 588 : mesh.y().push_back( y );
100 [ + - ]: 588 : mesh.z().push_back( z );
101 : : }
102 : 1 : }
103 : :
104 : : void
105 : 1 : HyperMeshReader::readElements( const std::string& filename, UnsMesh& mesh )
106 : : const
107 : : // *****************************************************************************
108 : : // Read element connectivity
109 : : //! \param[in] filename Filename to read nodes from
110 : : //! \param[in] mesh Unstructured mesh object to put element connectivity
111 : : //! \note We throw away the element ID.
112 : : // *****************************************************************************
113 : : {
114 [ + - ][ + - ]: 2351 : for (auto& l : tk::Reader(filename).lines()) {
[ + + ]
115 [ + - ]: 4700 : std::stringstream ss(l);
116 : : int id;
117 : : std::array< std::size_t, 4 > n;
118 [ + - ][ + - ]: 2350 : ss >> id >> n[0] >> n[1] >> n[2] >> n[3];
[ + - ][ + - ]
[ + - ]
119 [ + - ]: 2350 : mesh.tetinpoel().push_back( n[0] );
120 [ + - ]: 2350 : mesh.tetinpoel().push_back( n[1] );
121 [ + - ]: 2350 : mesh.tetinpoel().push_back( n[2] );
122 [ + - ]: 2350 : mesh.tetinpoel().push_back( n[3] );
123 : : }
124 : 1 : }
|