sgrid.hh

Go to the documentation of this file.
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   // globally define the persistent index type
00032   const int sgrid_dim_bits = 24;   // bits for encoding each dimension
00033   const int sgrid_level_bits = 6;  // bits for encoding level number
00034   const int sgrid_codim_bits = 4;  // bits for encoding codimension
00035 
00036 //************************************************************************
00037 // forward declaration of templates
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                   // encode codim, this would actually not be necessary
00294           // because z is unique in codim
00295                   PersistentIndexType id(codim);
00296 
00297                   // encode level
00298                   id = id << sgrid_level_bits;
00299                   id = id+PersistentIndexType(l);
00300         
00301                   // encode coordinates
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                   // determine min number of trailing zeroes
00313                   // consider that z is on the doubled grid !
00314                   int trailing = 1000;
00315                   for (int i=0; i<dim; i++)
00316                         {
00317                           // count trailing zeros
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                   // determine the level of this vertex
00328                   int level = l-trailing;
00329 
00330                   // encode codim
00331                   PersistentIndexType id(dim);
00332 
00333                   // encode level
00334                   id = id << sgrid_level_bits;
00335                   id = id+PersistentIndexType(level);
00336         
00337                   // encode coordinates
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           // codim != dim -> there are no copies of entities
00358           // maxlevel -> ids are fine
00359           if (codim<dim || l==grid->maxLevel())
00360                 return id;
00361           
00362           // this is a vertex which is not on the finest level
00363           // move coordinates up to maxlevel (multiply by 2 for each level
00364           array<int,dim> coord;
00365           for (int k=0; k<dim; k++)
00366                 coord[k] = z[k]*(1<<(grid->maxLevel()-l));
00367 
00368           // compute number with respect to maxLevel
00369           return grid->n(grid->maxLevel(),coord);
00370     }
00371 
00372 protected:
00373   // this is how we implement our elements
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   // disambiguate member functions with the same name in both bases
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   // specific to SEntity
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   // disambiguate member functions with the same name in both bases
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   // members specific to SEntity
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   // disambiguate member functions with the same name in both bases
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         // members specific to SEntity
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       // without sons, we are done
00722       // (the end iterator is equal to the calling iterator)
00723       if (makeend) return;
00724       
00725       // remember element where begin has been called
00726       orig_l = this->entity().level();
00727       orig_id = _grid->template getRealEntity<0>(this->entity()).index();
00728       
00729       // push original element on stack
00730       SHierarchicStackElem originalElement(orig_l, orig_id);
00731       stack.push(originalElement);
00732       
00733       // compute maxLevel
00734       maxLevel = std::min(_maxLevel,this->grid->maxLevel());
00735       
00736       // ok, push all the sons as well
00737       push_sons(orig_l,orig_id);
00738       
00739       // and pop the first son
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       // while we are at it, compute normal direction
00818       FieldVector<sgrid_ctype, dimworld> normal(0.0);
00819       if (count%2)
00820         normal[count/2] =  1.0; // odd
00821       else
00822         normal[count/2] = -1.0; // even
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;
00847   int numberInSelf () const;
00849   int numberInNeighbor () const;
00850 
00852   SIntersectionIterator (GridImp* _grid, const SEntity<0,dim,GridImp >* _self, int _count);
00853 
00855   SIntersectionIterator& operator = (const SIntersectionIterator& it)
00856     {
00857       assert(grid == it.grid);
00858       
00859       /* Assert same Iterator Context */
00860       if (! self.equals(it.self))
00861         DUNE_THROW(GridError, "assignment of SIntersectionIterator "
00862                    << "with different inside Entity");
00863       if (partition != it.partition)
00864         DUNE_THROW(GridError, "assignment of SIntersectionIterator "
00865                    << "with different partition");
00866 
00867       /* Assign current position and update ne */
00868       ne = it.ne;
00869       count = it.count;
00870       make(count);
00871 
00872       return *this;
00873     }
00874   
00875 private:
00876   void make (int _count) const;                 
00877   void makeintersections () const;              
00878   const EntityPointer self;                     
00879   mutable EntityPointer ne;                     
00880   const GridImp * grid;                         
00881   const int partition;                          
00882   const array<int,dim> zred;                 
00883   mutable int count;                              
00884   mutable bool valid_count;                       
00885   mutable bool valid_nb;                          
00886   mutable bool is_on_boundary;                    
00887   mutable bool built_intersections;               
00888   mutable SMakeableGeometry<dim-1,dim,const GridImp> is_self_local;      
00889   mutable SMakeableGeometry<dim-1,dimworld,const GridImp> is_global;     
00890   mutable SMakeableGeometry<dim-1,dim,const GridImp> is_nb_local;        
00891 };
00892 
00893 //************************************************************************
00894 
00897 template<int codim, class GridImp>
00898 class SEntityPointer
00899 {
00900   enum { dim = GridImp::dimension };
00901   friend class SIntersectionIterator<GridImp>;
00902 public:
00903   typedef SEntityPointer<codim,GridImp> EntityPointerImp;
00904   typedef typename GridImp::template Codim<codim>::Entity Entity;
00906   enum { codimension = codim };
00907   
00909   bool equals(const SEntityPointer<codim,GridImp>& i) const;
00911   Entity& dereference() const;
00913   int level () const;
00914 
00916   SEntityPointer (GridImp * _grid, int _l, int _id) :
00917     grid(_grid), l(_l), id(_id), 
00918     e(0) 
00919   {
00920   }
00921 
00923   SEntityPointer (const SEntity<codim,dim,GridImp> & _e) :
00924     grid(_e.grid), l(_e.l), id(_e.id),
00925     e(0)
00926   {
00927   }
00928 
00930   SEntityPointer (const SEntityPointer<codim,GridImp>& other) :
00931     grid(other.grid), l(other.l), id(other.id),
00932     e( 0 )
00933   {
00934   }
00935 
00937   ~SEntityPointer()
00938   {
00939     compactify();
00940 #ifndef NDEBUG 
00941     id = -1;
00942 #endif
00943   }
00944 
00946   SEntityPointer& operator = (const SEntityPointer& other)
00947   {
00948     grid = other.grid;
00949     l = other.l;
00950     id = other.id;
00951 
00952     compactify();
00953     return *this;
00954   }
00955 
00957   void compactify()
00958   {
00959     if( e )
00960     {
00961       enStack().push( e );
00962       e = 0;
00963     }
00964   }
00965   
00966 protected:
00967   SMakeableEntity<codim,dim,GridImp>& entity() const
00968   {
00969     if( ! e )
00970     {
00971       e = getEntity( grid, l, id );
00972     }
00973     return *e;
00974   }
00975 
00976   typedef std::stack< SMakeableEntity<codim,dim,GridImp> * > EntityStackType;
00977   static inline EntityStackType& enStack()
00978   {
00979     static EntityStackType eStack;
00980     return eStack;
00981   }
00982 
00983   inline SMakeableEntity<codim,dim,GridImp>* getEntity(GridImp* _grid, int _l, int _id ) const
00984   {
00985     // get stack reference 
00986     EntityStackType& enSt = enStack();
00987 
00988     if( enSt.empty() )
00989     {
00990       return (new SMakeableEntity<codim,dim,GridImp>(_grid, _l, _id));
00991     }
00992     else
00993     {
00994       SMakeableEntity<codim,dim,GridImp>* e = enSt.top();
00995       enSt.pop();
00996       e->make(_grid, _l,_id);
00997       return e;
00998     }
00999   }
01000 
01001   GridImp* grid;                 
01002   int l;                         
01003   mutable int id;                
01004   mutable SMakeableEntity<codim,dim,GridImp>* e;  
01005 };
01006 //************************************************************************
01007 
01008 
01011 template<int codim, PartitionIteratorType pitype, class GridImp>
01012 class SLevelIterator :
01013   public Dune::SEntityPointer <codim,GridImp>
01014 {
01015   friend class SLevelIterator<codim, pitype,const GridImp>;
01016   enum { dim = GridImp::dimension };
01017 public:
01018   typedef typename GridImp::template Codim<codim>::Entity Entity;
01019 
01021   void increment();
01022 
01024   SLevelIterator (GridImp * _grid, int _l, int _id) :
01025     Dune::SEntityPointer<codim,GridImp>(_grid,_l,_id) {}
01026 };
01027 
01028 
01029 //========================================================================
01034 //========================================================================
01035 
01036 template <class GridImp> 
01037 struct SGridLevelIndexSetTypes
01038 {
01040   template<int cd>
01041   struct Codim
01042   {
01043         template<PartitionIteratorType pitype>
01044         struct Partition
01045         {
01046           typedef typename GridImp::Traits::template Codim<cd>::template Partition<pitype>::LevelIterator Iterator;
01047         };
01048   };
01049 };
01050 
01051 template<class GridImp>
01052 class SGridLevelIndexSet : public IndexSetDefaultImplementation<GridImp,SGridLevelIndexSet<GridImp>,SGridLevelIndexSetTypes<GridImp> >
01053 {
01054   typedef IndexSetDefaultImplementation<GridImp,SGridLevelIndexSet<GridImp>,SGridLevelIndexSetTypes<GridImp> > Base;
01055 public:
01056 
01058   SGridLevelIndexSet (const GridImp& g, int l) : grid(g), level(l)
01059   {
01060     // contains a single element type;
01061         for (int codim=0; codim<=GridImp::dimension; codim++)
01062           mytypes[codim].push_back(GeometryType(GeometryType::cube,GridImp::dimension-codim));
01063   }
01064 
01066   template<int cd>
01067   int index (const typename GridImp::Traits::template Codim<cd>::Entity& e) const 
01068   {
01069         return grid.template getRealEntity<cd>(e).compressedIndex(); 
01070   }
01071 
01073   template<int cc>
01074   int subIndex (const typename GridImp::Traits::template Codim<0>::Entity& e, int i) const
01075   {
01076         return grid.template getRealEntity<0>(e).template subCompressedIndex<cc>(i);
01077   }
01078 
01080   int size (GeometryType type) const
01081   {
01082       return grid.size(level,GridImp::dimension-type.dim());
01083   }
01084   
01086   int size (int codim) const
01087   {
01088     return Base::size(codim);
01089   }
01090 
01092   const std::vector<GeometryType>& geomTypes (int codim) const
01093   {
01094         return mytypes[codim];
01095   }
01096 
01098   template<int cd, PartitionIteratorType pitype>
01099   typename Base::template Codim<cd>::template Partition<pitype>::Iterator begin () const
01100   {
01101         return grid.template lbegin<cd,pitype>(level);
01102   }
01103   
01105   template<int cd, PartitionIteratorType pitype>
01106   typename Base::template Codim<cd>::template Partition<pitype>::Iterator end () const
01107   {
01108         return grid.template lend<cd,pitype>(level);
01109   }
01110 
01111 private:
01112   const GridImp& grid;
01113   int level;
01114   std::vector<GeometryType> mytypes[GridImp::dimension+1];
01115 };
01116 
01117 // Leaf Index Set
01118 
01119 template <class GridImp> 
01120 struct SGridLeafIndexSetTypes
01121 {
01123   template<int cd>
01124   struct Codim
01125   {
01126         template<PartitionIteratorType pitype>
01127         struct Partition
01128         {
01129           typedef typename GridImp::Traits::template Codim<cd>::template Partition<pitype>::LeafIterator Iterator;
01130         };
01131   };
01132 };
01133 
01134 template<class GridImp>
01135 class SGridLeafIndexSet : public IndexSetDefaultImplementation<GridImp,SGridLeafIndexSet<GridImp>,SGridLeafIndexSetTypes<GridImp> >
01136 {
01137   typedef IndexSetDefaultImplementation<GridImp,SGridLeafIndexSet<GridImp>,SGridLeafIndexSetTypes<GridImp> > Base;
01138     enum {dim = remove_const<GridImp>::type::dimension};
01139 public:
01140 
01142   SGridLeafIndexSet (const GridImp& g) : grid(g)
01143   {
01144     // contains a single element type;
01145         for (int codim=0; codim<=dim; codim++)
01146           mytypes[codim].push_back(GeometryType(GeometryType::cube,dim-codim));
01147   }
01148 
01150   /*
01151     We use the remove_const to extract the Type from the mutable class,
01152     because the const class is not instantiated yet.
01153   */
01154   template<int cd>
01155   int index (const typename remove_const<GridImp>::type::Traits::template Codim<cd>::Entity& e) const 
01156   {
01157         return grid.template getRealEntity<cd>(e).compressedLeafIndex(); 
01158   }
01159 
01161   /*
01162     We use the remove_const to extract the Type from the mutable class,
01163     because the const class is not instantiated yet.
01164   */
01165   template<int cc>
01166   int subIndex (const typename remove_const<GridImp>::type::Traits::template Codim<0>::Entity& e, int i) const
01167   {
01168         return grid.template getRealEntity<0>(e).template subCompressedLeafIndex<cc>(i);
01169   }
01170 
01172   int size (GeometryType type) const
01173   {
01174       return grid.size(grid.maxLevel(),GridImp::dimension-type.dim());
01175   }
01176 
01178   int size (int codim) const
01179   {
01180     return Base::size(codim);
01181   }
01182 
01184   const std::vector<GeometryType>& geomTypes (int codim) const
01185   {
01186         return mytypes[codim];
01187   }
01188 
01190   template<int cd, PartitionIteratorType pitype>
01191   typename Base::template Codim<cd>::template Partition<pitype>::Iterator begin () const
01192   {
01193         return grid.template leafbegin<cd,pitype>();
01194   }
01195   
01197   template<int cd, PartitionIteratorType pitype>
01198   typename Base::template Codim<cd>::template Partition<pitype>::Iterator end () const
01199   {
01200         return grid.template leafend<cd,pitype>();
01201   }
01202 
01203 private:
01204   const GridImp& grid;
01205   std::vector<GeometryType> mytypes[dim+1];
01206 };
01207 
01208 
01209 //========================================================================
01214 //========================================================================
01215 
01216 template<class GridImp>
01217 class SGridGlobalIdSet :
01218   public IdSetDefaultImplementation<GridImp,SGridGlobalIdSet<GridImp>, typename remove_const<GridImp>::type::PersistentIndexType>
01219   /*
01220     We used the remove_const to extract the Type from the mutable class,
01221     because the const class is not instantiated yet.
01222   */
01223 {
01224 public:
01226   /*
01227     We use the remove_const to extract the Type from the mutable class,
01228     because the const class is not instantiated yet.
01229   */
01230   typedef typename remove_const<GridImp>::type::PersistentIndexType IdType;
01231 
01233   SGridGlobalIdSet (const GridImp& g) : grid(g) {}
01234 
01236   /*
01237     We use the remove_const to extract the Type from the mutable class,
01238     because the const class is not instantiated yet.
01239   */
01240   template<int cd>
01241   IdType id (const typename remove_const<GridImp>::type::Traits::template Codim<cd>::Entity& e) const 
01242   {
01243           return grid.template getRealEntity<cd>(e).persistentIndex();
01244   }
01245 
01247   /*
01248     We use the remove_const to extract the Type from the mutable class,
01249     because the const class is not instantiated yet.
01250   */
01251   template<int cc>
01252   IdType subId (const typename remove_const<GridImp>::type::Traits::template Codim<0>::Entity& e, int i) const
01253   {
01254         return grid.template getRealEntity<0>(e).template subPersistentIndex<cc>(i);
01255   }
01256 
01257 private:
01258   const GridImp& grid;
01259 };
01260 
01261 
01262 template<int dim, int dimworld>
01263 struct SGridFamily
01264 {
01265   typedef GridTraits<dim,dimworld,Dune::SGrid<dim,dimworld>,
01266                      SGeometry,SEntity,
01267                      SEntityPointer,SLevelIterator,
01268                      SIntersectionIterator, // leaf intersection
01269                      SIntersectionIterator, // level intersection
01270                      SIntersectionIterator, // leaf  intersection iter 
01271                      SIntersectionIterator, // level intersection iter
01272                      SHierarchicIterator,
01273                      SLevelIterator,
01274                                          SGridLevelIndexSet<const SGrid<dim,dimworld> >,
01275                                          SGridLevelIndexSetTypes<const SGrid<dim,dimworld> >,
01276                                          SGridLeafIndexSet<const SGrid<dim,dimworld> >,
01277                                          SGridLeafIndexSetTypes<const SGrid<dim,dimworld> >,
01278                                          SGridGlobalIdSet<const SGrid<dim,dimworld> >,
01279                                          bigunsignedint<dim*sgrid_dim_bits+sgrid_level_bits+sgrid_codim_bits>,
01280                                          SGridGlobalIdSet<const SGrid<dim,dimworld> >,
01281                                          bigunsignedint<dim*sgrid_dim_bits+sgrid_level_bits+sgrid_codim_bits>, 
01282                                          CollectiveCommunication<Dune::SGrid<dim,dimworld> > > 
01283   Traits;
01284 };
01285 
01286 
01287 //************************************************************************
01341 template<int dim, int dimworld>
01342 class SGrid : public GridDefaultImplementation <dim,dimworld,sgrid_ctype,SGridFamily<dim,dimworld> >
01343 {
01344 public:
01345   typedef SGridFamily<dim,dimworld> GridFamily;
01346   typedef bigunsignedint<dim*sgrid_dim_bits+sgrid_level_bits+sgrid_codim_bits> PersistentIndexType;
01347 
01348   // need for friend declarations in entity
01349   typedef SGridLevelIndexSet<SGrid<dim,dimworld> > LevelIndexSetType;
01350   typedef SGridLeafIndexSet<SGrid<dim,dimworld> > LeafIndexSetType;
01351   typedef SGridGlobalIdSet<SGrid<dim,dimworld> > GlobalIdSetType;
01352 
01353   typedef typename SGridFamily<dim,dimworld>::Traits Traits;
01354 
01356   enum { MAXL=32 };
01357 
01359   typedef sgrid_ctype ctype;
01360 
01362   std::string name() const { return "SGrid"; };
01363 
01364   // constructors
01365 
01373   SGrid (const int* N_, const sgrid_ctype* H_);
01374   
01382   SGrid (const int* N_, const sgrid_ctype* L_, const sgrid_ctype* H_);
01383 
01393   SGrid (FieldVector<int,dim> N_, FieldVector<sgrid_ctype,dim> L_, FieldVector<sgrid_ctype,dim> H_);
01394 
01396   SGrid ();
01397 
01399   ~SGrid ();
01400 
01403   int maxLevel() const;
01404 
01406   template<int cd, PartitionIteratorType pitype>
01407   typename Traits::template Codim<cd>::template Partition<pitype>::LevelIterator lbegin (int level) const;
01408 
01410   template<int cd, PartitionIteratorType pitype>
01411   typename Traits::template Codim<cd>::template Partition<pitype>::LevelIterator lend (int level) const;
01412 
01414   template<int cd>