Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/IO/MeshReader.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 Polymorphic mesh reader class for connecting to various readers
9 : : \brief Polymorphic mesh reader class for connecting to various lower
10 : : level, specific mesh readers.
11 : : */
12 : : // *****************************************************************************
13 : : #ifndef MeshReader_h
14 : : #define MeshReader_h
15 : :
16 : : #include <vector>
17 : : #include <array>
18 : : #include <string>
19 : : #include <memory>
20 : :
21 : : #include "Types.hpp"
22 : : #include "MeshDetect.hpp"
23 : : #include "ExodusIIMeshReader.hpp"
24 : :
25 : : #ifdef HAS_OMEGA_H
26 : : #include "Omega_h_MeshReader.hpp"
27 : : #endif
28 : :
29 : : namespace tk {
30 : :
31 : : //! Polymorphic mesh reader class for connecting to various mesh readers
32 : : //! \details This class uses runtime polymorphism without client-side
33 : : //! inheritance: inheritance is confined to the internals of the this class,
34 : : //! invisible to client-code. The class exclusively deals with ownership
35 : : //! enabling client-side value semantics. Credit goes to Sean Parent at Adobe.
36 : : //! \see http://sean-parent.stlab.cc/papers-and-presentations/#value-semantics-and-concept-based-polymorphism.
37 : : //! \see For example client code that models a MeshReader, see
38 : : //! tk::ExodusIIMeshReader or tk::Omega_h_MeshReader.
39 : : class MeshReader {
40 : :
41 : : public:
42 : : //! Constructor
43 : : //! \param[in] filename Input mesh filename
44 : : //! \details Dispatch constructor call to various low level mesh readers by
45 : : //! creating child class and assigning to base to be used in polymorphic
46 : : //! fashion.
47 : 899 : explicit MeshReader( const std::string& filename ) {
48 [ + - ]: 899 : auto meshtype = detectInput( filename );
49 [ + + ]: 899 : if (meshtype == MeshReaderType::EXODUSII) {
50 : : using R = ExodusIIMeshReader;
51 [ + - ][ + - ]: 894 : self = std::make_unique< Model<R> >( R(filename) );
52 : : #ifdef HAS_OMEGA_H
53 [ + - ]: 5 : } else if (meshtype == MeshReaderType::OMEGA_H) {
54 : : using R = Omega_h_MeshReader;
55 [ + - ][ + - ]: 5 : self = std::make_unique< Model<R> >( R(filename) );
56 : : #endif
57 [ - - ][ - - ]: 0 : } else Throw( "Mesh type not implemented or not supported" );
[ - - ]
58 : 899 : }
59 : :
60 : : //! Public interface to return the total number of nodes in mesh file
61 : 233 : std::size_t npoin() { return self->npoin(); }
62 : :
63 : : //! Public interface to read part of the mesh (graph and coords) from file
64 : : //! \details Total number of PEs defaults to 1 for a single-CPU read, this
65 : : //! PE defaults to 0 for a single-CPU read.
66 : 666 : void readMeshPart( std::vector< std::size_t >& ginpoel,
67 : : std::vector< std::size_t >& inpoel,
68 : : std::vector< std::size_t >& triinp,
69 : : std::unordered_map< std::size_t, std::size_t >& lid,
70 : : tk::UnsMesh::Coords& coord,
71 : : int numpes=1, int mype=0 )
72 : 666 : { self->readMeshPart( ginpoel, inpoel, triinp, lid, coord, numpes, mype ); }
73 : : //! ...
74 : 666 : std::vector< std::size_t > triinpoel(
75 : : std::map< int, std::vector< std::size_t > >& bface,
76 : : const std::map< int, std::vector< std::size_t > >& faceid,
77 : : const std::vector< std::size_t >& ginpoel,
78 : : const std::vector< std::size_t >& triinp )
79 : 666 : { return self->triinpoel( bface, faceid, ginpoel, triinp ); }
80 : :
81 : : //! Public interface to side sets from mesh file
82 : : void
83 : 233 : readSidesetFaces( std::map< int, std::vector< std::size_t > >& bface,
84 : : std::map< int, std::vector< std::size_t > >& faces )
85 : 233 : { self->readSidesetFaces( bface, faces ); }
86 : :
87 : : //! Public interface to read face connectivity of boundary faces from file
88 : : void readFaces( std::vector< std::size_t >& conn )
89 : : { self->readFaces( conn ); }
90 : :
91 : : //! Public interfaces to read node list of all side sets from mesh file
92 : 137 : std::map< int, std::vector< std::size_t > > readSidesetNodes()
93 : 137 : { return self->readSidesetNodes(); }
94 : :
95 : : //! Copy assignment
96 : : MeshReader& operator=( const MeshReader& x )
97 : : { MeshReader tmp(x); *this = std::move(tmp); return *this; }
98 : : //! Copy constructor
99 : : MeshReader( const MeshReader& x ) : self( x.self->copy() ) {}
100 : : //! Move assignment
101 : : MeshReader& operator=( MeshReader&& ) noexcept = default;
102 : : //! Move constructor
103 : : MeshReader( MeshReader&& ) noexcept = default;
104 : :
105 : : private:
106 : : //! \brief Concept is a pure virtual base class specifying the requirements
107 : : //! of polymorphic objects deriving from it
108 : : struct Concept {
109 : 899 : Concept() = default;
110 : 0 : Concept( const Concept& ) = default;
111 : 899 : virtual ~Concept() = default;
112 : : virtual Concept* copy() const = 0;
113 : : virtual std::size_t npoin() = 0;
114 : : virtual void readMeshPart(
115 : : std::vector< std::size_t >&,
116 : : std::vector< std::size_t >&,
117 : : std::vector< std::size_t >&,
118 : : std::unordered_map< std::size_t, std::size_t >&,
119 : : tk::UnsMesh::Coords&,
120 : : int, int ) = 0;
121 : : virtual void
122 : : readSidesetFaces( std::map< int, std::vector< std::size_t > >&,
123 : : std::map< int, std::vector< std::size_t > >& ) = 0;
124 : : virtual std::vector< std::size_t >
125 : : triinpoel( std::map< int, std::vector< std::size_t > >&,
126 : : const std::map< int, std::vector< std::size_t > >&,
127 : : const std::vector< std::size_t >&,
128 : : const std::vector< std::size_t >& ) = 0;
129 : : virtual void readFaces( std::vector< std::size_t >& ) const = 0;
130 : : virtual std::map< int, std::vector< std::size_t > >
131 : : readSidesetNodes() = 0;
132 : : };
133 : :
134 : : //! \brief Model models the Concept above by deriving from it and overriding
135 : : //! the the virtual functions required by Concept
136 : : template< typename T >
137 : : struct Model : Concept {
138 [ + - ]: 899 : Model( T x ) : data( std::move(x) ) {}
139 [ - - ]: 0 : Concept* copy() const override { return new Model( *this ); }
140 : 233 : std::size_t npoin() override { return data.npoin(); }
141 : 666 : void readMeshPart( std::vector< std::size_t >& ginpoel,
142 : : std::vector< std::size_t >& inpoel,
143 : : std::vector< std::size_t >& triinp,
144 : : std::unordered_map< std::size_t, std::size_t >& lid,
145 : : tk::UnsMesh::Coords& coord,
146 : : int numpes, int mype ) override
147 : 666 : { data.readMeshPart( ginpoel, inpoel, triinp, lid, coord, numpes,
148 : 666 : mype ); }
149 : 666 : std::vector< std::size_t > triinpoel(
150 : : std::map< int, std::vector< std::size_t > >& bface,
151 : : const std::map< int, std::vector< std::size_t > >& faceid,
152 : : const std::vector< std::size_t >& ginpoel,
153 : : const std::vector< std::size_t >& triinp ) override
154 : 666 : { return data.triinpoel( bface, faceid, ginpoel, triinp ); }
155 : : void
156 : 233 : readSidesetFaces( std::map< int, std::vector< std::size_t > >& bface,
157 : : std::map< int, std::vector< std::size_t > >& faces )
158 : 233 : override { data.readSidesetFaces( bface, faces ); }
159 : 0 : void readFaces( std::vector< std::size_t >& conn )
160 : 0 : const override { data.readFaces( conn ); }
161 : 137 : std::map< int, std::vector< std::size_t > > readSidesetNodes() override
162 : 137 : { return data.readSidesetNodes(); }
163 : : T data;
164 : : };
165 : :
166 : : std::unique_ptr< Concept > self; //!< Base pointer used polymorphically
167 : : };
168 : :
169 : : } // tk::
170 : :
171 : : #endif // MeshReader_h
|