Dune Core Modules (2.6.0)

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 #include <fstream>
7 #include <iostream>
8 #include <iomanip>
9 #include <string>
10 #include <vector>
11 
13 #include <dune/geometry/type.hh>
14 #include <dune/geometry/referenceelements.hh>
15 #include <dune/grid/common/grid.hh>
17 
18 namespace Dune {
19 
33  template <class GridView>
34  class GmshWriter
35  {
36  private:
37  const GridView gv;
38  int precision;
39 
40  static const unsigned int dim = GridView::dimension;
41  static const unsigned int dimWorld = GridView::dimensionworld;
42  static_assert( (dimWorld <= 3), "GmshWriter requires dimWorld <= 3." );
43 
45  template<typename Entity>
46  std::size_t nodeIndexFromEntity(const Entity& entity, int i) const {
47  return gv.indexSet().subIndex(entity, i, dim)+1;
48  }
49 
53  static std::size_t translateDuneToGmshType(const GeometryType& type) {
54  std::size_t element_type;
55 
56  if (type.isLine())
57  element_type = 1;
58  else if (type.isTriangle())
59  element_type = 2;
60  else if (type.isQuadrilateral())
61  element_type = 3;
62  else if (type.isTetrahedron())
63  element_type = 4;
64  else if (type.isHexahedron())
65  element_type = 5;
66  else if (type.isPrism())
67  element_type = 6;
68  else if (type.isPyramid())
69  element_type = 7;
70  else if (type.isVertex())
71  element_type = 15;
72  else
73  DUNE_THROW(Dune::IOError, "GeometryType " << type << " is not supported by gmsh.");
74 
75  return element_type;
76  }
77 
92  void outputElements(std::ofstream& file, const std::vector<int>& physicalEntities, const std::vector<int>& physicalBoundaries) const {
94  std::size_t counter(1);
95  for (const auto& entity : elements(gv)) {
96  // Check whether the type is compatible. If not, close file and rethrow exception.
97  try {
98  std::size_t element_type = translateDuneToGmshType(entity.type());
99 
100  file << counter << " " << element_type;
101  // If present, set the first tag to the physical entity
102  if (!physicalEntities.empty())
103  file << " " << 1 << " " << physicalEntities[elementMapper.index(entity)];
104  else
105  file << " " << 0; // "0" for "I do not use any tags."
106 
107  // Output list of nodes.
108  // 3, 5 and 7 got different vertex numbering compared to Dune
109  if (3 == element_type)
110  file << " "
111  << nodeIndexFromEntity(entity, 0) << " " << nodeIndexFromEntity(entity, 1) << " "
112  << nodeIndexFromEntity(entity, 3) << " " << nodeIndexFromEntity(entity, 2);
113  else if (5 == element_type)
114  file << " "
115  << nodeIndexFromEntity(entity, 0) << " " << nodeIndexFromEntity(entity, 1) << " "
116  << nodeIndexFromEntity(entity, 3) << " " << nodeIndexFromEntity(entity, 2) << " "
117  << nodeIndexFromEntity(entity, 4) << " " << nodeIndexFromEntity(entity, 5) << " "
118  << nodeIndexFromEntity(entity, 7) << " " << nodeIndexFromEntity(entity, 6);
119  else if (7 == element_type)
120  file << " "
121  << nodeIndexFromEntity(entity, 0) << " " << nodeIndexFromEntity(entity, 1) << " "
122  << nodeIndexFromEntity(entity, 3) << " " << nodeIndexFromEntity(entity, 2) << " "
123  << nodeIndexFromEntity(entity, 4);
124  else {
125  for (int k = 0; k < entity.geometry().corners(); ++k)
126  file << " " << nodeIndexFromEntity(entity, k);
127  }
128  ++counter;
129 
130  file << std::endl;
131 
132  // Write boundaries
133  if (!physicalBoundaries.empty()) {
134  auto refElement = referenceElement<typename GridView::ctype,dim>(entity.type());
135  for(const auto& intersection : intersections(gv, entity)) {
136  if(intersection.boundary()) {
137  const auto faceLocalIndex(intersection.indexInInside());
138  file << counter << " " << translateDuneToGmshType(intersection.type())
139  << " " << 1 << " " << physicalBoundaries[intersection.boundarySegmentIndex()];
140  for (int k = 0; k < intersection.geometry().corners(); ++k)
141  {
142  const auto vtxLocalIndex(refElement.subEntity(faceLocalIndex, 1, k, dim));
143  file << " " << nodeIndexFromEntity(entity, vtxLocalIndex);
144  }
145  ++counter;
146  file << std::endl;
147  }
148  }
149  }
150 
151  } catch(Exception& e) {
152  file.close();
153  throw;
154  }
155  }
156  }
157 
158 
165  void outputNodes(std::ofstream& file) const {
166  for (const auto& vertex : vertices(gv)) {
167  const auto globalCoord = vertex.geometry().center();
168  const auto nodeIndex = gv.indexSet().index(vertex)+1; // Start counting indices by "1".
169 
170  if (1 == dimWorld)
171  file << nodeIndex << " " << globalCoord[0] << " " << 0 << " " << 0 << std::endl;
172  else if (2 == dimWorld)
173  file << nodeIndex << " " << globalCoord[0] << " " << globalCoord[1] << " " << 0 << std::endl;
174  else // (3 == dimWorld)
175  file << nodeIndex << " " << globalCoord[0] << " " << globalCoord[1] << " " << globalCoord[2] << std::endl;
176  }
177  }
178 
179  public:
185  GmshWriter(const GridView& gridView, int numDigits=6) : gv(gridView), precision(numDigits) {}
186 
191  void setPrecision(int numDigits) {
192  precision = numDigits;
193  }
194 
216  void write(const std::string& fileName,
217  const std::vector<int>& physicalEntities=std::vector<int>(),
218  const std::vector<int>& physicalBoundaries=std::vector<int>()) const {
219  // Open file
220  std::ofstream file(fileName.c_str());
221  if (!file.is_open())
222  DUNE_THROW(Dune::IOError, "Could not open " << fileName << " with write access.");
223 
224  // Set precision
225  file << std::setprecision( precision );
226 
227  // Output Header
228  file << "$MeshFormat" << std::endl
229  << "2.0 0 " << sizeof(double) << std::endl // "2.0" for "version 2.0", "0" for ASCII
230  << "$EndMeshFormat" << std::endl;
231 
232  // Output Nodes
233  file << "$Nodes" << std::endl
234  << gv.size(dim) << std::endl;
235 
236  outputNodes(file);
237 
238  file << "$EndNodes" << std::endl;
239 
240  // Output Elements;
241  int boundariesSize(0);
242  if(!physicalBoundaries.empty())
243  for(const auto& entity : elements(gv))
244  for(const auto& intersection : intersections(gv, entity))
245  if(intersection.boundary())
246  ++boundariesSize;
247 
248  file << "$Elements" << std::endl
249  << gv.size(0) + boundariesSize<< std::endl;
250 
251  outputElements(file, physicalEntities, physicalBoundaries);
252 
253  file << "$EndElements" << std::endl;
254  }
255 
256  };
257 
258 } // namespace Dune
259 
260 #endif // DUNE_GRID_IO_FILE_GMSHWRITER_HH
Wrapper class for entities.
Definition: entity.hh:64
Geometry geometry() const
obtain geometric realization of the entity
Definition: entity.hh:143
GeometryType type() const
Return the name of the reference element. The type can be used to access the Dune::ReferenceElement.
Definition: entity.hh:148
Base class for Dune-Exceptions.
Definition: exceptions.hh:94
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:277
constexpr bool isPyramid() const
Return true if entity is a pyramid.
Definition: type.hh:542
constexpr bool isTetrahedron() const
Return true if entity is a tetrahedron.
Definition: type.hh:537
constexpr bool isPrism() const
Return true if entity is a prism.
Definition: type.hh:547
constexpr bool isVertex() const
Return true if entity is a vertex.
Definition: type.hh:517
constexpr bool isTriangle() const
Return true if entity is a triangle.
Definition: type.hh:527
constexpr bool isLine() const
Return true if entity is a line segment.
Definition: type.hh:522
constexpr bool isQuadrilateral() const
Return true if entity is a quadrilateral.
Definition: type.hh:532
constexpr bool isHexahedron() const
Return true if entity is a hexahedron.
Definition: type.hh:552
Write Gmsh mesh file.
Definition: gmshwriter.hh:35
GmshWriter(const GridView &gridView, int numDigits=6)
Constructor expecting GridView of Grid to be written.
Definition: gmshwriter.hh:185
void setPrecision(int numDigits)
Set the number of digits to be used when writing the vertices. By default is 6.
Definition: gmshwriter.hh:191
void write(const std::string &fileName, const std::vector< int > &physicalEntities=std::vector< int >(), const std::vector< int > &physicalBoundaries=std::vector< int >()) const
Write given grid in Gmsh 2.0 compatible ASCII file.
Definition: gmshwriter.hh:216
Grid view abstract base class.
Definition: gridview.hh:60
Default exception class for I/O errors.
Definition: exceptions.hh:229
Implementation class for a multiple codim and multiple geometry type mapper.
Definition: mcmgmapper.hh:200
Index index(const EntityType &e) const
Map entity to starting index in array for dof block.
Definition: mcmgmapper.hh:254
Different resources needed by all grid implementations.
A few common exception classes.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
int size(int codim) const
obtain number of entities in a given codimension
Definition: gridview.hh:178
const IndexSet & indexSet() const
obtain the index set
Definition: gridview.hh:172
@ dimensionworld
The dimension of the world the grid lives in.
Definition: gridview.hh:131
@ dimension
The dimension of the grid.
Definition: gridview.hh:127
constexpr GeometryType vertex
GeometryType representing a vertex.
Definition: type.hh:727
MCMGLayout mcmgElementLayout()
layout for elements (codim-0 entities)
Definition: mcmgmapper.hh:150
Mapper for multiple codim and multiple geometry types.
Dune namespace.
Definition: alignedallocator.hh:10
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 5, 22:29, 2024)