polyhedralgridconverter.hh
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  Copyright 2014 IRIS AS
5 
6  This file is part of the Open Porous Media project (OPM).
7 
8  OPM is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  OPM is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with OPM. If not, see <http://www.gnu.org/licenses/>.
20 */
21 #ifndef EWOMS_POLYHEDRALGRIDCONVERTER_HH
22 #define EWOMS_POLYHEDRALGRIDCONVERTER_HH
23 
24 //#if HAVE_DUNE_CORNERPOINT
25 #include <dune/grid/polyhedralgrid.hh>
26 // we need dune-cornerpoint for reading the Dune grid.
27 #include <dune/grid/CpGrid.hpp>
28 //#else
29 //#error "This header needs the dune-cornerpoint module"
30 //#endif
31 
32 namespace Ewoms
33 {
34  namespace detail{
35  // key for generating intersection index
36  struct FaceKey : public std::pair< int, int >
37  {
38  typedef std::pair< int, int > BaseType;
39  FaceKey() : BaseType(-1,-1) {}
40  FaceKey( const int inside, const int outside )
41  : BaseType( inside < outside ? std::make_pair(inside,outside) : std::make_pair(outside,inside) )
42  {}
43  };
44  }
45 
46 
47  template <class GridView, class CartesianIndexMapper>
48  inline UnstructuredGrid*
49  dune2UnstructuredGrid( const GridView& gridView,
50  const CartesianIndexMapper& cartesianIndexMapper,
51  const bool faceTags,
52  const bool onlyInterior = true )
53  {
54  // if grid is empty return nullptr
55  if( gridView.grid().size( 0 ) == 0 )
56  return nullptr;
57 
58  typedef double ctype;
59  typedef typename GridView :: template Codim< 0 > :: template Partition<
60  Dune :: All_Partition > :: Iterator Iterator;
61  typedef typename GridView :: template Codim< 0 > :: Entity Element;
62  typedef typename Element :: Geometry ElementGeometry;
63  typedef typename GridView :: IntersectionIterator IntersectionIterator;
64  typedef typename IntersectionIterator :: Intersection Intersection;
65  typedef typename Intersection :: Geometry IntersectionGeometry;
66  typedef typename GridView :: IndexSet IndexSet;
67 
68  typedef typename ElementGeometry :: GlobalCoordinate GlobalCoordinate;
69 
70  const IndexSet& indexSet = gridView.indexSet();
71  const int dimension = GridView::Grid::dimension;
72 
73  const int numCells = indexSet.size( 0 );
74  const int numNodes = indexSet.size( dimension );
75 
76  const int maxNumVerticesPerFace = 4;
77  const int maxNumFacesPerCell = 6;
78 
79  int maxFaceIdx = indexSet.size( 1 );
80  const bool validFaceIndexSet = maxFaceIdx > 0;
81 
82  typedef detail::FaceKey FaceKey;
83 
84  std::map< FaceKey, int > faceIndexSet;
85 
86  if( ! validFaceIndexSet )
87  {
88  maxFaceIdx = 0;
89  const Iterator end = gridView.template end<0, Dune::All_Partition> ();
90  for( Iterator it = gridView.template begin<0, Dune::All_Partition> (); it != end; ++it )
91  {
92  const auto& element = *it;
93  const int elIndex = indexSet.index( element );
94  const IntersectionIterator endiit = gridView.iend( element );
95  for( IntersectionIterator iit = gridView.ibegin( element ); iit != endiit; ++iit)
96  {
97  const Intersection& intersection = *iit;
98  int nbIndex = -1;
99 
100  // store face --> cell relation
101  if( intersection.neighbor() )
102  {
103 #if DUNE_VERSION_NEWER(DUNE_GRID,2,4)
104  const Element& neighbor = intersection.outside();
105 #else
106  auto ep = intersection.outside();
107  const Element& neighbor = *ep;
108 #endif
109  if( ! ( onlyInterior && neighbor.partitionType() != Dune::InteriorEntity ) )
110  nbIndex = indexSet.index( neighbor );
111  }
112 
113  FaceKey faceKey( elIndex, nbIndex );
114  if( faceIndexSet.find( faceKey ) == faceIndexSet.end() )
115  faceIndexSet[ faceKey ] = maxFaceIdx++;
116  }
117  }
118  }
119  const int numFaces = maxFaceIdx ;
120 
121  // create Unstructured grid struct
122  UnstructuredGrid* ug = allocate_grid( dimension, numCells, numFaces,
123  numFaces*maxNumVerticesPerFace,
124  numCells * maxNumFacesPerCell,
125  numNodes );
126 
127  std::fill( ug->face_cells, ug->face_cells+(numCells * maxNumFacesPerCell), -1 );
128 
129  for( int d=0; d<dimension; ++d )
130  ug->cartdims[ d ] = cartesianIndexMapper.cartesianDimensions()[ d ];
131 
132  assert( ug->number_of_cells > 0 );
133  // allocate data structure for storage of cartesian index
134  if( ! ug->global_cell )
135  ug->global_cell = (int *) std::malloc( ug->number_of_cells * sizeof(int) );
136 
137  int count = 0;
138  int cellFace = 0;
139  maxFaceIdx = 0;
140  const Iterator end = gridView.template end<0, Dune::All_Partition> ();
141  for( Iterator it = gridView.template begin<0, Dune::All_Partition> (); it != end; ++it, ++count )
142  {
143  const Element& element = *it;
144  const ElementGeometry geometry = element.geometry();
145 
146  // currently only hexahedrons are supported
147  // assert( element.type().isHexahedron() );
148 
149  const int elIndex = indexSet.index( element );
150  assert( indexSet.index( element ) == elIndex );
151 
152  const bool isGhost = element.partitionType() != Dune :: InteriorEntity ;
153 
154  // make sure that the elements are ordered as before,
155  // otherwise the globalCell mapping is invalid
156  assert( count == elIndex );
157 
158  // store cartesian index
159  ug->global_cell[ elIndex ] = cartesianIndexMapper.cartesianIndex( elIndex );
160  //std::cout << "global index of cell " << elIndex << " = " <<
161  // ug->global_cell[ elIndex ] << std::endl;
162 
163  const GlobalCoordinate center = geometry.center();
164  int idx = elIndex * dimension;
165  for( int d=0; d<dimension; ++d, ++idx )
166  ug->cell_centroids[ idx ] = center[ d ];
167  ug->cell_volumes[ elIndex ] = geometry.volume();
168 
169  const int vertices = geometry.corners();
170  for( int vx=0; vx<vertices; ++vx )
171  {
172  const GlobalCoordinate vertex = geometry.corner( vx );
173  int idx = indexSet.subIndex( element, vx, dimension ) * dimension;
174  for( int d=0; d<dimension; ++d, ++idx )
175  ug->node_coordinates[ idx ] = vertex[ d ];
176  }
177 
178  ug->cell_facepos[ elIndex ] = cellFace;
179 
180  Dune::GeometryType geomType = element.type();
181  if( geomType.isNone() )
182  geomType = Dune::GeometryType( Dune::GeometryType::cube, dimension );
183 
184  const Dune::ReferenceElement< ctype, dimension > &refElem
185  = Dune::ReferenceElements< ctype, dimension >::general( geomType );
186 
187  int faceCount = 0;
188  const IntersectionIterator endiit = gridView.iend( element );
189  for( IntersectionIterator iit = gridView.ibegin( element ); iit != endiit; ++iit, ++faceCount )
190  {
191  const Intersection& intersection = *iit;
192  IntersectionGeometry intersectionGeometry = intersection.geometry();
193  const double faceVol = intersectionGeometry.volume();
194 
195  const int localFace = intersection.indexInInside();
196  const int localFaceIdx = isGhost ? 0 : localFace;
197 
198  int faceIndex = validFaceIndexSet ? indexSet.subIndex( element, localFace, 1 ) : -1;
199  if( ! validFaceIndexSet )
200  {
201  int nbIndex = -1;
202  if( intersection.neighbor() )
203  {
204 #if DUNE_VERSION_NEWER(DUNE_GRID,2,4)
205  const Element& neighbor = intersection.outside();
206 #else
207  auto ep = intersection.outside();
208  const Element& neighbor = *ep;
209 #endif
210  if( ! ( onlyInterior && neighbor.partitionType() != Dune::InteriorEntity ) )
211  nbIndex = indexSet.index( neighbor );
212  }
213  FaceKey faceKey( elIndex, nbIndex );
214  faceIndex = faceIndexSet[ faceKey ];
215  }
216 
217  maxFaceIdx = std::max( faceIndex, maxFaceIdx );
218 
219  ug->face_areas[ faceIndex ] = faceVol;
220 
221  // get number of vertices (should be 4)
222  const int vxSize = refElem.size( localFace, 1, dimension );
223  int faceIdx = faceIndex * maxNumVerticesPerFace ;
224  ug->face_nodepos[ faceIndex ] = faceIdx;
225  ug->face_nodepos[ faceIndex+1 ] = faceIdx + maxNumVerticesPerFace;
226  for( int vx=0; vx<vxSize; ++vx, ++faceIdx )
227  {
228  const int localVx = refElem.subEntity( localFace, 1, vx, dimension );
229  const int vxIndex = indexSet.subIndex( element, localVx, dimension );
230  ug->face_nodes[ faceIdx ] = vxIndex ;
231  }
232 
233  assert( vxSize <= maxNumVerticesPerFace );
234  assert( localFace < maxNumFacesPerCell );
235 
236  // store cell --> face relation
237  ug->cell_faces [ cellFace + localFaceIdx ] = faceIndex;
238  if( faceTags )
239  {
240  // fill logical cartesian orientation of the face (here indexInInside)
241  ug->cell_facetag[ cellFace + localFaceIdx ] = localFaceIdx;
242  }
243 
244  GlobalCoordinate normal = intersection.centerUnitOuterNormal();
245  normal *= faceVol;
246 
247  // store face --> cell relation
248  if( intersection.neighbor() )
249  {
250 #if DUNE_VERSION_NEWER(DUNE_GRID,2,4)
251  const Element& neighbor = intersection.outside();
252 #else
253  auto ep = intersection.outside();
254  const Element& neighbor = *ep;
255 #endif
256 
257  int nbIndex = -1;
258  if( ! ( onlyInterior && neighbor.partitionType() != Dune::InteriorEntity ) )
259  nbIndex = indexSet.index( neighbor );
260 
261  if( nbIndex == -1 || elIndex < nbIndex )
262  {
263  ug->face_cells[ 2*faceIndex ] = elIndex;
264  ug->face_cells[ 2*faceIndex + 1 ] = nbIndex;
265  }
266  else
267  {
268  ug->face_cells[ 2*faceIndex ] = nbIndex;
269  ug->face_cells[ 2*faceIndex + 1 ] = elIndex;
270  // flip normal
271  normal *= -1.0;
272  }
273  }
274  else // domain boundary
275  {
276  ug->face_cells[ 2*faceIndex ] = elIndex;
277  ug->face_cells[ 2*faceIndex + 1 ] = -1; // boundary
278  }
279 
280  const GlobalCoordinate center = intersectionGeometry.center();
281  // store normal
282  int idx = faceIndex * dimension;
283  for( int d=0; d<dimension; ++d, ++idx )
284  {
285  ug->face_normals [ idx ] = normal[ d ];
286  ug->face_centroids[ idx ] = center[ d ];
287  }
288  }
289  if( faceCount > maxNumFacesPerCell )
290  OPM_THROW(std::logic_error,"DuneGrid only supports conforming hexahedral currently");
291  cellFace += faceCount;
292  }
293 
294  // set last entry
295  ug->cell_facepos[ numCells ] = cellFace;
296  // set number of faces found
297  ug->number_of_faces = maxFaceIdx+1;
298 
299  // std::cout << cellFace << " " << indexSet.size( 1 ) << " " << maxFaceIdx << std::endl;
300  return ug;
301  }
302 } // end namespace Opm
303 
304 #endif
FaceKey()
Definition: polyhedralgridconverter.hh:39
Definition: polyhedralgridconverter.hh:36
FaceKey(const int inside, const int outside)
Definition: polyhedralgridconverter.hh:40
STL namespace.
Definition: baseauxiliarymodule.hh:35
std::pair< int, int > BaseType
Definition: polyhedralgridconverter.hh:38
UnstructuredGrid * dune2UnstructuredGrid(const GridView &gridView, const CartesianIndexMapper &cartesianIndexMapper, const bool faceTags, const bool onlyInterior=true)
Definition: polyhedralgridconverter.hh:49