00001 #ifndef DUNE_SGRID_HH
00002 #define DUNE_SGRID_HH
00003
00004 #include <limits>
00005 #include <vector>
00006 #include <stack>
00007
00008 #include <dune/common/fvector.hh>
00009 #include <dune/common/fmatrix.hh>
00010 #include <dune/common/finitestack.hh>
00011 #include <dune/grid/common/capabilities.hh>
00012 #include <dune/common/bigunsignedint.hh>
00013 #include <dune/common/collectivecommunication.hh>
00014 #include <dune/grid/common/grid.hh>
00015 #include <dune/grid/sgrid/numbering.hh>
00016 #include <dune/grid/common/indexidset.hh>
00017
00023 namespace Dune {
00024
00025
00029 typedef double sgrid_ctype;
00030
00031
00032 const int sgrid_dim_bits = 24;
00033 const int sgrid_level_bits = 6;
00034 const int sgrid_codim_bits = 4;
00035
00036
00037
00038
00039 template<int dim, int dimworld, class GridImp> class SGeometry;
00040 template<int codim, int dim, class GridImp> class SEntity;
00041 template<int codim, class GridImp> class SEntityPointer;
00042 template<int codim, PartitionIteratorType, class GridImp> class SLevelIterator;
00043 template<int dim, int dimworld> class SGrid;
00044 template<class GridImp> class SIntersectionIterator;
00045 template<class GridImp> class SHierarchicIterator;
00046
00047
00078 template<int mydim, int cdim, class GridImp>
00079 class SGeometry : public GeometryDefaultImplementation<mydim,cdim,GridImp,SGeometry>
00080 {
00081 public:
00083 typedef sgrid_ctype ctype;
00084
00086 GeometryType type () const;
00087
00089 int corners () const;
00090
00092 const FieldVector<sgrid_ctype, cdim>& operator[] (int i) const;
00093
00095 FieldVector<sgrid_ctype, cdim> global (const FieldVector<sgrid_ctype, mydim>& local) const;
00096
00098 FieldVector<sgrid_ctype, mydim> local (const FieldVector<sgrid_ctype, cdim>& global) const;
00099
00101 bool checkInside (const FieldVector<sgrid_ctype, mydim>& local) const;
00102
00122 sgrid_ctype integrationElement (const FieldVector<sgrid_ctype, mydim>& local) const;
00123
00125 const FieldMatrix<sgrid_ctype,cdim,mydim>& jacobianInverseTransposed (const FieldVector<sgrid_ctype, mydim>& local) const;
00126
00128 void print (std::ostream& ss, int indent) const;
00129
00134 void make (FieldMatrix<sgrid_ctype,mydim+1,cdim>& __As);
00135
00137 SGeometry () : builtinverse(false) {};
00138
00139 private:
00140 FieldVector<sgrid_ctype, cdim> s;
00141 FieldMatrix<sgrid_ctype,mydim,cdim> A;
00142 array<FieldVector<sgrid_ctype, cdim>, 1<<mydim> c;
00143 mutable FieldMatrix<sgrid_ctype,cdim,mydim> Jinv;
00144 mutable bool builtinverse;
00145 };
00146
00148 template<int cdim, class GridImp>
00149 class SGeometry<0,cdim,GridImp> : public GeometryDefaultImplementation<0,cdim,GridImp,SGeometry>
00150 {
00151 public:
00153 typedef sgrid_ctype ctype;
00154
00156 GeometryType type () const;
00157
00159 int corners () const;
00160
00162 const FieldVector<sgrid_ctype, cdim>& operator[] (int i) const;
00163
00165 void print (std::ostream& ss, int indent) const;
00166
00168 void make (FieldMatrix<sgrid_ctype,1,cdim>& __As);
00169
00171 FieldVector<sgrid_ctype, cdim> global (const FieldVector<sgrid_ctype, 0>& local) const { return this->operator[] (0); }
00172
00174 FieldVector<sgrid_ctype, 0> local (const FieldVector<sgrid_ctype, cdim>& global) const { return FieldVector<sgrid_ctype,0> (0.0); }
00175
00197
00198 SGeometry () {};
00199
00205 sgrid_ctype integrationElement(const FieldVector<sgrid_ctype, 0>& local) const {
00206 return 1.;
00207 }
00208
00210 bool checkInside (const FieldVector<sgrid_ctype, 0>& local) const
00211 {
00212 return true;
00213 }
00214
00216 const FieldMatrix<sgrid_ctype,cdim,0>& jacobianInverseTransposed (const FieldVector<sgrid_ctype, 0>& local) const
00217 {
00218 static FieldMatrix<sgrid_ctype,cdim,0> dummy( sgrid_ctype(0) );
00219 return dummy;
00220 }
00221
00222 protected:
00223 FieldVector<sgrid_ctype, cdim> s;
00224 };
00225
00226 template <int mydim, int cdim, class GridImp>
00227 inline std::ostream& operator<< (std::ostream& s, SGeometry<mydim,cdim,GridImp>& e)
00228 {
00229 e.print(s,0);
00230 return s;
00231 }
00232
00233 template<int mydim, int cdim, class GridImp>
00234 class SMakeableGeometry : public Geometry<mydim, cdim, GridImp, SGeometry>
00235 {
00236 public:
00237 SMakeableGeometry() :
00238 Geometry<mydim, cdim, GridImp, SGeometry>(SGeometry<mydim, cdim, GridImp>())
00239 {};
00240
00241 void make (FieldMatrix<sgrid_ctype,mydim+1,cdim>& __As) { this->realGeometry.make(__As); }
00242 };
00243
00244
00249 template<int codim, int dim, class GridImp>
00250 class SEntityBase {
00251 friend class SEntityPointer<codim,GridImp>;
00252 friend class SIntersectionIterator<GridImp>;
00253 enum { dimworld = GridImp::dimensionworld };
00254 public:
00255 typedef typename GridImp::template Codim<codim>::Geometry Geometry;
00256 typedef SMakeableGeometry<dim-codim, dimworld, const GridImp> MakeableGeometry;
00257 typedef typename GridImp::PersistentIndexType PersistentIndexType;
00258
00260 int level () const
00261 {
00262 return l;
00263 }
00264
00267 int index () const
00268 {
00269 return compressedIndex();
00270 }
00271
00273 int globalIndex() const;
00274
00276 const Geometry& geometry () const;
00277
00279 SEntityBase (GridImp* _grid, int _l, int _id);
00280 SEntityBase ();
00281
00283 void make (GridImp* _grid, int _l, int _id);
00284
00286 void make (int _l, int _id);
00287
00289 PersistentIndexType persistentIndex () const
00290 {
00291 if (codim!=dim)
00292 {
00293
00294
00295 PersistentIndexType id(codim);
00296
00297
00298 id = id << sgrid_level_bits;
00299 id = id+PersistentIndexType(l);
00300
00301
00302 for (int i=dim-1; i>=0; i--)
00303 {
00304 id = id << sgrid_dim_bits;
00305 id = id+PersistentIndexType(z[i]);
00306 }
00307
00308 return id;
00309 }
00310 else
00311 {
00312
00313
00314 int trailing = 1000;
00315 for (int i=0; i<dim; i++)
00316 {
00317
00318 int zeros = 0;
00319 for (int j=0; j<l; j++)
00320 if (z[i]&(1<<(j+1)))
00321 break;
00322 else
00323 zeros++;
00324 trailing = std::min(trailing,zeros);
00325 }
00326
00327
00328 int level = l-trailing;
00329
00330
00331 PersistentIndexType id(dim);
00332
00333
00334 id = id << sgrid_level_bits;
00335 id = id+PersistentIndexType(level);
00336
00337
00338 for (int i=dim-1; i>=0; i--)
00339 {
00340 id = id << sgrid_dim_bits;
00341 id = id+PersistentIndexType(z[i]>>trailing);
00342 }
00343
00344 return id;
00345 }
00346 }
00347
00349 int compressedIndex () const
00350 {
00351 return id;
00352 }
00353
00355 int compressedLeafIndex () const
00356 {
00357
00358
00359 if (codim<dim || l==grid->maxLevel())
00360 return id;
00361
00362
00363
00364 array<int,dim> coord;
00365 for (int k=0; k<dim; k++)
00366 coord[k] = z[k]*(1<<(grid->maxLevel()-l));
00367
00368
00369 return grid->n(grid->maxLevel(),coord);
00370 }
00371
00372 protected:
00373
00374 GridImp* grid;
00375 int l;
00376 int id;
00377 array<int,dim> z;
00378 mutable MakeableGeometry geo;
00379 mutable bool builtgeometry;
00380 };
00381
00382
00390 template<int codim, int dim, class GridImp>
00391 class SEntity : public SEntityBase<codim,dim,GridImp>,
00392 public EntityDefaultImplementation<codim,dim,GridImp,SEntity>
00393 {
00394 enum { dimworld = GridImp::dimensionworld };
00395 public:
00396 typedef typename GridImp::template Codim<codim>::Geometry Geometry;
00397 typedef typename GridImp::template Codim<codim>::LevelIterator LevelIterator;
00398 typedef typename GridImp::template Codim<0>::LeafIntersectionIterator IntersectionIterator;
00399 typedef typename GridImp::template Codim<0>::HierarchicIterator HierarchicIterator;
00400
00401
00403 int level () const {return SEntityBase<codim,dim,GridImp>::level();}
00404
00406 int index () const {return SEntityBase<codim,dim,GridImp>::index();}
00407
00409 const Geometry& geometry () const { return SEntityBase<codim,dim,GridImp>::geometry(); }
00410
00412 PartitionType partitionType () const { return InteriorEntity; }
00413
00414
00416 SEntity (GridImp* _grid, int _l, int _id) : SEntityBase<codim,dim,GridImp>::SEntityBase(_grid,_l,_id) {};
00417 };
00418
00445 template<int dim, class GridImp>
00446 class SEntity<0,dim,GridImp> : public SEntityBase<0,dim,GridImp>,
00447 public EntityDefaultImplementation<0,dim,GridImp,SEntity>
00448 {
00449 enum { dimworld = GridImp::dimensionworld };
00450 public:
00451 typedef typename GridImp::template Codim<0>::Geometry Geometry;
00452 typedef typename GridImp::template Codim<0>::LocalGeometry LocalGeometry;
00453 typedef SMakeableGeometry<dim, dimworld, const GridImp> MakeableGeometry;
00454 template <int cd>
00455 struct Codim
00456 {
00457 typedef typename GridImp::template Codim<cd>::EntityPointer EntityPointer;
00458 };
00459 typedef typename GridImp::template Codim<0>::EntityPointer EntityPointer;
00460 typedef typename GridImp::template Codim<0>::LeafIntersectionIterator IntersectionIterator;
00461 typedef typename GridImp::template Codim<0>::HierarchicIterator HierarchicIterator;
00462 typedef typename GridImp::PersistentIndexType PersistentIndexType;
00463
00465 friend class SHierarchicIterator<GridImp>;
00466
00467
00469 int level () const {return SEntityBase<0,dim,GridImp>::level();}
00470
00473 int index () const {return SEntityBase<0,dim,GridImp>::index();}
00474
00476 PartitionType partitionType () const { return InteriorEntity; }
00477
00479 const Geometry& geometry () const {return SEntityBase<0,dim,GridImp>::geometry();}
00480
00485 template<int cc> int count () const;
00486
00491 template<int cc> typename Codim<cc>::EntityPointer entity (int i) const;
00492
00494 template<int cc>
00495 int subCompressedIndex (int i) const
00496 {
00497 if (cc==0) return this->compressedIndex();
00498 return this->grid->template getRealEntity<cc>(*entity<cc>(i)).compressedIndex();
00499 }
00500
00502 template<int cc>
00503 int subCompressedLeafIndex (int i) const
00504 {
00505 if (cc==0) return this->compressedLeafIndex();
00506 return this->grid->template getRealEntity<cc>(*entity<cc>(i)).compressedLeafIndex();
00507 }
00508
00510 template<int cc>
00511 PersistentIndexType subPersistentIndex (int i) const
00512 {
00513 if (cc==0) return this->persistentIndex();
00514 return this->grid->template getRealEntity<cc>(*entity<cc>(i)).persistentIndex();
00515 }
00516
00524 IntersectionIterator ibegin () const;
00525 IntersectionIterator ileafbegin () const;
00526 IntersectionIterator ilevelbegin () const;
00528 IntersectionIterator iend () const;
00529 IntersectionIterator ileafend () const;
00530 IntersectionIterator ilevelend () const;
00531
00537 EntityPointer father () const;
00538
00540 bool isLeaf () const
00541 {
00542 return ( this->grid->maxLevel() == level() );
00543 }
00544
00556 const LocalGeometry& geometryInFather () const;
00557
00564 HierarchicIterator hbegin (int maxLevel) const;
00565
00567 HierarchicIterator hend (int maxLevel) const;
00568
00569
00571 SEntity (GridImp* _grid, int _l, int _id) :
00572 SEntityBase<0,dim,GridImp>::SEntityBase(_grid,_l,_id)
00573 {
00574 built_father = false;
00575 }
00576
00577 SEntity ()
00578 {
00579 built_father = false;
00580 }
00581
00583 void make (GridImp* _grid, int _l, int _id)
00584 {
00585 SEntityBase<0,dim,GridImp>::make(_grid,_l,_id);
00586 built_father = false;
00587 }
00588
00590 void make (int _l, int _id)
00591 {
00592 SEntityBase<0,dim,GridImp>::make(_l,_id);
00593 built_father = false;
00594 }
00595
00596 private:
00597
00598 mutable bool built_father;
00599 mutable int father_id;
00600 mutable SMakeableGeometry<dim,dim,const GridImp> in_father_local;
00601 void make_father() const;
00602 };
00603
00613 template<int dim, class GridImp>
00614 class SEntity<dim,dim,GridImp> : public SEntityBase<dim,dim,GridImp>,
00615 public EntityDefaultImplementation <dim,dim,GridImp,SEntity>
00616 {
00617 enum { dimworld = GridImp::dimensionworld };
00618 public:
00619 typedef typename GridImp::template Codim<dim>::Geometry Geometry;
00620 typedef typename GridImp::template Codim<0>::EntityPointer EntityPointer;
00621
00622
00624 int level () const {return SEntityBase<dim,dim,GridImp>::level();}
00625
00627 int index () const {return SEntityBase<dim,dim,GridImp>::index();}
00628
00630 PartitionType partitionType () const { return InteriorEntity; }
00631
00633 const Geometry& geometry () const {return SEntityBase<dim,dim,GridImp>::geometry();}
00634
00635
00637 SEntity (GridImp* _grid, int _l, int _id) : SEntityBase<dim,dim,GridImp>::SEntityBase(_grid,_l,_id)
00638 {
00639 built_father = false;
00640 }
00641
00643 void make (GridImp* _grid, int _l, int _id)
00644 {
00645 SEntityBase<dim,dim,GridImp>::make(_grid, _l,_id);
00646 built_father = false;
00647 }
00648
00650 void make (int _l, int _id)
00651 {
00652 SEntityBase<dim,dim,GridImp>::make(_l,_id);
00653 built_father = false;
00654 }
00655
00656 private:
00657 mutable bool built_father;
00658 mutable int father_id;
00659 mutable FieldVector<sgrid_ctype, dim> in_father_local;
00660 void make_father() const;
00661 };
00662
00663 template<int codim, int dim, class GridImp>
00664 class SMakeableEntity :
00665 public GridImp::template Codim<codim>::Entity
00666 {
00667 public:
00668
00669 SMakeableEntity(GridImp* _grid, int _l, int _id) :
00670 GridImp::template Codim<codim>::Entity (SEntity<codim, dim, GridImp>(_grid,_l,_id))
00671 {};
00672 SMakeableEntity(const SEntity<codim, dim, GridImp>& e) :
00673 GridImp::template Codim<codim>::Entity (e)
00674 {};
00675 void make (int _l, int _id) { this->realEntity.make(_l, _id); }
00676 void make (GridImp* _grid, int _l, int _id) { this->realEntity.make(_grid, _l, _id); }
00677 };
00678
00679
00687 struct SHierarchicStackElem {
00688 int l;
00689 int id;
00690 SHierarchicStackElem () : l(-1), id(-1) {}
00691 SHierarchicStackElem (int _l, int _id) {l=_l; id=_id;}
00692 bool operator== (const SHierarchicStackElem& s) const {return !operator!=(s);}
00693 bool operator!= (const SHierarchicStackElem& s) const {return l!=s.l || id!=s.id;}
00694 };
00695
00696 template<class GridImp>
00697 class SHierarchicIterator :
00698 public Dune::SEntityPointer <0,GridImp>
00699 {
00700 friend class SHierarchicIterator<const GridImp>;
00701 enum { dim = GridImp::dimension };
00702 enum { dimworld = GridImp::dimensionworld };
00703 public:
00704 typedef typename GridImp::template Codim<0>::Entity Entity;
00705 typedef typename GridImp::ctype ctype;
00706
00708 void increment();
00709
00716 SHierarchicIterator (GridImp* _grid,
00717 const Dune::SEntity<0,GridImp::dimension,GridImp>& _e,
00718 int _maxLevel, bool makeend) :
00719 Dune::SEntityPointer<0,GridImp>(_grid,_e.level(),_e.index())
00720 {
00721
00722
00723 if (makeend) return;
00724
00725
00726 orig_l = this->entity().level();
00727 orig_id = _grid->template getRealEntity<0>(this->entity()).index();
00728
00729
00730 SHierarchicStackElem originalElement(orig_l, orig_id);
00731 stack.push(originalElement);
00732
00733
00734 maxLevel = std::min(_maxLevel,this->grid->maxLevel());
00735
00736
00737 push_sons(orig_l,orig_id);
00738
00739
00740 increment();
00741 }
00742
00743 private:
00744 int maxLevel;
00745 int orig_l, orig_id;
00746
00747 FiniteStack<SHierarchicStackElem,GridImp::MAXL> stack;
00748
00749 void push_sons (int level, int fatherid);
00750 };
00751
00752
00759 template<class GridImp>
00760 class SIntersectionIterator
00761 {
00762 enum { dim=GridImp::dimension };
00763 enum { dimworld=GridImp::dimensionworld };
00764 public:
00765 typedef typename GridImp::template Codim<0>::Entity Entity;
00766 typedef typename GridImp::template Codim<0>::EntityPointer EntityPointer;
00767 typedef typename GridImp::template Codim<1>::Geometry Geometry;
00768 typedef typename GridImp::template Codim<1>::LocalGeometry LocalGeometry;
00769 typedef Dune::Intersection<const GridImp, Dune::SIntersectionIterator> Intersection;
00771 enum { dimension=dim };
00773 enum { dimensionworld=dimworld };
00775 typedef typename GridImp::ctype ctype;
00776
00778 bool equals(const SIntersectionIterator<GridImp>& i) const;
00780 void increment();
00781
00783 const Intersection & dereference() const
00784 {
00785 return reinterpret_cast<const Intersection&>(*this);
00786 }
00787
00790 EntityPointer inside() const;
00791
00794 EntityPointer outside() const;
00795
00797 bool boundary () const;
00798
00800 bool conforming () const;
00801
00802 int boundaryId () const {
00803 if (boundary()) return count + 1;
00804 return 0;
00805 };
00807 bool neighbor () const;
00808
00810 FieldVector<ctype, GridImp::dimensionworld> outerNormal (const FieldVector<ctype, GridImp::dimension-1>& local) const
00811 {
00812 return unitOuterNormal(local);
00813 }
00815 FieldVector<ctype, GridImp::dimensionworld> unitOuterNormal (const FieldVector<ctype, GridImp::dimension-1>& local) const
00816 {
00817
00818 FieldVector<sgrid_ctype, dimworld> normal(0.0);
00819 if (count%2)
00820 normal[count/2] = 1.0;
00821 else
00822 normal[count/2] = -1.0;
00823
00824 return normal;
00825 }
00827 FieldVector<ctype, GridImp::dimensionworld> integrationOuterNormal (const FieldVector<ctype, GridImp::dimension-1>& local) const
00828 {
00829 FieldVector<sgrid_ctype, dimworld> n = unitOuterNormal(local);
00830 n *= is_global.integrationElement(local);
00831 return n;
00832 }
00833
00837 LocalGeometry& intersectionSelfLocal () const;
00841 LocalGeometry& intersectionNeighborLocal () const;
00845 Geometry& intersectionGlobal () const;
00846
00848 GeometryType type () const
00849 {
00850 return intersectionSelfLocal().type();
00851 }
00852
00854 int numberInSelf () const;
00856 int numberInNeighbor () const;
00857
00859 SIntersectionIterator (GridImp* _grid, const SEntity<0,dim,GridImp >* _self, int _count);
00860
00862 SIntersectionIterator& operator = (const SIntersectionIterator& it)
00863 {
00864 assert(grid == it.grid);
00865
00866
00867 if (! self.equals(it.self))
00868 DUNE_THROW(GridError, "assignment of SIntersectionIterator "
00869 << "with different inside Entity");
00870 if (partition != it.partition)
00871 DUNE_THROW(GridError, "assignment of SIntersectionIterator "
00872 << "with different partition");
00873
00874
00875 ne = it.ne;
00876 count = it.count;
00877 make(count);
00878
00879 return *this;
00880 }
00881
00882 private:
00883 void make (int _count) const;
00884 void makeintersections () const;
00885 const EntityPointer self;
00886 mutable EntityPointer ne;
00887 const GridImp * grid;
00888 const int partition;
00889 const array<int,dim> zred;
00890 mutable int count;
00891 mutable bool valid_count;
00892 mutable bool valid_nb;
00893 mutable bool is_on_boundary;
00894 mutable bool built_intersections;
00895 mutable SMakeableGeometry<dim-1,dim,const GridImp> is_self_local;
00896 mutable SMakeableGeometry<dim-1,dimworld,const GridImp> is_global;
00897 mutable SMakeableGeometry<dim-1,dim,const GridImp> is_nb_local;
00898 };
00899
00900
00901
00904 template<int codim, class GridImp>
00905 class SEntityPointer
00906 {
00907 enum { dim = GridImp::dimension };
00908 friend class SIntersectionIterator<GridImp>;
00909 public:
00910 typedef SEntityPointer<codim,GridImp> EntityPointerImp;
00911 typedef typename GridImp::template Codim<codim>::Entity Entity;
00913 enum { codimension = codim };
00914
00916 bool equals(const SEntityPointer<codim,GridImp>& i) const;
00918 Entity& dereference() const;
00920 int level () const;
00921
00923 SEntityPointer (GridImp * _grid, int _l, int _id) :
00924 grid(_grid), l(_l), id(_id),
00925 e(0)
00926 {
00927 }
00928
00930 SEntityPointer (const SEntity<codim,dim,GridImp> & _e) :
00931 grid(_e.grid), l(_e.l), id(_e.id),
00932 e(0)
00933 {
00934 }
00935
00937 SEntityPointer (const SEntityPointer<codim,GridImp>& other) :
00938 grid(other.grid), l(other.l), id(other.id),
00939 e( 0 )
00940 {
00941 }
00942
00944 ~SEntityPointer()
00945 {
00946 compactify();
00947 #ifndef NDEBUG
00948 id = -1;
00949 #endif
00950 }
00951
00953 SEntityPointer& operator = (const SEntityPointer& other)
00954 {
00955 grid = other.grid;
00956 l = other.l;
00957 id = other.id;
00958
00959 compactify();
00960 return *this;
00961 }
00962
00964 void compactify()
00965 {
00966 if( e )
00967 {
00968 enStack().push( e );
00969 e = 0;
00970 }
00971 }
00972
00973 protected:
00974 SMakeableEntity<codim,dim,GridImp>& entity() const
00975 {
00976 if( ! e )
00977 {
00978 e = getEntity( grid, l, id );
00979 }
00980 return *e;
00981 }
00982
00983 typedef std::stack< SMakeableEntity<codim,dim,GridImp> * > EntityStackType;
00984 static inline EntityStackType& enStack()
00985 {
00986 static EntityStackType eStack;
00987 return eStack;
00988 }
00989
00990 inline SMakeableEntity<codim,dim,GridImp>* getEntity(GridImp* _grid, int _l, int _id ) const
00991 {
00992
00993 EntityStackType& enSt = enStack();
00994
00995 if( enSt.empty() )
00996 {
00997 return (new SMakeableEntity<codim,dim,GridImp>(_grid, _l, _id));
00998 }
00999 else
01000 {
01001 SMakeableEntity<codim,dim,GridImp>* e = enSt.top();
01002 enSt.pop();
01003 e->make(_grid, _l,_id);
01004 return e;
01005 }
01006 }
01007
01008 GridImp* grid;
01009 int l;
01010 mutable int id;
01011 mutable SMakeableEntity<codim,dim,GridImp>* e;
01012 };
01013
01014
01015
01018 template<int codim, PartitionIteratorType pitype, class GridImp>
01019 class SLevelIterator :
01020 public Dune::SEntityPointer <codim,GridImp>
01021 {
01022 friend class SLevelIterator<codim, pitype,const GridImp>;
01023 enum { dim = GridImp::dimension };
01024 public:
01025 typedef typename GridImp::template Codim<codim>::Entity Entity;
01026
01028 void increment();
01029
01031 SLevelIterator (GridImp * _grid, int _l, int _id) :
01032 Dune::SEntityPointer<codim,GridImp>(_grid,_l,_id) {}
01033 };
01034
01035
01036
01041
01042
01043 template <class GridImp>
01044 struct SGridLevelIndexSetTypes
01045 {
01047 template<int cd>
01048 struct Codim
01049 {
01050 template<PartitionIteratorType pitype>
01051 struct Partition
01052 {
01053 typedef typename GridImp::Traits::template Codim<cd>::template Partition<pitype>::LevelIterator Iterator;
01054 };
01055 };
01056 };
01057
01058 template<class GridImp>
01059 class SGridLevelIndexSet : public IndexSetDefaultImplementation<GridImp,SGridLevelIndexSet<GridImp>,SGridLevelIndexSetTypes<GridImp> >
01060 {
01061 typedef IndexSetDefaultImplementation<GridImp,SGridLevelIndexSet<GridImp>,SGridLevelIndexSetTypes<GridImp> > Base;
01062 public:
01063
01065 SGridLevelIndexSet (const GridImp& g, int l) : grid(g), level(l)
01066 {
01067
01068 for (int codim=0; codim<=GridImp::dimension; codim++)
01069 mytypes[codim].push_back(GeometryType(GeometryType::cube,GridImp::dimension-codim));
01070 }
01071
01073 template<int cd>
01074 int index (const typename GridImp::Traits::template Codim<cd>::Entity& e) const
01075 {
01076 return grid.template getRealEntity<cd>(e).compressedIndex();
01077 }
01078
01080 template<int cc>
01081 int subIndex (const typename GridImp::Traits::template Codim<0>::Entity& e, int i) const
01082 {
01083 return grid.template getRealEntity<0>(e).template subCompressedIndex<cc>(i);
01084 }
01085
01087 int size (GeometryType type) const
01088 {
01089 return grid.size(level,GridImp::dimension-type.dim());
01090 }
01091
01093 int size (int codim) const
01094 {
01095 return Base::size(codim);
01096 }
01097
01099 const std::vector<GeometryType>& geomTypes (int codim) const
01100 {
01101 return mytypes[codim];
01102 }
01103
01105 template<int cd, PartitionIteratorType pitype>
01106 typename Base::template Codim<cd>::template Partition<pitype>::Iterator begin () const
01107 {
01108 return grid.template lbegin<cd,pitype>(level);
01109 }
01110
01112 template<int cd, PartitionIteratorType pitype>
01113 typename Base::template Codim<cd>::template Partition<pitype>::Iterator end () const
01114 {
01115 return grid.template lend<cd,pitype>(level);
01116 }
01117
01118 private:
01119 const GridImp& grid;
01120 int level;
01121 std::vector<GeometryType> mytypes[GridImp::dimension+1];
01122 };
01123
01124
01125
01126 template <class GridImp>
01127 struct SGridLeafIndexSetTypes
01128 {
01130 template<int cd>
01131 struct Codim
01132 {
01133 template<PartitionIteratorType pitype>
01134 struct Partition
01135 {
01136 typedef typename GridImp::Traits::template Codim<cd>::template Partition<pitype>::LeafIterator Iterator;
01137 };
01138 };
01139 };
01140
01141 template<class GridImp>
01142 class SGridLeafIndexSet : public IndexSetDefaultImplementation<GridImp,SGridLeafIndexSet<GridImp>,SGridLeafIndexSetTypes<GridImp> >
01143 {
01144 typedef IndexSetDefaultImplementation<GridImp,SGridLeafIndexSet<GridImp>,SGridLeafIndexSetTypes<GridImp> > Base;
01145 enum {dim = remove_const<GridImp>::type::dimension};
01146 public:
01147
01149 SGridLeafIndexSet (const GridImp& g) : grid(g)
01150 {
01151
01152 for (int codim=0; codim<=dim; codim++)
01153 mytypes[codim].push_back(GeometryType(GeometryType::cube,dim-codim));
01154 }
01155
01157
01158
01159
01160
01161 template<int cd>
01162 int index (const typename remove_const<GridImp>::type::Traits::template Codim<cd>::Entity& e) const
01163 {
01164 return grid.template getRealEntity<cd>(e).compressedLeafIndex();
01165 }
01166
01168
01169
01170
01171
01172 template<int cc>
01173 int subIndex (const typename remove_const<GridImp>::type::Traits::template Codim<0>::Entity& e, int i) const
01174 {
01175 return grid.template getRealEntity<0>(e).template subCompressedLeafIndex<cc>(i);
01176 }
01177
01179 int size (GeometryType type) const
01180 {
01181 return grid.size(grid.maxLevel(),GridImp::dimension-type.dim());
01182 }
01183
01185 int size (int codim) const
01186 {
01187 return Base::size(codim);
01188 }
01189
01191 const std::vector<GeometryType>& geomTypes (int codim) const
01192 {
01193 return mytypes[codim];
01194 }
01195
01197 template<int cd, PartitionIteratorType pitype>
01198 typename Base::template Codim<cd>::template Partition<pitype>::Iterator begin () const
01199 {
01200 return grid.template leafbegin<cd,pitype>();
01201 }
01202
01204 template<int cd, PartitionIteratorType pitype>
01205 typename Base::template Codim<cd>::template Partition<pitype>::Iterator end () const
01206 {
01207 return grid.template leafend<cd,pitype>();
01208 }
01209
01210 private:
01211 const GridImp& grid;
01212 std::vector<GeometryType> mytypes[dim+1];
01213 };
01214
01215
01216
01221
01222
01223 template<class GridImp>
01224 class SGridGlobalIdSet :
01225 public IdSetDefaultImplementation<GridImp,SGridGlobalIdSet<GridImp>, typename remove_const<GridImp>::type::PersistentIndexType>
01226
01227
01228
01229
01230 {
01231 public:
01233
01234
01235
01236
01237 typedef typename remove_const<GridImp>::type::PersistentIndexType IdType;
01238
01240 SGridGlobalIdSet (const GridImp& g) : grid(g) {}
01241
01243
01244
01245
01246
01247 template<int cd>
01248 IdType id (const typename remove_const<GridImp>::type::Traits::template Codim<cd>::Entity& e) const
01249 {
01250 return grid.template getRealEntity<cd>(e).persistentIndex();
01251 }
01252
01254
01255
01256
01257
01258 template<int cc>
01259 IdType subId (const typename remove_const<GridImp>::type::Traits::template Codim<0>::Entity& e, int i) const
01260 {
01261 return grid.template getRealEntity<0>(e).template subPersistentIndex<cc>(i);
01262 }
01263
01264 private:
01265 const GridImp& grid;
01266 };
01267
01268
01269 template<int dim, int dimworld>
01270 struct SGridFamily
01271 {
01272 typedef GridTraits<dim,dimworld,Dune::SGrid<dim,dimworld>,
01273 SGeometry,SEntity,
01274 SEntityPointer,SLevelIterator,
01275 SIntersectionIterator,
01276 SIntersectionIterator,
01277 SIntersectionIterator,
01278 SIntersectionIterator,
01279 SHierarchicIterator,
01280 SLevelIterator,
01281 SGridLevelIndexSet<const SGrid<dim,dimworld> >,
01282 SGridLevelIndexSetTypes<const SGrid<dim,dimworld> >,
01283 SGridLeafIndexSet<const SGrid<dim,dimworld> >,
01284 SGridLeafIndexSetTypes<const SGrid<dim,dimworld> >,
01285 SGridGlobalIdSet<const SGrid<dim,dimworld> >,
01286 bigunsignedint<dim*sgrid_dim_bits+sgrid_level_bits+sgrid_codim_bits>,
01287 SGridGlobalIdSet<const SGrid<dim,dimworld> >,
01288 bigunsignedint<dim*sgrid_dim_bits+sgrid_level_bits+sgrid_codim_bits>,
01289 CollectiveCommunication<Dune::SGrid<dim,dimworld> > >
01290 Traits;
01291 };
01292
01293
01294
01348 template<int dim, int dimworld>
01349 class SGrid : public GridDefaultImplementation <dim,dimworld,sgrid_ctype,SGridFamily<dim,dimworld> >
01350 {
01351 public:
01352 typedef SGridFamily<dim,dimworld> GridFamily;
01353 typedef bigunsignedint<dim*sgrid_dim_bits+sgrid_level_bits+sgrid_codim_bits> PersistentIndexType;
01354
01355
01356 typedef SGridLevelIndexSet<SGrid<dim,dimworld> > LevelIndexSetType;
01357 typedef SGridLeafIndexSet<SGrid<dim,dimworld> > LeafIndexSetType;
01358 typedef SGridGlobalIdSet<SGrid<dim,dimworld> > GlobalIdSetType;
01359
01360 typedef typename SGridFamily<dim,dimworld>::Traits Traits;
01361
01363 enum { MAXL=32 };
01364
01366 typedef sgrid_ctype ctype;
01367
01369 std::string name() const { return "SGrid"; };
01370
01371
01372
01380 SGrid (const int* N_, const sgrid_ctype* H_);
01381
01389 SGrid (const int* N_, const sgrid_ctype* L_, const sgrid_ctype* H_);
01390
01400 SGrid (FieldVector<int,dim> N_, FieldVector<sgrid_ctype,dim> L_, FieldVector<sgrid_ctype,dim> H_);
01401
01403 SGrid ();
01404
01406 ~SGrid ();
01407
01410 int maxLevel() const;
01411
01413 template<int cd, PartitionIteratorType pitype>
01414 typename Traits::template Codim<cd>::template Partition<pitype>::LevelIterator lbegin (int level) const;
01415
01417 template<int cd, PartitionIteratorType pitype>
01418 typename Traits::template Codim<cd>::template Partition<pitype>::LevelIterator lend (int level) const;
01419
01421 template<int cd>
01422 typename Traits::template Codim<cd>::template Partition<All_Partition>::LevelIterator lbegin (int level) const
01423 {
01424 return lbegin<cd,All_Partition>(level);
01425 }
01426
01428 template<int cd>
01429 typename Traits::template Codim<cd>::template Partition<All_Partition>::LevelIterator lend (int level) const
01430 {
01431 return lend<cd,All_Partition>(level);
01432 }
01433
01435 template<int cd, PartitionIteratorType pitype>
01436 typename Traits::template Codim<cd>::template Partition<pitype>::LeafIterator leafbegin () const;
01437
01439 template<int cd, PartitionIteratorType pitype>
01440 typename Traits::template Codim<cd>::template Partition<pitype>::LeafIterator leafend () const;
01441
01443 template<int cd>
01444 typename Traits::template Codim<cd>::template Partition<All_Partition>::LeafIterator leafbegin () const
01445 {
01446 return leafbegin<cd,All_Partition>();
01447 }
01448
01450 template<int cd>
01451 typename Traits::template Codim<cd>::template Partition<All_Partition>::LeafIterator leafend () const
01452 {
01453 return leafend<cd,All_Partition>();
01454 }
01455
01467 template<class T, template<class> class P, int codim>
01468 void communicate (T& t, InterfaceType iftype, CommunicationDirection dir, int level)
01469 {
01470
01471 return;
01472 }
01473
01475 int size (int level, int codim) const;
01476
01478 int size (int codim) const
01479 {
01480 return size(maxLevel(),codim);
01481 }
01482
01484 int size (int level, GeometryType type) const
01485 {
01486 return (type.isCube()) ? size(level,dim-type.dim()) : 0;
01487 }
01488
01490 int size (GeometryType type) const
01491 {
01492 return size(maxLevel(),type);
01493 }
01494
01495
01497 int global_size (int codim) const;
01498
01500 int overlapSize (int level, int codim)
01501 {
01502 return 0;
01503 }
01504
01506 int ghostSize (int level, int codim)
01507 {
01508 return 0;
01509 }
01510
01511
01512
01514 void globalRefine (int refCount);
01515
01517 const array<int, dim>& dims(int level) const {
01518 return N[level];
01519 }
01520
01522 const FieldVector<sgrid_ctype, dimworld>& lowerLeft() const {
01523 return low;
01524 }
01525
01527 FieldVector<sgrid_ctype, dimworld> upperRight() const {
01528 return H;
01529 }
01530
01532 bool adapt ()
01533 {
01534 globalRefine(1);
01535 return true;
01536 }
01537
01538
01540 FieldVector<sgrid_ctype, dimworld> pos (int level, array<int,dim>& z) const;
01541
01543 int calc_codim (int level, const array<int,dim>& z) const;
01544
01546 int n (int level, const array<int,dim>& z) const;
01547
01549 array<int,dim> z (int level, int i, int codim) const;
01550
01552 array<int,dim> compress (int level, const array<int,dim>& z) const;
01553
01555 array<int,dim> expand (int level, const array<int,dim>& r, int b) const;
01556
01560 int partition (int level, const array<int,dim>& z) const;
01561
01563 bool exists (int level, const array<int,dim>& zred) const;
01564
01565
01566
01567 const typename Traits::GlobalIdSet& globalIdSet() const
01568 {
01569 return *theglobalidset;
01570 }
01571
01572 const typename Traits::LocalIdSet& localIdSet() const
01573 {
01574 return *theglobalidset;
01575 }
01576
01577 const typename Traits::LevelIndexSet& levelIndexSet(int level) const
01578 {
01579 assert(level>=0 && level<=maxLevel());
01580 return *(indexsets[level]);
01581 }
01582
01583 const typename Traits::LeafIndexSet& leafIndexSet() const
01584 {
01585 return *theleafindexset;
01586 }
01587
01588
01589
01590 template<class DataHandle>
01591 void communicate (DataHandle& data, InterfaceType iftype, CommunicationDirection dir, int level) const
01592 {
01593 }
01594
01595 template<class DataHandle>
01596 void communicate (DataHandle& data, InterfaceType iftype, CommunicationDirection dir) const
01597 {
01598 }
01599
01600 const CollectiveCommunication<SGrid>& comm () const
01601 {
01602 return ccobj;
01603 }
01604
01606 int overlapSize (int level, int codim) const
01607 {
01608 return 0;
01609 }
01610
01612 int overlapSize (int codim) const
01613 {
01614 return 0;
01615 }
01616
01618 int ghostSize (int level, int codim) const
01619 {
01620 return 0;
01621 }
01622
01624 int ghostSize (int codim) const
01625 {
01626 return 0;
01627 }
01628
01629 SIntersectionIterator<const SGrid<dim, dimworld> >&
01630 getRealIntersectionIterator(typename Traits::LeafIntersectionIterator& it)
01631 {
01632 return this->getRealImplementation(it);
01633 }
01634
01635 const SIntersectionIterator<const SGrid<dim, dimworld> >&
01636 getRealIntersectionIterator(const typename Traits::LeafIntersectionIterator& it) const
01637 {
01638 return this->getRealImplementation(it);
01639 }
01640
01641
01642 private:
01643
01644
01645
01646 friend class Dune::SGridLevelIndexSet<Dune::SGrid<dim,dimworld> >;
01647 friend class Dune::SGridLeafIndexSet<Dune::SGrid<dim,dimworld> >;
01648 friend class Dune::SGridGlobalIdSet<Dune::SGrid<dim,dimworld> >;
01649 friend class Dune::SIntersectionIterator<Dune::SGrid<dim,dimworld> >;
01650 friend class Dune::SHierarchicIterator<Dune::SGrid<dim,dimworld> >;
01651 friend class Dune::SEntity<0,dim,Dune::SGrid<dim,dimworld> >;
01652
01653 friend class Dune::SGridLevelIndexSet<const Dune::SGrid<dim,dimworld> >;
01654 friend class Dune::SGridLeafIndexSet<const Dune::SGrid<dim,dimworld> >;
01655 friend class Dune::SGridGlobalIdSet<const Dune::SGrid<dim,dimworld> >;
01656 friend class Dune::SIntersectionIterator<const Dune::SGrid<dim,dimworld> >;
01657 friend class Dune::SHierarchicIterator<const Dune::SGrid<dim,dimworld> >;
01658 friend class Dune::SEntity<0,dim,const Dune::SGrid<dim,dimworld> >;
01659
01660 template<int codim_, int dim_, class GridImp_, template<int,int,class> class EntityImp_>
01661 friend class Entity;
01662
01663
01664
01665
01666 template<int codim>
01667 SEntity<codim,dim,const SGrid<dim,dimworld> >& getRealEntity(typename Traits::template Codim<codim>::Entity& e )
01668 {
01669 return this->getRealImplementaion(e);
01670 }
01671
01672 template<int codim>
01673 const SEntity<codim,dim,const SGrid<dim,dimworld> >& getRealEntity(const typename Traits::template Codim<codim>::Entity& e ) const
01674 {
01675 return this->getRealImplementation(e);
01676 }
01677
01678
01679 SGrid(const SGrid &) {};
01680 SGrid & operator = (const SGrid &) { return *this; };
01681
01682 void makeSGrid (const int* N_, const sgrid_ctype* L_, const sgrid_ctype* H_);
01683
01684
01685
01686
01687 CollectiveCommunication<SGrid> ccobj;
01688
01689 std::vector<SGridLevelIndexSet<const SGrid<dim,dimworld> >*> indexsets;
01690 SGridLeafIndexSet<const SGrid<dim,dimworld> > *theleafindexset;
01691 SGridGlobalIdSet<const SGrid<dim,dimworld> > *theglobalidset;
01692
01693 int L;
01694 FieldVector<sgrid_ctype, dim> low;
01695 FieldVector<sgrid_ctype, dim> H;
01696 array<int,dim> *N;
01697 FieldVector<sgrid_ctype, dim> *h;
01698 mutable CubeMapper<dim> *mapper;
01699
01700
01701 mutable array <int,dim> zrefStatic;
01702 mutable array <int,dim> zentityStatic;
01703 };
01704
01705 namespace Capabilities
01706 {
01707
01719 template<int dim, int dimw, int cdim>
01720 struct hasEntity< SGrid<dim,dimw>, cdim>
01721 {
01722 static const bool v = true;
01723 };
01724
01728 template<int dim, int dimw>
01729 struct isLevelwiseConforming< SGrid<dim,dimw> >
01730 {
01731 static const bool v = true;
01732 };
01733
01737 template<int dim, int dimw>
01738 struct isLeafwiseConforming< SGrid<dim,dimw> >
01739 {
01740 static const bool v = true;
01741 };
01742
01746 template<int dim, int dimw>
01747 struct IsUnstructured< SGrid<dim,dimw> >
01748 {
01749 static const bool v = false;
01750 };
01751
01755 template<int dim, int dimw>
01756 struct hasHangingNodes< SGrid<dim,dimw> >
01757 {
01758 static const bool v = false;
01759 };
01760
01761 }
01762
01763 }
01764
01765 #include"sgrid/sgrid.cc"
01766
01767 #endif