gridfactory.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_GRIDFACTORY_HH
4#define DUNE_POLYHEDRALGRID_GRIDFACTORY_HH
5
6#include <algorithm>
7#include <numeric>
8
9#include <dune/common/typetraits.hh>
10#include <dune/common/version.hh>
11
12#include <dune/grid/common/gridfactory.hh>
14
15namespace Dune
16{
17
18
19 // GridFactory for PolyhedralGrid
20 // ---------------------------------
21
22 template< int dim, int dimworld, class coord_t >
23 class GridFactory< PolyhedralGrid< dim, dimworld, coord_t > >
24 : public GridFactoryInterface< PolyhedralGrid< dim, dimworld, coord_t > >
25 {
26 public:
28
29 const static int dimension = Grid::dimension;
30 const static int dimensionworld = Grid::dimensionworld;
31 typedef typename Grid::ctype ctype;
32
33 typedef MPIHelper::MPICommunicator MPICommunicatorType;
34 typedef typename Grid::template Codim<0>::Entity Element;
35 typedef typename Grid::template Codim<dimension>::Entity Vertex;
36
37 typedef Dune::FieldVector<ctype,dimensionworld> CoordinateType;
39
40 using UniquePtrType = std::unique_ptr<Grid>;
41
43 explicit GridFactory ( const MPICommunicatorType& = MPIHelper::getCommunicator() )
44 : nodes_(),
45 faces_(),
46 cells_()
47 {}
48
49 virtual void insertVertex(const CoordinateType& pos)
50 {
51 nodes_.push_back( pos );
52 }
53
63 virtual void insertElement(const GeometryType& type,
64 const std::vector<unsigned int>& items)
65 {
66 if( type.isNone() )
67 {
68 // copy into vector of integers
69 std::vector< int > numbers( items.size() );
70 std::copy( items.begin(), items.end(), numbers.begin() );
71
72 if( type.dim() == dimension-1 )
73 {
74 faces_.push_back( numbers );
75 }
76 else if( type.dim() == dimension )
77 {
78 // note vertices holds the face
79 // numbers in this case
80 cells_.push_back( numbers );
81 }
82 else
83 {
84 DUNE_THROW(Dune::NotImplemented,"insertElement not implemented for type " << type );
85 }
86 }
87 else // use ReferenceElement to insert faces
88 {
89
90
91 }
92 }
93
94 void insertBoundarySegment(const std::vector<unsigned int>&)
95 {
96 DUNE_THROW(NotImplemented,"yet");
97 }
98
100 {
101 std::vector< CoordinateType >& nodes = nodes_;
102 std::vector< std::vector< int > >& faces = faces_;
103 std::vector< std::vector< int > >& cells = cells_;
104
105 if( cells.empty() )
106 {
107 DUNE_THROW( GridError, "No cells found for PolyhedralGrid" );
108 }
109
110 const auto sumSize = [] ( std::size_t s, const std::vector< int > &v ) { return s + v.size(); };
111 const std::size_t numFaceNodes = std::accumulate( faces.begin(), faces.end(), std::size_t( 0 ), sumSize );
112 const std::size_t numCellFaces = std::accumulate( cells.begin(), cells.end(), std::size_t( 0 ), sumSize );
113
114 typename Grid::UnstructuredGridPtr ug =
115 Grid::allocateGrid( cells.size(), faces.size(), numFaceNodes, numCellFaces, nodes.size() );
116
117 // copy faces
118 {
119#ifndef NDEBUG
120 std::map< std::vector< int >, std::vector< int > > faceMap;
121#endif
122
123 const int nFaces = faces.size();
124 // set all face_cells values to -2 as default
125 std::fill( ug->face_cells, ug->face_cells + 2*nFaces, -1 );
126
127 int facepos = 0;
128 std::vector< int > faceVertices;
129 faceVertices.reserve( 30 );
130 for( int face = 0; face < nFaces; ++face )
131 {
132 //std::cout << "face " << face << ": ";
133 faceVertices.clear();
134 ug->face_nodepos[ face ] = facepos;
135 const int nVertices = faces[ face ].size();
136 for( int vx = 0; vx < nVertices; ++vx, ++facepos )
137 {
138 //std::cout << " " << faces[ face ][ vx ];
139 ug->face_nodes[ facepos ] = faces[ face ][ vx ];
140 faceVertices.push_back( faces[ face ][ vx ] );
141 }
142 //std::cout << std::endl;
143
144#ifndef NDEBUG
145 // sort vertices
146 std::sort( faceVertices.begin(), faceVertices.end() );
147 // make sure each face only exists once
148 faceMap[ faceVertices ].push_back( face );
149 assert( faceMap[ faceVertices ].size() == 1 );
150#endif
151 }
152 ug->face_nodepos[ nFaces ] = facepos ;
153 }
154
155 // copy cells
156 {
157 const int nCells = cells.size();
158 int cellpos = 0;
159 for( int cell = 0; cell < nCells; ++cell )
160 {
161 //std::cout << "Cell " << cell << ": ";
162 ug->cell_facepos[ cell ] = cellpos;
163 const int nFaces = cells[ cell ].size();
164 for( int f = 0; f < nFaces; ++f, ++cellpos )
165 {
166 const int face = cells[ cell ][ f ];
167 // std::cout << " " << face ;
168 ug->cell_faces[ cellpos ] = face;
169
170 // TODO find cells for each face
171 if( ug->face_cells[ 2*face ] == -1 )
172 {
173 ug->face_cells[ 2*face ] = cell;
174 }
175 else // if ( ug->face_cells[ 2*face+1 ] == -1 )
176 {
177 //assert( ug->face_cells[ 2*face+1 ] == -1 );
178 ug->face_cells[ 2*face+1 ] = cell;
179 }
180 }
181 //std::cout << std::endl;
182 }
183 ug->cell_facepos[ nCells ] = cellpos ;
184 }
185
186 // copy node coordinates
187 {
188 const int nNodes = nodes.size();
189 int nodepos = 0;
190 for( int vx = 0 ; vx < nNodes; ++vx )
191 {
192 for( int d=0; d<dim; ++d, ++nodepos )
193 ug->node_coordinates[ nodepos ] = nodes[ vx ][ d ];
194 }
195 }
196
197 /*
198 for( int i=0; i<int(faces.size() ); ++i)
199 {
200 std::cout << "face "<< i<< " connects to " << ug->face_cells[ 2*i ] << " " <<
201 ug->face_cells[ 2*i+1] << std::endl;
202 }
203 */
204
205 // free cell face tag since it's not a cartesian grid
206 if( ug->cell_facetag )
207 {
208 std::free( ug->cell_facetag );
209 ug->cell_facetag = nullptr ;
210 for( int i=0; i<3; ++i ) ug->cartdims[ i ] = 0;
211 }
212
213 // compute geometric quantities like cell volume and face normals
214 Grid::computeGeometry( ug );
215
216 // check normal direction
217 {
218 for( int face = 0 ; face < ug->number_of_faces; ++face )
219 {
220 const int a = ug->face_cells[ 2*face ];
221 const int b = ug->face_cells[ 2*face + 1 ];
222 if( a < 0 || b < 0 )
223 continue ;
224
225 Coordinate centerDiff( 0 );
226 Coordinate normal( 0 );
227 //std::cout << "Cell center " << a << " " << b << std::endl;
228 for( int d=0; d<dim; ++d )
229 {
230 //std::cout << ug->cell_centroids[ a*dim + d ] << " " << ug->cell_centroids[ b*dim + d ] << std::endl;
231 centerDiff[ d ] = ug->cell_centroids[ b*dim + d ] - ug->cell_centroids[ a*dim + d ];
232 normal[ d ] = ug->face_normals[ face*dim + d ];
233 }
234
235 // if diff and normal point in different direction, flip faces
236 if( centerDiff * normal > 0 )
237 {
238 ug->face_cells[ 2*face ] = b;
239 ug->face_cells[ 2*face + 1 ] = a;
240 }
241 }
242 }
243
244 return UniquePtrType( new Grid( std::move( ug ) ));
245 }
246
247 protected:
248 std::vector< CoordinateType > nodes_;
249 std::vector< std::vector< int > > faces_;
250 std::vector< std::vector< int > > cells_;
251 };
252
253} // namespace Dune
254
255#endif // #ifndef DUNE_POLYHEDRALGRID_DGFPARSER_HH
virtual void insertElement(const GeometryType &type, const std::vector< unsigned int > &items)
Insert an element into the coarse grid.
Definition: gridfactory.hh:63
std::vector< std::vector< int > > faces_
Definition: gridfactory.hh:249
void insertBoundarySegment(const std::vector< unsigned int > &)
Definition: gridfactory.hh:94
virtual void insertVertex(const CoordinateType &pos)
Definition: gridfactory.hh:49
PolyhedralGrid< dim, dimworld, coord_t > Grid
Definition: gridfactory.hh:27
Grid::template Codim< 0 >::Entity Element
Definition: gridfactory.hh:34
std::unique_ptr< Grid > UniquePtrType
Definition: gridfactory.hh:40
GridFactory(const MPICommunicatorType &=MPIHelper::getCommunicator())
Default constructor.
Definition: gridfactory.hh:43
std::vector< CoordinateType > nodes_
Definition: gridfactory.hh:248
Grid::template Codim< dimension >::Entity Vertex
Definition: gridfactory.hh:35
MPIHelper::MPICommunicator MPICommunicatorType
Definition: gridfactory.hh:33
Dune::FieldVector< ctype, dimensionworld > CoordinateType
Definition: gridfactory.hh:37
UniquePtrType createGrid()
Definition: gridfactory.hh:99
CoordinateType Coordinate
Definition: gridfactory.hh:38
Grid::ctype ctype
Definition: gridfactory.hh:31
std::vector< std::vector< int > > cells_
Definition: gridfactory.hh:250
identical grid wrapper
Definition: grid.hh:159
Traits::ctype ctype
type of vector coordinates (e.g., double)
Definition: grid.hh:308
std::unique_ptr< UnstructuredGridType, UnstructuredGridDeleter > UnstructuredGridPtr
Definition: grid.hh:178
The namespace Dune is the main namespace for all Dune code.
Definition: common/CartesianIndexMapper.hpp:10
int numCellFaces(const Dune::CpGrid &grid)
Get the number of faces, where each face counts as many times as there are adjacent faces.
double b(const Dune::FieldVector< ct, dimworld > &, double)
Definition: transportproblem2.hh:25