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 
01079   // return true if the given entity is contained in \f$E\f$.
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 // Leaf Index Set
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     // contains a single element type;
01159         for (int codim=0; codim<=dim; codim++)
01160           mytypes[codim].push_back(GeometryType(GeometryType::cube,dim-codim));
01161   }
01162 
01164   /*
01165     We use the remove_const to extract the Type from the mutable class,
01166     because the const class is not instantiated yet.
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   // return true if the given entity is contained in \f$E\f$.
01175   template< class EntityType >
01176   bool contains ( const EntityType &e ) const
01177   {
01178     return (e.level() == grid.maxLevel());
01179   }
01180 
01182   /*
01183     We use the remove_const to extract the Type from the mutable class,
01184     because the const class is not instantiated yet.
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     We used the remove_const to extract the Type from the mutable class,
01242     because the const class is not instantiated yet.
01243   */
01244 {
01245 public:
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   typedef typename remove_const<GridImp>::type::PersistentIndexType IdType;
01252 
01254   SGridGlobalIdSet (const GridImp& g) : grid(g) {}
01255 
01257   /*
01258     We use the remove_const to extract the Type from the mutable class,
01259     because the const class is not instantiated yet.
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     We use the remove_const to extract the Type from the mutable class,
01270     because the const class is not instantiated yet.
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, // leaf intersection
01290                      SIntersectionIterator, // level intersection
01291                      SIntersectionIterator, // leaf  intersection iter 
01292                      SIntersectionIterator, // level intersection iter
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   // need for friend declarations in entity
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   // constructors
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           // SGrid is sequential and has no periodic boundaries, so do nothing ...
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   // these are all members specific to sgrid
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   // The new index sets from DDM 11.07.2005
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   // dummy parallel functions
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     Make associated classes friends to grant access to the real entity
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     private methods
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   // disable copy and assign
01693   SGrid(const SGrid &) {};
01694   SGrid & operator = (const SGrid &) { return *this; };
01695   // generate SGrid 
01696   void makeSGrid (const int* N_,  const sgrid_ctype* L_, const sgrid_ctype* H_);
01697 
01698   /*
01699     internal data
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;                          // number of levels in hierarchic mesh 0<=level<L
01708   FieldVector<sgrid_ctype, dim> low;     // lower left corner of the grid
01709   FieldVector<sgrid_ctype, dim> H;       // length of cube per direction
01710   array<int,dim> *N;                // number of elements per direction
01711   FieldVector<sgrid_ctype, dim> *h;      // mesh size per direction
01712   mutable CubeMapper<dim> *mapper;       // a mapper for each level
01713   
01714   // faster implementation of subIndex 
01715   mutable array <int,dim> zrefStatic;     // for subIndex of SEntity
01716   mutable array <int,dim> zentityStatic;  // for subIndex of SEntity
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 } // end namespace Capabilities
01776 
01777 } // end namespace Dune
01778 
01779 #include"sgrid/sgrid.cc"
01780 
01781 #endif

Generated on Sun Nov 15 22:28:43 2009 for dune-grid by  doxygen 1.5.6