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