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>
22template <
class Gr
idImp,
class IntersectionImp>
27template <
class Gr
id,
bool useImplicitGr
idFactory = false>
28struct GmshGridFactory {
29 const static int dimension = Grid::dimension;
30 typedef MPIHelper::MPICommunicator MPICommunicatorType;
31 typedef typename Grid::template Codim<0>::Entity Element;
32 typedef typename Grid::template Codim<dimension>::Entity Vertex;
33 typedef typename Grid::FieldType FieldType;
34 typedef FieldVector<FieldType, dimension> GlobalPosition;
37 typedef std::conditional_t<useImplicitGridFactory,
38 MMeshImplicitGridFactory<Grid>,
39 MMeshExplicitGridFactory<Grid> >
43 explicit GmshGridFactory(std::istream &input) {
46 if (!input) DUNE_THROW(DGFException,
"Error resetting input stream.");
51 explicit GmshGridFactory(
const std::string &filename) {
52 factory_ =
new GridFactory();
53 std::ifstream input(filename.c_str());
55 DUNE_THROW(DGFException,
"Macrofile " << filename <<
" not found.");
57 DUNE_THROW(DGFException,
58 "Could not generate MMesh from macrofile " << filename);
62 explicit GmshGridFactory(Dune::GridFactory<Grid> &gridFactory,
63 const std::string &filename) {
64 factory_ = &gridFactory;
65 std::ifstream input(filename.c_str());
67 DUNE_THROW(DGFException,
"Macrofile " << filename <<
" not found.");
69 DUNE_THROW(DGFException,
70 "Could not generate MMesh from macrofile " << filename);
75 std::shared_ptr<Grid> grid()
const {
76 if (!grid_) grid_ = factory_->createGrid();
82 template <
class Intersection>
83 bool wasInserted(
const Intersection &intersection)
const {
84 return factory_->wasInserted(intersection);
88 bool generate(std::istream &gridFile) {
91 std::getline(gridFile, line);
92 while (line.find(
"$Nodes") == std::string::npos) {
93 if (!std::getline(gridFile, line))
94 DUNE_THROW(IOError,
"Gmsh file not valid!");
98 std::getline(gridFile, line);
99 const auto numVertices = convertString<std::size_t>(line);
101 std::getline(gridFile, line);
102 std::size_t vertexCount = 0;
103 while (line.find(
"$EndNodes") == std::string::npos) {
105 std::istringstream stream(line);
109 for (
auto &coord : v) {
112 DUNE_THROW(Dune::IOError,
"Could not read vertex coordinate");
116 factory_->insertVertex(v);
117 if (!std::getline(gridFile, line))
118 DUNE_THROW(IOError,
"Gmsh file not valid!");
123 if (vertexCount != numVertices)
124 DUNE_THROW(Dune::InvalidStateException,
125 "Couldn't find as many vertices as stated in the .msh file");
128 while (line.find(
"$Elements") == std::string::npos)
129 if (!std::getline(gridFile, line))
130 DUNE_THROW(IOError,
"Gmsh file not valid!");
133 std::getline(gridFile, line);
134 const auto numElements = convertString<std::size_t>(line);
136 std::size_t elemCount = 0;
137 std::getline(gridFile, line);
138 while (line.find(
"$EndElements") == std::string::npos) {
140 std::istringstream stream(line);
142 std::vector<std::size_t> lineData;
143 while (stream >> buf) lineData.push_back(convertString<std::size_t>(buf));
144 assert(lineData.size() >= 4 &&
"Grid format erroneous or unsupported");
147 const auto gt = obtainGeometryType(lineData[1]);
149 std::vector<unsigned int> cornersIndices;
150 auto it = lineData.begin() + 2 + lineData[2] + 1;
151 for (; it != lineData.end(); ++it)
152 cornersIndices.push_back(*it - 1);
155 if (gt.dim() == dimension)
156 factory_->insertElement(gt, cornersIndices, lineData[2 + lineData[2]]);
159 if (gt.dim() == dimension - 1) {
160 factory_->insertInterface(cornersIndices, lineData[2 + lineData[2]]);
161 factory_->insertBoundarySegment(cornersIndices);
165 if (gt.dim() == dimension - 2)
166 factory_->insertInterfaceBoundarySegment(cornersIndices);
169 if (!std::getline(gridFile, line))
170 DUNE_THROW(IOError,
"Gmsh file not valid!");
175 if (elemCount != numElements)
176 DUNE_THROW(Dune::InvalidStateException,
177 "Didn't read as many elements as stated in the .msh file");
185 T convertString(
const std::string &
string)
const {
187 std::istringstream stream(
string);
190 DUNE_THROW(Dune::InvalidStateException,
191 "Couldn't convert string: " <<
string <<
"to type: "
192 <<
typeid(T).name());
197 Dune::GeometryType obtainGeometryType(std::size_t gmshElemType)
const {
198 switch (gmshElemType) {
200 return Dune::GeometryTypes::vertex;
202 return Dune::GeometryTypes::line;
204 return Dune::GeometryTypes::triangle;
206 return Dune::GeometryTypes::quadrilateral;
208 return Dune::GeometryTypes::tetrahedron;
210 return Dune::GeometryTypes::hexahedron;
213 Dune::NotImplemented,
214 "FacetCoupling gmsh reader for gmsh element type " << gmshElemType);
218 mutable std::shared_ptr<Grid> grid_;
219 GridFactory *factory_;