dune-grid  2.11
gmshreader.hh
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
2 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4 // vi: set et ts=4 sw=2 sts=2:
5 
6 #ifndef DUNE_GRID_IO_FILE_GMSHREADER_HH
7 #define DUNE_GRID_IO_FILE_GMSHREADER_HH
8 
9 #include <iostream>
10 #include <memory>
11 #include <string>
12 #include <vector>
13 #include <utility>
14 
15 #include <dune/common/exceptions.hh>
16 
21 
22 namespace Dune
23 {
24 
35  struct [[deprecated]] GmshReaderOptions
36  {
41  secondOrder
42  };
43  };
44 
45  namespace Gmsh {
51  enum class ReaderOptions
52  {
53  verbose = 1,
55  readElementData = 4,
57  };
58 
61  {
62  return static_cast<ReaderOptions>(
63  static_cast<int>(a) | static_cast<int>(b)
64  );
65  }
66 
69  {
70  return static_cast<int>(a) & static_cast<int>(b);
71  }
72 
73  } // end namespace Gmsh
74 
85  template <typename GridType>
86  struct [[deprecated("Public interface of the GmshReaderParser has been deprecated since dune 2.11.")]]
87  GmshReaderParser : Impl::Gmsh::Gmsh2Parser<GridType>
88  {
89  using Impl::Gmsh::Gmsh2Parser<GridType>::Gmsh2Parser;
90  };
91 
108  template<typename GridType>
110  {
112 
131  static void doRead(Dune::GridFactory<GridType> &factory,
132  const std::string &fileName,
133  std::vector<int>& boundarySegmentToPhysicalEntity,
134  std::vector<int>& elementToPhysicalEntity,
135  bool verbose, bool insertBoundarySegments)
136  {
137  // register boundary segment to boundary segment factory for possible load balancing
138  // this needs to be done on all cores since the type might not be known otherwise
139  Impl::Gmsh::GmshReaderQuadraticBoundarySegment< Grid::dimension, Grid::dimensionworld >::registerFactory();
140 
141 #ifndef NDEBUG
142  // check that this method is called on all cores
143  factory.comm().barrier();
144 #endif
145 
146  // create parse object and read grid on process 0
147  if (factory.comm().rank() == 0)
148  {
149  Impl::Gmsh::Gmsh2Parser<Grid> parser(factory,verbose,insertBoundarySegments);
150  parser.read(fileName);
151 
152  boundarySegmentToPhysicalEntity = std::move(parser.boundaryIdMap());
153  elementToPhysicalEntity = std::move(parser.elementIndexMap());
154  }
155  else
156  {
157  boundarySegmentToPhysicalEntity = {};
158  elementToPhysicalEntity = {};
159  }
160  }
161 
163 
182  template<class T>
183  static T &discarded(T &&value) { return static_cast<T&>(value); }
184 
185  struct DataArg {
186  std::vector<int> *data_ = nullptr;
187  DataArg(std::vector<int> &data) : data_(&data) {}
188  DataArg(const decltype(std::ignore)&) {}
189  DataArg() = default;
190  };
191 
192  struct DataFlagArg : DataArg {
193  bool flag_ = false;
194  using DataArg::DataArg;
195  DataFlagArg(bool flag) : flag_(flag) {}
196  };
197 
198  public:
199  typedef GridType Grid;
200 
203  static std::unique_ptr<Grid> read (const std::string& fileName, bool verbose = true, bool insertBoundarySegments=true)
204  {
205  // make a grid factory
206  Dune::GridFactory<Grid> factory;
207 
208  read(factory, fileName, verbose, insertBoundarySegments);
209 
210  return factory.createGrid();
211  }
212 
236  static std::unique_ptr<Grid> read (const std::string& fileName,
237  std::vector<int>& boundarySegmentToPhysicalEntity,
238  std::vector<int>& elementToPhysicalEntity,
239  bool verbose = true, bool insertBoundarySegments=true)
240  {
241  // make a grid factory
242  Dune::GridFactory<Grid> factory;
243 
244  if (Impl::Gmsh::fileVersion(fileName)[0]==4)
245  {
246  Impl::Gmsh::Gmsh4Reader<Grid>::fillFactory(factory, fileName);
247  return factory.createGrid();
248  }
249 
250  doRead(
251  factory, fileName, boundarySegmentToPhysicalEntity,
252  elementToPhysicalEntity, verbose, insertBoundarySegments
253  );
254 
255  return factory.createGrid();
256  }
257 
263  static void read (Dune::GridFactory<Grid>& factory, const std::string& fileName,
264  bool verbose = true, bool insertBoundarySegments=true)
265  {
266  if (Impl::Gmsh::fileVersion(fileName)[0]==4)
267  {
268  Impl::Gmsh::Gmsh4Reader<Grid>::fillFactory(factory, fileName);
269  return;
270  }
271 
272  doRead(
273  factory, fileName, discarded(std::vector<int>{}),
274  discarded(std::vector<int>{}), verbose, insertBoundarySegments
275  );
276  }
277 
279 
305  static void read (Dune::GridFactory<Grid> &factory,
306  const std::string &fileName,
307  DataFlagArg boundarySegmentData,
308  DataArg elementData,
309  bool verbose=true)
310  {
311  if (Impl::Gmsh::fileVersion(fileName)[0]==4)
312  {
313  Impl::Gmsh::Gmsh4Reader<Grid>::fillFactory(factory, fileName);
314  return;
315  }
316 
317  doRead(
318  factory, fileName,
319  boundarySegmentData.data_
320  ? *boundarySegmentData.data_ : discarded(std::vector<int>{}),
321  elementData.data_
322  ? *elementData.data_ : discarded(std::vector<int>{}),
323  verbose,
324  boundarySegmentData.flag_ || boundarySegmentData.data_
325  );
326  }
327 
352  static void read (Dune::GridFactory<Grid>& factory,
353  const std::string& fileName,
354  std::vector<int>& boundarySegmentToPhysicalEntity,
355  std::vector<int>& elementToPhysicalEntity,
356  bool verbose, bool insertBoundarySegments)
357  {
358  if (Impl::Gmsh::fileVersion(fileName)[0]==4)
359  {
360  Impl::Gmsh::Gmsh4Reader<Grid>::fillFactory(factory, fileName);
361  return;
362  }
363 
364  doRead(
365  factory, fileName, boundarySegmentToPhysicalEntity,
366  elementToPhysicalEntity, verbose, insertBoundarySegments
367  );
368  }
369 
371  //\{
372 
374 
375  static constexpr Opts defaultOpts =
376  Opts::verbose | Opts::insertBoundarySegments | Opts::readElementData | Opts::readBoundaryData;
377 
379 
404  GmshReader(const std::string& fileName,
406  {
407  gridFactory_ = std::make_unique<Dune::GridFactory<Grid>>();
408  readGridFile(fileName, *gridFactory_, options);
409  }
410 
419  GmshReader(const std::string& fileName, GridFactory<Grid>& factory,
421  {
422  readGridFile(fileName, factory, options);
423  }
424 
426  const std::vector<int>& elementData () const
427  {
428  checkElementData();
429  return elementIndexToGmshPhysicalEntity_;
430  }
431 
433  const std::vector<int>& boundaryData () const
434  {
435  checkBoundaryData();
436  return boundarySegmentIndexToGmshPhysicalEntity_;
437  }
438 
443  bool hasElementData () const
444  { return hasElementData_ && !extractedElementData_; }
445 
450  bool hasBoundaryData () const
451  { return hasBoundaryData_ && !extractedBoundaryData_; }
452 
454  std::vector<int> extractElementData ()
455  {
456  checkElementData();
457  extractedElementData_ = true;
458  return std::move(elementIndexToGmshPhysicalEntity_);
459  }
460 
462  std::vector<int> extractBoundaryData ()
463  {
464  checkBoundaryData();
465  extractedBoundaryData_ = true;
466  return std::move(boundarySegmentIndexToGmshPhysicalEntity_);
467  }
468 
470  std::unique_ptr<Grid> createGrid ()
471  {
472  if (!gridFactory_)
473  DUNE_THROW(Dune::InvalidStateException,
474  "This GmshReader has been constructed with a Dune::GridFactory. "
475  << "This grid factory has been filled with all information to create a grid. "
476  << "Please use this factory to create the grid by calling factory.createGrid(). "
477  << "Alternatively use the constructor without passing the factory in combination with this member function."
478  );
479 
480  return gridFactory_->createGrid();
481  }
482 
483  //\}
484 
485  private:
486  void checkElementData () const
487  {
488  if (!hasElementData_)
489  DUNE_THROW(Dune::InvalidStateException,
490  "This GmshReader has been constructed without the option 'readElementData'. "
491  << "Please enable reading element data by passing the option 'Gmsh::ReaderOpts::readElementData' "
492  << "to the constructor of this class."
493  );
494 
495  if (extractedElementData_)
496  DUNE_THROW(Dune::InvalidStateException,
497  "The element data has already been extracted from this GmshReader "
498  << "via a function call to reader.extractElementData(). Use the extracted data or "
499  << "read the grid data from file again by constructing a new reader."
500  );
501  }
502 
503  void checkBoundaryData () const
504  {
505  if (!hasBoundaryData_)
506  DUNE_THROW(Dune::InvalidStateException,
507  "This GmshReader has been constructed without the option 'readBoundaryData'. "
508  << "Please enable reading boundary data by passing the option 'Gmsh::ReaderOpts::readBoundaryData' "
509  << "to the constructor of this class."
510  );
511 
512  if (extractedBoundaryData_)
513  DUNE_THROW(Dune::InvalidStateException,
514  "The boundary data has already been extracted from this GmshReader "
515  << "via a function call to reader.extractBoundaryData(). Use the extracted data or "
516  << "read the grid data from file again by constructing a new reader."
517  );
518  }
519 
520  void readGridFile (const std::string& fileName, GridFactory<Grid>& factory, Gmsh::ReaderOptions options)
521  {
522  if (Impl::Gmsh::fileVersion(fileName)[0]==4)
523  {
524  Impl::Gmsh::Gmsh4Reader<Grid>::fillFactory(factory, fileName);
525  return;
526  }
527 
528  const bool verbose = options & Opts::verbose;
529  const bool insertBoundarySegments = options & Opts::insertBoundarySegments;
530  const bool readBoundaryData = options & Opts::readBoundaryData;
531  const bool readElementData = options & Opts::readElementData;
532 
533  doRead(
534  factory, fileName, boundarySegmentIndexToGmshPhysicalEntity_,
535  elementIndexToGmshPhysicalEntity_, verbose,
536  readBoundaryData || insertBoundarySegments
537  );
538 
539  // clear unwanted data
540  if (!readBoundaryData)
541  boundarySegmentIndexToGmshPhysicalEntity_ = std::vector<int>{};
542  if (!readElementData)
543  elementIndexToGmshPhysicalEntity_ = std::vector<int>{};
544 
545  hasElementData_ = readElementData;
546  hasBoundaryData_ = readBoundaryData;
547  }
548 
549  std::unique_ptr<Dune::GridFactory<Grid>> gridFactory_;
550 
551  std::vector<int> elementIndexToGmshPhysicalEntity_;
552  std::vector<int> boundarySegmentIndexToGmshPhysicalEntity_;
553 
554  bool hasElementData_ = false;
555  bool hasBoundaryData_ = false;
556 
557  // for better error messages, we keep track of these separately
558  bool extractedElementData_ = false;
559  bool extractedBoundaryData_ = false;
560  };
561 
564 } // namespace Dune
565 
566 #endif
static std::unique_ptr< Grid > read(const std::string &fileName, std::vector< int > &boundarySegmentToPhysicalEntity, std::vector< int > &elementToPhysicalEntity, bool verbose=true, bool insertBoundarySegments=true)
Read Gmsh file, possibly with data.
Definition: gmshreader.hh:236
std::vector< int > extractBoundaryData()
Erase boundary data from reader and return the data.
Definition: gmshreader.hh:462
ReaderOptions
Options for the Gmsh mesh file reader.
Definition: gmshreader.hh:51
static void read(Dune::GridFactory< Grid > &factory, const std::string &fileName, std::vector< int > &boundarySegmentToPhysicalEntity, std::vector< int > &elementToPhysicalEntity, bool verbose, bool insertBoundarySegments)
Read Gmsh file, possibly with data.
Definition: gmshreader.hh:352
GridType Grid
Definition: gmshreader.hh:199
GeometryOrder
Definition: gmshreader.hh:37
std::vector< int > extractElementData()
Erase element data from reader and return the data.
Definition: gmshreader.hh:454
const std::vector< int > & boundaryData() const
Access boundary data (maps boundary segment index to Gmsh physical entity)
Definition: gmshreader.hh:433
const std::vector< int > & elementData() const
Access element data (maps element index to Gmsh physical entity)
Definition: gmshreader.hh:426
GmshReader(const std::string &fileName, Gmsh::ReaderOptions options=defaultOpts)
Construct a Gmsh reader object (alternatively use one of the static member functions) ...
Definition: gmshreader.hh:404
static void read(Dune::GridFactory< Grid > &factory, const std::string &fileName, DataFlagArg boundarySegmentData, DataArg elementData, bool verbose=true)
read Gmsh file, possibly with data
Definition: gmshreader.hh:305
bool hasElementData() const
If element data is available.
Definition: gmshreader.hh:443
std::unique_ptr< Grid > createGrid()
Create the grid.
Definition: gmshreader.hh:470
bool hasBoundaryData() const
If boundary data is available.
Definition: gmshreader.hh:450
Provide a generic factory class for unstructured grids.
edges are straight lines.
Definition: gmshreader.hh:39
static void read(Dune::GridFactory< Grid > &factory, const std::string &fileName, bool verbose=true, bool insertBoundarySegments=true)
Read Gmsh grid file into a GridFactory object.
Definition: gmshreader.hh:263
virtual std::unique_ptr< GridType > createGrid()
Finalize grid creation and hand over the grid.
Definition: common/gridfactory.hh:333
Options for read operation.
Definition: gmshreader.hh:35
static constexpr Opts defaultOpts
Definition: gmshreader.hh:375
Communication comm() const
Return the Communication used by the grid factory.
Definition: common/gridfactory.hh:258
Read Gmsh mesh file.
Definition: gmshreader.hh:109
Include standard header files.
Definition: agrid.hh:59
GmshReader(const std::string &fileName, GridFactory< Grid > &factory, Gmsh::ReaderOptions options=defaultOpts)
Construct a Gmsh reader object from a file name and a grid factory.
Definition: gmshreader.hh:419
static std::unique_ptr< Grid > read(const std::string &fileName, bool verbose=true, bool insertBoundarySegments=true)
Definition: gmshreader.hh:203
The GmshReaderParser class has been renamed and moved to the Impl::Gmsh namespace.
Definition: gmshreader.hh:86
Provide a generic factory class for unstructured grids.
Definition: common/gridfactory.hh:275
constexpr ReaderOptions operator|(ReaderOptions a, ReaderOptions b)
composition operator for reader options
Definition: gmshreader.hh:60
constexpr bool operator&(ReaderOptions a, ReaderOptions b)
query operator for reader options (is b set in a)
Definition: gmshreader.hh:68