3#ifndef DUNE_MMESH_GRID_GMSHGRIDFACTORY_HH
4#define DUNE_MMESH_GRID_GMSHGRIDFACTORY_HH
12#include <dune/grid/common/intersection.hh>
15#include <dune/mmesh/grid/explicitgridfactory.hh>
16#include <dune/mmesh/grid/implicitgridfactory.hh>
23 template<
class Gr
idImp,
class IntersectionImp >
28 template<
class Gr
id,
bool useImplicitGr
idFactory = false >
29 struct GmshGridFactory
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;
39 typedef std::conditional_t< useImplicitGridFactory,
40 MMeshImplicitGridFactory<Grid>,
41 MMeshExplicitGridFactory<Grid>
45 explicit GmshGridFactory ( std::istream &input )
50 DUNE_THROW(DGFException,
"Error resetting input stream." );
55 explicit GmshGridFactory (
const std::string &filename )
57 factory_ =
new GridFactory();
58 std::ifstream input( filename.c_str() );
60 DUNE_THROW( DGFException,
"Macrofile " << filename <<
" not found." );
61 if( !generate( input ) )
62 DUNE_THROW( DGFException,
"Could not generate MMesh from macrofile " << filename );
66 explicit GmshGridFactory ( Dune::GridFactory< Grid >& gridFactory,
const std::string &filename )
68 factory_ = &gridFactory;
69 std::ifstream input( filename.c_str() );
71 DUNE_THROW( DGFException,
"Macrofile " << filename <<
" not found." );
72 if( !generate( input ) )
73 DUNE_THROW( DGFException,
"Could not generate MMesh from macrofile " << filename );
78 std::shared_ptr<Grid> grid()
const
81 grid_ = factory_->createGrid();
87 template<
class Intersection >
88 bool wasInserted (
const Intersection &intersection )
const
90 return factory_->wasInserted( intersection );
94 bool generate( std::istream &gridFile )
98 std::getline(gridFile, line);
99 while (line.find(
"$Nodes") == std::string::npos)
101 if (!std::getline(gridFile, line))
102 DUNE_THROW(IOError,
"Gmsh file not valid!");
106 std::getline(gridFile, line);
107 const auto numVertices = convertString<std::size_t>(line);
109 std::getline(gridFile, line);
110 std::size_t vertexCount = 0;
111 while (line.find(
"$EndNodes") == std::string::npos)
114 std::istringstream stream(line);
115 std::string buf; stream >> buf;
117 for (
auto& coord : v)
120 if (stream.fail()) DUNE_THROW(Dune::IOError,
"Could not read vertex coordinate");
124 factory_->insertVertex( v );
125 if (!std::getline(gridFile, line))
126 DUNE_THROW(IOError,
"Gmsh file not valid!");
131 if (vertexCount != numVertices)
132 DUNE_THROW(Dune::InvalidStateException,
"Couldn't find as many vertices as stated in the .msh file");
135 while(line.find(
"$Elements") == std::string::npos)
136 if (!std::getline(gridFile, line))
137 DUNE_THROW(IOError,
"Gmsh file not valid!");
140 std::getline(gridFile, line);
141 const auto numElements = convertString<std::size_t>(line);
143 std::size_t elemCount = 0;
144 std::getline(gridFile, line);
145 while (line.find(
"$EndElements") == std::string::npos)
148 std::istringstream stream(line);
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");
155 const auto gt = obtainGeometryType( lineData[1] );
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);
163 if ( gt.dim() == dimension )
164 factory_->insertElement( gt, cornersIndices, lineData[2+lineData[2]] );
167 if ( gt.dim() == dimension-1 )
169 factory_->insertInterface( cornersIndices, lineData[2+lineData[2]] );
170 factory_->insertBoundarySegment( cornersIndices );
174 if ( gt.dim() == dimension-2 )
175 factory_->insertInterfaceBoundarySegment( cornersIndices );
178 if (!std::getline(gridFile, line))
179 DUNE_THROW(IOError,
"Gmsh file not valid!");
184 if (elemCount != numElements)
185 DUNE_THROW(Dune::InvalidStateException,
"Didn't read as many elements as stated in the .msh file");
193 T convertString(
const std::string&
string)
const
196 std::istringstream stream(
string);
199 DUNE_THROW(Dune::InvalidStateException,
"Couldn't convert string: " <<
string <<
"to type: " <<
typeid(T).name());
204 Dune::GeometryType obtainGeometryType(std::size_t gmshElemType)
const
206 switch (gmshElemType)
208 case 15:
return Dune::GeometryTypes::vertex;
209 case 1:
return Dune::GeometryTypes::line;
210 case 2:
return Dune::GeometryTypes::triangle;
211 case 3:
return Dune::GeometryTypes::quadrilateral;
212 case 4:
return Dune::GeometryTypes::tetrahedron;
213 case 5:
return Dune::GeometryTypes::hexahedron;
215 DUNE_THROW(Dune::NotImplemented,
"FacetCoupling gmsh reader for gmsh element type " << gmshElemType);
219 mutable std::shared_ptr<Grid> grid_;
220 GridFactory* factory_;