Dune Core Modules (2.4.2)

indexsets.hh
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_ALU3DGRIDINDEXSETS_HH
4 #define DUNE_ALU3DGRIDINDEXSETS_HH
5 
6 //- System includes
7 #include <vector>
8 
9 //- Dune includes
12 #include <dune/common/hash.hh>
13 
14 #include <dune/grid/common/grid.hh>
16 
17 
18 //- Local includes
19 #include "alu3dinclude.hh"
20 #include "topology.hh"
21 #include "alu3diterators.hh"
22 
23 namespace Dune
24 {
25 
26  // External Forward Declarations
27  // -----------------------------
28 
29  template< ALU3dGridElementType, class >
30  class ALU3dGrid;
31 
32  template<int cd, int dim, class GridImp>
33  class ALU3dGridEntity;
34 
35 
36 
37  // ALU3dGridHierarchicIndexSet
38  // ---------------------------
39 
41  template< ALU3dGridElementType elType, class Comm >
43  : public IndexSet< ALU3dGrid< elType, Comm >, ALU3dGridHierarchicIndexSet< elType, Comm > >
44  {
46 
48  enum { numCodim = GridType::dimension + 1 };
49 
50  friend class ALU3dGrid< elType, Comm >;
51 
52  // constructor
54  : grid_( grid )
55  {}
56 
57  public:
58  typedef typename GridType::Traits::template Codim<0>::Entity EntityCodim0Type;
59 
61  template <class EntityType>
62  int index (const EntityType & ep) const
63  {
64  enum { cd = EntityType :: codimension };
65  return index<cd>(ep);
66  }
67 
69  template< int codim >
70  int index ( const typename GridType::Traits::template Codim< codim >::Entity &entity ) const
71  {
72  return GridType::getRealImplementation( entity ).getIndex();
73  }
74 
76  int subIndex ( const EntityCodim0Type &e, int i, unsigned int codim ) const
77  {
78  // call method subIndex on real implementation
79  return GridType::getRealImplementation( e ).subIndex( i, codim );
80  }
81 
84  int size ( GeometryType type ) const
85  {
86  if( elType == tetra && !type.isSimplex() ) return 0;
87  if( elType == hexa && !type.isCube() ) return 0;
88  // return size of hierarchic index set
89  return this->size(GridType::dimension-type.dim());
90  }
91 
93  int size ( int codim ) const
94  {
95  // return size of hierarchic index set
96  return grid_.hierSetSize(codim);
97  }
98 
100  const std::vector<GeometryType>& geomTypes (int codim) const
101  {
102  return grid_.geomTypes(codim);
103  }
104 
106  template <class EntityType>
107  bool contains (const EntityType &) const { return true; }
108 
109  private:
110  // our Grid
111  const GridType & grid_;
112  };
113 
118 
119  class ALUMacroKey : public ALU3DSPACE Key4<int>
120  {
121  typedef int A;
122  typedef ALUMacroKey ThisType;
123  typedef ALU3DSPACE Key4<A> BaseType;
124 
125  public:
126  ALUMacroKey() : BaseType(-1,-1,-1,-1) {}
127  ALUMacroKey(const A&a,const A&b,const A&c,const A&d) : BaseType(a,b,c,d) {}
128  ALUMacroKey(const ALUMacroKey & org ) : BaseType(org) {}
129  ALUMacroKey & operator = (const ALUMacroKey & org )
130  {
131  BaseType::operator = (org);
132  return *this;
133  }
134 
135  bool operator == (const ALUMacroKey & org) const
136  {
137  return ( (this->_a == org._a) &&
138  (this->_b == org._b) &&
139  (this->_c == org._c) &&
140  (this->_d == org._d) );
141  }
142 
143  // operator < is already implemented in BaseType
144  bool operator > (const ALUMacroKey & org) const
145  {
146  return ( (!this->operator == (org)) && (!this->operator <(org)) );
147  }
148 
149  void print(std::ostream & out) const
150  {
151  out << "[" << this->_a << "," << this->_b << "," << this->_c << "," << this->_d << "]";
152  }
153 
154 #ifdef HAVE_DUNE_HASH
155 
156  inline friend std::size_t hash_value(const ALUMacroKey& arg)
157  {
158  std::size_t seed = 0;
159  hash_combine(seed,arg._a);
160  hash_combine(seed,arg._b);
161  hash_combine(seed,arg._c);
162  hash_combine(seed,arg._d);
163  return seed;
164  }
165 
166 #endif // HAVE_DUNE_HASH
167 
168  };
169 
170  template <class MacroKeyImp>
171  class ALUGridId
172  {
173  MacroKeyImp key_;
174  int nChild_;
175  int codim_;
176 
177  public:
178  ALUGridId() : key_()
179  , nChild_(-1)
180  , codim_(-1)
181  {}
182 
183  ALUGridId(const MacroKeyImp & key, int nChild , int cd)
184  : key_(key) , nChild_(nChild)
185  , codim_(cd)
186  {}
187 
188  ALUGridId(const ALUGridId & org )
189  : key_(org.key_)
190  , nChild_(org.nChild_)
191  , codim_(org.codim_)
192  {}
193 
194  ALUGridId & operator = (const ALUGridId & org )
195  {
196  key_ = org.key_;
197  nChild_ = org.nChild_;
198  codim_ = org.codim_;
199  return *this;
200  }
201 
202  bool operator == (const ALUGridId & org) const
203  {
204  return equals(org);
205  }
206 
207  bool operator != (const ALUGridId & org) const
208  {
209  return ! equals(org);
210  }
211 
212  bool operator <= (const ALUGridId & org) const
213  {
214  if(equals(org)) return true;
215  else return lesser(org);
216  }
217 
218  bool operator >= (const ALUGridId & org) const
219  {
220  if(equals(org)) return true;
221  else return ! lesser(org);
222  }
223 
224  bool operator < (const ALUGridId & org) const
225  {
226  return lesser(org);
227  }
228 
229  bool operator > (const ALUGridId & org) const
230  {
231  return (!equals(org) && ! lesser(org));
232  }
233 
234  const MacroKeyImp & getKey() const { return key_; }
235  int nChild() const { return nChild_; }
236  int codim() const { return codim_; }
237 
238  bool isValid () const
239  {
240  return ( (nChild_ >= 0) && (codim_ >= 0) );
241  }
242 
243  void reset()
244  {
245  nChild_ = -1;
246  codim_ = -1;
247  }
248 
249  void print(std::ostream & out) const
250  {
251  out << "(" << getKey() << "," << nChild_ << "," << codim_ << ")";
252  }
253 
254 #ifdef HAVE_DUNE_HASH
255 
256  inline friend std::size_t hash_value(const ALUGridId& arg)
257  {
258  std::size_t seed = hash<MacroKeyImp>() (arg.getKey());
259  hash_combine(seed,arg.nChild());
260  hash_combine(seed,arg.codim());
261  return seed;
262  }
263 
264 #endif // HAVE_DUNE_HASH
265 
266  protected:
267  // returns true is the id is lesser then org
268  bool lesser(const ALUGridId & org) const
269  {
270  if(getKey() < org.getKey() ) return true;
271  if(getKey() > org.getKey() ) return false;
272  if(getKey() == org.getKey() )
273  {
274  if(nChild_ == org.nChild_)
275  {
276  return codim_ < org.codim_;
277  }
278  else
279  return nChild_ < org.nChild_;
280  }
281  assert( equals(org) );
282  return false;
283  }
284 
285  // returns true if this id equals org
286  bool equals(const ALUGridId & org) const
287  {
288  return ( (getKey() == org.getKey() ) && (nChild_ == org.nChild_)
289  && (codim_ == org.codim_) );
290  }
291  };
292 
293 } // drop out of namespace Dune, as hash definitions have to be done in global namespace
294 
296 DUNE_DEFINE_HASH(DUNE_HASH_TEMPLATE_ARGS(typename MacroKeyImp),DUNE_HASH_TYPE(Dune::ALUGridId<MacroKeyImp>))
297 
298 namespace Dune {
299 
300  inline std::ostream& operator<< (std::ostream& s, const ALUMacroKey & key)
301  {
302  key.print(s);
303  return s;
304  }
305 
306  template <class KeyImp>
307  inline std::ostream& operator<< (std::ostream& s, const ALUGridId<KeyImp> & id)
308  {
309  id.print(s);
310  return s;
311  }
312 
313  //*****************************************************************
314  //
315  // --GlobalIdSet
316  //
317  //*****************************************************************
319  template< ALU3dGridElementType elType, class Comm >
320  class ALU3dGridGlobalIdSet
321  : public IdSet< ALU3dGrid< elType, Comm >, ALU3dGridGlobalIdSet< elType, Comm > ,
322  typename ALU3dGrid< elType, Comm >::Traits::GlobalIdType >,
323  public ALU3DSPACE AdaptRestrictProlongType
324  {
325  typedef ALU3dGrid< elType, Comm > GridType;
326  typedef typename GridType::HierarchicIndexSet HierarchicIndexSetType;
327 
328  typedef ALU3dImplTraits< elType, Comm > ImplTraitsType;
329  typedef typename ImplTraitsType::IMPLElementType IMPLElementType;
330  typedef typename ImplTraitsType::GEOElementType GEOElementType;
331  typedef typename ImplTraitsType::GEOFaceType GEOFaceType;
332  typedef typename ImplTraitsType::GEOEdgeType GEOEdgeType;
333 
334  typedef typename ImplTraitsType::GitterImplType GitterImplType;
335 
336  typedef typename ImplTraitsType::HElementType HElementType;
337  typedef typename ImplTraitsType::HFaceType HFaceType;
338  typedef typename ImplTraitsType::HEdgeType HEdgeType;
339  typedef typename ImplTraitsType::VertexType VertexType;
340  typedef typename ImplTraitsType::HBndSegType HBndSegType;
341 
342  typedef EntityCount< elType > EntityCountType;
343 
344  using ALU3DSPACE AdaptRestrictProlongType :: postRefinement ;
345  using ALU3DSPACE AdaptRestrictProlongType :: preCoarsening ;
346 
347  public:
349  typedef typename GridType::Traits::GlobalIdType IdType;
350 
351  private:
352  typedef ALUMacroKey MacroKeyType;
353 
354  typedef ALUGridId < MacroKeyType > MacroIdType; // same as IdType
355  enum { numCodim = GridType::dimension+1 };
356 
357  // this means that only up to 300000000 entities are allowed
358  typedef typename GridType::Traits::template Codim<0>::Entity EntityCodim0Type;
359  private:
360  mutable std::map< int , IdType > ids_[numCodim];
361  //mutable std::map< int , MacroKeyType > macroKeys_[numCodim];
362 
363  // our Grid
364  const GridType & grid_;
365 
366  // the hierarchicIndexSet
367  const HierarchicIndexSetType & hset_;
368 
369  int vertexKey_[4];
370 
371  int chunkSize_ ;
372 
373  enum { startOffSet_ = 0 };
374 
375  public:
376 
379  using IdSet < GridType , ALU3dGridGlobalIdSet, IdType > :: subId;
380 
382  ALU3dGridGlobalIdSet(const GridType & grid)
383  : grid_(grid), hset_(grid.hierarchicIndexSet())
384  , chunkSize_(100)
385  {
386  if(elType == hexa)
387  {
388  // see ALUGrid/src/serial/gitter_mgb.cc
389  // InsertUniqueHexa
390  const int vxKey[4] = {0,1,3,4};
391  for(int i=0; i<4; i++) vertexKey_[i] = vxKey[i];
392  }
393  else
394  {
395  assert( elType == tetra );
396  // see ALUGrid/src/serial/gitter_mgb.cc
397  // InsertUniqueTetra
398  const int vxKey[4] = {0,1,2,3};
399  for(int i=0; i<4; i++) vertexKey_[i] = vxKey[i];
400  }
401 
402  // setup the id set
403  buildIdSet();
404  }
405 
406  virtual ~ALU3dGridGlobalIdSet() {}
407 
408  // update id set after adaptation
409  void updateIdSet()
410  {
411  // to be revised
412  buildIdSet();
413  }
414 
415  // print all ids
416  void print () const
417  {
418  for(int i=0 ; i<numCodim; ++i)
419  {
420  std::cout << "*****************************************************\n";
421  std::cout << "Ids for codim " << i << "\n";
422  std::cout << "*****************************************************\n";
423  for(unsigned int k=0; k<ids_[i].size(); ++k)
424  {
425  std::cout << "Item[" << i << "," << k <<"] has id " << ids_[i][k] << "\n";
426  }
427  std::cout << "\n\n\n";
428  }
429  }
430 
431  template <class IterType>
432  void checkId(const IdType & macroId, const IterType & idIter) const //int codim , unsigned int num ) const
433  {
434 
435  IdType id = getId(macroId);
436  for(int i=0 ; i<numCodim; ++i)
437  {
438  typedef typename std::map<int,IdType>::iterator IteratorType;
439  IteratorType end = ids_[i].end();
440  for(IteratorType it = ids_[i].begin(); it != end; ++it)
441  //for(unsigned int k=0; k<ids_[i].size(); ++k)
442  {
443  if(idIter == it) continue;
444  //if((i == codim) && (k == num)) continue;
445  const IdType & checkMId = (*it).second; //ids_[i][k];
446  IdType checkId = getId(checkMId);
447  if( id == checkId )
448  {
449  //std::cout << "Check(codim,num = " << codim<< "," << num <<") failed for k="<<k << " codim = " << i << "\n";
450  std::cout << id << " equals " << checkId << "\n";
451  assert( id != checkId );
452  DUNE_THROW(GridError," " << id << " equals " << checkId << "\n");
453  }
454  else
455  {
456  bool lesser = (id < checkId);
457  bool greater = (id > checkId);
458  assert( lesser != greater );
459  if( lesser == greater )
460  {
461  assert( lesser != greater );
462  DUNE_THROW(GridError," lesser equals greater of one id ");
463  }
464  }
465  }
466  }
467  }
468 
469  // check id set for uniqueness
470  void uniquenessCheck() const
471  {
472  for(int i=0 ; i<numCodim; i++)
473  {
474  typedef typename std::map<int,IdType>::iterator IteratorType;
475  IteratorType end = ids_[i].end();
476  for(IteratorType it = ids_[i].begin(); it != end; ++it)
477  //unsigned int k=0; k<ids_[i].size(); ++k)
478  {
479  const IdType & id = (*it).second; //ids_[i][k];
480  if( id.isValid() )
481  checkId(id,it); //i,k);
482  }
483  }
484  }
485 
486  void setChunkSize( int chunkSize )
487  {
488  chunkSize_ = chunkSize;
489  }
490 
491  // creates the id set
492  void buildIdSet ()
493  {
494  for(int i=0; i<numCodim; ++i)
495  {
496  ids_[i].clear();
497  }
498 
499  GitterImplType &gitter = grid_.myGrid();
500 
501  // all interior and border vertices
502  {
503  typename ALU3DSPACE AccessIterator< VertexType >::Handle fw( gitter.container() );
504  for( fw.first (); !fw.done(); fw.next() )
505  {
506  int idx = fw.item().getIndex();
507  ids_[3][idx] = buildMacroVertexId( fw.item() );
508  }
509  }
510 
511  // all ghost vertices
512  {
513  typedef typename ALU3DSPACE ALU3dGridLevelIteratorWrapper< 3, Ghost_Partition, Comm > IteratorType;
514  IteratorType fw (grid_ , 0 , grid_.nlinks() );
515  typedef typename IteratorType :: val_t val_t;
516  for (fw.first () ; ! fw.done () ; fw.next ())
517  {
518  val_t & item = fw.item();
519  assert( item.first );
520  VertexType & vx = * (item.first);
521  int idx = vx.getIndex();
522  ids_[3][idx] = buildMacroVertexId( vx );
523  }
524  }
525 
526  // create ids for all macro edges
527  {
528  typename ALU3DSPACE AccessIterator< HEdgeType >::Handle w( gitter.container() );
529  for (w.first(); !w.done(); w.next())
530  {
531  int idx = w.item().getIndex();
532  ids_[2][idx] = buildMacroEdgeId( w.item() );
533  buildEdgeIds( w.item() , ids_[2][idx] , startOffSet_ );
534  }
535  }
536 
537  // all ghost edges
538  {
539  typedef typename ALU3DSPACE ALU3dGridLevelIteratorWrapper< 2, Ghost_Partition, Comm > IteratorType;
540  IteratorType fw( grid_, 0, grid_.nlinks() );
541  typedef typename IteratorType :: val_t val_t;
542  for (fw.first () ; ! fw.done () ; fw.next ())
543  {
544  val_t & item = fw.item();
545  assert( item.first );
546  HEdgeType & edge = * (item.first);
547  int idx = edge.getIndex();
548 
549  ids_[2][idx] = buildMacroEdgeId( edge );
550  buildEdgeIds( edge , ids_[2][idx] , startOffSet_ );
551  }
552  }
553 
554 
555  // for all macro faces and all children
556  {
557  typename ALU3DSPACE AccessIterator< HFaceType >::Handle w( gitter.container() );
558  for (w.first () ; ! w.done () ; w.next ())
559  {
560  int idx = w.item().getIndex();
561  ids_[1][idx] = buildMacroFaceId( w.item() );
562  buildFaceIds( w.item() , ids_[1][idx] , startOffSet_ );
563  }
564  }
565 
566  // all ghost faces
567  {
568  typedef typename ALU3DSPACE ALU3dGridLevelIteratorWrapper< 1, Ghost_Partition, Comm > IteratorType;
569  IteratorType fw (grid_ , 0 , grid_.nlinks() );
570  typedef typename IteratorType :: val_t val_t;
571  for (fw.first () ; ! fw.done () ; fw.next ())
572  {
573  val_t & item = fw.item();
574  assert( item.first );
575  HFaceType & face = * (item.first);
576  int idx = face.getIndex();
577  ids_[1][idx] = buildMacroFaceId( face );
578  buildFaceIds( face , ids_[1][idx] , startOffSet_ );
579  }
580  }
581 
582  // for all macro elements and all internal entities
583  {
584  typename ALU3DSPACE AccessIterator< HElementType >::Handle w( gitter.container() );
585  for (w.first () ; ! w.done () ; w.next ())
586  {
587  int idx = w.item().getIndex();
588  ids_[0][idx] = buildMacroElementId( w.item() );
589  buildElementIds( w.item() , ids_[0][idx] , startOffSet_ );
590  }
591  }
592 
593  // all ghost elements
594  {
595  typedef typename ALU3DSPACE ALU3dGridLevelIteratorWrapper< 0, Ghost_Partition, Comm > IteratorType;
596  IteratorType fw (grid_ , 0 , grid_.nlinks() );
597  typedef typename IteratorType :: val_t val_t;
598  for (fw.first () ; ! fw.done () ; fw.next ())
599  {
600  val_t & item = fw.item();
601  assert( item.second );
602  HElementType & elem = * ( item.second->getGhost().first );
603  int idx = elem.getIndex();
604  ids_[0][idx] = buildMacroElementId( elem );
605  buildElementIds( elem , ids_[0][idx] , startOffSet_ );
606  }
607  }
608 
609  // check uniqueness of id only in serial, because
610  // in parallel some faces and edges of ghost exists more than once
611  // but have the same id, but not the same index, there for the check
612  // will fail for ghost elements
613 #if ! ALU3DGRID_PARALLEL
614  // be carefull with this check, it's complexity is O(N^2)
615  //uniquenessCheck();
616 #endif
617  }
618 
619  IdType buildMacroVertexId(const VertexType & item )
620  {
621  int vx[4] = { item.ident(), -1, -1, -1};
622  enum {codim = 3 };
623  MacroKeyType key(vx[0],vx[1],vx[2],vx[3]);
624  MacroIdType id(key,1, codim + startOffSet_ );
625  return id;
626  }
627 
628  IdType buildMacroEdgeId(const HEdgeType & item )
629  {
630  const GEOEdgeType & edge = static_cast<const GEOEdgeType &> (item);
631  int vx[4] = {-1,-1,-1,-1};
632  for(int i=0; i<2; ++i)
633  {
634  vx[i] = edge.myvertex(i)->ident();
635  }
636 
637  enum { codim = 2 };
638  MacroKeyType key(vx[0],vx[1],vx[2],vx[3]);
639  MacroIdType id( key,1, codim + startOffSet_ );
640  return id;
641  }
642 
643  IdType buildMacroFaceId(const HFaceType & item )
644  {
645  const GEOFaceType & face = static_cast<const GEOFaceType &> (item);
646  int vx[4] = {-1,-1,-1,-1};
647  for(int i=0; i<3; ++i)
648  {
649  vx[i] = face.myvertex(i)->ident();
650  }
651 
652  enum { codim = 1 };
653  MacroKeyType key(vx[0],vx[1],vx[2],vx[3]);
654  MacroIdType id(key,1, codim + startOffSet_ );
655  return id;
656  }
657 
658  IdType buildMacroElementId(const HElementType & item )
659  {
660  const GEOElementType & elem = static_cast<const GEOElementType &> (item);
661  int vx[4] = {-1,-1,-1,-1};
662  for(int i=0; i<4; ++i)
663  {
664  vx[i] = elem.myvertex(vertexKey_[i])->ident();
665  }
666  enum { codim = 0 };
667  MacroKeyType key(vx[0],vx[1],vx[2],vx[3]);
668  return MacroIdType(key,1, codim + startOffSet_ );
669  }
670 
671  template <int cd>
672  IdType createId(const typename ImplTraitsType::
673  template Codim<cd>::InterfaceType & item , const IdType & creatorId , int nChild )
674  {
675  assert( creatorId.isValid() );
676 
677  // we have up to 12 internal hexa faces, therefore need 100 offset
678  enum { childOffSet = ((cd == 1) && (elType == hexa)) ? 16 : 8 };
679  enum { codimOffSet = 4 };
680 
681  assert( nChild < childOffSet );
682 
683  int newChild = (creatorId.nChild() * childOffSet ) + nChild;
684  int newCodim = (creatorId.codim() * codimOffSet ) + ( cd + startOffSet_ );
685 
686  IdType newId( creatorId.getKey() , newChild , newCodim );
687  assert( newId != creatorId );
688  return newId;
689  }
690 
691  // build ids for all children of this element
692  void buildElementIds(const HElementType & item , const IdType & macroId , int nChild)
693  {
694  enum { codim = 0 };
695  ids_[codim][item.getIndex()] = createId<codim>(item,macroId,nChild);
696 
697  const IdType & itemId = ids_[codim][item.getIndex()];
698 
699  buildInteriorElementIds(item,itemId);
700  }
701 
702  // build ids for all children of this element
703  void buildInteriorElementIds(const HElementType & item , const IdType & fatherId)
704  {
705  assert( fatherId.isValid() );
706 
707  // build id for inner vertex
708  {
709  const VertexType * v = item.innerVertex() ;
710  // for tetras there is no inner vertex, therefore check
711  if(v) buildVertexIds(*v,fatherId );
712  }
713 
714  // build edge ids for all inner edges
715  {
716  int inneredge = startOffSet_;
717  for(const HEdgeType * e = item.innerHedge () ; e ; e = e->next ())
718  {
719  buildEdgeIds(*e,fatherId,inneredge);
720  ++inneredge;
721  }
722  }
723 
724  // build face ids for all inner faces
725  {
726  int innerface = startOffSet_;
727  for(const HFaceType * f = item.innerHface () ; f ; f = f->next ())
728  {
729  buildFaceIds(*f,fatherId,innerface);
730  ++innerface;
731  }
732  }
733 
734  // build ids of all children
735  {
736  int numChild = startOffSet_;
737  for(const HElementType * child = item.down(); child; child =child->next() )
738  {
739  //assert( numChild == child->nChild() );
740  buildElementIds(*child, fatherId, numChild);
741  ++numChild;
742  }
743  }
744  }
745 
746  // build ids for all children of this face
747  void buildFaceIds(const HFaceType & face, const IdType & fatherId , int innerFace )
748  {
749  enum { codim = 1 };
750  ids_[codim][face.getIndex()] = createId<codim>(face,fatherId,innerFace);
751  const IdType & faceId = ids_[codim][face.getIndex()];
752 
753  buildInteriorFaceIds(face,faceId);
754  }
755 
756  // build ids for all children of this face
757  void buildInteriorFaceIds(const HFaceType & face, const IdType & faceId)
758  {
759  assert( faceId.isValid () );
760 
761  // build id for inner vertex
762  {
763  const VertexType * v = face.innerVertex() ;
764  //std::cout << "create inner vertex of face " << face.getIndex() << "\n";
765  if(v) buildVertexIds(*v,faceId );
766  }
767 
768  // build ids for all inner edges
769  {
770  int inneredge = startOffSet_;
771  for (const HEdgeType * e = face.innerHedge () ; e ; e = e->next ())
772  {
773  buildEdgeIds(*e,faceId ,inneredge );
774  ++inneredge;
775  }
776  }
777 
778  // build ids for all child faces
779  {
780  int child = startOffSet_;
781  for(const HFaceType * f = face.down () ; f ; f = f->next ())
782  {
783  assert( child == f->nChild()+startOffSet_);
784  buildFaceIds(*f,faceId,child);
785  ++child;
786  }
787  }
788  }
789 
790  // build ids for all children of this edge
791  void buildEdgeIds(const HEdgeType & edge, const IdType & fatherId , int inneredge)
792  {
793  enum { codim = 2 };
794  ids_[codim][edge.getIndex()] = createId<codim>(edge,fatherId,inneredge);
795  const IdType & edgeId = ids_[codim][edge.getIndex()];
796  buildInteriorEdgeIds(edge,edgeId);
797  }
798 
799  void buildInteriorEdgeIds(const HEdgeType & edge, const IdType & edgeId)
800  {
801  assert( edgeId.isValid() );
802 
803  // build id for inner vertex
804  {
805  const VertexType * v = edge.innerVertex() ;
806  if(v) buildVertexIds(*v,edgeId );
807  }
808 
809  // build ids for all inner edges
810  {
811  int child = startOffSet_;
812  for (const HEdgeType * e = edge.down () ; e ; e = e->next ())
813  {
814  assert( child == e->nChild()+ startOffSet_ );
815  buildEdgeIds(*e,edgeId , child );
816  ++child;
817  }
818  }
819  }
820 
821  // build id for this vertex
822  void buildVertexIds(const VertexType & vertex, const IdType & fatherId )
823  {
824  enum { codim = 3 };
825  // inner vertex number is 1
826  ids_[codim][vertex.getIndex()] = createId<codim>(vertex,fatherId,1);
827  assert( ids_[codim][vertex.getIndex()].isValid() );
828  }
829 
830  friend class ALU3dGrid< elType, Comm >;
831 
832  const IdType & getId(const IdType & macroId) const
833  {
834  return macroId;
835  }
836 
837  public:
839  template <class EntityType>
840  IdType id (const EntityType & ep) const
841  {
842  enum { cd = EntityType :: codimension };
843  assert( ids_[cd].find( hset_.index(ep) ) != ids_[cd].end() );
844  const IdType & macroId = ids_[cd][hset_.index(ep)];
845  assert( macroId.isValid() );
846  return getId(macroId);
847  }
848 
850  template <int codim>
851  IdType id (const typename GridType:: template Codim<codim> :: Entity & ep) const
852  {
853  assert( ids_[codim].find( hset_.index(ep) ) != ids_[codim].end() );
854  const IdType & macroId = ids_[codim][hset_.index(ep)];
855  assert( macroId.isValid() );
856  return getId(macroId);
857  }
858 
860  IdType subId ( const EntityCodim0Type &e, int i, unsigned int codim ) const
861  {
862  const int hIndex = hset_.subIndex( e, i, codim );
863  assert( ids_[ codim ].find( hIndex ) != ids_[ codim ].end() );
864  const IdType &macroId = ids_[ codim ][ hIndex ];
865  assert( macroId.isValid() );
866  return getId( macroId );
867  }
868 
869  template <int d, ALU3dGridElementType element_t >
870  struct BuildIds;
871 
872  template <int d>
873  struct BuildIds<d,tetra>
874  {
875  //static const IdType zero;
876  template <class MyIdSet, class IdStorageType>
877  static void buildFace(MyIdSet & set, const HElementType & item, int faceNum,
878  IdStorageType & ids )
879  {
880  const IMPLElementType & elem = static_cast<const IMPLElementType &> (item);
881  const HFaceType & face = *(elem.myhface3(faceNum));
882  const IdType & id = ids[face.getIndex()];
883  assert( id.isValid() );
884  set.buildInteriorFaceIds(face,id);
885  }
886  };
887 
888  template <int d>
889  struct BuildIds<d,hexa>
890  {
891  //static const IdType zero;
892  template <class MyIdSet, class IdStorageType>
893  static void buildFace(MyIdSet & set, const HElementType & item, int faceNum,
894  IdStorageType & ids )
895  {
896  const IMPLElementType & elem = static_cast<const IMPLElementType &> (item);
897  const HFaceType & face = *(elem.myhface4(faceNum));
898  const IdType & id = ids[face.getIndex()];
899  assert( id.isValid() );
900  set.buildInteriorFaceIds(face,id);
901  }
902  };
903 
904  // create ids for refined elements
905  int postRefinement( HElementType & item )
906  {
907  {
908  enum { elCodim = 0 };
909  const IdType & fatherId = ids_[elCodim][item.getIndex()];
910  assert( fatherId.isValid() );
911  buildInteriorElementIds(item, fatherId );
912  }
913 
914  for(int i=0; i<EntityCountType::numFaces; ++i)
915  {
916  enum { faceCodim = 1 };
917  BuildIds< GridType::dimension, elType >::buildFace(*this,item,i,ids_[faceCodim]);
918  }
919 
920  for(int i=0; i<EntityCountType::numEdges; ++i)
921  {
922  enum { edgeCodim = 2 };
923  const IMPLElementType & elem = static_cast<const IMPLElementType &> (item);
924  const HEdgeType & edge = *( elem.myhedge1(i));
925  const IdType & id = ids_[edgeCodim][edge.getIndex()];
926  assert( id.isValid() );
927  buildInteriorEdgeIds(edge,id);
928  }
929  return 0;
930  }
931 
932  // dummy functions
933  int preCoarsening( HElementType & elem )
934  {
935  /*
936  const IdType & fatherId = ids_[0][item.getIndex()];
937 
938  removeElementIds(item,fatherId,item.nChild());
939 
940  for(int i=0; i<EntityCountType::numFaces; ++i)
941  BuildIds<dim,elType>::buildFace(*this,item,i,ids_[1]);
942 
943  for(int i=0; i<EntityCountType::numEdges; ++i)
944  {
945  const IMPLElementType & elem = static_cast<const IMPLElementType &> (item);
946  const HEdgeType & edge = *( elem.myhedge1(i));
947  const HEdgeType * child = edge.down();
948  assert( child );
949  if( ids_[2][child->getIndex() ] > zero_ ) continue;
950  buildEdgeIds(edge,ids_[2][edge.getIndex()],0);
951  }
952  #ifndef NDEBUG
953  //uniquenessCheck();
954  #endif
955  */
956  return 0;
957  }
958 
959  // dummy functions
960  int preCoarsening ( HBndSegType & el ) { return 0; }
961 
963  int postRefinement ( HBndSegType & el ) { return 0; }
964 
965  };
966 
967  //***********************************************************
968  //
969  // --LocalIdSet
970  //
971  //***********************************************************
972 
974  template< ALU3dGridElementType elType, class Comm >
975  class ALU3dGridLocalIdSet
976  : public IdSet< ALU3dGrid< elType, Comm >, ALU3dGridLocalIdSet< elType, Comm >, int >,
977  public ALU3DSPACE AdaptRestrictProlongType
978  {
979  typedef ALU3dGridLocalIdSet< elType, Comm > This;
980 
981  typedef ALU3dImplTraits< elType, Comm > ImplTraitsType;
982  typedef typename ImplTraitsType::HElementType HElementType;
983  typedef typename ImplTraitsType::HBndSegType HBndSegType;
984 
985  typedef ALU3dGrid< elType, Comm > GridType;
986  typedef typename GridType::HierarchicIndexSet HierarchicIndexSetType;
987 
988  // this means that only up to 300000000 entities are allowed
989  enum { codimMultiplier = 300000000 };
990  typedef typename GridType::Traits::template Codim<0>::Entity EntityCodim0Type;
991 
992  // create local id set , only for the grid allowed
993  ALU3dGridLocalIdSet(const GridType & grid) : hset_(grid.hierarchicIndexSet())
994  {
995  for( int codim = 0; codim <= GridType::dimension; ++codim )
996  codimStart_[ codim ] = codim * codimMultiplier;
997  }
998 
999  friend class ALU3dGrid< elType, Comm >;
1000 
1001  // fake method to have the same method like GlobalIdSet
1002  void updateIdSet() {}
1003 
1004  using ALU3DSPACE AdaptRestrictProlongType :: postRefinement ;
1005  using ALU3DSPACE AdaptRestrictProlongType :: preCoarsening ;
1006 
1007  public:
1009  typedef int IdType;
1010 
1013  using IdSet < GridType , ALU3dGridLocalIdSet, IdType > :: subId;
1014 
1016  template <class EntityType>
1017  int id (const EntityType & ep) const
1018  {
1019  enum { cd = EntityType :: codimension };
1020  assert( hset_.size(cd) < codimMultiplier );
1021  return codimStart_[cd] + hset_.index(ep);
1022  }
1023 
1025  template <int codim>
1026  int id (const typename GridType:: template Codim<codim> :: Entity & ep) const
1027  {
1028  //enum { cd = EntityType :: codimension };
1029  assert( hset_.size(codim) < codimMultiplier );
1030  return codimStart_[codim] + hset_.index(ep);
1031  }
1032 
1034  IdType subId ( const EntityCodim0Type &e, int i, unsigned int codim ) const
1035  {
1036  assert( hset_.size( codim ) < codimMultiplier );
1037  return codimStart_[ codim ] + hset_.subIndex( e, i, codim );
1038  }
1039 
1040  // dummy functions
1041  int preCoarsening( HElementType & elem ) { return 0; }
1042  // create ids for refined elements
1043  int postRefinement( HElementType & item ) { return 0; }
1044 
1045  // dummy functions
1046  int preCoarsening ( HBndSegType & el ) { return 0; }
1047 
1049  int postRefinement ( HBndSegType & el ) { return 0; }
1050 
1051  void setChunkSize( int chunkSize ) {}
1052 
1053  private:
1054  // our HierarchicIndexSet
1055  const HierarchicIndexSetType & hset_;
1056 
1057  // store start of each codim numbers
1058  int codimStart_[ GridType::dimension+1 ];
1059  };
1060 
1061 } // end namespace Dune
1062 
1063 #endif // #ifndef DUNE_ALU3DGRIDINDEXSETS_HH
Portable very large unsigned integers.
hierarchic index set of ALU3dGrid
Definition: indexsets.hh:44
const std::vector< GeometryType > & geomTypes(int codim) const
deliver all geometry types used in this grid
Definition: indexsets.hh:100
int index(const EntityType &ep) const
return hierarchic index of given entity
Definition: indexsets.hh:62
bool contains(const EntityType &) const
return true because all entities are contained in this set
Definition: indexsets.hh:107
int index(const typename GridType::Traits::template Codim< codim >::Entity &entity) const
return hierarchic index of given entity
Definition: indexsets.hh:70
int subIndex(const EntityCodim0Type &e, int i, unsigned int codim) const
return subIndex i of given entity for subEntity with codim
Definition: indexsets.hh:76
int size(GeometryType type) const
Definition: indexsets.hh:84
int size(int codim) const
return size of indexset, i.e. maxindex+1
Definition: indexsets.hh:93
[ provides Dune::Grid ]
Definition: grid.hh:406
const std::vector< GeometryType > & geomTypes(int codim) const
deliver all geometry types used in this grid
Definition: grid.hh:870
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:25
unsigned int dim() const
Return dimension of the type.
Definition: type.hh:321
bool isCube() const
Return true if entity is a cube of any dimension.
Definition: type.hh:311
bool isSimplex() const
Return true if entity is a simplex of any dimension.
Definition: type.hh:306
static std::conditional< std::is_reference< InterfaceType >::value, typename std::add_lvalue_reference< typename ReturnImplementationType< typename std::remove_reference< InterfaceType >::type >::ImplementationType >::type, typename std::remove_const< typename ReturnImplementationType< typename std::remove_reference< InterfaceType >::type >::ImplementationType >::type >::type getRealImplementation(InterfaceType &&i)
return real implementation of interface class
Definition: grid.hh:1305
Index Set Interface base class.
Definition: indexidset.hh:76
Different resources needed by all grid implementations.
std::ostream & operator<<(std::ostream &s, const array< T, N > &e)
Output operator for array.
Definition: array.hh:26
#define DUNE_THROW(E, m)
Definition: exceptions.hh:243
InterfaceType
Parameter to be used for the communication functions.
Definition: gridenums.hh:84
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:252
EnableIfInterOperable< T1, T2, bool >::type operator>(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:672
EnableIfInterOperable< T1, T2, bool >::type operator<(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:626
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:230
EnableIfInterOperable< T1, T2, bool >::type operator>=(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:694
EnableIfInterOperable< T1, T2, bool >::type operator<=(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:649
Support for calculating hash values of objects.
#define DUNE_DEFINE_HASH(template_args, type)
Defines the required struct specialization to make type hashable via Dune::hash.
Definition: hash.hh:98
#define DUNE_HASH_TYPE(...)
Wrapper macro for the type to be hashed in DUNE_DEFINE_HASH.
Definition: hash.hh:115
#define DUNE_HASH_TEMPLATE_ARGS(...)
Wrapper macro for the template arguments in DUNE_DEFINE_HASH.
Definition: hash.hh:107
Provides base classes for index and id sets.
Dune namespace.
Definition: alignment.hh:10
void hash_combine(std::size_t &seed, const T &arg)
Calculates the hash value of arg and combines it in-place with seed.
Definition: hash.hh:293
Standard Dune debug streams.
Static tag representing a codimension.
Definition: dimension.hh:22
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)