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;
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       /* Assert same Iterator Context */
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       /* Assign current position and update ne */
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     // get stack reference 
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     // contains a single element type;
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 // Leaf Index Set
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     // contains a single element type;
01152         for (int codim=0; codim<=dim; codim++)
01153           mytypes[codim].push_back(GeometryType(GeometryType::cube,dim-codim));
01154   }
01155 
01157   /*
01158     We use the remove_const to extract the Type from the mutable class,
01159     because the const class is not instantiated yet.
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     We use the remove_const to extract the Type from the mutable class,
01170     because the const class is not instantiated yet.
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     We used the remove_const to extract the Type from the mutable class,
01228     because the const class is not instantiated yet.
01229   */
01230 {
01231 public:
01233   /*
01234     We use the remove_const to extract the Type from the mutable class,
01235     because the const class is not instantiated yet.
01236   */
01237   typedef typename remove_const<GridImp>::type::PersistentIndexType IdType;
01238 
01240   SGridGlobalIdSet (const GridImp& g) : grid(g) {}
01241 
01243   /*
01244     We use the remove_const to extract the Type from the mutable class,
01245     because the const class is not instantiated yet.
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     We use the remove_const to extract the Type from the mutable class,
01256     because the const class is not instantiated yet.
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, // leaf intersection
01276                      SIntersectionIterator, // level intersection
01277                      SIntersectionIterator, // leaf  intersection iter 
01278                      SIntersectionIterator, // level intersection iter
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   // need for friend declarations in entity
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   // constructors
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           // SGrid is sequential and has no periodic boundaries, so do nothing ...
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   // these are all members specific to sgrid
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   // The new index sets from DDM 11.07.2005
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   // dummy parallel functions
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     Make associated classes friends to grant access to the real entity
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     private methods
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   // disable copy and assign
01679   SGrid(const SGrid &) {};
01680   SGrid & operator = (const SGrid &) { return *this; };
01681   // generate SGrid 
01682   void makeSGrid (const int* N_,  const sgrid_ctype* L_, const sgrid_ctype* H_);
01683 
01684   /*
01685     internal data
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;                          // number of levels in hierarchic mesh 0<=level<L
01694   FieldVector<sgrid_ctype, dim> low;     // lower left corner of the grid
01695   FieldVector<sgrid_ctype, dim> H;       // length of cube per direction
01696   array<int,dim> *N;                // number of elements per direction
01697   FieldVector<sgrid_ctype, dim> *h;      // mesh size per direction
01698   mutable CubeMapper<dim> *mapper;       // a mapper for each level
01699   
01700   // faster implementation of subIndex 
01701   mutable array <int,dim> zrefStatic;     // for subIndex of SEntity
01702   mutable array <int,dim> zentityStatic;  // for subIndex of SEntity
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 } // end namespace Capabilities
01762 
01763 } // end namespace Dune
01764 
01765 #include"sgrid/sgrid.cc"
01766 
01767 #endif

Generated on Tue Mar 3 12:06:53 2009 for dune-grid by  doxygen 1.5.6