Loading [MathJax]/extensions/tex2jax.js

dune-mmesh (1.4)

gmshgridfactory.hh
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_MMESH_GRID_GMSHGRIDFACTORY_HH
4#define DUNE_MMESH_GRID_GMSHGRIDFACTORY_HH
5
6// System includes
7#include <memory>
8#include <utility>
9#include <vector>
10
11// Dune includes
12#include <dune/grid/common/intersection.hh>
13
14// MMesh includes
15#include <dune/mmesh/grid/explicitgridfactory.hh>
16#include <dune/mmesh/grid/implicitgridfactory.hh>
17
18namespace Dune
19{
20
21 // External Forward Declarations
22 // -----------------------------
23 template< class GridImp, class IntersectionImp >
24 class Intersection;
25
26 // GmshGridFactory for MMesh
27 // ------------------------
28 template< class Grid, bool useImplicitGridFactory = false >
29 struct GmshGridFactory
30 {
31 const static int dimension = Grid::dimension;
32 typedef MPIHelper::MPICommunicator MPICommunicatorType;
33 typedef typename Grid::template Codim<0>::Entity Element;
34 typedef typename Grid::template Codim<dimension>::Entity Vertex;
35 typedef typename Grid::FieldType FieldType;
36 typedef FieldVector< FieldType, dimension > GlobalPosition;
37
38 // Choose explicit or implicit grid factory
39 typedef std::conditional_t< useImplicitGridFactory,
40 MMeshImplicitGridFactory<Grid>,
41 MMeshExplicitGridFactory<Grid>
42 > GridFactory;
43
45 explicit GmshGridFactory ( std::istream &input )
46 {
47 input.clear();
48 input.seekg( 0 );
49 if( !input )
50 DUNE_THROW(DGFException, "Error resetting input stream." );
51 generate( input );
52 }
53
55 explicit GmshGridFactory ( const std::string &filename )
56 {
57 factory_ = new GridFactory();
58 std::ifstream input( filename.c_str() );
59 if( !input )
60 DUNE_THROW( DGFException, "Macrofile " << filename << " not found." );
61 if( !generate( input ) )
62 DUNE_THROW( DGFException, "Could not generate MMesh from macrofile " << filename );
63 input.close();
64 }
65
66 explicit GmshGridFactory ( Dune::GridFactory< Grid >& gridFactory, const std::string &filename )
67 {
68 factory_ = &gridFactory;
69 std::ifstream input( filename.c_str() );
70 if( !input )
71 DUNE_THROW( DGFException, "Macrofile " << filename << " not found." );
72 if( !generate( input ) )
73 DUNE_THROW( DGFException, "Could not generate MMesh from macrofile " << filename );
74 input.close();
75 }
76
78 std::shared_ptr<Grid> grid() const
79 {
80 if ( !grid_ )
81 grid_ = factory_->createGrid();
82
83 return grid_;
84 }
85
87 template< class Intersection >
88 bool wasInserted ( const Intersection &intersection ) const
89 {
90 return factory_->wasInserted( intersection );
91 }
92
93 private:
94 bool generate( std::istream &gridFile )
95 {
96 // read file until we get to the list of nodes
97 std::string line;
98 std::getline(gridFile, line);
99 while (line.find("$Nodes") == std::string::npos)
100 {
101 if (!std::getline(gridFile, line))
102 DUNE_THROW(IOError, "Gmsh file not valid!");
103 }
104
105 // read all vertices
106 std::getline(gridFile, line);
107 const auto numVertices = convertString<std::size_t>(line);
108
109 std::getline(gridFile, line);
110 std::size_t vertexCount = 0;
111 while (line.find("$EndNodes") == std::string::npos)
112 {
113 // drop first entry in line (vertex index) and read coordinates
114 std::istringstream stream(line);
115 std::string buf; stream >> buf;
116 GlobalPosition v;
117 for (auto& coord : v)
118 {
119 stream >> coord;
120 if (stream.fail()) DUNE_THROW(Dune::IOError, "Could not read vertex coordinate");
121 }
122
123 // insert vertex and move to next line
124 factory_->insertVertex( v );
125 if (!std::getline(gridFile, line))
126 DUNE_THROW(IOError, "Gmsh file not valid!");
127 vertexCount++;
128 }
129
130 // we should always find as many vertices as the mesh file states
131 if (vertexCount != numVertices)
132 DUNE_THROW(Dune::InvalidStateException, "Couldn't find as many vertices as stated in the .msh file");
133
134 // read file until we get to the list of elements
135 while(line.find("$Elements") == std::string::npos)
136 if (!std::getline(gridFile, line))
137 DUNE_THROW(IOError, "Gmsh file not valid!");
138
139 // read elements
140 std::getline(gridFile, line);
141 const auto numElements = convertString<std::size_t>(line);
142
143 std::size_t elemCount = 0;
144 std::getline(gridFile, line);
145 while (line.find("$EndElements") == std::string::npos)
146 {
147 // pass all indices into vector
148 std::istringstream stream(line);
149 std::string buf;
150 std::vector<std::size_t> lineData;
151 while (stream >> buf) lineData.push_back(convertString<std::size_t>(buf));
152 assert(lineData.size() >= 4 && "Grid format erroneous or unsupported");
153
154 // obtain geometry type
155 const auto gt = obtainGeometryType( lineData[1] );
156
157 std::vector< unsigned int > cornersIndices;
158 auto it = lineData.begin()+2+lineData[2]+1;
159 for (; it != lineData.end(); ++it)
160 cornersIndices.push_back(*it-1); // gmsh indices start from 1
161
162 // insert element
163 if ( gt.dim() == dimension )
164 factory_->insertElement( gt, cornersIndices, lineData[2+lineData[2]] );
165
166 // insert interface/boundary segments
167 if ( gt.dim() == dimension-1 )
168 {
169 factory_->insertInterface( cornersIndices, lineData[2+lineData[2]] );
170 factory_->insertBoundarySegment( cornersIndices );
171 }
172
173 // insert interface's boundary segments
174 if ( gt.dim() == dimension-2 )
175 factory_->insertInterfaceBoundarySegment( cornersIndices );
176
177 // get next line
178 if (!std::getline(gridFile, line))
179 DUNE_THROW(IOError, "Gmsh file not valid!");
180 elemCount++;
181 }
182
183 // make sure we read all elements
184 if (elemCount != numElements)
185 DUNE_THROW(Dune::InvalidStateException, "Didn't read as many elements as stated in the .msh file");
186
187 return true;
188 }
189
190 private:
192 template<class T>
193 T convertString(const std::string& string) const
194 {
195 T value;
196 std::istringstream stream(string);
197 stream >> value;
198 if (stream.fail())
199 DUNE_THROW(Dune::InvalidStateException, "Couldn't convert string: " << string << "to type: " << typeid(T).name());
200 return value;
201 }
202
204 Dune::GeometryType obtainGeometryType(std::size_t gmshElemType) const
205 {
206 switch (gmshElemType)
207 {
208 case 15: return Dune::GeometryTypes::vertex; // points
209 case 1: return Dune::GeometryTypes::line; // lines
210 case 2: return Dune::GeometryTypes::triangle; // triangle
211 case 3: return Dune::GeometryTypes::quadrilateral; // quadrilateral
212 case 4: return Dune::GeometryTypes::tetrahedron; // tetrahedron
213 case 5: return Dune::GeometryTypes::hexahedron; // hexahedron
214 default:
215 DUNE_THROW(Dune::NotImplemented, "FacetCoupling gmsh reader for gmsh element type " << gmshElemType);
216 }
217 }
218
219 mutable std::shared_ptr<Grid> grid_;
220 GridFactory* factory_;
221 };
222
223} // end namespace Dune
224
225#endif
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Apr 13, 22:42, 2025)