yaspgrid.hh

Go to the documentation of this file.
00001 #ifndef DUNE_YASPGRID_HH
00002 #define DUNE_YASPGRID_HH
00003 
00004 #include<iostream>
00005 #include<vector>
00006 #include<map>
00007 #include<algorithm>
00008 #include<stack>
00009 
00010 #include <dune/grid/common/grid.hh>     // the grid base classes
00011 #include <dune/grid/yaspgrid/grids.hh>  // the yaspgrid base classes
00012 #include <dune/grid/common/capabilities.hh> // the capabilities
00013 #include <dune/common/misc.hh>
00014 #include <dune/common/helpertemplates.hh>
00015 #include <dune/common/bigunsignedint.hh>
00016 #include <dune/common/typetraits.hh>
00017 #include <dune/common/collectivecommunication.hh>
00018 #include <dune/grid/common/indexidset.hh>
00019 #include <dune/grid/common/datahandleif.hh>
00020 
00021 
00022 #if HAVE_MPI
00023 #include <dune/common/mpicollectivecommunication.hh>
00024 #endif
00025 
00033 namespace Dune {
00034 
00035 //************************************************************************
00039 typedef double yaspgrid_ctype;
00040 static const yaspgrid_ctype yasptolerance=1E-13; // tolerance in coordinate computations
00041 
00042 /* some sizes for building global ids
00043  */
00044   const int yaspgrid_dim_bits = 24;   // bits for encoding each dimension
00045   const int yaspgrid_level_bits = 6;  // bits for encoding level number
00046   const int yaspgrid_codim_bits = 4;  // bits for encoding codimension
00047 
00048 
00049 //************************************************************************
00050 // forward declaration of templates
00051 
00052 template<int dim, int dimworld>               class YaspGrid;
00053 template<int mydim, int cdim, class GridImp>  class YaspGeometry;
00054 template<int codim, int dim, class GridImp>   class YaspEntity;
00055 template<int codim, class GridImp>            class YaspEntityPointer;
00056 template<int codim, PartitionIteratorType pitype, class GridImp> class YaspLevelIterator;
00057 template<class GridImp>            class YaspIntersectionIterator;
00058 template<class GridImp>            class YaspHierarchicIterator;
00059 template<class GridImp>            class YaspLevelIndexSet;
00060 template<class GridImp>            class YaspLeafIndexSet;
00061 template<class GridImp>            class YaspGlobalIdSet;
00062 
00063 //========================================================================
00071 //========================================================================
00072 
00073 template<int mydim, int cdim, class GridImp>
00074 class YaspSpecialGeometry : public Geometry<mydim, cdim, GridImp, YaspGeometry>
00075 {
00077   typedef typename GridImp::ctype ctype;
00078 public:
00079   YaspSpecialGeometry(const FieldVector<ctype, cdim>& p, const FieldVector<ctype, cdim>& h, int& m) :
00080     Geometry<mydim, cdim, GridImp, YaspGeometry>(YaspGeometry<mydim, cdim, GridImp>(p,h,m))
00081     {}
00082   YaspSpecialGeometry() :
00083     Geometry<mydim, cdim, GridImp, YaspGeometry>(YaspGeometry<mydim, cdim, GridImp>(false))
00084     {};
00085 };
00086 
00087 template<int mydim, class GridImp>
00088 class YaspSpecialGeometry<mydim,mydim,GridImp> : public Geometry<mydim, mydim, GridImp, YaspGeometry>
00089 {
00091   typedef typename GridImp::ctype ctype;
00092 public:
00093   YaspSpecialGeometry(const FieldVector<ctype, mydim>& p, const FieldVector<ctype, mydim>& h) :
00094     Geometry<mydim, mydim, GridImp, YaspGeometry>(YaspGeometry<mydim, mydim, GridImp>(p,h))
00095     {}
00096   YaspSpecialGeometry() :
00097     Geometry<mydim, mydim, GridImp, YaspGeometry>(YaspGeometry<mydim, mydim, GridImp>(false))
00098     {};
00099 };
00100 
00101 template<int cdim, class GridImp>
00102 class YaspSpecialGeometry<0,cdim,GridImp> : public Geometry<0, cdim, GridImp, YaspGeometry>
00103 {
00105   typedef typename GridImp::ctype ctype;
00106 public:
00107   YaspSpecialGeometry(const FieldVector<ctype, cdim>& p) :
00108     Geometry<0, cdim, GridImp, YaspGeometry>(YaspGeometry<0, cdim, GridImp>(p))
00109     {}
00110   YaspSpecialGeometry(const FieldVector<ctype, cdim>& p, const FieldVector<ctype, cdim>& h, int& m) :
00111     Geometry<0, cdim, GridImp, YaspGeometry>(YaspGeometry<0, cdim, GridImp>(p))
00112     {}
00113   YaspSpecialGeometry() :
00114     Geometry<0, cdim, GridImp, YaspGeometry>(YaspGeometry<0, cdim, GridImp>(false))
00115     {};
00116 };
00117 
00118 //========================================================================
00119 // The transformation describing the refinement rule
00120 
00121 template<int dim, class GridImp>
00122 class YaspFatherRelativeLocalElement {
00123 public:
00124   static FieldVector<yaspgrid_ctype, dim> midpoint;  // data neded for the refelem below
00125   static FieldVector<yaspgrid_ctype, dim> extension; // data needed for the refelem below
00126   static YaspSpecialGeometry<dim,dim,GridImp> geo;
00127   static YaspSpecialGeometry<dim,dim,GridImp>& getson (int i)
00128   {
00129     for (int k=0; k<dim; k++)
00130       if (i&(1<<k))
00131         midpoint[k] = 0.75;
00132       else
00133         midpoint[k] = 0.25;
00134     return geo;
00135   }
00136 };
00137 
00138 // initialize static variable with bool constructor (which makes reference elements)
00139 template<int dim, class GridImp>
00140 YaspSpecialGeometry<dim,dim,GridImp> 
00141 YaspFatherRelativeLocalElement<dim,GridImp>::geo(YaspFatherRelativeLocalElement<dim,GridImp>::midpoint,
00142                                                  YaspFatherRelativeLocalElement<dim,GridImp>::extension);
00143 template<int dim, class GridImp>
00144 FieldVector<yaspgrid_ctype,dim> YaspFatherRelativeLocalElement<dim,GridImp>::midpoint(0.25);
00145 
00146 template<int dim, class GridImp>
00147 FieldVector<yaspgrid_ctype,dim> YaspFatherRelativeLocalElement<dim,GridImp>::extension(0.5);
00148 
00150 template<int mydim,int cdim, class GridImp>
00151 class YaspGeometry : public GeometryDefaultImplementation<mydim,cdim,GridImp,YaspGeometry>
00152 {
00153 public:
00155   typedef typename GridImp::ctype ctype;
00157   typedef Geometry<mydim,mydim,GridImp,Dune::YaspGeometry> ReferenceGeometry;
00158   
00160   GeometryType type () const
00161   {
00162       return GeometryType(GeometryType::cube,mydim);
00163   }
00164 
00166   int corners () const
00167   {
00168         return 1<<mydim;
00169   }
00170 
00172   const FieldVector<ctype, cdim>& operator[] (int i) const
00173   {
00174         assert( i >= 0 && i < (int) coord_.N() ); 
00175         FieldVector<ctype, cdim>& c = coord_[i];
00176         int bit=0;
00177         for (int k=0; k<cdim; k++) // run over all directions in world
00178           {
00179                 if (k==missing)
00180                   {
00181                         c[k] = midpoint[k];
00182                         continue;
00183                   }
00184                 //k is not the missing direction
00185                 if (i&(1<<bit))  // check whether bit is set or not
00186                   c[k] = midpoint[k]+0.5*extension[k]; // bit is 1 in i
00187                 else
00188                   c[k] = midpoint[k]-0.5*extension[k]; // bit is 0 in i
00189                 bit++; // we have processed a direction
00190           }
00191 
00192         return c;
00193   }
00194 
00196   FieldVector<ctype, cdim> global (const FieldVector<ctype, mydim>& local) const
00197   {
00198       FieldVector<ctype, cdim> g;
00199       int bit=0;
00200       for (int k=0; k<cdim; k++)
00201           if (k==missing)
00202               g[k] = midpoint[k];
00203           else
00204           {
00205               g[k] = midpoint[k] + (local[bit]-0.5)*extension[k];
00206               bit++;
00207           }
00208       return g;
00209   }
00210 
00212   FieldVector<ctype, mydim> local (const FieldVector<ctype, cdim>& global) const
00213   {
00214       FieldVector<ctype, mydim> l; // result
00215       int bit=0;
00216       for (int k=0; k<cdim; k++)
00217           if (k!=missing)
00218           {
00219               l[bit] = (global[k]-midpoint[k])/extension[k] + 0.5;
00220               bit++;
00221           }
00222       return l;
00223   }
00224 
00226   ctype volume () const
00227   {
00228     ctype volume=1.0;
00229     for (int k=0; k<cdim; k++)
00230       if (k!=missing) volume *= extension[k];
00231     return volume;
00232   }
00233 
00236   ctype integrationElement (const FieldVector<ctype, mydim>& local) const
00237   {
00238     return volume();
00239   }
00240 
00242   FieldMatrix<ctype,cdim,mydim>& jacobianInverseTransposed (const FieldVector<ctype, mydim>& local) const
00243   {
00244       Jinv = 0.0;
00245       int k=0;
00246       for (int i=0; i<cdim; ++i)
00247       {
00248           if (i != missing)
00249           {
00250               Jinv[i][k] = 1.0/extension[i]; // set diagonal element
00251               k++;
00252           }
00253       }
00254       return Jinv;
00255   }
00256 
00258   bool checkInside (const FieldVector<ctype, mydim>& local) const
00259   {
00260         for (int i=0; i<mydim; i++)
00261           if (local[i]<-yasptolerance || local[i]>1+yasptolerance) return false;
00262         return true;
00263   }
00264 
00266   YaspGeometry (const FieldVector<ctype, cdim>& p, const FieldVector<ctype, cdim>& h, int& m)
00267         : midpoint(p), extension(h), missing(m)
00268   {
00269         if (cdim!=mydim+1)
00270           DUNE_THROW(GridError, "general YaspGeometry assumes cdim=mydim+1");
00271   }
00272 
00274   YaspGeometry (const YaspGeometry& other) 
00275         : midpoint(other.midpoint), 
00276           extension(other.extension), 
00277           missing(other.missing)
00278   {
00279   }
00280 
00282   void print (std::ostream& s) const
00283   {
00284         s << "YaspGeometry<"<<mydim<<","<<cdim<< "> ";
00285         s << "midpoint";
00286         for (int i=0; i<cdim; i++)
00287                   s << " " << midpoint[i];
00288                 s << " extension";
00289         for (int i=0; i<cdim; i++)
00290                   s << " " << extension[i];
00291                 s << " missing is " << missing;
00292   }
00293 private:
00294   // the element is fully defined by its midpoint the extension
00295   // in each direction and the missing direction.
00296   // References are used because this information
00297   // is known outside the element in many cases.
00298   // Note cdim==cdim+1
00299 
00300   // IMPORTANT midpoint and extension are references,
00301   // YaspGeometry can't be copied
00302   const FieldVector<ctype, cdim> & midpoint;    // the midpoint
00303   const FieldVector<ctype, cdim> & extension;   // the extension
00304   int& missing;                         // the missing, i.e. constant direction
00305 
00306   // In addition we need memory in order to return references.
00307   // Possibly we should change this in the interface ...
00308   mutable FieldMatrix<ctype, cdim, mydim> Jinv;   // the jacobian inverse
00309   mutable FieldMatrix<ctype,  Power_m_p<2,mydim>::power, cdim> coord_;   // the coordinates 
00310 
00311   const YaspGeometry<mydim,cdim,GridImp>&
00312   operator = (const YaspGeometry<mydim,cdim,GridImp>& g);
00313   
00314 };
00315 
00316 
00317 
00319 template<int mydim, class GridImp>
00320 class YaspGeometry<mydim,mydim,GridImp> : public GeometryDefaultImplementation<mydim,mydim,GridImp,YaspGeometry>
00321 {
00322 public:
00323   typedef typename GridImp::ctype ctype;
00325   typedef Geometry<mydim,mydim,GridImp,Dune::YaspGeometry> ReferenceGeometry;
00326   
00328   GeometryType type () const
00329   {
00330       return GeometryType(GeometryType::cube,mydim);
00331   }
00332 
00334   int corners () const
00335   {
00336         return 1<<mydim;
00337   }
00338 
00340   const FieldVector<ctype, mydim>& operator[] (int i) const
00341   {
00342         assert( i >= 0 && i < (int) coord_.N() ); 
00343         FieldVector<ctype, mydim>& c = coord_[i];
00344         for (int k=0; k<mydim; k++)
00345           if (i&(1<<k))
00346                 c[k] = midpoint[k]+0.5*extension[k]; // kth bit is 1 in i
00347           else
00348                 c[k] = midpoint[k]-0.5*extension[k]; // kth bit is 0 in i
00349         return c;
00350   }
00351 
00353   FieldVector<ctype, mydim> global (const FieldVector<ctype, mydim>& local) const
00354   {
00355       FieldVector<ctype,mydim> g;
00356         for (int k=0; k<mydim; k++)
00357           g[k] = midpoint[k] + (local[k]-0.5)*extension[k];
00358         return g;
00359   }
00360 
00362   FieldVector<ctype, mydim> local (const FieldVector<ctype,mydim>& global) const
00363   {
00364       FieldVector<ctype, mydim> l; // result
00365         for (int k=0; k<mydim; k++)
00366           l[k] = (global[k]-midpoint[k])/extension[k] + 0.5;
00367         return l;
00368   }
00369 
00372   ctype integrationElement (const FieldVector<ctype, mydim>& local) const
00373   {
00374     return volume();
00375   }
00376 
00378   ctype volume () const
00379   {
00380     ctype vol=1.0;
00381     for (int k=0; k<mydim; k++) vol *= extension[k];
00382     return vol;
00383   }
00384 
00386   FieldMatrix<ctype,mydim,mydim>& jacobianInverseTransposed (const FieldVector<ctype, mydim>& local) const
00387   {
00388         for (int i=0; i<mydim; ++i)
00389           {
00390                 Jinv[i] = 0.0;                // set column to zero
00391                 Jinv[i][i] = 1.0/extension[i]; // set diagonal element
00392           }
00393         return Jinv;
00394   }
00395 
00397   bool checkInside (const FieldVector<ctype, mydim>& local) const
00398   {
00399         for (int i=0; i<mydim; i++)
00400           if (local[i]<-yasptolerance || local[i]>1+yasptolerance) return false;
00401         return true;
00402   }
00403 
00405   YaspGeometry (const FieldVector<ctype, mydim>& p, const FieldVector<ctype, mydim>& h)
00406         : midpoint(p), extension(h)
00407   {}
00408 
00410   YaspGeometry (const YaspGeometry& other) 
00411         : midpoint(other.midpoint), 
00412           extension(other.extension) 
00413   {
00414   }
00415 
00417   void print (std::ostream& s) const
00418   {
00419         s << "YaspGeometry<"<<mydim<<","<<mydim<< "> ";
00420         s << "midpoint";
00421         for (int i=0; i<mydim; i++)
00422                   s << " " << midpoint[i];
00423                 s << " extension";
00424         for (int i=0; i<mydim; i++)
00425                   s << " " << extension[i];
00426   }
00427 
00428 private:
00429   // the element is fully defined by midpoint and the extension
00430   // in each direction. References are used because this information
00431   // is known outside the element in many cases.
00432   // Note mydim==cdim
00433 
00434   // IMPORTANT midpoint and extension are references,
00435   // YaspGeometry can't be copied
00436   const FieldVector<ctype, mydim> & midpoint;   // the midpoint
00437   const FieldVector<ctype, mydim> & extension;  // the extension
00438 
00439   // In addition we need memory in order to return references.
00440   // Possibly we should change this in the interface ...
00441   mutable FieldMatrix<ctype, mydim, mydim> Jinv;   // the jacobian inverse
00442   mutable FieldMatrix<ctype, Power_m_p<2,mydim>::power, mydim> coord_;   // the coordinates 
00443 
00444   // disable copy
00445   const YaspGeometry<mydim,mydim,GridImp>&
00446   operator = (const YaspGeometry<mydim,mydim,GridImp>& g);
00447 };
00448 
00450 template<int cdim, class GridImp>
00451 class YaspGeometry<0,cdim,GridImp> : public GeometryDefaultImplementation<0,cdim,GridImp,YaspGeometry>
00452 {
00453 public:
00454   typedef typename GridImp::ctype ctype;
00455   
00457   GeometryType type () const
00458   {
00459       return GeometryType(GeometryType::cube,0);
00460   }
00461 
00463   int corners () const
00464   {
00465         return 1;
00466   }
00467 
00469   const FieldVector<ctype, cdim>& operator[] (int i) const
00470   {
00471         return position;
00472   }
00473 
00476   ctype integrationElement (const FieldVector<ctype, 0>& local) const
00477   {
00478         return 1.0;
00479   }
00480 
00482   FieldMatrix<ctype,cdim,0>& jacobianInverseTransposed (const FieldVector<ctype, 0>& local) const
00483   {
00484       static FieldMatrix<ctype,cdim,0> Jinv(0.0);
00485       return Jinv;
00486   }
00487 
00489   YaspGeometry (const FieldVector<ctype, cdim>& p) : position(p)
00490   {}
00491 
00493   void print (std::ostream& s) const
00494   {
00495         s << "YaspGeometry<"<<0<<","<<cdim<< "> ";
00496         s << "position " << position;
00497   }
00498 
00499 private:
00500   // IMPORTANT position is a reference,
00501   // YaspGeometry can't be copied
00502   const FieldVector<ctype, cdim> & position; 
00503 
00504   const YaspGeometry<0,cdim,GridImp>&
00505   operator = (const YaspGeometry<0,cdim,GridImp>& g);
00506 };
00507 
00508 // operator<< for all YaspGeometrys
00509 template <int mydim, int cdim, class GridImp>
00510 inline
00511 std::ostream& operator<< (std::ostream& s, YaspGeometry<mydim,cdim,GridImp>& e)
00512 {
00513   e.print(s);
00514   return s;
00515 }
00516 
00517 //========================================================================
00525 //========================================================================
00526 
00527 template<int codim, int dim, class GridImp>
00528 class YaspSpecialEntity :
00529   public GridImp::template Codim<codim>::Entity
00530 {
00531 public:
00532   typedef typename GridImp::ctype ctype;
00533   
00534   typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
00535   typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
00536 
00537   YaspSpecialEntity(const YGLI& g, const TSI& it) :
00538     GridImp::template Codim<codim>::Entity (YaspEntity<codim, dim, GridImp>(g,it))
00539     {};
00540   YaspSpecialEntity(const YaspEntity<codim, dim, GridImp>& e) :
00541     GridImp::template Codim<codim>::Entity (e)
00542     {};
00543   const TSI& transformingsubiterator () const
00544   {
00545         return this->realEntity.transformingsubiterator();
00546   }
00547   const YGLI& gridlevel () const
00548   {
00549         return this->realEntity.gridlevel();
00550   }
00551 };
00552 
00553 template<int codim, int dim, class GridImp>
00554 class YaspEntity 
00555 :  public EntityDefaultImplementation <codim,dim,GridImp,YaspEntity>
00556 {
00557 public:
00558   typedef typename GridImp::ctype ctype;
00559   
00560   typedef typename GridImp::template Codim<codim>::Geometry Geometry;
00562   int level () const
00563   {
00564         DUNE_THROW(GridError, "YaspEntity not implemented");
00565   }
00566 
00568   int index () const
00569   {
00570         DUNE_THROW(GridError, "YaspEntity not implemented");
00571   }
00572 
00574   const Geometry& geometry () const
00575   {
00576         DUNE_THROW(GridError, "YaspEntity not implemented");
00577   }
00578 
00580   PartitionType partitionType () const
00581   {
00582         DUNE_THROW(GridError, "YaspEntity not implemented");
00583   }
00584 
00585   typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
00586   typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
00587   YaspEntity (const YGLI& g, const TSI& it)
00588   {
00589         DUNE_THROW(GridError, "YaspEntity not implemented");
00590   }
00591 
00592   // IndexSets needs access to the private index methods
00593   friend class Dune::YaspLevelIndexSet<GridImp>;
00594   friend class Dune::YaspLeafIndexSet<GridImp>;
00595   friend class Dune::YaspGlobalIdSet<GridImp>;
00596   typedef typename GridImp::PersistentIndexType PersistentIndexType;
00597 
00599   PersistentIndexType persistentIndex () const 
00600   { 
00601     DUNE_THROW(GridError, "YaspEntity not implemented");
00602   }
00603 
00605   int compressedIndex () const 
00606   {
00607     DUNE_THROW(GridError, "YaspEntity not implemented");
00608   }
00609 
00611   int compressedLeafIndex () const 
00612   {
00613     DUNE_THROW(GridError, "YaspEntity not implemented");
00614   }
00615 };
00616 
00617 
00618 // specialization for codim=0
00619 template<int dim, class GridImp>
00620 class YaspEntity<0,dim,GridImp> 
00621 : public EntityDefaultImplementation <0,dim,GridImp,YaspEntity>
00622 {
00623   enum { dimworld = GridImp::dimensionworld };
00624 public:
00625   typedef typename GridImp::ctype ctype;
00626   
00627   typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
00628   typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
00629 
00630   typedef YaspSpecialGeometry<dim-0,dim,GridImp> SpecialGeometry;
00631   
00632   typedef typename GridImp::template Codim<0>::Geometry Geometry;
00633   template <int cd>
00634   struct Codim
00635   {
00636     typedef typename GridImp::template Codim<cd>::EntityPointer EntityPointer;
00637   };
00638   typedef typename GridImp::template Codim<0>::EntityPointer EntityPointer;
00639   typedef typename GridImp::template Codim<0>::LevelIntersectionIterator IntersectionIterator;
00640   typedef typename GridImp::template Codim<0>::LevelIntersectionIterator LevelIntersectionIterator;
00641   typedef typename GridImp::template Codim<0>::LeafIntersectionIterator  LeafIntersectionIterator;
00642   typedef typename GridImp::template Codim<0>::HierarchicIterator HierarchicIterator;
00643 
00645   typedef typename GridImp::PersistentIndexType PersistentIndexType;
00646 
00648   typedef typename YGrid<dim,ctype>::iTupel iTupel;
00649 
00650   // constructor
00651   YaspEntity (const YGLI& g, const TSI& it)
00652     : _it(it), _g(g), _geometry(it.position(),it.meshsize())
00653   {
00654   }
00655 
00657   int level () const {return _g.level();}
00658 
00660   int index () const { return _it.superindex();} // superindex works also for iteration over subgrids
00661 
00663   int globalIndex () const {
00664     return _g.cell_global().index(_it.coord());
00665   }
00666 
00668   PartitionType partitionType () const
00669   {
00670         if (_g.cell_interior().inside(_it.coord())) return InteriorEntity;
00671         if (_g.cell_overlap().inside(_it.coord())) return OverlapEntity;
00672         return GhostEntity;
00673   }
00674 
00676   const Geometry& geometry () const { return _geometry; }
00677 
00680   template<int cc> int count () const
00681   {
00682     if (cc==dim) return 1<<dim;
00683     if (cc==1) return 2*dim;
00684     if (cc==dim-1) return dim*(1<<(dim-1));
00685     if (cc==0) return 1;
00686     DUNE_THROW(GridError, "codim " << cc << " (dim=" << dim << ") not (yet) implemented");
00687   }
00688 
00691   template<int cc>
00692   typename Codim<cc>::EntityPointer entity (int i) const
00693   {
00694       dune_static_assert( cc == dim || cc == 0 ,
00695           "YaspGrid only supports Entities with codim=dim and codim=0");
00696       // coordinates of the cell == coordinates of lower left corner
00697       if (cc==dim)
00698           {
00699                 iTupel coord = _it.coord();
00700 
00701                 // get corner from there
00702                 for (int k=0; k<dim; k++)
00703                   if (i&(1<<k)) (coord[k])++;
00704 
00705                 return YaspEntityPointer<cc,GridImp>(_g,_g.vertex_overlapfront().tsubbegin(coord));
00706           }
00707       if (cc==0)
00708           {
00709                 return YaspEntityPointer<cc,GridImp>(_g,_it);
00710           }
00711       DUNE_THROW(GridError, "codim " << cc << " (dim=" << dim << ") not (yet) implemented");
00712   }
00713 
00715   EntityPointer father () const
00716   {
00717         // check if coarse level exists
00718         if (_g.level()<=0)
00719           DUNE_THROW(GridError, "tried to call father on level 0");
00720 
00721         // yes, get iterator to it
00722         YGLI cg = _g.coarser();
00723 
00724         // coordinates of the cell
00725         iTupel coord = _it.coord();
00726 
00727         // get coordinates on next coarser level
00728         for (int k=0; k<dim; k++) coord[k] = coord[k]/2;
00729 
00730         return YaspEntityPointer<0,GridImp>(cg,cg.cell_overlap().tsubbegin(coord));
00731   }
00732 
00742   const Geometry& geometryInFather () const
00743   {
00744     // determine which son we are
00745     int son = 0;
00746     for (int k=0; k<dim; k++)
00747       if (_it.coord(k)%2)
00748         son += (1<<k);
00749     
00750     // configure one of the 2^dim transformations
00751     return YaspFatherRelativeLocalElement<dim,GridImp>::getson(son);
00752   }
00753 
00754   const TSI& transformingsubiterator () const
00755   {
00756         return _it;
00757   }
00758 
00759   const YGLI& gridlevel () const
00760   {
00761         return _g;
00762   }
00763 
00764   bool isLeaf() const
00765   {
00766     return (_g.level() == _g.mg()->maxlevel());
00767   }
00768   
00770   IntersectionIterator ibegin () const
00771   {
00772     return YaspIntersectionIterator<GridImp>(*this,false);
00773   }
00774 
00776   LeafIntersectionIterator ileafbegin () const
00777   {
00778     // only if entity is leaf this iterator delivers intersections
00779     return YaspIntersectionIterator<GridImp>(*this, ! isLeaf() );
00780   }
00781 
00783   LevelIntersectionIterator ilevelbegin () const
00784   {
00785     return ibegin(); 
00786   }
00787 
00789   IntersectionIterator iend () const
00790   {
00791     return YaspIntersectionIterator<GridImp>(*this,true);
00792   }
00793 
00795   LeafIntersectionIterator ileafend () const
00796   {
00797     return iend();
00798   }
00799 
00801   LevelIntersectionIterator ilevelend () const
00802   {
00803     return iend();
00804   }
00805 
00810   HierarchicIterator hbegin (int maxlevel) const
00811   {
00812         return YaspHierarchicIterator<GridImp>(_g,_it,maxlevel);
00813   }
00814 
00816   HierarchicIterator hend (int maxlevel) const
00817   {
00818         return YaspHierarchicIterator<GridImp>(_g,_it,_g.level());
00819   }
00820 
00821 private:
00822   // IndexSets needs access to the private index methods
00823   friend class Dune::YaspLevelIndexSet<GridImp>;
00824   friend class Dune::YaspLeafIndexSet<GridImp>;
00825   friend class Dune::YaspGlobalIdSet<GridImp>;
00826 
00828   PersistentIndexType persistentIndex () const 
00829   { 
00830     // get size of global grid
00831     const iTupel& size =  _g.cell_global().size();
00832 
00833     // get coordinate correction for periodic boundaries
00834     int coord[dim];
00835     for (int i=0; i<dim; i++)
00836       {
00837         coord[i] = _it.coord(i);
00838         if (coord[i]<0) coord[i] += size[i];
00839         if (coord[i]>=size[i]) coord[i] -= size[i];
00840       }
00841 
00842     // encode codim
00843     PersistentIndexType id(0);
00844 
00845     // encode level
00846     id = id << yaspgrid_level_bits;
00847     id = id+PersistentIndexType(_g.level());
00848     
00849 
00850     // encode coordinates
00851     for (int i=dim-1; i>=0; i--)
00852       {
00853         id = id << yaspgrid_dim_bits;
00854         id = id+PersistentIndexType(coord[i]);
00855       }
00856     
00857     return id;
00858   }
00859 
00861   int compressedIndex () const 
00862   {
00863     return _it.superindex();
00864   }
00865 
00867   int compressedLeafIndex () const 
00868   {
00869     return _it.superindex();
00870   }
00871 
00873   template<int cc>
00874   PersistentIndexType subPersistentIndex (int i) const
00875   {
00876     if (cc==0)
00877       return persistentIndex();
00878 
00879     // get position of cell, note that global origin is zero
00880     // adjust for periodic boundaries
00881     int coord[dim];
00882     for (int k=0; k<dim; k++)
00883       {
00884         coord[k] = _it.coord(k);
00885         if (coord[k]<0) coord[k] += _g.cell_global().size(k);
00886         if (coord[k]>=_g.cell_global().size(k)) coord[k] -= _g.cell_global().size(k);
00887       }
00888     
00889     if (cc==dim)
00890       {
00891         // transform to vertex coordinates
00892         for (int k=0; k<dim; k++)
00893           if (i&(1<<k)) (coord[k])++;
00894 
00895         // determine min number of trailing zeroes
00896         int trailing = 1000;
00897         for (int i=0; i<dim; i++)
00898           {
00899             // count trailing zeros
00900             int zeros = 0;
00901             for (int j=0; j<_g.level(); j++)
00902               if (coord[i]&(1<<j))
00903                 break;
00904               else
00905                 zeros++;
00906             trailing = std::min(trailing,zeros);
00907           } 
00908 
00909         // determine the level of this vertex
00910         int level = _g.level()-trailing;
00911 
00912         // encode codim
00913         PersistentIndexType id(dim);
00914         
00915         // encode level
00916         id = id << yaspgrid_level_bits;
00917         id = id+PersistentIndexType(level);
00918         
00919         // encode coordinates
00920         for (int i=dim-1; i>=0; i--)
00921           {
00922             id = id << yaspgrid_dim_bits;
00923             id = id+PersistentIndexType(coord[i]>>trailing);
00924           }
00925         
00926         return id;
00927       }
00928 
00929     if (cc==1) // faces, i.e. for dim=2 codim=1 is treated as a face
00930       {
00931         // Idea: Use the doubled grid to assign coordinates to faces
00932 
00933         // ivar is the direction that varies
00934         int ivar=i/2; 
00935 
00936         // compute position from cell position
00937         for (int k=0; k<dim; k++)
00938           coord[k] = coord[k]*2 + 1; // the doubled grid
00939         if (i%2) 
00940           coord[ivar] += 1;
00941         else
00942           coord[ivar] -= 1;
00943 
00944         // encode codim
00945         PersistentIndexType id(1);
00946         
00947         // encode level
00948         id = id << yaspgrid_level_bits;
00949         id = id+PersistentIndexType(_g.level());
00950         
00951         // encode coordinates
00952         for (int i=dim-1; i>=0; i--)
00953           {
00954             id = id << yaspgrid_dim_bits;
00955             id = id+PersistentIndexType(coord[i]);
00956           }
00957         
00958         return id;
00959       }
00960 
00961     if (cc==dim-1) // edges, exist only for dim>2
00962       {
00963         // Idea: direction i is fixed, all others are vary, i.e. 2^(dim-1) possibilities per direction
00964 
00965         // number of entities per direction
00966         int m=1<<(dim-1);
00967 
00968         // ifix is the direction that is fixed
00969         int ifix=(dim-1)-(i/m); 
00970 
00971         // compute position from cell position
00972         int bit=1;
00973         for (int k=0; k<dim; k++)
00974           {
00975             coord[k] = coord[k]*2+1; // cell position in doubled grid
00976             if (k==ifix) continue;
00977             if ((i%m)&bit) coord[k] += 1; else coord[k] -= 1;
00978             bit *= 2;
00979           } 
00980 
00981         // encode codim
00982         PersistentIndexType id(dim-1);
00983         
00984         // encode level
00985         id = id << yaspgrid_level_bits;
00986         id = id+PersistentIndexType(_g.level());
00987         
00988         // encode coordinates
00989         for (int i=dim-1; i>=0; i--)
00990           {
00991             id = id << yaspgrid_dim_bits;
00992             id = id+PersistentIndexType(coord[i]);
00993           }
00994         
00995         return id;
00996       }
00997 
00998     DUNE_THROW(GridError, "codim " << cc << " (dim=" << dim << ") not (yet) implemented");
00999   }
01000 
01002   template<int cc>
01003   int subCompressedIndex (int i) const
01004   {
01005     if (cc==0)
01006       return compressedIndex();
01007     
01008     // get cell position relative to origin of local cell grid
01009     iTupel coord;
01010     for (int k=0; k<dim; ++k) 
01011       coord[k] = _it.coord(k)-_g.cell_overlap().origin(k);
01012 
01013     if (cc==dim) // vertices
01014       {
01015         // transform cell coordinate to corner coordinate
01016         for (int k=0; k<dim; k++)
01017           if (i&(1<<k)) (coord[k])++;
01018 
01019         // do lexicographic numbering
01020         int index = coord[dim-1];
01021         for (int k=dim-2; k>=0; --k)
01022           index = (index*(_g.cell_overlap().size(k)+1))+coord[k];
01023         return index;
01024       }
01025 
01026     if (cc==1) // faces, i.e. for dim=2 codim=1 is treated as a face
01027       {
01028         // Idea: direction ivar varies, all others are fixed, i.e. 2 possibilities per direction
01029 
01030         // ivar is the direction that varies
01031         int ivar=i/2; 
01032 
01033         // compute position from cell position
01034         if (i%2) coord[ivar] += 1; 
01035 
01036         // do lexicographic numbering
01037         int index = coord[dim-1];
01038         for (int k=dim-2; k>=0; --k)
01039           if (k==ivar)
01040             index = (index*(_g.cell_overlap().size(k)+1))+coord[k]; // one more
01041           else
01042             index = (index*(_g.cell_overlap().size(k)))+coord[k];
01043 
01044         // add size of all subsets for smaller directions
01045         for (int j=0; j<ivar; j++)
01046           {
01047             int n=_g.cell_overlap().size(j)+1;
01048             for (int l=0; l<dim; l++)
01049               if (l!=j) n *= _g.cell_overlap().size(l);
01050             index += n;
01051           }
01052 
01053         return index;
01054       }
01055 
01056     if (cc==dim-1) // edges, exist only for dim>2
01057       {
01058         // Idea: direction i is fixed, all others are vary, i.e. 2^(dim-1) possibilities per direction
01059 
01060         // number of entities per direction
01061         int m=1<<(dim-1);
01062 
01063         // ifix is the direction that is fixed
01064         int ifix=(dim-1)-(i/m); 
01065 
01066         // compute position from cell position
01067         int bit=1;
01068         for (int k=0; k<dim; k++)
01069           {
01070             if (k==ifix) continue;
01071             if ((i%m)&bit) coord[k] += 1;
01072             bit *= 2;
01073           } 
01074 
01075         // do lexicographic numbering
01076         int index = coord[dim-1];
01077         for (int k=dim-2; k>=0; --k)
01078           if (k!=ifix)
01079             index = (index*(_g.cell_overlap().size(k)+1))+coord[k]; // one more
01080           else
01081             index = (index*(_g.cell_overlap().size(k)))+coord[k];
01082 
01083         // add size of all subsets for smaller directions
01084         for (int j=dim-1; j>ifix; j--)
01085           {
01086             int n=_g.cell_overlap().size(j);
01087             for (int l=0; l<dim; l++)
01088               if (l!=j) n *= _g.cell_overlap().size(l)+1;
01089             index += n;
01090           }
01091 
01092         return index;
01093       }
01094 
01095     DUNE_THROW(GridError, "codim " << cc << " (dim=" << dim << ") not (yet) implemented");
01096   }
01097 
01099   template<int cc>
01100   int subCompressedLeafIndex (int i) const
01101   {
01102     if (cc==0)
01103       return compressedIndex();
01104     
01105     // get cell position relative to origin of local cell grid
01106     iTupel coord;
01107     for (int k=0; k<dim; ++k) 
01108       coord[k] = _it.coord(k)-_g.cell_overlap().origin(k);
01109 
01110     if (cc==dim) // vertices
01111       {
01112         // transform cell coordinate to corner coordinate
01113         for (int k=0; k<dim; k++)
01114           if (i&(1<<k)) (coord[k])++;
01115 
01116         // move coordinates up to maxlevel
01117         for (int k=0; k<dim; k++)
01118           coord[k] = coord[k]<<(_g.mg()->maxlevel()-_g.level());
01119 
01120         // do lexicographic numbering
01121         int index = coord[dim-1];
01122         for (int k=dim-2; k>=0; --k)
01123           index = (index*(_g.mg()->rbegin().cell_overlap().size(k)+1))+coord[k];
01124         return index;
01125       }
01126 
01127     if (cc==1) // faces, i.e. for dim=2 codim=1 is treated as a face
01128       {
01129         // Idea: direction ivar varies, all others are fixed, i.e. 2 possibilities per direction
01130 
01131         // ivar is the direction that varies
01132         int ivar=i/2; 
01133 
01134         // compute position from cell position
01135         if (i%2) coord[ivar] += 1; 
01136 
01137         // do lexicographic numbering
01138         int index = coord[dim-1];
01139         for (int k=dim-2; k>=0; --k)
01140           if (k==ivar)
01141             index = (index*(_g.cell_overlap().size(k)+1))+coord[k]; // one more
01142           else
01143             index = (index*(_g.cell_overlap().size(k)))+coord[k];
01144 
01145         // add size of all subsets for smaller directions
01146         for (int j=0; j<ivar; j++)
01147           {
01148             int n=_g.cell_overlap().size(j)+1;
01149             for (int l=0; l<dim; l++)
01150               if (l!=j) n *= _g.cell_overlap().size(l);
01151             index += n;
01152           }
01153 
01154         return index;
01155       }
01156 
01157     if (cc==dim-1) // edges, exist only for dim>2
01158       {
01159         // Idea: direction i is fixed, all others are vary, i.e. 2^(dim-1) possibilities per direction
01160 
01161         // number of entities per direction
01162         int m=1<<(dim-1);
01163 
01164         // ifix is the direction that is fixed
01165         int ifix=(dim-1)-(i/m); 
01166 
01167         // compute position from cell position
01168         int bit=1;
01169         for (int k=0; k<dim; k++)
01170           {
01171             if (k==ifix) continue;
01172             if ((i%m)&bit) coord[k] += 1;
01173             bit *= 2;
01174           } 
01175 
01176         // do lexicographic numbering
01177         int index = coord[dim-1];
01178         for (int k=dim-2; k>=0; --k)
01179           if (k!=ifix)
01180             index = (index*(_g.cell_overlap().size(k)+1))+coord[k]; // one more
01181           else
01182             index = (index*(_g.cell_overlap().size(k)))+coord[k];
01183 
01184         // add size of all subsets for smaller directions
01185         for (int j=dim-1; j>ifix; j--)
01186           {
01187             int n=_g.cell_overlap().size(j);
01188             for (int l=0; l<dim; l++)
01189               if (l!=j) n *= _g.cell_overlap().size(l)+1;
01190             index += n;
01191           }
01192 
01193         return index;
01194       }
01195 
01196     DUNE_THROW(GridError, "codim " << cc << " (dim=" << dim << ") not (yet) implemented");
01197   }
01198   
01199   const TSI& _it;           // position in the grid level
01200   const YGLI& _g;           // access to grid level
01201   SpecialGeometry _geometry; // the element geometry
01202 };
01203 
01204 
01205 // specialization for codim=dim (vertex)
01206 template<int dim, class GridImp>
01207 class YaspEntity<dim,dim,GridImp> 
01208 : public EntityDefaultImplementation <dim,dim,GridImp,YaspEntity>
01209 {
01210   enum { dimworld = GridImp::dimensionworld };
01211 public:
01212   typedef typename GridImp::ctype ctype;
01213   
01214   typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
01215   typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
01216 
01217   typedef YaspSpecialGeometry<dim-dim,dim,GridImp> SpecialGeometry;
01218   
01219   typedef typename GridImp::template Codim<dim>::Geometry Geometry;
01220   template <int cd>
01221   struct Codim
01222   {
01223     typedef typename GridImp::template Codim<cd>::EntityPointer EntityPointer;
01224   };
01225   typedef typename GridImp::template Codim<0>::EntityPointer EntityPointer;
01226 
01228   typedef typename GridImp::PersistentIndexType PersistentIndexType;
01229 
01231   typedef typename YGrid<dim,ctype>::iTupel iTupel;
01232 
01233   // constructor
01234   YaspEntity (const YGLI& g, const TSI& it)
01235         : _it(it), _g(g), _geometry(it.position())
01236   {  }
01237 
01239   int level () const {return _g.level();}
01240 
01242   int index () const {return _it.superindex();}
01243 
01245   int globalIndex () const { return _g.cell_global().index(_it.coord()); }
01246 
01247 
01249   const Geometry& geometry () const { return _geometry; }
01250 
01252   PartitionType partitionType () const
01253   {
01254         if (_g.vertex_interior().inside(_it.coord())) return InteriorEntity;
01255         if (_g.vertex_interiorborder().inside(_it.coord())) return BorderEntity;
01256         if (_g.vertex_overlap().inside(_it.coord())) return OverlapEntity;
01257         if (_g.vertex_overlapfront().inside(_it.coord())) return FrontEntity;
01258         return GhostEntity;
01259   }
01260 
01261 private:
01262   // IndexSets needs access to the private index methods
01263   friend class Dune::YaspLevelIndexSet<GridImp>;
01264   friend class Dune::YaspLeafIndexSet<GridImp>;
01265   friend class Dune::YaspGlobalIdSet<GridImp>;
01266 
01268   PersistentIndexType persistentIndex () const 
01269   { 
01270     // get coordinate and size of global grid
01271     const iTupel& size =  _g.vertex_global().size();
01272     int coord[dim];
01273 
01274     // correction for periodic boundaries
01275     for (int i=0; i<dim; i++)
01276       {
01277         coord[i] = _it.coord(i);
01278         if (coord[i]<0) coord[i] += size[i];
01279         if (coord[i]>=size[i]) coord[i] -= size[i];
01280       }
01281 
01282     // determine min number of trailing zeroes
01283     int trailing = 1000;
01284     for (int i=0; i<dim; i++)
01285       {
01286         // count trailing zeros
01287         int zeros = 0;
01288         for (int j=0; j<_g.level(); j++)
01289           if (coord[i]&(1<<j))
01290             break;
01291           else
01292             zeros++;
01293         trailing = std::min(trailing,zeros);
01294       } 
01295 
01296     // determine the level of this vertex
01297     int level = _g.level()-trailing;
01298 
01299     // encode codim
01300     PersistentIndexType id(dim);
01301 
01302     // encode level
01303     id = id << yaspgrid_level_bits;
01304     id = id+PersistentIndexType(level);
01305     
01306     // encode coordinates
01307     for (int i=dim-1; i>=0; i--)
01308       {
01309         id = id << yaspgrid_dim_bits;
01310         id = id+PersistentIndexType(coord[i]>>trailing);
01311       }
01312     
01313     return id;
01314   }
01315 
01317   int compressedIndex () const { return _it.superindex();}
01318 
01320   int compressedLeafIndex () const 
01321   { 
01322     if (_g.level()==_g.mg()->maxlevel())
01323       return _it.superindex();
01324 
01325     // not on leaf level, interpolate to finest grid
01326     int coord[dim];
01327     for (int i=0; i<dim; i++) coord[i] = _it.coord(i)-(_g).vertex_overlap().origin(i);
01328 
01329     // move coordinates up to maxlevel (multiply by 2 for each level
01330     for (int k=0; k<dim; k++)
01331       coord[k] = coord[k]*(1<<(_g.mg()->maxlevel()-_g.level()));
01332 
01333     // do lexicographic numbering
01334     int index = coord[dim-1];
01335     for (int k=dim-2; k>=0; --k)
01336       index = (index*(_g.mg()->rbegin().cell_overlap().size(k)+1))+coord[k];
01337     return index;
01338   }
01339 
01340 public:  
01341   const TSI& transformingsubiterator() const { return _it; }
01342   const YGLI& gridlevel() const { return _g; }
01343 protected:
01344   const TSI& _it;                // position in the grid level
01345   const YGLI& _g;                // access to grid level
01346   SpecialGeometry  _geometry;     // the element geometry
01347   // temporary object
01348   mutable FieldVector<ctype, dim> loc;   // always computed before being returned
01349 };
01350 
01351 
01352 //========================================================================
01357 //========================================================================
01358 
01359 template<class GridImp>
01360 class YaspIntersectionIterator
01361 {
01362   enum { dim=GridImp::dimension };
01363   enum { dimworld=GridImp::dimensionworld };  
01364   typedef typename GridImp::ctype ctype;
01365   YaspIntersectionIterator();
01366 public:
01367   // types used from grids
01368   typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
01369   typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
01370   typedef typename GridImp::template Codim<0>::Entity Entity;
01371   typedef typename GridImp::template Codim<0>::EntityPointer EntityPointer;
01372   typedef typename GridImp::template Codim<1>::Geometry Geometry;
01373   typedef typename GridImp::template Codim<1>::LocalGeometry LocalGeometry;
01374   typedef YaspSpecialEntity<0,dim,GridImp> SpecialEntity;
01375   typedef YaspSpecialGeometry<dim-1,dimworld,GridImp> SpecialGeometry;
01376   typedef YaspSpecialGeometry<dim-1,dim,GridImp> SpecialLocalGeometry;
01377   typedef Dune::Intersection<const GridImp, Dune::YaspIntersectionIterator> Intersection;
01378   
01380   void increment()
01381   {
01382         // check end
01383         if (_count==2*dim) return; // end iterator reached, we are done
01384         // update count, check end
01385         _count++;
01386 
01387         // update intersec