dune-grid  2.3.1-rc1
gmshwriter.hh
Go to the documentation of this file.
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 
12 #include <dune/common/exceptions.hh>
13 
14 #include <dune/geometry/type.hh>
15 
16 #include <dune/grid/common/grid.hh>
17 
18 
19 namespace Dune {
20 
36  template <class GridView>
37  class GmshWriter
38  {
39  private:
40  const GridView gv;
41 
42  static const int dim = GridView::dimension;
43  static const int dimWorld = GridView::dimensionworld;
44  dune_static_assert( (dimWorld <= 3), "GmshWriter requires dimWorld <= 3." );
45 
46  typedef typename GridView::template Codim<dim>::Iterator VertexIterator;
47  typedef typename GridView::template Codim<0>::Iterator ElementIterator;
48 
49 
51  size_t nodeIndexFromIterator(const ElementIterator& eIt, int i) const {
52  return gv.indexSet().subIndex(*eIt, i, dim)+1;
53  }
54 
58  static size_t translateDuneToGmshType(const GeometryType& type) {
59  // Probably the non-clever, but hopefully readable way of translating the GeometryTypes to the gmsh types
60  size_t element_type;
61 
62  if (type.isLine())
63  element_type = 1;
64  else if (type.isTriangle())
65  element_type = 2;
66  else if (type.isQuadrilateral())
67  element_type = 3;
68  else if (type.isTetrahedron())
69  element_type = 4;
70  else if (type.isHexahedron())
71  element_type = 5;
72  else if (type.isPrism())
73  element_type = 6;
74  else if (type.isPyramid())
75  element_type = 7;
76  else if (type.isVertex())
77  element_type = 15;
78  else
79  DUNE_THROW(Dune::IOError, "GeometryType " << type << " is not supported by gmsh.");
80 
81  return element_type;
82  }
83 
92  void outputElements(std::ofstream& file) const {
93  ElementIterator eIt = gv.template begin<0>();
94  ElementIterator eEndIt = gv.template end<0>();
95 
96  for (size_t i = 1; eIt != eEndIt; ++eIt, ++i) {
97  // Check whether the type is compatible. If not, close file and rethrow exception.
98  try {
99  size_t element_type = translateDuneToGmshType(eIt->type());
100 
101  file << i << " " << element_type << " " << 0; // "0" for "I do not use any tags."
102 
103  // Output list of nodes.
104  // 3, 5 and 7 got different vertex numbering compared to Dune
105  if (3 == element_type)
106  file << " "
107  << nodeIndexFromIterator(eIt, 0) << " " << nodeIndexFromIterator(eIt, 1) << " "
108  << nodeIndexFromIterator(eIt, 3) << " " << nodeIndexFromIterator(eIt, 2);
109  else if (5 == element_type)
110  file << " "
111  << nodeIndexFromIterator(eIt, 0) << " " << nodeIndexFromIterator(eIt, 1) << " "
112  << nodeIndexFromIterator(eIt, 3) << " " << nodeIndexFromIterator(eIt, 2) << " "
113  << nodeIndexFromIterator(eIt, 4) << " " << nodeIndexFromIterator(eIt, 5) << " "
114  << nodeIndexFromIterator(eIt, 7) << " " << nodeIndexFromIterator(eIt, 6);
115  else if (7 == element_type)
116  file << " "
117  << nodeIndexFromIterator(eIt, 0) << " " << nodeIndexFromIterator(eIt, 1) << " "
118  << nodeIndexFromIterator(eIt, 3) << " " << nodeIndexFromIterator(eIt, 2) << " "
119  << nodeIndexFromIterator(eIt, 4);
120  else {
121  for (int k = 0; k < eIt->geometry().corners(); ++k)
122  file << " " << nodeIndexFromIterator(eIt, k);
123  }
124 
125  file << std::endl;
126 
127  } catch(Exception& e) {
128  file.close();
129  throw;
130  }
131  }
132  }
133 
134 
141  void outputNodes(std::ofstream& file) const {
142  VertexIterator vIt = gv.template begin<dim>();
143  VertexIterator vEndIt = gv.template end<dim>();
144 
145  for (; vIt != vEndIt; ++vIt) {
146  typename VertexIterator::Entity::Geometry::GlobalCoordinate globalCoord = vIt->geometry().center();
147  int nodeIndex = gv.indexSet().index(*vIt)+1; // Start counting indices by "1".
148 
149  if (1 == dimWorld)
150  file << nodeIndex << " " << globalCoord[0] << " " << 0 << " " << 0 << std::endl;
151  else if (2 == dimWorld)
152  file << nodeIndex << " " << globalCoord[0] << " " << globalCoord[1] << " " << 0 << std::endl;
153  else // (3 == dimWorld)
154  file << nodeIndex << " " << globalCoord[0] << " " << globalCoord[1] << " " << globalCoord[2] << std::endl;
155  }
156  }
157 
158 
159  public:
163  GmshWriter(const GridView& gridView) : gv(gridView) {}
164 
176  void write(const std::string& fileName) const {
177  std::ofstream file(fileName.c_str());
178 
179  if (!file.is_open())
180  DUNE_THROW(Dune::IOError, "Could not open " << fileName << " with write access.");
181 
182  // Output Header
183  file << "$MeshFormat" << std::endl
184  << "2.0 0 " << sizeof(double) << std::endl // "2.0" for "version 2.0", "0" for ASCII
185  << "$EndMeshFormat" << std::endl;
186 
187 
188  // Output Nodes
189  const size_t number_of_nodes = gv.size(dim);
190  file << "$Nodes" << std::endl
191  << number_of_nodes << std::endl;
192 
193  outputNodes(file);
194 
195  file << "$EndNodes" << std::endl;
196 
197 
198  // Output Elements
199  const size_t number_of_elements = gv.size(0);
200  file << "$Elements" << std::endl
201  << number_of_elements << std::endl;
202 
203  outputElements(file);
204 
205  file << "$EndElements" << std::endl; // Add an additional new line for good measure.
206 
207 
208  file.close();
209  }
210  };
211 
212 } // namespace Dune
213 
214 #endif // DUNE_GRID_IO_FILE_GMSHWRITER_HH
The dimension of the world the grid lives in.
Definition: common/gridview.hh:124
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:178
The dimension of the grid.
Definition: common/gridview.hh:120
void write(const std::string &fileName) const
Write given grid in Gmsh 2.0 compatible ASCII file.
Definition: gmshwriter.hh:176
Write Gmsh mesh file.
Definition: gmshwriter.hh:37
GmshWriter(const GridView &gridView)
Constructor expecting GridView of Grid to be written.
Definition: gmshwriter.hh:163
Grid view abstract base classInterface class for a view on grids. Grids return two types of view...
Definition: common/gridview.hh:56
Different resources needed by all grid implementations.
const IndexSet & indexSet() const
obtain the index set
Definition: common/gridview.hh:158
int size(int codim) const
obtain number of entities in a given codimension
Definition: common/gridview.hh:164