1
#ifndef DUNE_UGGRID_INDEXSETS_HH
2
#define DUNE_UGGRID_INDEXSETS_HH
5
\brief The index and id sets for the UGGrid class
11
#include <dune/grid/common/grid.hh>
15
template<class GridImp>
16
class UGGridLevelIndexSet : public IndexSet<GridImp,UGGridLevelIndexSet<GridImp>, UG::UINT>
18
enum {dim = GridImp::dimension};
22
/** \brief Default constructor
24
Unfortunately we can't force the user to init grid_ and level_, because
25
UGGridLevelIndexSets are meant to be stored in an array.
27
\todo I want to make this constructor private, but I can't, because
28
it is called by UGGrid through a std::vector::resize()
30
UGGridLevelIndexSet () {}
32
//! get index of an entity
34
unsigned int index (const typename GridImp::Traits::template Codim<cd>::Entity& e) const
36
return UG_NS<dim>::levelIndex(grid_->getRealImplementation(e).target_);
39
//! get index of subEntity of a codim 0 entity
41
unsigned int subIndex (const typename GridImp::Traits::template Codim<cc>::Entity& e,
43
unsigned int codim) const
46
return UG_NS<dim>::levelIndex(grid_->getRealImplementation(e).target_);
49
return UG_NS<dim>::levelIndex(UG_NS<dim>::Corner(grid_->getRealImplementation(e).target_,
50
UGGridRenumberer<dim>::verticesDUNEtoUG(i,e.type())));
53
return UG_NS<dim>::levelIndex(grid_->getRealImplementation(e).target_);
57
int a=GenericReferenceElements<double,dim>::general(e.type()).subEntity(i,dim-1,0,dim);
58
int b=GenericReferenceElements<double,dim>::general(e.type()).subEntity(i,dim-1,1,dim);
59
return UG_NS<dim>::levelIndex(UG_NS<dim>::GetEdge(UG_NS<dim>::Corner(grid_->getRealImplementation(e).target_,
60
UGGridRenumberer<dim>::verticesDUNEtoUG(a,e.type())),
61
UG_NS<dim>::Corner(grid_->getRealImplementation(e).target_,
62
UGGridRenumberer<dim>::verticesDUNEtoUG(b,e.type()))));
66
return UG_NS<dim>::levelIndex(UG_NS<dim>::SideVector(grid_->getRealImplementation(e).target_,
67
UGGridRenumberer<dim>::facesDUNEtoUG(i,e.type())));
69
DUNE_THROW(GridError, "UGGrid<" << dim << "," << dim << ">::subIndex isn't implemented for codim==" << codim );
73
//! get number of entities of given codim, type and on this level
74
int size (int codim) const {
76
return numSimplices_+numPyramids_+numPrisms_+numCubes_;
82
return numTriFaces_+numQuadFaces_;
83
DUNE_THROW(NotImplemented, "wrong codim!");
86
//! get number of entities of given codim, type and on this level
87
int size (GeometryType type) const
89
int codim = GridImp::dimension-type.dim();
94
else if (type.isPyramid())
96
else if (type.isPrism())
98
else if (type.isCube())
112
if (type.isSimplex())
114
else if (type.isCube())
115
return numQuadFaces_;
120
DUNE_THROW(NotImplemented, "Wrong codim!");
123
/** \brief Deliver all geometry types used in this grid */
124
const std::vector<GeometryType>& geomTypes (int codim) const
126
return myTypes_[codim];
129
/** \brief Return true if e is contained in the index set.
131
\note If 'entity' is from another grid this method may still return 'true'.
132
This is acceptable by the Dune grid interface specification.
134
template <class EntityType>
135
bool contains (const EntityType& entity) const
137
return entity.level() == level_;
140
/** \brief Update the level indices. This method is called after each grid change */
141
void update(const GridImp& grid, int level, std::vector<unsigned int>* nodePermutation=0);
143
const GridImp* grid_;
155
std::vector<GeometryType> myTypes_[dim+1];
158
template<class GridImp>
159
class UGGridLeafIndexSet: public IndexSet<GridImp,UGGridLeafIndexSet<GridImp>, UG::UINT>
164
We use the remove_const to extract the Type from the mutable class,
165
because the const class is not instantiated yet.
167
enum {dim = remove_const<GridImp>::type::dimension};
169
//! constructor stores reference to a grid and level
170
UGGridLeafIndexSet (const GridImp& g)
171
: grid_(g), coarsestLevelWithLeafElements_(0)
175
//! get index of an entity
177
We use the remove_const to extract the Type from the mutable class,
178
because the const class is not instantiated yet.
181
int index (const typename remove_const<GridImp>::type::Traits::template Codim<cd>::Entity& e) const
183
return UG_NS<dim>::leafIndex(grid_.getRealImplementation(e).target_);
186
//! get index of subEntity of a codim 0 entity
188
We use the remove_const to extract the Type from the mutable class,
189
because the const class is not instantiated yet.
192
unsigned int subIndex (const typename remove_const<GridImp>::type::Traits::template Codim<cc>::Entity& e,
194
unsigned int codim) const
197
return UG_NS<dim>::levelIndex(grid_.getRealImplementation(e).target_);
200
return UG_NS<dim>::leafIndex(grid_.getRealImplementation(e).target_);
202
const GeometryType type = e.type();
205
return UG_NS<dim>::leafIndex(UG_NS<dim>::Corner(grid_.getRealImplementation(e).target_,
206
UGGridRenumberer<dim>::verticesDUNEtoUG(i,type)));
210
int a=GenericReferenceElements<double,dim>::general(type).subEntity(i,dim-1,0,dim);
211
int b=GenericReferenceElements<double,dim>::general(type).subEntity(i,dim-1,1,dim);
212
return UG_NS<dim>::leafIndex(UG_NS<dim>::GetEdge(UG_NS<dim>::Corner(grid_.getRealImplementation(e).target_,
213
UGGridRenumberer<dim>::verticesDUNEtoUG(a,type)),
214
UG_NS<dim>::Corner(grid_.getRealImplementation(e).target_,
215
UGGridRenumberer<dim>::verticesDUNEtoUG(b,type))));
219
return UG_NS<dim>::leafIndex(UG_NS<dim>::SideVector(grid_.getRealImplementation(e).target_,
220
UGGridRenumberer<dim>::facesDUNEtoUG(i,type)));
222
DUNE_THROW(GridError, "UGGrid<" << dim << "," << dim << ">::subLeafIndex isn't implemented for codim==" << codim );
225
//! get number of entities of given codim and type
226
int size (GeometryType type) const
228
if (type.dim()==GridImp::dimension) {
229
if (type.isSimplex())
230
return numSimplices_;
231
else if (type.isPyramid())
233
else if (type.isPrism())
235
else if (type.isCube())
246
if (type.isTriangle())
248
else if (type.isQuadrilateral())
249
return numQuadFaces_;
254
//! get number of entities of given codim
255
int size (int codim) const
258
const std::vector<GeometryType>& geomTs = geomTypes(codim);
259
for (unsigned int i=0; i<geomTs.size(); ++i)
260
s += size(geomTs[i]);
264
/** deliver all geometry types used in this grid */
265
const std::vector<GeometryType>& geomTypes (int codim) const
267
return myTypes_[codim];
270
/** \brief Return true if e is contained in the index set.
272
\note If 'entity' is from another grid this method may still return 'true'.
273
This is acceptable by the Dune grid interface specification.
275
template <class EntityType>
276
bool contains (const EntityType& entity) const
278
return UG_NS<dim>::isLeaf(GridImp::getRealImplementation(entity).target_);
282
/** \brief Update the leaf indices. This method is called after each grid change. */
283
void update(std::vector<unsigned int>* nodePermutation=0);
285
const GridImp& grid_;
287
/** \brief The lowest level that contains leaf elements
289
This corresponds to UG's fullRefineLevel, which is, unfortunately only
290
computed if you use some nontrivial UG algebra. Thus we compute it
291
ourselves, and use it to speed up the leaf iterators.
293
unsigned int coarsestLevelWithLeafElements_;
306
std::vector<GeometryType> myTypes_[dim+1];
310
/** \brief Implementation class for the UGGrid Id sets
312
The UGGridGlobalIdSet and the UGGridLocalIdSet are virtually identical. This
313
class implements them both at once. You can select the one you want using
314
the <tt>Local</tt> template parameter.
315
\tparam Local false for GlobalIdSet, true for LocalIdSet
317
template <class GridImp, bool Local>
318
class UGGridIdSet : public IdSet<GridImp,UGGridIdSet<GridImp,Local>,unsigned int>
320
enum {dim = remove_const<GridImp>::type::dimension};
322
typedef typename std::pair<const typename UG_NS<dim>::Element*, int> Face;
324
/** \brief Look for copy of a face on the next-lower grid level.
326
\todo This method is not implemented very efficiently, but I will not put
327
further work into it as long as the much-awaited face objects are not included
330
static Face getFatherFace(const Face& face) {
332
// set up result object
334
resultFace.first = UG_NS<dim>::EFather(face.first);
336
// If there is no father element then we know there is no father face
337
/** \bug This is not true when doing vertical load balancing. */
338
if (resultFace.first == NULL)
341
// Get all corners of the face
342
std::set<const typename UG_NS<dim>::Vertex*> corners;
344
for (int i=0; i<UG_NS<dim>::Corners_Of_Side(face.first, face.second); i++)
345
corners.insert(UG_NS<dim>::Corner(face.first, UG_NS<dim>::Corner_Of_Side(face.first, face.second, i))->myvertex);
347
// Loop over all faces of the father element and look for a face that has the same vertices
348
for (int i=0; i<UG_NS<dim>::Sides_Of_Elem(resultFace.first); i++) {
350
// Copy father face into set
351
std::set<const typename UG_NS<dim>::Vertex*> fatherFaceCorners;
353
for (int j=0; j<UG_NS<dim>::Corners_Of_Side(resultFace.first, i); j++)
354
fatherFaceCorners.insert(UG_NS<dim>::Corner(resultFace.first, UG_NS<dim>::Corner_Of_Side(resultFace.first, i, j))->myvertex);
356
// Do the vertex sets match?
357
if (corners==fatherFaceCorners) {
358
resultFace.second = i;
364
// No father face found
365
resultFace.first = NULL;
370
//! constructor stores reference to a grid
371
UGGridIdSet (const GridImp& g) : grid_(g) {}
373
//! get id of an entity
375
We use the remove_const to extract the Type from the mutable class,
376
because the const class is not instantiated yet.
379
unsigned int id (const typename remove_const<GridImp>::type::Traits::template Codim<cd>::Entity& e) const
382
// If we're asked for the id of an element, and that element is a copy of its father, then
383
// we return the id of the lowest ancestor that the element is a copy from. That way copies
384
// of elements have the same id
385
const typename UG_NS<dim>::Element* ancestor = (typename UG_NS<dim>::Element* const)(grid_.getRealImplementation(e).target_);
386
/** \todo We should really be using an isCopy() method rather than hasCopy() */
387
while (UG_NS<dim>::EFather(ancestor) && UG_NS<dim>::hasCopy(UG_NS<dim>::EFather(ancestor)))
388
ancestor = UG_NS<dim>::EFather(ancestor);
391
return ancestor->ge.ddd.gid;
393
return UG_NS<dim>::id(ancestor);
399
typename UG_NS<dim>::Node *node =
400
reinterpret_cast<typename UG_NS<dim>::Node *>(grid_.getRealImplementation(e).target_);
402
return node->ddd.gid;
405
DUNE_THROW(NotImplemented,
406
(Local ? "Local" : "Global") <<
407
" persistent index for entities which are neither nodes nor elements.");
410
return UG_NS<dim>::id(grid_.getRealImplementation(e).target_);
415
//! get id of subEntity
417
We use the remove_const to extract the Type from the mutable class,
418
because the const class is not instantiated yet.
420
unsigned int subId (const typename remove_const<GridImp>::type::Traits::template Codim<0>::Entity& e,
422
unsigned int codim) const
427
const typename UG_NS<dim>::Element* target = grid_.getRealImplementation(e).target_;
428
GeometryType type = e.type();
432
int a=GenericReferenceElements<double,dim>::general(type).subEntity(i,dim-1,0,dim);
433
int b=GenericReferenceElements<double,dim>::general(type).subEntity(i,dim-1,1,dim);
434
const typename UG_NS<dim>::Edge* edge = UG_NS<dim>::GetEdge(UG_NS<dim>::Corner(target, UGGridRenumberer<dim>::verticesDUNEtoUG(a,type)),
435
UG_NS<dim>::Corner(target, UGGridRenumberer<dim>::verticesDUNEtoUG(b,type)));
437
// If this edge is the copy of an edge on a lower level we return the id of that lower
438
// edge, because Dune wants entities which are copies of each other to have the same id.
439
const typename UG_NS<dim>::Edge* fatherEdge;
440
fatherEdge = GetFatherEdge(edge);
442
while (fatherEdge // fatherEdge exists
443
// ... and it must be a true copy father
444
&& ( (fatherEdge->links[0].nbnode->myvertex == edge->links[0].nbnode->myvertex
445
&& fatherEdge->links[1].nbnode->myvertex == edge->links[1].nbnode->myvertex)
447
(fatherEdge->links[0].nbnode->myvertex == edge->links[1].nbnode->myvertex
448
&& fatherEdge->links[1].nbnode->myvertex == edge->links[0].nbnode->myvertex) ) ) {
450
fatherEdge = GetFatherEdge(edge);
454
//return (Local) ? edge->id : edge->ddd.gid;
455
DUNE_THROW(NotImplemented, "!");
461
if (codim==1) { // Faces
463
Face face(target, UGGridRenumberer<dim>::facesDUNEtoUG(i,type));
465
// If this face is the copy of a face on a lower level we return the id of that lower
466
// face, because Dune wants entities which are copies of each other to have the same id.
468
fatherFace = getFatherFace(face);
469
while (fatherFace.first) {
471
fatherFace = getFatherFace(face);
476
? UG_NS<dim>::SideVector(face.first, face.second)->id
477
: UG_NS<dim>::SideVector(face.first, face.second)->ddd.gid;
479
return UG_NS<dim>::SideVector(face.first, face.second)->id;
486
? UG_NS<dim>::id(UG_NS<dim>::Corner(target,UGGridRenumberer<dim>::verticesDUNEtoUG(i,type)))
487
: UG_NS<dim>::Corner(target, UGGridRenumberer<dim>::verticesDUNEtoUG(i,type))->ddd.gid;
489
return UG_NS<dim>::id(UG_NS<dim>::Corner(target,UGGridRenumberer<dim>::verticesDUNEtoUG(i,type)));
493
DUNE_THROW(GridError, "UGGrid<" << dim << ">::subId isn't implemented for codim==" << codim );
498
const GridImp& grid_;