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
01079
01080 template< class EntityType >
01081 bool contains ( const EntityType &e ) const
01082 {
01083 return (e.level() == level);
01084 }
01085
01087 template<int cc>
01088 int subIndex (const typename GridImp::Traits::template Codim<0>::Entity& e, int i) const
01089 {
01090 return grid.template getRealEntity<0>(e).template subCompressedIndex<cc>(i);
01091 }
01092
01094 int size (GeometryType type) const
01095 {
01096 return grid.size(level,GridImp::dimension-type.dim());
01097 }
01098
01100 int size (int codim) const
01101 {
01102 return Base::size(codim);
01103 }
01104
01106 const std::vector<GeometryType>& geomTypes (int codim) const
01107 {
01108 return mytypes[codim];
01109 }
01110
01112 template<int cd, PartitionIteratorType pitype>
01113 typename Base::template Codim<cd>::template Partition<pitype>::Iterator begin () const
01114 {
01115 return grid.template lbegin<cd,pitype>(level);
01116 }
01117
01119 template<int cd, PartitionIteratorType pitype>
01120 typename Base::template Codim<cd>::template Partition<pitype>::Iterator end () const
01121 {
01122 return grid.template lend<cd,pitype>(level);
01123 }
01124
01125 private:
01126 const GridImp& grid;
01127 int level;
01128 std::vector<GeometryType> mytypes[GridImp::dimension+1];
01129 };
01130
01131
01132
01133 template <class GridImp>
01134 struct SGridLeafIndexSetTypes
01135 {
01137 template<int cd>
01138 struct Codim
01139 {
01140 template<PartitionIteratorType pitype>
01141 struct Partition
01142 {
01143 typedef typename GridImp::Traits::template Codim<cd>::template Partition<pitype>::LeafIterator Iterator;
01144 };
01145 };
01146 };
01147
01148 template<class GridImp>
01149 class SGridLeafIndexSet : public IndexSetDefaultImplementation<GridImp,SGridLeafIndexSet<GridImp>,SGridLeafIndexSetTypes<GridImp> >
01150 {
01151 typedef IndexSetDefaultImplementation<GridImp,SGridLeafIndexSet<GridImp>,SGridLeafIndexSetTypes<GridImp> > Base;
01152 enum {dim = remove_const<GridImp>::type::dimension};
01153 public:
01154
01156 SGridLeafIndexSet (const GridImp& g) : grid(g)
01157 {
01158
01159 for (int codim=0; codim<=dim; codim++)
01160 mytypes[codim].push_back(GeometryType(GeometryType::cube,dim-codim));
01161 }
01162
01164
01165
01166
01167
01168 template<int cd>
01169 int index (const typename remove_const<GridImp>::type::Traits::template Codim<cd>::Entity& e) const
01170 {
01171 return grid.template getRealEntity<cd>(e).compressedLeafIndex();
01172 }
01173
01174
01175 template< class EntityType >
01176 bool contains ( const EntityType &e ) const
01177 {
01178 return (e.level() == grid.maxLevel());
01179 }
01180
01182
01183
01184
01185
01186 template<int cc>
01187 int subIndex (const typename remove_const<GridImp>::type::Traits::template Codim<0>::Entity& e, int i) const
01188 {
01189 return grid.template getRealEntity<0>(e).template subCompressedLeafIndex<cc>(i);
01190 }
01191
01193 int size (GeometryType type) const
01194 {
01195 return grid.size(grid.maxLevel(),GridImp::dimension-type.dim());
01196 }
01197
01199 int size (int codim) const
01200 {
01201 return Base::size(codim);
01202 }
01203
01205 const std::vector<GeometryType>& geomTypes (int codim) const
01206 {
01207 return mytypes[codim];
01208 }
01209
01211 template<int cd, PartitionIteratorType pitype>
01212 typename Base::template Codim<cd>::template Partition<pitype>::Iterator begin () const
01213 {
01214 return grid.template leafbegin<cd,pitype>();
01215 }
01216
01218 template<int cd, PartitionIteratorType pitype>
01219 typename Base::template Codim<cd>::template Partition<pitype>::Iterator end () const
01220 {
01221 return grid.template leafend<cd,pitype>();
01222 }
01223
01224 private:
01225 const GridImp& grid;
01226 std::vector<GeometryType> mytypes[dim+1];
01227 };
01228
01229
01230
01235
01236
01237 template<class GridImp>
01238 class SGridGlobalIdSet :
01239 public IdSetDefaultImplementation<GridImp,SGridGlobalIdSet<GridImp>, typename remove_const<GridImp>::type::PersistentIndexType>
01240
01241
01242
01243
01244 {
01245 public:
01247
01248
01249
01250
01251 typedef typename remove_const<GridImp>::type::PersistentIndexType IdType;
01252
01254 SGridGlobalIdSet (const GridImp& g) : grid(g) {}
01255
01257
01258
01259
01260
01261 template<int cd>
01262 IdType id (const typename remove_const<GridImp>::type::Traits::template Codim<cd>::Entity& e) const
01263 {
01264 return grid.template getRealEntity<cd>(e).persistentIndex();
01265 }
01266
01268
01269
01270
01271
01272 template<int cc>
01273 IdType subId (const typename remove_const<GridImp>::type::Traits::template Codim<0>::Entity& e, int i) const
01274 {
01275 return grid.template getRealEntity<0>(e).template subPersistentIndex<cc>(i);
01276 }
01277
01278 private:
01279 const GridImp& grid;
01280 };
01281
01282
01283 template<int dim, int dimworld>
01284 struct SGridFamily
01285 {
01286 typedef GridTraits<dim,dimworld,Dune::SGrid<dim,dimworld>,
01287 SGeometry,SEntity,
01288 SEntityPointer,SLevelIterator,
01289 SIntersectionIterator,
01290 SIntersectionIterator,
01291 SIntersectionIterator,
01292 SIntersectionIterator,
01293 SHierarchicIterator,
01294 SLevelIterator,
01295 SGridLevelIndexSet<const SGrid<dim,dimworld> >,
01296 SGridLevelIndexSetTypes<const SGrid<dim,dimworld> >,
01297 SGridLeafIndexSet<const SGrid<dim,dimworld> >,
01298 SGridLeafIndexSetTypes<const SGrid<dim,dimworld> >,
01299 SGridGlobalIdSet<const SGrid<dim,dimworld> >,
01300 bigunsignedint<dim*sgrid_dim_bits+sgrid_level_bits+sgrid_codim_bits>,
01301 SGridGlobalIdSet<const SGrid<dim,dimworld> >,
01302 bigunsignedint<dim*sgrid_dim_bits+sgrid_level_bits+sgrid_codim_bits>,
01303 CollectiveCommunication<Dune::SGrid<dim,dimworld> > >
01304 Traits;
01305 };
01306
01307
01308
01362 template<int dim, int dimworld>
01363 class SGrid : public GridDefaultImplementation <dim,dimworld,sgrid_ctype,SGridFamily<dim,dimworld> >
01364 {
01365 public:
01366 typedef SGridFamily<dim,dimworld> GridFamily;
01367 typedef bigunsignedint<dim*sgrid_dim_bits+sgrid_level_bits+sgrid_codim_bits> PersistentIndexType;
01368
01369
01370 typedef SGridLevelIndexSet<SGrid<dim,dimworld> > LevelIndexSetType;
01371 typedef SGridLeafIndexSet<SGrid<dim,dimworld> > LeafIndexSetType;
01372 typedef SGridGlobalIdSet<SGrid<dim,dimworld> > GlobalIdSetType;
01373
01374 typedef typename SGridFamily<dim,dimworld>::Traits Traits;
01375
01377 enum { MAXL=32 };
01378
01380 typedef sgrid_ctype ctype;
01381
01383 std::string name() const { return "SGrid"; };
01384
01385
01386
01394 SGrid (const int* N_, const sgrid_ctype* H_);
01395
01403 SGrid (const int* N_, const sgrid_ctype* L_, const sgrid_ctype* H_);
01404
01414 SGrid (FieldVector<int,dim> N_, FieldVector<sgrid_ctype,dim> L_, FieldVector<sgrid_ctype,dim> H_);
01415
01417 SGrid ();
01418
01420 ~SGrid ();
01421
01424 int maxLevel() const;
01425
01427 template<int cd, PartitionIteratorType pitype>
01428 typename Traits::template Codim<cd>::template Partition<pitype>::LevelIterator lbegin (int level) const;
01429
01431 template<int cd, PartitionIteratorType pitype>
01432 typename Traits::template Codim<cd>::template Partition<pitype>::LevelIterator lend (int level) const;
01433
01435 template<int cd>
01436 typename Traits::template Codim<cd>::template Partition<All_Partition>::LevelIterator lbegin (int level) const
01437 {
01438 return lbegin<cd,All_Partition>(level);
01439 }
01440
01442 template<int cd>
01443 typename Traits::template Codim<cd>::template Partition<All_Partition>::LevelIterator lend (int level) const
01444 {
01445 return lend<cd,All_Partition>(level);
01446 }
01447
01449 template<int cd, PartitionIteratorType pitype>
01450 typename Traits::template Codim<cd>::template Partition<pitype>::LeafIterator leafbegin () const;
01451
01453 template<int cd, PartitionIteratorType pitype>
01454 typename Traits::template Codim<cd>::template Partition<pitype>::LeafIterator leafend () const;
01455
01457 template<int cd>
01458 typename Traits::template Codim<cd>::template Partition<All_Partition>::LeafIterator leafbegin () const
01459 {
01460 return leafbegin<cd,All_Partition>();
01461 }
01462
01464 template<int cd>
01465 typename Traits::template Codim<cd>::template Partition<All_Partition>::LeafIterator leafend () const
01466 {
01467 return leafend<cd,All_Partition>();
01468 }
01469
01481 template<class T, template<class> class P, int codim>
01482 void communicate (T& t, InterfaceType iftype, CommunicationDirection dir, int level)
01483 {
01484
01485 return;
01486 }
01487
01489 int size (int level, int codim) const;
01490
01492 int size (int codim) const
01493 {
01494 return size(maxLevel(),codim);
01495 }
01496
01498 int size (int level, GeometryType type) const
01499 {
01500 return (type.isCube()) ? size(level,dim-type.dim()) : 0;
01501 }
01502
01504 int size (GeometryType type) const
01505 {
01506 return size(maxLevel(),type);
01507 }
01508
01509
01511 int global_size (int codim) const;
01512
01514 int overlapSize (int level, int codim)
01515 {
01516 return 0;
01517 }
01518
01520 int ghostSize (int level, int codim)
01521 {
01522 return 0;
01523 }
01524
01525
01526
01528 void globalRefine (int refCount);
01529
01531 const array<int, dim>& dims(int level) const {
01532 return N[level];
01533 }
01534
01536 const FieldVector<sgrid_ctype, dimworld>& lowerLeft() const {
01537 return low;
01538 }
01539
01541 FieldVector<sgrid_ctype, dimworld> upperRight() const {
01542 return H;
01543 }
01544
01546 bool adapt ()
01547 {
01548 globalRefine(1);
01549 return true;
01550 }
01551
01552
01554 FieldVector<sgrid_ctype, dimworld> pos (int level, array<int,dim>& z) const;
01555
01557 int calc_codim (int level, const array<int,dim>& z) const;
01558
01560 int n (int level, const array<int,dim>& z) const;
01561
01563 array<int,dim> z (int level, int i, int codim) const;
01564
01566 array<int,dim> compress (int level, const array<int,dim>& z) const;
01567
01569 array<int,dim> expand (int level, const array<int,dim>& r, int b) const;
01570
01574 int partition (int level, const array<int,dim>& z) const;
01575
01577 bool exists (int level, const array<int,dim>& zred) const;
01578
01579
01580
01581 const typename Traits::GlobalIdSet& globalIdSet() const
01582 {
01583 return *theglobalidset;
01584 }
01585
01586 const typename Traits::LocalIdSet& localIdSet() const
01587 {
01588 return *theglobalidset;
01589 }
01590
01591 const typename Traits::LevelIndexSet& levelIndexSet(int level) const
01592 {
01593 assert(level>=0 && level<=maxLevel());
01594 return *(indexsets[level]);
01595 }
01596
01597 const typename Traits::LeafIndexSet& leafIndexSet() const
01598 {
01599 return *theleafindexset;
01600 }
01601
01602
01603
01604 template<class DataHandle>
01605 void communicate (DataHandle& data, InterfaceType iftype, CommunicationDirection dir, int level) const
01606 {
01607 }
01608
01609 template<class DataHandle>
01610 void communicate (DataHandle& data, InterfaceType iftype, CommunicationDirection dir) const
01611 {
01612 }
01613
01614 const CollectiveCommunication<SGrid>& comm () const
01615 {
01616 return ccobj;
01617 }
01618
01620 int overlapSize (int level, int codim) const
01621 {
01622 return 0;
01623 }
01624
01626 int overlapSize (int codim) const
01627 {
01628 return 0;
01629 }
01630
01632 int ghostSize (int level, int codim) const
01633 {
01634 return 0;
01635 }
01636
01638 int ghostSize (int codim) const
01639 {
01640 return 0;
01641 }
01642
01643 SIntersectionIterator<const SGrid<dim, dimworld> >&
01644 getRealIntersectionIterator(typename Traits::LeafIntersectionIterator& it)
01645 {
01646 return this->getRealImplementation(it);
01647 }
01648
01649 const SIntersectionIterator<const SGrid<dim, dimworld> >&
01650 getRealIntersectionIterator(const typename Traits::LeafIntersectionIterator& it) const
01651 {
01652 return this->getRealImplementation(it);
01653 }
01654
01655
01656 private:
01657
01658
01659
01660 friend class Dune::SGridLevelIndexSet<Dune::SGrid<dim,dimworld> >;
01661 friend class Dune::SGridLeafIndexSet<Dune::SGrid<dim,dimworld> >;
01662 friend class Dune::SGridGlobalIdSet<Dune::SGrid<dim,dimworld> >;
01663 friend class Dune::SIntersectionIterator<Dune::SGrid<dim,dimworld> >;
01664 friend class Dune::SHierarchicIterator<Dune::SGrid<dim,dimworld> >;
01665 friend class Dune::SEntity<0,dim,Dune::SGrid<dim,dimworld> >;
01666
01667 friend class Dune::SGridLevelIndexSet<const Dune::SGrid<dim,dimworld> >;
01668 friend class Dune::SGridLeafIndexSet<const Dune::SGrid<dim,dimworld> >;
01669 friend class Dune::SGridGlobalIdSet<const Dune::SGrid<dim,dimworld> >;
01670 friend class Dune::SIntersectionIterator<const Dune::SGrid<dim,dimworld> >;
01671 friend class Dune::SHierarchicIterator<const Dune::SGrid<dim,dimworld> >;
01672 friend class Dune::SEntity<0,dim,const Dune::SGrid<dim,dimworld> >;
01673
01674 template<int codim_, int dim_, class GridImp_, template<int,int,class> class EntityImp_>
01675 friend class Entity;
01676
01677
01678
01679
01680 template<int codim>
01681 SEntity<codim,dim,const SGrid<dim,dimworld> >& getRealEntity(typename Traits::template Codim<codim>::Entity& e )
01682 {
01683 return this->getRealImplementaion(e);
01684 }
01685
01686 template<int codim>
01687 const SEntity<codim,dim,const SGrid<dim,dimworld> >& getRealEntity(const typename Traits::template Codim<codim>::Entity& e ) const
01688 {
01689 return this->getRealImplementation(e);
01690 }
01691
01692
01693 SGrid(const SGrid &) {};
01694 SGrid & operator = (const SGrid &) { return *this; };
01695
01696 void makeSGrid (const int* N_, const sgrid_ctype* L_, const sgrid_ctype* H_);
01697
01698
01699
01700
01701 CollectiveCommunication<SGrid> ccobj;
01702
01703 std::vector<SGridLevelIndexSet<const SGrid<dim,dimworld> >*> indexsets;
01704 SGridLeafIndexSet<const SGrid<dim,dimworld> > *theleafindexset;
01705 SGridGlobalIdSet<const SGrid<dim,dimworld> > *theglobalidset;
01706
01707 int L;
01708 FieldVector<sgrid_ctype, dim> low;
01709 FieldVector<sgrid_ctype, dim> H;
01710 array<int,dim> *N;
01711 FieldVector<sgrid_ctype, dim> *h;
01712 mutable CubeMapper<dim> *mapper;
01713
01714
01715 mutable array <int,dim> zrefStatic;
01716 mutable array <int,dim> zentityStatic;
01717 };
01718
01719 namespace Capabilities
01720 {
01721
01733 template<int dim, int dimw, int cdim>
01734 struct hasEntity< SGrid<dim,dimw>, cdim>
01735 {
01736 static const bool v = true;
01737 };
01738
01742 template<int dim, int dimw>
01743 struct isLevelwiseConforming< SGrid<dim,dimw> >
01744 {
01745 static const bool v = true;
01746 };
01747
01751 template<int dim, int dimw>
01752 struct isLeafwiseConforming< SGrid<dim,dimw> >
01753 {
01754 static const bool v = true;
01755 };
01756
01760 template<int dim, int dimw>
01761 struct IsUnstructured< SGrid<dim,dimw> >
01762 {
01763 static const bool v = false;
01764 };
01765
01769 template<int dim, int dimw>
01770 struct hasHangingNodes< SGrid<dim,dimw> >
01771 {
01772 static const bool v = false;
01773 };
01774
01775 }
01776
01777 }
01778
01779 #include"sgrid/sgrid.cc"
01780
01781 #endif