opm-grid
dgfparser.hh
1 // -*- mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=2 sw=2 sts=2:
3 #ifndef DUNE_POLYHEDRALGRID_DGFPARSER_HH
4 #define DUNE_POLYHEDRALGRID_DGFPARSER_HH
5 
6 #include <algorithm>
7 #include <numeric>
8 #include <memory>
9 #include <utility>
10 
11 #include <dune/common/typetraits.hh>
12 #include <dune/common/version.hh>
13 
14 #include <dune/geometry/referenceelements.hh>
15 
16 #include <dune/grid/common/gridfactory.hh>
17 #include <dune/grid/io/file/dgfparser/dgfparser.hh>
18 
19 #include <dune/grid/io/file/dgfparser/blocks/polyhedron.hh>
20 
21 #include <opm/grid/polyhedralgrid/gridfactory.hh>
22 
23 #if HAVE_OPM_COMMON
24 #include <opm/input/eclipse/Parser/ParseContext.hpp>
25 #include <opm/input/eclipse/Parser/Parser.hpp>
26 #include <opm/input/eclipse/Deck/Deck.hpp>
27 #endif
28 
29 namespace Dune
30 {
31  // DGFGridFactory for PolyhedralGrid
32  // ---------------------------------
33 
34  template< int dim, int dimworld, class coord_t >
35  struct DGFGridFactory< PolyhedralGrid< dim, dimworld, coord_t > >
36  {
38 
39  const static int dimension = Grid::dimension;
40  typedef MPIHelper::MPICommunicator MPICommunicator;
41  typedef typename Grid::template Codim<0>::Entity Element;
42  typedef typename Grid::template Codim<dimension>::Entity Vertex;
43 
44  explicit DGFGridFactory ( std::istream &input, MPICommunicator = MPIHelper::getCommunicator() )
45  : gridPtr_(),
46  grid_( nullptr )
47  {
48  input.clear();
49  input.seekg( 0 );
50  if( !input )
51  DUNE_THROW( DGFException, "Error resetting input stream" );
52  generate( input );
53  }
54 
55  explicit DGFGridFactory ( const std::string &filename, MPICommunicator /* comm */ = MPIHelper::getCommunicator() )
56  : gridPtr_(),
57  grid_( nullptr )
58  {
59  std::ifstream input( filename );
60  if( !input )
61  DUNE_THROW( DGFException, "Macrofile '" << filename << "' not found" );
62 
63 #if HAVE_OPM_COMMON
64  if( !DuneGridFormatParser::isDuneGridFormat( input ) )
65  {
66  Opm::Parser parser;
67  const auto deck = parser.parseString( filename );
68  std::vector<double> porv;
69 
70  gridPtr_.reset( new Grid( deck, porv ) );
71  return ;
72  }
73  else
74 #endif
75  {
76  generate( input );
77  }
78  }
79 
80  Grid *grid () const
81  {
82  if( ! grid_ )
83  {
84  // set pointer to grid and avoid grid being deleted
85  grid_ = gridPtr_.release();
86  }
87  return grid_;
88  }
89 
90  template< class Intersection >
91  bool wasInserted ( const Intersection& /*intersection*/ ) const
92  {
93  return false;
94  }
95 
96  template< class Intersection >
97  int boundaryId ( const Intersection& ) const
98  {
99  return false;
100  }
101 
102  bool haveBoundaryParameters () const { return false; }
103 
104  template< int codim >
105  int numParameters () const
106  {
107  //return (codim == dimension ? numVtxParams_ : 0);;
108  return 0;
109  }
110 
111  template< class Intersection >
112  const typename DGFBoundaryParameter::type &
113  boundaryParameter ( const Intersection& ) const
114  {
115  return DGFBoundaryParameter::defaultValue();;
116  }
117 
118  template< class Entity >
119  std::vector< double > &parameter ( const Entity& )
120  {
121  static std::vector< double > dummy;
122  return dummy;
123  }
124 
125  private:
126  int readVertices ( std::istream &input, std::vector< std::vector< double > > &vertices )
127  {
128  int dimWorld = Grid::dimensionworld ;
129  dgf::VertexBlock vtxBlock( input, dimWorld );
130  if( !vtxBlock.isactive() )
131  DUNE_THROW( DGFException, "Vertex block not found" );
132 
133  vtxBlock.get( vertices, vtxParams_, numVtxParams_ );
134  return vtxBlock.offset();
135  }
136 
137  std::vector< std::vector< int > > readPolygons ( std::istream &input, int numVtx, int vtxOfs )
138  {
139  dgf::PolygonBlock polygonBlock( input, numVtx, vtxOfs );
140  if( !polygonBlock.isactive() )
141  DUNE_THROW( DGFException, "Polygon block not found" );
142 
143  std::vector< std::vector< int > > polygons;
144  polygonBlock.get( polygons );
145  return polygons;
146  }
147 
148  std::vector< std::vector< int > > readPolyhedra ( std::istream &input, int numPolygons )
149  {
150  dgf::PolyhedronBlock polyhedronBlock( input, numPolygons );
151  std::vector< std::vector< int > > polyhedra;
152  if( polyhedronBlock.isactive() )
153  {
154  polyhedronBlock.get( polyhedra );
155  }
156  return polyhedra;
157  }
158 
159  template< class Iterator >
160  void copy ( Iterator begin, Iterator end, double *dest )
161  {
162  for( ; begin != end; ++begin )
163  dest = std::ranges::copy(*begin, dest);
164  }
165 
166  template< class Iterator >
167  void copy ( Iterator begin, Iterator end, int *dest, int *offset )
168  {
169  int size = 0;
170  for( ; begin != end; ++begin )
171  {
172  *(offset++) = size;
173  size += begin->size();
174  dest = std::ranges::copy(*begin, dest);
175  }
176  *offset = size;
177  }
178 
179  void generate ( std::istream &input )
180  {
181  // check whether an interval block is active, otherwise read polyhedrons
182  dgf::IntervalBlock intervalBlock( input );
183  if( intervalBlock.isactive() )
184  {
185  if( intervalBlock.numIntervals() != 1 )
186  DUNE_THROW( DGFException, "Currently, CpGrid can only handle 1 interval block." );
187 
188  if( intervalBlock.dimw() != dimworld )
189  DUNE_THROW( DGFException, "CpGrid cannot handle an interval of dimension " << intervalBlock.dimw() << "." );
190  const dgf::IntervalBlock::Interval &interval = intervalBlock.get( 0 );
191 
192  std::vector< double > spacing( dimworld );
193  for( int i=0; i<dimworld; ++i )
194  spacing[ i ] = (interval.p[ 1 ][ i ] - interval.p[ 0 ][ i ]) / interval.n[ i ];
195 
196  gridPtr_.reset( new Grid( interval.n, spacing ) );
197  return ;
198  }
199  else // polyhedral input
200  {
201  typedef std::vector< std::vector< double > > CoordinateVectorType;
202  CoordinateVectorType nodes;
203 
204  typedef std::vector< std::vector< int > > IndexVectorType;
205  IndexVectorType faces;
206  IndexVectorType cells;
207 
208  const int vtxOfs = readVertices( input, nodes );
209 
210  faces = readPolygons ( input, nodes.size(), vtxOfs );
211  cells = readPolyhedra( input, faces.size() );
212 
213  if( cells.empty() )
214  {
215  DUNE_THROW( DGFException, "Polyhedron block not found!" );
216  }
217 
218  typedef GridFactory< Grid > GridFactoryType;
219  typedef typename GridFactoryType :: Coordinate Coordinate ;
220 
221  GridFactoryType gridFactory;
222 
223  const int nNodes = nodes.size();
224  Coordinate node( 0 );
225  for( int i=0; i<nNodes; ++i )
226  {
227  for( int d=0; d<Coordinate::dimension; ++d )
228  node[ d ] = nodes[ i ][ d ];
229 
230  gridFactory.insertVertex( node );
231  }
232  //nodes.swap( CoordinateVectorType() );
233 
234  // insert faces with type none/dim-1
235  GeometryType type;
236  type = Dune::GeometryTypes::none(Grid::dimension-1);
237  std::vector< unsigned int > numbers;
238 
239  const int nFaces = faces.size();
240  for(int i = 0; i < nFaces; ++ i )
241  {
242  // copy values into appropriate data type
243  std::vector<int>& face = faces[ i ];
244  numbers.resize( face.size() );
245  std::ranges::copy(face, numbers.begin());
246  gridFactory.insertElement( type, numbers );
247  }
248 
249  // free memory
250  //faces.swap( IndexVectorType() );
251 
252  // insert cells with type none/dim
253  type = Dune::GeometryTypes::none(Grid::dimension);
254 
255  const int nCells = cells.size();
256  for(int i = 0; i < nCells; ++ i )
257  {
258  // copy values into appropriate data type
259  std::vector<int>& cell = cells[ i ];
260  numbers.resize( cell.size() );
261  std::ranges::copy(cell, numbers.begin());
262  gridFactory.insertElement( type, numbers );
263  }
264  //cells.swap( IndexVectorType() );
265 
266  gridPtr_ = gridFactory.createGrid();
267  } // end else branch
268 
269  // alternative conversion to polyhedral format that does not work yet.
270 #if 0
271  else // convert dgf input to polyhedral
272  {
273  nodes.resize( dgf.nofvtx );
274  // copy vertices
275  std::ranges::copy(dgf.vtx, nodes.begin());
276 
277  for( const auto& node : nodes )
278  {
279  for( size_t i=0; i<node.size(); ++i )
280  std::cout << node[i] << " ";
281  std::cout << std::endl;
282  }
283 
284  const unsigned int nVx = dgf.elements[ 0 ].size();
285 
286  typedef std::vector< int > face_t;
287  std::map< face_t, int > tmpFaces;
288 
289  const int nFaces = (nVx == dim+1) ? dim+1 : 2*dim;
290 
291  Dune::GeometryType type( (nVx == dim+1) ?
292  Impl :: SimplexTopology< dim > :: type :: id :
293  Impl :: CubeTopology < dim > :: type :: id,
294  dim );
295 
296  const auto& refElem = Dune::referenceElement< typename Grid::ctype, dim >( type );
297 
298  cells.resize( dgf.nofelements );
299 
300  face_t face;
301  int faceNo = 0;
302  for( int n = 0; n < dgf.nofelements; ++n )
303  {
304  const auto& elem = dgf.elements[ n ];
305  auto& cell = cells[ n ];
306  assert( elem.size() == nVx );
307  cell.resize( nFaces );
308  for(int f=0; f<nFaces; ++f )
309  {
310  const int nFaceVx = refElem.size(f, 1, dim);
311  face.resize( nFaceVx );
312  for( int j=0; j<nFaceVx; ++j )
313  {
314  face[ j ] = elem[ refElem.subEntity(f, 1, j , dim) ];
315  }
316  std::ranges::sort(face);
317  auto it = tmpFaces.find( face );
318  int myFaceNo = -1;
319  if( it == tmpFaces.end() )
320  {
321  myFaceNo = faceNo++;
322  tmpFaces.insert( std::make_pair( face, myFaceNo ) );
323  }
324  else
325  myFaceNo = it->second;
326 
327  cell[ f ] = myFaceNo;
328  }
329 
330  /*
331  for( const auto& c : cell )
332  {
333  std::cout << c << " ";
334  }
335  std::cout << std::endl;
336  */
337  }
338 #endif
339  }
340 
341  mutable std::unique_ptr< Grid > gridPtr_;
342  mutable Grid* grid_;
343  int numVtxParams_;
344  std::vector< std::vector< double > > vtxParams_;
345  };
346 
347 
348 
349  // DGFGridInfo for PolyhedralGrid
350  // ------------------------------
351 
352  template< int dim, int dimworld >
353  struct DGFGridInfo< PolyhedralGrid< dim, dimworld > >
354  {
355  static int refineStepsForHalf ()
356  {
357  return 0;
358  }
359 
360  static double refineWeight ()
361  {
362  return 0;
363  }
364  };
365 
366 } // namespace Dune
367 
368 #endif // #ifndef DUNE_POLYHEDRALGRID_DGFPARSER_HH
The namespace Dune is the main namespace for all Dune code.
Definition: CartesianIndexMapper.hpp:9
identical grid wrapper
Definition: declaration.hh:10