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