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>
00011 #include <dune/grid/yaspgrid/grids.hh>
00012 #include <dune/grid/common/capabilities.hh>
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;
00041
00042
00043
00044 const int yaspgrid_dim_bits = 24;
00045 const int yaspgrid_level_bits = 6;
00046 const int yaspgrid_codim_bits = 4;
00047
00048
00049
00050
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
00120
00121 template<int dim, class GridImp>
00122 class YaspFatherRelativeLocalElement {
00123 public:
00124 static FieldVector<yaspgrid_ctype, dim> midpoint;
00125 static FieldVector<yaspgrid_ctype, dim> extension;
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
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++)
00178 {
00179 if (k==missing)
00180 {
00181 c[k] = midpoint[k];
00182 continue;
00183 }
00184
00185 if (i&(1<<bit))
00186 c[k] = midpoint[k]+0.5*extension[k];
00187 else
00188 c[k] = midpoint[k]-0.5*extension[k];
00189 bit++;
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;
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];
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
00295
00296
00297
00298
00299
00300
00301
00302 const FieldVector<ctype, cdim> & midpoint;
00303 const FieldVector<ctype, cdim> & extension;
00304 int& missing;
00305
00306
00307
00308 mutable FieldMatrix<ctype, cdim, mydim> Jinv;
00309 mutable FieldMatrix<ctype, Power_m_p<2,mydim>::power, cdim> coord_;
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];
00347 else
00348 c[k] = midpoint[k]-0.5*extension[k];
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;
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;
00391 Jinv[i][i] = 1.0/extension[i];
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
00430
00431
00432
00433
00434
00435
00436 const FieldVector<ctype, mydim> & midpoint;
00437 const FieldVector<ctype, mydim> & extension;
00438
00439
00440
00441 mutable FieldMatrix<ctype, mydim, mydim> Jinv;
00442 mutable FieldMatrix<ctype, Power_m_p<2,mydim>::power, mydim> coord_;
00443
00444
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
00501
00502 const FieldVector<ctype, cdim> & position;
00503
00504 const YaspGeometry<0,cdim,GridImp>&
00505 operator = (const YaspGeometry<0,cdim,GridImp>& g);
00506 };
00507
00508
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
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
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
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();}
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
00697 if (cc==dim)
00698 {
00699 iTupel coord = _it.coord();
00700
00701
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
00718 if (_g.level()<=0)
00719 DUNE_THROW(GridError, "tried to call father on level 0");
00720
00721
00722 YGLI cg = _g.coarser();
00723
00724
00725 iTupel coord = _it.coord();
00726
00727
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
00745 int son = 0;
00746 for (int k=0; k<dim; k++)
00747 if (_it.coord(k)%2)
00748 son += (1<<k);
00749
00750
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
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
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
00831 const iTupel& size = _g.cell_global().size();
00832
00833
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
00843 PersistentIndexType id(0);
00844
00845
00846 id = id << yaspgrid_level_bits;
00847 id = id+PersistentIndexType(_g.level());
00848
00849
00850
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
00880
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
00892 for (int k=0; k<dim; k++)
00893 if (i&(1<<k)) (coord[k])++;
00894
00895
00896 int trailing = 1000;
00897 for (int i=0; i<dim; i++)
00898 {
00899
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
00910 int level = _g.level()-trailing;
00911
00912
00913 PersistentIndexType id(dim);
00914
00915
00916 id = id << yaspgrid_level_bits;
00917 id = id+PersistentIndexType(level);
00918
00919
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)
00930 {
00931
00932
00933
00934 int ivar=i/2;
00935
00936
00937 for (int k=0; k<dim; k++)
00938 coord[k] = coord[k]*2 + 1;
00939 if (i%2)
00940 coord[ivar] += 1;
00941 else
00942 coord[ivar] -= 1;
00943
00944
00945 PersistentIndexType id(1);
00946
00947
00948 id = id << yaspgrid_level_bits;
00949 id = id+PersistentIndexType(_g.level());
00950
00951
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)
00962 {
00963
00964
00965
00966 int m=1<<(dim-1);
00967
00968
00969 int ifix=(dim-1)-(i/m);
00970
00971
00972 int bit=1;
00973 for (int k=0; k<dim; k++)
00974 {
00975 coord[k] = coord[k]*2+1;
00976 if (k==ifix) continue;
00977 if ((i%m)&bit) coord[k] += 1; else coord[k] -= 1;
00978 bit *= 2;
00979 }
00980
00981
00982 PersistentIndexType id(dim-1);
00983
00984
00985 id = id << yaspgrid_level_bits;
00986 id = id+PersistentIndexType(_g.level());
00987
00988
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
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)
01014 {
01015
01016 for (int k=0; k<dim; k++)
01017 if (i&(1<<k)) (coord[k])++;
01018
01019
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)
01027 {
01028
01029
01030
01031 int ivar=i/2;
01032
01033
01034 if (i%2) coord[ivar] += 1;
01035
01036
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];
01041 else
01042 index = (index*(_g.cell_overlap().size(k)))+coord[k];
01043
01044
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)
01057 {
01058
01059
01060
01061 int m=1<<(dim-1);
01062
01063
01064 int ifix=(dim-1)-(i/m);
01065
01066
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
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];
01080 else
01081 index = (index*(_g.cell_overlap().size(k)))+coord[k];
01082
01083
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
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)
01111 {
01112
01113 for (int k=0; k<dim; k++)
01114 if (i&(1<<k)) (coord[k])++;
01115
01116
01117 for (int k=0; k<dim; k++)
01118 coord[k] = coord[k]<<(_g.mg()->maxlevel()-_g.level());
01119
01120
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)
01128 {
01129
01130
01131
01132 int ivar=i/2;
01133
01134
01135 if (i%2) coord[ivar] += 1;
01136
01137
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];
01142 else
01143 index = (index*(_g.cell_overlap().size(k)))+coord[k];
01144
01145
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)
01158 {
01159
01160
01161
01162 int m=1<<(dim-1);
01163
01164
01165 int ifix=(dim-1)-(i/m);
01166
01167
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
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];
01181 else
01182 index = (index*(_g.cell_overlap().size(k)))+coord[k];
01183
01184
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;
01200 const YGLI& _g;
01201 SpecialGeometry _geometry;
01202 };
01203
01204
01205
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
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
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
01271 const iTupel& size = _g.vertex_global().size();
01272 int coord[dim];
01273
01274
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
01283 int trailing = 1000;
01284 for (int i=0; i<dim; i++)
01285 {
01286
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
01297 int level = _g.level()-trailing;
01298
01299
01300 PersistentIndexType id(dim);
01301
01302
01303 id = id << yaspgrid_level_bits;
01304 id = id+PersistentIndexType(level);
01305
01306
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
01326 int coord[dim];
01327 for (int i=0; i<dim; i++) coord[i] = _it.coord(i)-(_g).vertex_overlap().origin(i);
01328
01329
01330 for (int k=0; k<dim; k++)
01331 coord[k] = coord[k]*(1<<(_g.mg()->maxlevel()-_g.level()));
01332
01333
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;
01345 const YGLI& _g;
01346 SpecialGeometry _geometry;
01347
01348 mutable FieldVector<ctype, dim> loc;
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
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
01383 if (_count==2*dim) return;
01384
01385 _count++;
01386
01387