Dune Core Modules (2.4.2)

gmshwriter.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_GRID_IO_FILE_GMSHWRITER_HH
4 #define DUNE_GRID_IO_FILE_GMSHWRITER_HH
5 
6 
7 #include <fstream>
8 #include <iostream>
9 
10 #include <string>
11 
13 
14 #include <dune/geometry/type.hh>
15 
16 #include <dune/grid/common/grid.hh>
18 
19 
20 namespace Dune {
21 
37  template <class GridView>
38  class GmshWriter
39  {
40  private:
41  const GridView gv;
42 
43  static const int dim = GridView::dimension;
44  static const int dimWorld = GridView::dimensionworld;
45  static_assert( (dimWorld <= 3), "GmshWriter requires dimWorld <= 3." );
46 
47  typedef typename GridView::template Codim<dim>::Iterator VertexIterator;
48  typedef typename GridView::template Codim<0>::Iterator ElementIterator;
49 
50 
52  size_t nodeIndexFromIterator(const ElementIterator& eIt, int i) const {
53  return gv.indexSet().subIndex(*eIt, i, dim)+1;
54  }
55 
59  static size_t translateDuneToGmshType(const GeometryType& type) {
60  // Probably the non-clever, but hopefully readable way of translating the GeometryTypes to the gmsh types
61  size_t element_type;
62 
63  if (type.isLine())
64  element_type = 1;
65  else if (type.isTriangle())
66  element_type = 2;
67  else if (type.isQuadrilateral())
68  element_type = 3;
69  else if (type.isTetrahedron())
70  element_type = 4;
71  else if (type.isHexahedron())
72  element_type = 5;
73  else if (type.isPrism())
74  element_type = 6;
75  else if (type.isPyramid())
76  element_type = 7;
77  else if (type.isVertex())
78  element_type = 15;
79  else
80  DUNE_THROW(Dune::IOError, "GeometryType " << type << " is not supported by gmsh.");
81 
82  return element_type;
83  }
84 
95  void outputElements(std::ofstream& file,
96  const std::vector<int>* physicalEntities = nullptr) const {
98  ElementIterator eIt = gv.template begin<0>();
99  ElementIterator eEndIt = gv.template end<0>();
100 
101  for (size_t i = 1; eIt != eEndIt; ++eIt, ++i) {
102  // Check whether the type is compatible. If not, close file and rethrow exception.
103  try {
104  size_t element_type = translateDuneToGmshType(eIt->type());
105 
106  file << i << " " << element_type;
107  // If present, set the first tag to the physical entity
108  if (physicalEntities) {
109  file << " " << 1 << " " << (*physicalEntities)[elementMapper.index(*eIt)];
110  } else {
111  file << " " << 0; // "0" for "I do not use any tags."
112  }
113 
114  // Output list of nodes.
115  // 3, 5 and 7 got different vertex numbering compared to Dune
116  if (3 == element_type)
117  file << " "
118  << nodeIndexFromIterator(eIt, 0) << " " << nodeIndexFromIterator(eIt, 1) << " "
119  << nodeIndexFromIterator(eIt, 3) << " " << nodeIndexFromIterator(eIt, 2);
120  else if (5 == element_type)
121  file << " "
122  << nodeIndexFromIterator(eIt, 0) << " " << nodeIndexFromIterator(eIt, 1) << " "
123  << nodeIndexFromIterator(eIt, 3) << " " << nodeIndexFromIterator(eIt, 2) << " "
124  << nodeIndexFromIterator(eIt, 4) << " " << nodeIndexFromIterator(eIt, 5) << " "
125  << nodeIndexFromIterator(eIt, 7) << " " << nodeIndexFromIterator(eIt, 6);
126  else if (7 == element_type)
127  file << " "
128  << nodeIndexFromIterator(eIt, 0) << " " << nodeIndexFromIterator(eIt, 1) << " "
129  << nodeIndexFromIterator(eIt, 3) << " " << nodeIndexFromIterator(eIt, 2) << " "
130  << nodeIndexFromIterator(eIt, 4);
131  else {
132  for (int k = 0; k < eIt->geometry().corners(); ++k)
133  file << " " << nodeIndexFromIterator(eIt, k);
134  }
135 
136  file << std::endl;
137 
138  } catch(Exception& e) {
139  file.close();
140  throw;
141  }
142  }
143  }
144 
145 
152  void outputNodes(std::ofstream& file) const {
153  VertexIterator vIt = gv.template begin<dim>();
154  VertexIterator vEndIt = gv.template end<dim>();
155 
156  for (; vIt != vEndIt; ++vIt) {
157  typename VertexIterator::Entity::Geometry::GlobalCoordinate globalCoord = vIt->geometry().center();
158  int nodeIndex = gv.indexSet().index(*vIt)+1; // Start counting indices by "1".
159 
160  if (1 == dimWorld)
161  file << nodeIndex << " " << globalCoord[0] << " " << 0 << " " << 0 << std::endl;
162  else if (2 == dimWorld)
163  file << nodeIndex << " " << globalCoord[0] << " " << globalCoord[1] << " " << 0 << std::endl;
164  else // (3 == dimWorld)
165  file << nodeIndex << " " << globalCoord[0] << " " << globalCoord[1] << " " << globalCoord[2] << std::endl;
166  }
167  }
168 
183  void writeImpl(const std::string& fileName, const std::vector<int>* physicalEntities = nullptr) const {
184  std::ofstream file(fileName.c_str());
185 
186  if (!file.is_open())
187  DUNE_THROW(Dune::IOError, "Could not open " << fileName << " with write access.");
188 
189  // Output Header
190  file << "$MeshFormat" << std::endl
191  << "2.0 0 " << sizeof(double) << std::endl // "2.0" for "version 2.0", "0" for ASCII
192  << "$EndMeshFormat" << std::endl;
193 
194 
195  // Output Nodes
196  const size_t number_of_nodes = gv.size(dim);
197  file << "$Nodes" << std::endl
198  << number_of_nodes << std::endl;
199 
200  outputNodes(file);
201 
202  file << "$EndNodes" << std::endl;
203 
204 
205  // Output Elements
206  const size_t number_of_elements = gv.size(0);
207  file << "$Elements" << std::endl
208  << number_of_elements << std::endl;
209 
210  outputElements(file, physicalEntities);
211 
212  file << "$EndElements" << std::endl; // Add an additional new line for good measure.
213 
214 
215  file.close();
216  }
217 
218 
219  public:
223  GmshWriter(const GridView& gridView) : gv(gridView) {}
224 
236  void write(const std::string& fileName) const {
237  writeImpl(fileName);
238  }
239 
255  void write(const std::string& fileName, const std::vector<int>& physicalEntities) const {
256  writeImpl(fileName, &physicalEntities);
257  }
258  };
259 
260 } // namespace Dune
261 
262 #endif // DUNE_GRID_IO_FILE_GMSHWRITER_HH
Base class for Dune-Exceptions.
Definition: exceptions.hh:91
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:25
bool isPrism() const
Return true if entity is a prism.
Definition: type.hh:296
bool isLine() const
Return true if entity is a line segment.
Definition: type.hh:271
bool isPyramid() const
Return true if entity is a pyramid.
Definition: type.hh:291
bool isTetrahedron() const
Return true if entity is a tetrahedron.
Definition: type.hh:286
bool isVertex() const
Return true if entity is a vertex.
Definition: type.hh:266
bool isHexahedron() const
Return true if entity is a hexahedron.
Definition: type.hh:301
bool isQuadrilateral() const
Return true if entity is a quadrilateral.
Definition: type.hh:281
bool isTriangle() const
Return true if entity is a triangle.
Definition: type.hh:276
Write Gmsh mesh file.
Definition: gmshwriter.hh:39
void write(const std::string &fileName) const
Write given grid in Gmsh 2.0 compatible ASCII file.
Definition: gmshwriter.hh:236
void write(const std::string &fileName, const std::vector< int > &physicalEntities) const
Write given grid in Gmsh 2.0 compatible ASCII file.
Definition: gmshwriter.hh:255
GmshWriter(const GridView &gridView)
Constructor expecting GridView of Grid to be written.
Definition: gmshwriter.hh:223
Grid view abstract base class.
Definition: gridview.hh:59
Default exception class for I/O errors.
Definition: exceptions.hh:256
Implementation class for a multiple codim and multiple geometry type mapper.
Definition: mcmgmapper.hh:104
Index index(const EntityType &e) const
Map entity to array index.
Definition: mcmgmapper.hh:162
Different resources needed by all grid implementations.
A few common exception classes.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:243
int size(int codim) const
obtain number of entities in a given codimension
Definition: gridview.hh:181
const IndexSet & indexSet() const
obtain the index set
Definition: gridview.hh:175
@ dimension
The dimension of the grid.
Definition: gridview.hh:130
@ dimensionworld
The dimension of the world the grid lives in.
Definition: gridview.hh:134
Mapper for multiple codim and multiple geometry types.
Dune namespace.
Definition: alignment.hh:10
Static tag representing a codimension.
Definition: dimension.hh:22
A unique label for each type of element that can occur in a grid.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)