16
18
#include <dune/grid/common/grid.hh> // the grid base classes
17
19
#include <dune/grid/yaspgrid/grids.hh> // the yaspgrid base classes
18
20
#include <dune/grid/common/capabilities.hh> // the capabilities
19
#include <dune/common/misc.hh>
21
#include <dune/common/shared_ptr.hh>
20
22
#include <dune/common/bigunsignedint.hh>
21
23
#include <dune/common/typetraits.hh>
22
#include <dune/common/collectivecommunication.hh>
23
#include <dune/common/mpihelper.hh>
24
#include <dune/common/reservedvector.hh>
25
#include <dune/common/parallel/collectivecommunication.hh>
26
#include <dune/common/parallel/mpihelper.hh>
24
27
#include <dune/geometry/genericgeometry/topologytypes.hh>
28
#include <dune/geometry/axisalignedcubegeometry.hh>
25
29
#include <dune/grid/common/indexidset.hh>
26
30
#include <dune/grid/common/datahandleif.hh>
30
#include <dune/common/mpicollectivecommunication.hh>
34
#include <dune/common/parallel/mpicollectivecommunication.hh>
33
37
/*! \file yaspgrid.hh
34
YaspGrid stands for yet another structured parallel grid.
35
It will implement the dune grid interface for structured grids with codim 0
36
and dim, with arbitrary overlap, parallel features with two overlap
37
models, periodic boundaries and fast a implementation allowing on-the-fly computations.
42
//************************************************************************
43
/*! define name for floating point type used for coordinates in yaspgrid.
44
You can change the type for coordinates by changing this single typedef.
46
typedef double yaspgrid_ctype;
47
static const yaspgrid_ctype yasptolerance=1E-13; // tolerance in coordinate computations
49
/* some sizes for building global ids
51
const int yaspgrid_dim_bits = 24; // bits for encoding each dimension
52
const int yaspgrid_level_bits = 6; // bits for encoding level number
53
const int yaspgrid_codim_bits = 4; // bits for encoding codimension
56
//************************************************************************
57
// forward declaration of templates
59
template<int dim> class YaspGrid;
60
template<int mydim, int cdim, class GridImp> class YaspGeometry;
61
template<int codim, int dim, class GridImp> class YaspEntity;
62
template<int codim, class GridImp> class YaspEntityPointer;
63
template<int codim, class GridImp> class YaspEntitySeed;
64
template<int codim, PartitionIteratorType pitype, class GridImp> class YaspLevelIterator;
65
template<class GridImp> class YaspIntersectionIterator;
66
template<class GridImp> class YaspIntersection;
67
template<class GridImp> class YaspHierarchicIterator;
68
template<class GridImp> class YaspLevelIndexSet;
69
template<class GridImp> class YaspLeafIndexSet;
70
template<class GridImp> class YaspGlobalIdSet;
72
namespace FacadeOptions
75
template<int dim, int mydim, int cdim>
76
struct StoreGeometryReference<mydim, cdim, YaspGrid<dim>, YaspGeometry>
78
static const bool v = false;
81
template<int dim, int mydim, int cdim>
82
struct StoreGeometryReference<mydim, cdim, const YaspGrid<dim>, YaspGeometry>
84
static const bool v = false;
89
//========================================================================
90
// The transformation describing the refinement rule
92
template<int dim, class GridImp>
93
struct YaspFatherRelativeLocalElement {
94
static const array<YaspGeometry<dim,dim,GridImp>, (1<<dim) > _geo;
95
static array<YaspGeometry<dim,dim,GridImp>, (1<<dim) > initSons()
97
array<YaspGeometry<dim,dim,GridImp>, (1<<dim) > geo;
98
FieldVector<yaspgrid_ctype,dim> midpoint(0.25);
99
FieldVector<yaspgrid_ctype,dim> extension(0.5);
100
for (int i=0; i<(1<<dim); i++)
103
for (int k=0; k<dim; k++)
108
geo[i] = YaspGeometry<dim,dim,GridImp>(midpoint, extension);
114
template<int dim, class GridImp>
115
const array<YaspGeometry<dim,dim,GridImp>, (1<<dim)>
116
YaspFatherRelativeLocalElement<dim, GridImp>::_geo =
117
YaspFatherRelativeLocalElement<dim, GridImp>::initSons();
119
//========================================================================
121
YaspGeometry realizes the concept of the geometric part of a mesh entity.
123
We have specializations for dim == dimworld (elements) and dim == 0
124
(vertices). The general version implements dim == dimworld-1 (faces)
125
and otherwise throws a GridError.
127
//========================================================================
129
//! The general version implements dim==dimworld-1. If this is not the case an error is thrown
130
template<int mydim,int cdim, class GridImp>
131
class YaspGeometry : public GeometryDefaultImplementation<mydim,cdim,GridImp,YaspGeometry>
134
//! define type used for coordinates in grid module
135
typedef typename GridImp::ctype ctype;
137
//! return the element type identifier
138
GeometryType type () const
140
return GeometryType(GeometryType::cube,mydim);
143
//! here we have always an affine geometry
144
bool affine() const { return true; }
146
//! return the number of corners of this element. Corners are numbered 0...n-1
152
//! access to coordinates of corners. Index is the number of the corner
153
FieldVector< ctype, cdim > corner ( const int i ) const
155
assert( i >= 0 && i < (int) coord_.N() );
156
FieldVector<ctype, cdim>& c = coord_[i];
158
for (int k=0; k<cdim; k++) // run over all directions in world
165
//k is not the missing direction
166
if (i&(1<<bit)) // check whether bit is set or not
167
c[k] = midpoint[k]+0.5*extension[k]; // bit is 1 in i
169
c[k] = midpoint[k]-0.5*extension[k]; // bit is 0 in i
170
bit++; // we have processed a direction
176
//! access to the center/centroid
177
FieldVector< ctype, cdim > center ( ) const
182
//! maps a local coordinate within reference element to global coordinate in element
183
FieldVector<ctype, cdim> global (const FieldVector<ctype, mydim>& local) const
185
FieldVector<ctype, cdim> g;
187
for (int k=0; k<cdim; k++)
192
g[k] = midpoint[k] + (local[bit]-0.5)*extension[k];
198
//! maps a global coordinate within the element to a local coordinate in its reference element
199
FieldVector<ctype, mydim> local (const FieldVector<ctype, cdim>& global) const
201
FieldVector<ctype, mydim> l; // result
203
for (int k=0; k<cdim; k++)
206
l[bit] = (global[k]-midpoint[k])/extension[k] + 0.5;
212
//! return volume of geometry
213
ctype volume () const
216
for (int k=0; k<cdim; k++)
217
if (k!=missing) volume *= extension[k];
221
/*! determinant of the jacobian of the mapping
223
ctype integrationElement (const FieldVector<ctype, mydim>& local) const
228
//! Compute the transposed of the jacobi matrix
229
FieldMatrix<ctype,mydim,cdim>& jacobianTransposed (const FieldVector<ctype, mydim>& local) const
233
for (int i=0; i<cdim; ++i)
237
JT[k][i] = extension[i]; // set diagonal element
243
//! Compute the transposed of the inverse jacobi matrix
244
FieldMatrix<ctype,cdim,mydim>& jacobianInverseTransposed (const FieldVector<ctype, mydim>& local) const
248
for (int i=0; i<cdim; ++i)
252
Jinv[i][k] = 1.0/extension[i]; // set diagonal element
259
//! default constructor
262
//! constructor from midpoint and extension and missing direction number
263
YaspGeometry (const FieldVector<ctype, cdim>& p, const FieldVector<ctype, cdim>& h, uint8_t& m)
264
: midpoint(p), extension(h), missing(m)
267
DUNE_THROW(GridError, "general YaspGeometry assumes cdim=mydim+1");
270
//! copy constructor (skipping temporary variables)
271
YaspGeometry (const YaspGeometry& other)
272
: midpoint(other.midpoint),
273
extension(other.extension),
274
missing(other.missing)
279
void print (std::ostream& s) const
281
s << "YaspGeometry<"<<mydim<<","<<cdim<< "> ";
283
for (int i=0; i<cdim; i++)
284
s << " " << midpoint[i];
286
for (int i=0; i<cdim; i++)
287
s << " " << extension[i];
288
s << " missing is " << missing;
291
// const YaspGeometry<mydim,cdim,GridImp>&
292
// operator = (const YaspGeometry<mydim,cdim,GridImp>& g);
295
// the element is fully defined by its midpoint the extension
296
// in each direction and the missing direction.
297
// Note cdim == mydim+1
299
FieldVector<ctype, cdim> midpoint; // the midpoint
300
FieldVector<ctype, cdim> extension; // the extension
301
uint8_t missing; // the missing, i.e. constant direction
303
// In addition we need memory in order to return references.
304
// Possibly we should change this in the interface ...
305
mutable FieldMatrix<ctype, mydim, cdim> JT; // the transposed of the jacobian
306
mutable FieldMatrix<ctype, cdim, mydim> Jinv; // the transposed of the jacobian inverse
307
mutable FieldMatrix<ctype, Power_m_p<2,mydim>::power, cdim> coord_; // the coordinates
313
//! specialize for dim=dimworld, i.e. a volume element
314
template<int mydim, class GridImp>
315
class YaspGeometry<mydim,mydim,GridImp> : public GeometryDefaultImplementation<mydim,mydim,GridImp,YaspGeometry>
318
typedef typename GridImp::ctype ctype;
320
//! return the element type identifier
321
GeometryType type () const
323
return GeometryType(GeometryType::cube,mydim);
326
//! here we have always an affine geometry
327
bool affine() const { return true; }
329
//! return the number of corners of this element. Corners are numbered 0...n-1
335
//! access to coordinates of corners. Index is the number of the corner
336
const FieldVector<ctype, mydim>& operator[] (int i) const
341
//! access to coordinates of corners. Index is the number of the corner
342
FieldVector< ctype, mydim > corner ( const int i ) const
344
assert( i >= 0 && i < (int) coord_.N() );
345
FieldVector<ctype, mydim>& c = coord_[i];
346
for (int k=0; k<mydim; k++)
348
c[k] = midpoint[k]+0.5*extension[k]; // kth bit is 1 in i
350
c[k] = midpoint[k]-0.5*extension[k]; // kth bit is 0 in i
354
//! access to the center/centroid
355
FieldVector< ctype, mydim > center ( ) const
360
//! maps a local coordinate within reference element to global coordinate in element
361
FieldVector<ctype, mydim> global (const FieldVector<ctype, mydim>& local) const
363
FieldVector<ctype,mydim> g;
364
for (int k=0; k<mydim; k++)
365
g[k] = midpoint[k] + (local[k]-0.5)*extension[k];
369
//! maps a global coordinate within the element to a local coordinate in its reference element
370
FieldVector<ctype, mydim> local (const FieldVector<ctype,mydim>& global) const
372
FieldVector<ctype, mydim> l; // result
373
for (int k=0; k<mydim; k++)
374
l[k] = (global[k]-midpoint[k])/extension[k] + 0.5;
378
/*! determinant of the jacobian of the mapping
380
ctype integrationElement (const FieldVector<ctype, mydim>& local) const
385
//! return volume of geometry
386
ctype volume () const
389
for (int k=0; k<mydim; k++) vol *= extension[k];
393
//! Compute the transposed of the jacobi matrix
394
FieldMatrix<ctype,mydim,mydim>& jacobianTransposed (const FieldVector<ctype, mydim>& local) const
396
for (int i=0; i<mydim; ++i)
398
JT[i] = 0.0; // set column to zero
399
JT[i][i] = extension[i]; // set diagonal element
403
//! Compute the transposed of the inverse jacobi matrix
404
FieldMatrix<ctype,mydim,mydim>& jacobianInverseTransposed (const FieldVector<ctype, mydim>& local) const
406
for (int i=0; i<mydim; ++i)
408
Jinv[i] = 0.0; // set column to zero
409
Jinv[i][i] = 1.0/extension[i]; // set diagonal element
414
//! default constructor
417
//! constructor from midpoint and extension
418
YaspGeometry (const FieldVector<ctype, mydim>& p, const FieldVector<ctype, mydim>& h)
419
: midpoint(p), extension(h)
422
//! copy constructor (skipping temporary variables)
423
YaspGeometry (const YaspGeometry& other)
424
: midpoint(other.midpoint),
425
extension(other.extension)
430
void print (std::ostream& s) const
432
s << "YaspGeometry<"<<mydim<<","<<mydim<< "> ";
434
for (int i=0; i<mydim; i++)
435
s << " " << midpoint[i];
437
for (int i=0; i<mydim; i++)
438
s << " " << extension[i];
441
// const YaspGeometry<mydim,mydim,GridImp>&
442
// operator = (const YaspGeometry<mydim,mydim,GridImp>& g);
445
// the element is fully defined by midpoint and the extension
446
// in each direction. References are used because this information
447
// is known outside the element in many cases.
450
FieldVector<ctype, mydim> midpoint; // the midpoint
451
FieldVector<ctype, mydim> extension; // the extension
453
// In addition we need memory in order to return references.
454
// Possibly we should change this in the interface ...
455
mutable FieldMatrix<ctype, mydim, mydim> Jinv,JT; // the transpose of the jacobian and its inverse inverse
456
mutable FieldMatrix<ctype, Power_m_p<2,mydim>::power, mydim> coord_; // the coordinates
459
//! specialization for dim=0, this is a vertex
460
template<int cdim, class GridImp>
461
class YaspGeometry<0,cdim,GridImp> : public GeometryDefaultImplementation<0,cdim,GridImp,YaspGeometry>
464
typedef typename GridImp::ctype ctype;
466
//! return the element type identifier
467
GeometryType type () const
469
return GeometryType(GeometryType::cube,0);
472
//! here we have always an affine geometry
473
bool affine() const { return true; }
475
//! return the number of corners of this element. Corners are numbered 0...n-1
481
//! access to coordinates of corners. Index is the number of the corner
482
const FieldVector<ctype, cdim>& operator[] (int i) const
487
//! access to coordinates of corners. Index is the number of the corner
488
FieldVector< ctype, cdim > corner ( const int i ) const
493
//! access to the center/centroid
494
FieldVector< ctype, cdim > center ( ) const
499
/*! determinant of the jacobian of the mapping
501
ctype integrationElement (const FieldVector<ctype, 0>& local) const
506
//! Compute the transposed of the jacobi matrix
507
FieldMatrix<ctype,0,cdim>& jacobianTransposed (const FieldVector<ctype, 0>& local) const
509
static FieldMatrix<ctype,0,cdim> JT(0.0);
512
//! Compute the transposed of the inverse jacobi matrix
513
FieldMatrix<ctype,cdim,0>& jacobianInverseTransposed (const FieldVector<ctype, 0>& local) const
515
static FieldMatrix<ctype,cdim,0> Jinv(0.0);
519
//! default constructor
524
explicit YaspGeometry ( const FieldVector< ctype, cdim > &p )
528
YaspGeometry ( const FieldVector< ctype, cdim > &p, const FieldVector< ctype, cdim > &, uint8_t &)
533
void print (std::ostream& s) const
535
s << "YaspGeometry<"<<0<<","<<cdim<< "> ";
536
s << "position " << position;
539
// const YaspGeometry<0,cdim,GridImp>&
540
// operator = (const YaspGeometry<0,cdim,GridImp>& g);
543
FieldVector<ctype, cdim> position; //!< position of the vertex
546
// operator<< for all YaspGeometrys
547
template <int mydim, int cdim, class GridImp>
549
std::ostream& operator<< (std::ostream& s, YaspGeometry<mydim,cdim,GridImp>& e)
555
//========================================================================
557
YaspEntity realizes the concept a mesh entity.
559
We have specializations for codim==0 (elements) and
560
codim=dim (vertices).
561
The general version throws a GridError.
563
//========================================================================
565
template<int codim, int dim, class GridImp>
566
class YaspSpecialEntity :
567
public GridImp::template Codim<codim>::Entity
570
typedef typename GridImp::ctype ctype;
572
typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
573
typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
575
YaspSpecialEntity(const GridImp* yg, const YGLI& g, const TSI& it) :
576
GridImp::template Codim<codim>::Entity (YaspEntity<codim, dim, GridImp>(yg,g,it))
578
YaspSpecialEntity(const YaspEntity<codim, dim, GridImp>& e) :
579
GridImp::template Codim<codim>::Entity (e)
581
const TSI& transformingsubiterator () const
583
return this->realEntity.transformingsubiterator();
585
const YGLI& gridlevel () const
587
return this->realEntity.gridlevel();
589
const GridImp * yaspgrid() const
591
return this->realEntity.yaspgrid();
595
template<int codim, int dim, class GridImp>
597
: public EntityDefaultImplementation <codim,dim,GridImp,YaspEntity>
600
typedef typename GridImp::ctype ctype;
602
typedef typename GridImp::template Codim<codim>::Geometry Geometry;
603
//! level of this element
606
DUNE_THROW(GridError, "YaspEntity not implemented");
609
//! index is unique and consecutive per level and codim used for access to degrees of freedom
612
DUNE_THROW(GridError, "YaspEntity not implemented");
615
//! geometry of this entity
616
Geometry geometry () const
618
DUNE_THROW(GridError, "YaspEntity not implemented");
621
//! return partition type attribute
622
PartitionType partitionType () const
624
DUNE_THROW(GridError, "YaspEntity not implemented");
627
const GridImp * yaspgrid() const
629
DUNE_THROW(GridError, "YaspEntity not implemented");
632
typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
633
typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
634
YaspEntity (const GridImp* yg, const YGLI& g, const TSI& it)
636
DUNE_THROW(GridError, "YaspEntity not implemented");
639
// IndexSets needs access to the private index methods
640
friend class Dune::YaspLevelIndexSet<GridImp>;
641
friend class Dune::YaspLeafIndexSet<GridImp>;
642
friend class Dune::YaspGlobalIdSet<GridImp>;
643
typedef typename GridImp::PersistentIndexType PersistentIndexType;
645
//! globally unique, persistent index
646
PersistentIndexType persistentIndex () const
648
DUNE_THROW(GridError, "YaspEntity not implemented");
651
//! consecutive, codim-wise, level-wise index
652
int compressedIndex () const
654
DUNE_THROW(GridError, "YaspEntity not implemented");
657
//! consecutive, codim-wise, level-wise index
658
int compressedLeafIndex () const
660
DUNE_THROW(GridError, "YaspEntity not implemented");
665
// specialization for codim=0
666
template<int dim, class GridImp>
667
class YaspEntity<0,dim,GridImp>
668
: public EntityDefaultImplementation <0,dim,GridImp,YaspEntity>
670
enum { dimworld = GridImp::dimensionworld };
672
typedef typename GridImp::Traits::template Codim< 0 >::GeometryImpl GeometryImpl;
675
typedef typename GridImp::ctype ctype;
677
typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
678
typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
680
typedef typename GridImp::template Codim< 0 >::Geometry Geometry;
681
typedef typename GridImp::template Codim< 0 >::LocalGeometry LocalGeometry;
686
typedef typename GridImp::template Codim<cd>::EntityPointer EntityPointer;
689
typedef typename GridImp::template Codim<0>::EntityPointer EntityPointer;
690
typedef typename GridImp::template Codim<0>::EntitySeed EntitySeed;
691
typedef typename GridImp::LevelIntersectionIterator IntersectionIterator;
692
typedef typename GridImp::LevelIntersectionIterator LevelIntersectionIterator;
693
typedef typename GridImp::LeafIntersectionIterator LeafIntersectionIterator;
694
typedef typename GridImp::HierarchicIterator HierarchicIterator;
696
//! define the type used for persisitent indices
697
typedef typename GridImp::PersistentIndexType PersistentIndexType;
699
//! define type used for coordinates in grid module
700
typedef typename YGrid<dim,ctype>::iTupel iTupel;
703
YaspEntity (const GridImp * yg, const YGLI& g, const TSI& it)
704
: _yg(yg), _it(it), _g(g)
708
//! level of this element
709
int level () const { return _g.level(); }
711
//! index is unique and consecutive per level
712
int index () const { return _it.superindex(); } // superindex works also for iteration over subgrids
714
//! globalIndex is unique and consecutive per global level
715
int globalIndex () const {
716
return _g.cell_global().index(_it.coord());
719
/** \brief Return the entity seed which contains sufficient information
720
* to generate the entity again and uses as less memory as possible
722
EntitySeed seed () const {
723
return EntitySeed(_g.level(), _it.coord());
726
//! return partition type attribute
727
PartitionType partitionType () const
729
if (_g.cell_interior().inside(_it.coord())) return InteriorEntity;
730
if (_g.cell_overlap().inside(_it.coord())) return OverlapEntity;
731
DUNE_THROW(GridError, "Impossible GhostEntity " << _it.coord() << "\t"
732
<< _g.cell_interior().origin() << "/" << _g.cell_interior().size());
736
//! geometry of this entity
737
Geometry geometry () const {
738
// the element geometry
739
GeometryImpl _geometry(_it.position(),_it.meshsize());
740
return Geometry( _geometry );
743
/*! Return number of subentities with codimension cc.
745
template<int cc> int count () const
747
if (cc==dim) return 1<<dim;
748
if (cc==1) return 2*dim;
749
if (cc==dim-1) return dim*(1<<(dim-1));
751
DUNE_THROW(GridError, "codim " << cc << " (dim=" << dim << ") not (yet) implemented");
754
/*! Intra-element access to subentities of codimension cc > codim.
757
typename Codim<cc>::EntityPointer subEntity (int i) const
759
dune_static_assert( cc == dim || cc == 0 ,
760
"YaspGrid only supports Entities with codim=dim and codim=0");
761
// coordinates of the cell == coordinates of lower left corner
764
iTupel coord = _it.coord();
766
// get corner from there
767
for (int k=0; k<dim; k++)
768
if (i&(1<<k)) (coord[k])++;
770
return YaspEntityPointer<cc,GridImp>(_yg,_g,_g.vertex_overlapfront().tsubbegin(coord));
774
return YaspEntityPointer<cc,GridImp>(_yg,_g,_it);
776
DUNE_THROW(GridError, "codim " << cc << " (dim=" << dim << ") not (yet) implemented");
779
//! Inter-level access to father element on coarser grid. Assumes that meshes are nested.
780
EntityPointer father () const
782
// check if coarse level exists
784
DUNE_THROW(GridError, "tried to call father on level 0");
786
// yes, get iterator to it
787
YGLI cg = _g.coarser();
789
// coordinates of the cell
790
iTupel coord = _it.coord();
792
// get coordinates on next coarser level
793
for (int k=0; k<dim; k++) coord[k] = coord[k]/2;
795
return YaspEntityPointer<0,GridImp>(_yg,cg,cg.cell_overlap().tsubbegin(coord));
798
//! returns true if father entity exists
799
bool hasFather () const
801
return (_g.level()>0);
804
/*! Location of this element relative to the reference element element of the father.
805
This is sufficient to interpolate all dofs in conforming case.
806
Nonconforming case may require access to neighbors of father and
807
computations with local coordinates.
808
On the fly case is somewhat inefficient since dofs are visited several times.
809
If we store interpolation matrices, this is tolerable. We assume that on-the-fly
810
implementation of numerical algorithms is only done for simple discretizations.
811
Assumes that meshes are nested.
813
LocalGeometry geometryInFather () const
815
// determine which son we are
817
for (int k=0; k<dim; k++)
821
// configure one of the 2^dim transformations
822
return LocalGeometry( YaspFatherRelativeLocalElement<dim,GridImp>::_geo[son] );
825
const TSI& transformingsubiterator () const
830
const YGLI& gridlevel () const
835
const GridImp* yaspgrid () const
842
return (_g.level() == _g.mg()->maxlevel());
845
/**\brief Returns true, if the entity has been created during the last call to adapt()
847
bool isNew () const { return _yg->adaptRefCount > 0 && _g.mg()->maxlevel() < _g.level() + _yg->adaptRefCount; }
849
/**\brief Returns true, if entity might disappear during the next call to adapt()
851
bool mightVanish () const { return false; }
852
// { return _yg->adaptRefCount < 0 && _g.mg()->maxlevel() < _g.level() - _yg->adaptRefCount; }
854
//! returns intersection iterator for first intersection
855
IntersectionIterator ibegin () const
857
return YaspIntersectionIterator<GridImp>(*this,false);
860
//! returns intersection iterator for first intersection
861
LeafIntersectionIterator ileafbegin () const
863
// only if entity is leaf this iterator delivers intersections
864
return YaspIntersectionIterator<GridImp>(*this, ! isLeaf() );
867
//! returns intersection iterator for first intersection
868
LevelIntersectionIterator ilevelbegin () const
873
//! Reference to one past the last neighbor
874
IntersectionIterator iend () const
876
return YaspIntersectionIterator<GridImp>(*this,true);
879
//! Reference to one past the last neighbor
880
LeafIntersectionIterator ileafend () const
885
//! Reference to one past the last neighbor
886
LevelIntersectionIterator ilevelend () const
891
/*! Inter-level access to son elements on higher levels<=maxlevel.
892
This is provided for sparsely stored nested unstructured meshes.
893
Returns iterator to first son.
895
HierarchicIterator hbegin (int maxlevel) const
897
return YaspHierarchicIterator<GridImp>(_yg,_g,_it,maxlevel);
900
//! Returns iterator to one past the last son
901
HierarchicIterator hend (int maxlevel) const
903
return YaspHierarchicIterator<GridImp>(_yg,_g,_it,_g.level());
907
// IndexSets needs access to the private index methods
908
friend class Dune::YaspLevelIndexSet<GridImp>;
909
friend class Dune::YaspLeafIndexSet<GridImp>;
910
friend class Dune::YaspGlobalIdSet<GridImp>;
912
//! globally unique, persistent index
913
PersistentIndexType persistentIndex () const
915
// get size of global grid
916
const iTupel& size = _g.cell_global().size();
918
// get coordinate correction for periodic boundaries
920
for (int i=0; i<dim; i++)
922
coord[i] = _it.coord(i);
923
if (coord[i]<0) coord[i] += size[i];
924
if (coord[i]>=size[i]) coord[i] -= size[i];
928
PersistentIndexType id(0);
931
id = id << yaspgrid_level_bits;
932
id = id+PersistentIndexType(_g.level());
935
// encode coordinates
936
for (int i=dim-1; i>=0; i--)
938
id = id << yaspgrid_dim_bits;
939
id = id+PersistentIndexType(coord[i]);
945
//! consecutive, codim-wise, level-wise index
946
int compressedIndex () const
948
return _it.superindex();
951
//! consecutive, codim-wise, level-wise index
952
int compressedLeafIndex () const
954
return _it.superindex();
957
//! subentity persistent index
958
PersistentIndexType subPersistentIndex (int i, int cc) const
961
return persistentIndex();
963
// get position of cell, note that global origin is zero
964
// adjust for periodic boundaries
966
for (int k=0; k<dim; k++)
968
coord[k] = _it.coord(k);
969
if (coord[k]<0) coord[k] += _g.cell_global().size(k);
970
if (coord[k]>=_g.cell_global().size(k)) coord[k] -= _g.cell_global().size(k);
975
// transform to vertex coordinates
976
for (int k=0; k<dim; k++)
977
if (i&(1<<k)) (coord[k])++;
979
// determine min number of trailing zeroes
981
for (int i=0; i<dim; i++)
983
// count trailing zeros
985
for (int j=0; j<_g.level(); j++)
990
trailing = std::min(trailing,zeros);
993
// determine the level of this vertex
994
int level = _g.level()-trailing;
997
PersistentIndexType id(dim);
1000
id = id << yaspgrid_level_bits;
1001
id = id+PersistentIndexType(level);
1003
// encode coordinates
1004
for (int i=dim-1; i>=0; i--)
1006
id = id << yaspgrid_dim_bits;
1007
id = id+PersistentIndexType(coord[i]>>trailing);
1013
if (cc==1) // faces, i.e. for dim=2 codim=1 is treated as a face
1015
// Idea: Use the doubled grid to assign coordinates to faces
1017
// ivar is the direction that varies
1020
// compute position from cell position
1021
for (int k=0; k<dim; k++)
1022
coord[k] = coord[k]*2 + 1; // the doubled grid
1029
PersistentIndexType id(1);
1032
id = id << yaspgrid_level_bits;
1033
id = id+PersistentIndexType(_g.level());
1035
// encode coordinates
1036
for (int i=dim-1; i>=0; i--)
1038
id = id << yaspgrid_dim_bits;
1039
id = id+PersistentIndexType(coord[i]);
1045
// map to old numbering
1046
static unsigned int edge[ 12 ] = { 0, 1, 2, 3, 4, 5, 8, 9, 6, 7, 10, 11 };
1049
if (cc==dim-1) // edges, exist only for dim>2
1051
// Idea: direction i is fixed, all others are vary, i.e. 2^(dim-1) possibilities per direction
1053
// number of entities per direction
1056
// ifix is the direction that is fixed
1057
int ifix=(dim-1)-(i/m);
1059
// compute position from cell position
1061
for (int k=0; k<dim; k++)
1063
coord[k] = coord[k]*2+1; // cell position in doubled grid
1064
if (k==ifix) continue;
1065
if ((i%m)&bit) coord[k] += 1; else coord[k] -= 1;
1070
PersistentIndexType id(dim-1);
1073
id = id << yaspgrid_level_bits;
1074
id = id+PersistentIndexType(_g.level());
1076
// encode coordinates
1077
for (int i=dim-1; i>=0; i--)
1079
id = id << yaspgrid_dim_bits;
1080
id = id+PersistentIndexType(coord[i]);
1086
DUNE_THROW(GridError, "codim " << cc << " (dim=" << dim << ") not (yet) implemented");
1089
//! subentity compressed index
1090
int subCompressedIndex (int i, int cc) const
1093
return compressedIndex();
1095
// get cell position relative to origin of local cell grid
1097
for (int k=0; k<dim; ++k)
1098
coord[k] = _it.coord(k)-_g.cell_overlap().origin(k);
1100
if (cc==dim) // vertices
1102
// transform cell coordinate to corner coordinate
1103
for (int k=0; k<dim; k++)
1104
if (i&(1<<k)) (coord[k])++;
1106
// do lexicographic numbering
1107
int index = coord[dim-1];
1108
for (int k=dim-2; k>=0; --k)
1109
index = (index*(_g.cell_overlap().size(k)+1))+coord[k];
1113
if (cc==1) // faces, i.e. for dim=2 codim=1 is treated as a face
1115
// Idea: direction ivar varies, all others are fixed, i.e. 2 possibilities per direction
1117
// ivar is the direction that varies
1120
// compute position from cell position
1121
if (i%2) coord[ivar] += 1;
1123
// do lexicographic numbering
1124
int index = coord[dim-1];
1125
for (int k=dim-2; k>=0; --k)
1127
index = (index*(_g.cell_overlap().size(k)+1))+coord[k]; // one more
1129
index = (index*(_g.cell_overlap().size(k)))+coord[k];
1131
// add size of all subsets for smaller directions
1132
for (int j=0; j<ivar; j++)
1134
int n=_g.cell_overlap().size(j)+1;
1135
for (int l=0; l<dim; l++)
1136
if (l!=j) n *= _g.cell_overlap().size(l);
1143
// map to old numbering
1144
static unsigned int edge[ 12 ] = { 0, 1, 2, 3, 4, 5, 8, 9, 6, 7, 10, 11 };
1147
if (cc==dim-1) // edges, exist only for dim>2
1149
// Idea: direction i is fixed, all others are vary, i.e. 2^(dim-1) possibilities per direction
1151
// number of entities per direction
1154
// ifix is the direction that is fixed
1155
int ifix=(dim-1)-(i/m);
1157
// compute position from cell position
1159
for (int k=0; k<dim; k++)
1161
if (k==ifix) continue;
1162
if ((i%m)&bit) coord[k] += 1;
1166
// do lexicographic numbering
1167
int index = coord[dim-1];
1168
for (int k=dim-2; k>=0; --k)
1170
index = (index*(_g.cell_overlap().size(k)+1))+coord[k]; // one more
1172
index = (index*(_g.cell_overlap().size(k)))+coord[k];
1174
// add size of all subsets for smaller directions
1175
for (int j=dim-1; j>ifix; j--)
1177
int n=_g.cell_overlap().size(j);
1178
for (int l=0; l<dim; l++)
1179
if (l!=j) n *= _g.cell_overlap().size(l)+1;
1186
DUNE_THROW(GridError, "codim " << cc << " (dim=" << dim << ") not (yet) implemented");
1189
//! subentity compressed index
1190
int subCompressedLeafIndex (int i, int cc) const
1193
return compressedIndex();
1195
// get cell position relative to origin of local cell grid
1197
for (int k=0; k<dim; ++k)
1198
coord[k] = _it.coord(k)-_g.cell_overlap().origin(k);
1200
if (cc==dim) // vertices
1202
// transform cell coordinate to corner coordinate
1203
for (int k=0; k<dim; k++)
1204
if (i&(1<<k)) (coord[k])++;
1206
// move coordinates up to maxlevel
1207
for (int k=0; k<dim; k++)
1208
coord[k] = coord[k]<<(_g.mg()->maxlevel()-_g.level());
1210
// do lexicographic numbering
1211
int index = coord[dim-1];
1212
for (int k=dim-2; k>=0; --k)
1213
index = (index*(_g.mg()->rbegin().cell_overlap().size(k)+1))+coord[k];
1217
if (cc==1) // faces, i.e. for dim=2 codim=1 is treated as a face
1219
// Idea: direction ivar varies, all others are fixed, i.e. 2 possibilities per direction
1221
// ivar is the direction that varies
1224
// compute position from cell position
1225
if (i%2) coord[ivar] += 1;
1227
// do lexicographic numbering
1228
int index = coord[dim-1];
1229
for (int k=dim-2; k>=0; --k)
1231
index = (index*(_g.cell_overlap().size(k)+1))+coord[k]; // one more
1233
index = (index*(_g.cell_overlap().size(k)))+coord[k];
1235
// add size of all subsets for smaller directions
1236
for (int j=0; j<ivar; j++)
1238
int n=_g.cell_overlap().size(j)+1;
1239
for (int l=0; l<dim; l++)
1240
if (l!=j) n *= _g.cell_overlap().size(l);
1247
// map to old numbering
1248
static unsigned int edge[ 12 ] = { 0, 1, 2, 3, 4, 5, 8, 9, 6, 7, 10, 11 };
1251
if (cc==dim-1) // edges, exist only for dim>2
1253
// Idea: direction i is fixed, all others are vary, i.e. 2^(dim-1) possibilities per direction
1255
// number of entities per direction
1258
// ifix is the direction that is fixed
1259
int ifix=(dim-1)-(i/m);
1261
// compute position from cell position
1263
for (int k=0; k<dim; k++)
1265
if (k==ifix) continue;
1266
if ((i%m)&bit) coord[k] += 1;
1270
// do lexicographic numbering
1271
int index = coord[dim-1];
1272
for (int k=dim-2; k>=0; --k)
1274
index = (index*(_g.cell_overlap().size(k)+1))+coord[k]; // one more
1276
index = (index*(_g.cell_overlap().size(k)))+coord[k];
1278
// add size of all subsets for smaller directions
1279
for (int j=dim-1; j>ifix; j--)
1281
int n=_g.cell_overlap().size(j);
1282
for (int l=0; l<dim; l++)
1283
if (l!=j) n *= _g.cell_overlap().size(l)+1;
1290
DUNE_THROW(GridError, "codim " << cc << " (dim=" << dim << ") not (yet) implemented");
1293
const GridImp * _yg; // access to YaspGrid
1294
const TSI& _it; // position in the grid level
1295
const YGLI& _g; // access to grid level
1299
// specialization for codim=dim (vertex)
1300
template<int dim, class GridImp>
1301
class YaspEntity<dim,dim,GridImp>
1302
: public EntityDefaultImplementation <dim,dim,GridImp,YaspEntity>
1304
enum { dimworld = GridImp::dimensionworld };
1306
typedef typename GridImp::Traits::template Codim<dim>::GeometryImpl GeometryImpl;
1309
typedef typename GridImp::ctype ctype;
1311
typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
1312
typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
1314
typedef typename GridImp::template Codim<dim>::Geometry Geometry;
1319
typedef typename GridImp::template Codim<cd>::EntityPointer EntityPointer;
1322
typedef typename GridImp::template Codim<dim>::EntityPointer EntityPointer;
1323
typedef typename GridImp::template Codim<dim>::EntitySeed EntitySeed;
1325
//! define the type used for persisitent indices
1326
typedef typename GridImp::PersistentIndexType PersistentIndexType;
1328
//! define type used for coordinates in grid module
1329
typedef typename YGrid<dim,ctype>::iTupel iTupel;
1332
YaspEntity (const GridImp* yg, const YGLI& g, const TSI& it)
1333
: _yg(yg), _it(it), _g(g)
1336
//! level of this element
1337
int level () const {return _g.level();}
1339
//! index is unique and consecutive per level
1340
int index () const {return _it.superindex();}
1342
//! globally unique, persistent index
1343
int globalIndex () const { return _g.cell_global().index(_it.coord()); }
1345
/** \brief Return the entity seed which contains sufficient information
1346
* to generate the entity again and uses as less memory as possible
1348
EntitySeed seed () const {
1349
return EntitySeed(_g.level(), _it.coord());
1352
//! geometry of this entity
1353
Geometry geometry () const {
1354
GeometryImpl _geometry(_it.position());
1355
return Geometry( _geometry );
1358
//! return partition type attribute
1359
PartitionType partitionType () const
1361
if (_g.vertex_interior().inside(_it.coord())) return InteriorEntity;
1362
if (_g.vertex_interiorborder().inside(_it.coord())) return BorderEntity;
1363
if (_g.vertex_overlap().inside(_it.coord())) return OverlapEntity;
1364
if (_g.vertex_overlapfront().inside(_it.coord())) return FrontEntity;
1369
// IndexSets needs access to the private index methods
1370
friend class Dune::YaspLevelIndexSet<GridImp>;
1371
friend class Dune::YaspLeafIndexSet<GridImp>;
1372
friend class Dune::YaspGlobalIdSet<GridImp>;
1374
//! globally unique, persistent index
1375
PersistentIndexType persistentIndex () const
1377
// get coordinate and size of global grid
1378
const iTupel& size = _g.vertex_global().size();
1381
// correction for periodic boundaries
1382
for (int i=0; i<dim; i++)
1384
coord[i] = _it.coord(i);
1385
if (coord[i]<0) coord[i] += size[i];
1386
if (coord[i]>=size[i]) coord[i] -= size[i];
1389
// determine min number of trailing zeroes
1390
int trailing = 1000;
1391
for (int i=0; i<dim; i++)
1393
// count trailing zeros
1395
for (int j=0; j<_g.level(); j++)
1396
if (coord[i]&(1<<j))
1400
trailing = std::min(trailing,zeros);
1403
// determine the level of this vertex
1404
int level = _g.level()-trailing;
1407
PersistentIndexType id(dim);
1410
id = id << yaspgrid_level_bits;
1411
id = id+PersistentIndexType(level);
1413
// encode coordinates
1414
for (int i=dim-1; i>=0; i--)
1416
id = id << yaspgrid_dim_bits;
1417
id = id+PersistentIndexType(coord[i]>>trailing);
1423
//! consecutive, codim-wise, level-wise index
1424
int compressedIndex () const { return _it.superindex();}
1426
//! consecutive, codim-wise, level-wise index
1427
int compressedLeafIndex () const
1429
if (_g.level()==_g.mg()->maxlevel())
1430
return _it.superindex();
1432
// not on leaf level, interpolate to finest grid
1434
for (int i=0; i<dim; i++) coord[i] = _it.coord(i)-(_g).vertex_overlap().origin(i);
1436
// move coordinates up to maxlevel (multiply by 2 for each level
1437
for (int k=0; k<dim; k++)
1438
coord[k] = coord[k]*(1<<(_g.mg()->maxlevel()-_g.level()));
1440
// do lexicographic numbering
1441
int index = coord[dim-1];
1442
for (int k=dim-2; k>=0; --k)
1443
index = (index*(_g.mg()->rbegin().cell_overlap().size(k)+1))+coord[k];
1448
const TSI& transformingsubiterator() const { return _it; }
1449
const YGLI& gridlevel() const { return _g; }
1450
const GridImp * yaspgrid() const { return _yg; }
1452
const GridImp * _yg; // access to YaspGrid
1453
const TSI& _it; // position in the grid level
1454
const YGLI& _g; // access to grid level
1456
mutable FieldVector<ctype, dim> loc; // always computed before being returned
1459
//========================================================================
1461
YaspIntersection provides data about intersection with
1462
neighboring codim 0 entities.
1464
//========================================================================
1466
template<class GridImp>
1467
class YaspIntersection
1469
enum { dim=GridImp::dimension };
1470
enum { dimworld=GridImp::dimensionworld };
1471
typedef typename GridImp::ctype ctype;
1473
YaspIntersection& operator = (const YaspIntersection&);
1475
typedef typename GridImp::Traits::template Codim< 1 >::GeometryImpl GeometryImpl;
1476
typedef typename GridImp::Traits::template Codim< 1 >::LocalGeometryImpl LocalGeometryImpl;
1479
// types used from grids
1480
typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
1481
typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
1482
typedef typename GridImp::template Codim<0>::Entity Entity;
1483
typedef typename GridImp::template Codim<0>::EntityPointer EntityPointer;
1484
typedef typename GridImp::template Codim<1>::Geometry Geometry;
1485
typedef typename GridImp::template Codim<1>::LocalGeometry LocalGeometry;
1486
typedef YaspSpecialEntity<0,dim,GridImp> SpecialEntity;
1487
typedef Dune::Intersection<const GridImp, Dune::YaspIntersectionIterator> Intersection;
1489
// void update() const {
1490
// const_cast<YaspIntersection*>(this)->update();
1492
void update() const {
1493
if (_count == 2*_dir + _face || _count >= 2*dim)
1496
// cleanup old stuff
1497
_outside.transformingsubiterator().move(_dir,1-2*_face); // move home
1498
_pos_world[_dir] = _inside.transformingsubiterator().position(_dir);
1504
// move transforming iterator
1505
_outside.transformingsubiterator().move(_dir,-1+2*_face);
1508
_pos_world[_dir] += (-0.5+_face)*_inside.transformingsubiterator().meshsize(_dir);
1513
_count += (_count < 2*dim);
1517
bool equals (const YaspIntersection& other) const
1519
return _inside.equals(other._inside) && _count == other._count;
1522
/*! return true if neighbor ist outside the domain. Still the neighbor might
1523
exist in case of periodic boundary conditions, i.e. true is returned
1524
if the neighbor is outside the periodic unit cell
1526
bool boundary () const
1529
return (_inside.transformingsubiterator().coord(_count/2) + 2*(_count%2) - 1 < _inside.gridlevel().cell_global().min(_count/2)
1531
_inside.transformingsubiterator().coord(_count/2) + 2*(_count%2) - 1 > _inside.gridlevel().cell_global().max(_count/2));
1534
// The transforming iterator can be safely moved beyond the boundary.
1535
// So we only have to compare against the cell_global grid
1536
return (_outside.transformingsubiterator().coord(_dir) < _inside.gridlevel().cell_global().min(_dir)
1538
_outside.transformingsubiterator().coord(_dir) > _inside.gridlevel().cell_global().max(_dir));
1542
//! return true if neighbor across intersection exists in this processor
1543
bool neighbor () const
1546
return (_inside.transformingsubiterator().coord(_count/2) + 2*(_count%2) - 1 >= _inside.gridlevel().cell_overlap().min(_count/2)
1548
_inside.transformingsubiterator().coord(_count/2) + 2*(_count%2) - 1 <= _inside.gridlevel().cell_overlap().max(_count/2));
1551
return (_outside.transformingsubiterator().coord(_dir) >= _inside.gridlevel().cell_overlap().min(_dir)
1553
_outside.transformingsubiterator().coord(_dir) <= _inside.gridlevel().cell_overlap().max(_dir));
1557
//! Yasp is always conform
1558
bool conforming () const
1563
//! return EntityPointer to the Entity on the inside of this intersection
1564
//! (that is the Entity where we started this Iterator)
1565
EntityPointer inside() const
1570
//! return EntityPointer to the Entity on the outside of this intersection
1571
//! (that is the neighboring Entity)
1572
EntityPointer outside() const
1578
//! identifier for boundary segment from macro grid
1579
//! (attach your boundary condition as needed)
1580
int boundaryId() const
1582
if(boundary()) return indexInInside()+1;
1586
//! identifier for boundary segment from macro grid
1587
//! (attach your boundary condition as needed)
1588
int boundarySegmentIndex() const
1591
DUNE_THROW(GridError, "called boundarySegmentIndex while boundary() == false");
1593
// size of local macro grid
1594
const FieldVector<int, dim> & size = _inside.gridlevel().mg()->begin().cell_overlap().size();
1595
const FieldVector<int, dim> & origin = _inside.gridlevel().mg()->begin().cell_overlap().origin();
1596
FieldVector<int, dim> sides;
1598
for (int i=0; i<dim; i++)
1601
((_inside.gridlevel().mg()->begin().cell_overlap().origin(i)
1602
== _inside.gridlevel().mg()->begin().cell_global().origin(i))+
1603
(_inside.gridlevel().mg()->begin().cell_overlap().origin(i) +
1604
_inside.gridlevel().mg()->begin().cell_overlap().size(i)
1605
== _inside.gridlevel().mg()->begin().cell_global().origin(i) +
1606
_inside.gridlevel().mg()->begin().cell_global().size(i)));
1609
// gobal position of the cell on macro grid
1610
FieldVector<int, dim> pos = _inside.transformingsubiterator().coord();
1611
pos /= (1<<_inside.level());
1613
// compute unit-cube-face-sizes
1614
FieldVector<int, dim> fsize;
1617
for (int k=0; k<dim; k++)
1619
for (int k=0; k<dim; k++)
1620
fsize[k] = vol/size[k];
1622
// compute index in the unit-cube-face
1625
int localoffset = 1;
1626
for (int k=dim-1; k>=0; k--)
1628
if (k == _dir) continue;
1629
index += (pos[k]) * localoffset;
1630
localoffset *= size[k];
1633
// add unit-cube-face-offsets
1635
for (int k=0; k<_dir; k++)
1636
index += sides[k] * fsize[k];
1637
// add fsize if we are on the right face and there is a left-face-boundary on this processor
1638
index += _face * (sides[_dir]>1) * fsize[_dir];
1642
// MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1643
// std::cout << rank << "... size: " << size << " sides: " << sides
1644
// << " fsize: " << fsize
1645
// << " pos: " << pos << " face: " << int(_dir) << "/" << int(_face)
1646
// << " index: " << index << std::endl;
1651
//! return unit outer normal, this should be dependent on local coordinates for higher order boundary
1652
FieldVector<ctype, dimworld> outerNormal (const FieldVector<ctype, dim-1>& local) const
1654
return _faceInfo[_count].normal;
1657
//! return unit outer normal, this should be dependent on local coordinates for higher order boundary
1658
FieldVector<ctype, dimworld> unitOuterNormal (const FieldVector<ctype, dim-1>& local) const
1660
return _faceInfo[_count].normal;
1663
//! return unit outer normal at center of intersection geometry
1664
FieldVector<ctype, dimworld> centerUnitOuterNormal () const
1666
return _faceInfo[_count].normal;
1669
//! return unit outer normal, this should be dependent on
1670
//! local coordinates for higher order boundary
1671
//! the normal is scaled with the integration element of the intersection.
1672
FieldVector<ctype, dimworld> integrationOuterNormal (const FieldVector<ctype, dim-1>& local) const
1674
FieldVector<ctype, dimworld> n = _faceInfo[_count].normal;
1675
n *= geometry().volume();
1679
/*! intersection of codimension 1 of this neighbor with element where iteration started.
1680
Here returned element is in LOCAL coordinates of the element where iteration started.
1682
LocalGeometry geometryInInside () const
1684
return LocalGeometry( _faceInfo[_count].geom_inside );
1687
/*! intersection of codimension 1 of this neighbor with element where iteration started.
1688
Here returned element is in LOCAL coordinates of neighbor
1690
LocalGeometry geometryInOutside () const
1692
return LocalGeometry( _faceInfo[_count].geom_outside );
1695
/*! intersection of codimension 1 of this neighbor with element where iteration started.
1697
Geometry geometry () const
1701
_is_global(_pos_world,_inside.transformingsubiterator().meshsize(),_dir);
1702
return Geometry( _is_global );
1705
/** \brief obtain the type of reference element for this intersection */
1706
GeometryType type () const
1708
static const GeometryType cube(GeometryType::cube, dim-1);
1712
//! local index of codim 1 entity in self where intersection is contained in
1713
int indexInInside () const
1718
//! local index of codim 1 entity in neighbor where intersection is contained in
1719
int indexInOutside () const
1721
// flip the last bit
1725
//! make intersection iterator from entity, initialize to first neighbor
1726
YaspIntersection (const YaspEntity<0,dim,GridImp>& myself, bool toend) :
1727
_inside(myself.yaspgrid(), myself.gridlevel(),
1728
myself.transformingsubiterator()),
1729
_outside(myself.yaspgrid(), myself.gridlevel(),
1730
myself.transformingsubiterator()),
1731
// initialize to first neighbor
1735
_pos_world(myself.transformingsubiterator().position())
1739
// initialize end iterator
1745
// move transforming iterator
1746
_outside.transformingsubiterator().move(_dir,-1);
1749
_pos_world[0] -= 0.5*_inside.transformingsubiterator().meshsize(0);
1752
//! copy constructor
1753
YaspIntersection (const YaspIntersection& it) :
1754
_inside(it._inside),
1755
_outside(it._outside),
1759
_pos_world(it._pos_world)
1763
void assign (const YaspIntersection& it)
1765
_inside = it._inside;
1766
_outside = it._outside;
1770
_pos_world = it._pos_world;
1774
/* EntityPointers (get automatically updated) */
1775
mutable YaspEntityPointer<0,GridImp> _inside; //!< entitypointer to myself
1776
mutable YaspEntityPointer<0,GridImp> _outside; //!< outside entitypointer
1777
/* current position */
1778
uint8_t _count; //!< valid neighbor count in 0 .. 2*dim-1
1779
mutable uint8_t _dir; //!< count/2
1780
mutable uint8_t _face; //!< count%2
1781
/* current position */
1782
mutable FieldVector<ctype, dimworld> _pos_world; //!< center of face in world coordinates
1787
FieldVector<ctype, dimworld> normal;
1788
LocalGeometryImpl geom_inside; //!< intersection in own local coordinates
1789
LocalGeometryImpl geom_outside; //!< intersection in neighbors local coordinates
1792
/* static face info */
1793
static const array<faceInfo, 2*GridImp::dimension> _faceInfo;
1795
static array<faceInfo, 2*dim> initFaceInfo()
1797
const FieldVector<typename GridImp::ctype, GridImp::dimension> ext_local(1.0);
1798
array<faceInfo, 2*dim> I;
1799
for (uint8_t i=0; i<dim; i++)
1802
FieldVector<ctype, dim> a(0.5); a[i] = 0.0;
1803
FieldVector<ctype, dim> b(0.5); b[i] = 1.0;
1805
I[2*i].normal = 0.0;
1806
I[2*i+1].normal = 0.0;
1807
I[2*i].normal[i] = -1.0;
1808
I[2*i+1].normal[i] = +1.0;
1810
I[2*i].geom_inside =
1811
LocalGeometryImpl(a, ext_local, i);
1812
I[2*i].geom_outside =
1813
LocalGeometryImpl(b, ext_local, i);
1814
I[2*i+1].geom_inside =
1815
LocalGeometryImpl(b, ext_local, i);
1816
I[2*i+1].geom_outside =
1817
LocalGeometryImpl(a, ext_local, i);
1823
template<class GridImp>
1824
const array<typename YaspIntersection<GridImp>::faceInfo, 2*GridImp::dimension>
1825
YaspIntersection<GridImp>::_faceInfo =
1826
YaspIntersection<GridImp>::initFaceInfo();
1828
//========================================================================
1830
YaspIntersectionIterator enables iteration over intersection with
1831
neighboring codim 0 entities.
1833
//========================================================================
1835
template<class GridImp>
1836
class YaspIntersectionIterator : public MakeableInterfaceObject< Dune::Intersection<const GridImp, Dune::YaspIntersection > >
1838
enum { dim=GridImp::dimension };
1839
enum { dimworld=GridImp::dimensionworld };
1840
typedef typename GridImp::ctype ctype;
1841
YaspIntersectionIterator();
1843
// types used from grids
1844
typedef Dune::Intersection<const GridImp, Dune::YaspIntersection> Intersection;
1845
typedef MakeableInterfaceObject<Intersection> MakeableIntersection;
1850
GridImp::getRealImplementation(*this).increment();
1854
bool equals (const YaspIntersectionIterator& other) const
1856
return GridImp::getRealImplementation(*this).equals(
1857
GridImp::getRealImplementation(other));
1860
//! \brief dereferencing
1861
const Intersection & dereference() const
1866
//! make intersection iterator from entity
1867
YaspIntersectionIterator (const YaspEntity<0,dim,GridImp>& myself, bool toend) :
1868
MakeableIntersection(YaspIntersection<GridImp>(myself, toend))
1871
//! copy constructor
1872
YaspIntersectionIterator (const YaspIntersectionIterator& it) :
1873
MakeableIntersection(it)
1877
YaspIntersectionIterator & operator = (const YaspIntersectionIterator& it)
1879
GridImp::getRealImplementation(*this).assign(
1880
GridImp::getRealImplementation(it));
1885
//========================================================================
1887
YaspHierarchicIterator enables iteration over son entities of codim 0
1889
//========================================================================
1891
template<class GridImp>
1892
class YaspHierarchicIterator :
1893
public YaspEntityPointer<0,GridImp>
1895
enum { dim=GridImp::dimension };
1896
enum { dimworld=GridImp::dimensionworld };
1897
typedef typename GridImp::ctype ctype;
1899
// types used from grids
1900
typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
1901
typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
1902
typedef typename GridImp::template Codim<0>::Entity Entity;
1903
typedef YaspSpecialEntity<0,dim,GridImp> SpecialEntity;
1905
//! define type used for coordinates in grid module
1906
typedef typename YGrid<dim,ctype>::iTupel iTupel;
1909
YaspHierarchicIterator (const GridImp* yg, const YGLI& g, const TSI& it, int maxlevel) :
1910
YaspEntityPointer<0,GridImp>(yg,g,it)
1912
// now iterator points to current cell
1913
StackElem se(this->_g);
1914
se.coord = this->_it.coord();
1917
// determine maximum level
1918
_maxlevel = std::min(maxlevel,this->_g.mg()->maxlevel());
1920
// if maxlevel not reached then push yourself and sons
1921
if (this->_g.level()<_maxlevel)
1926
// and make iterator point to first son if stack is not empty
1932
YaspHierarchicIterator (const YaspHierarchicIterator& it) :
1933
YaspEntityPointer<0,GridImp>(it),
1934
_maxlevel(it._maxlevel), stack(it.stack)
1940
// sanity check: do nothing when stack is empty
1941
if (stack.empty()) return;
1943
// if maxlevel not reached then push sons
1944
if (this->_g.level()<_maxlevel)
1947
// in any case pop one element
1951
void print (std::ostream& s) const
1953
s << "HIER: " << "level=" << this->_g.level()
1954
<< " position=" << this->_it.coord()
1955
<< " superindex=" << this->_it.superindex()
1956
<< " maxlevel=" << this->_maxlevel
1957
<< " stacksize=" << stack.size()
1962
int _maxlevel; //!< maximum level of elements to be processed
1965
YGLI g; // grid level of the element
1966
iTupel coord; // and the coordinates
1967
StackElem(YGLI gg) : g(gg) {}
1969
std::stack<StackElem> stack; //!< stack holding elements to be processed
1971
// push sons of current element on the stack
1974
// yes, process all 1<<dim sons
1975
StackElem se(this->_g.finer());
1976
for (int i=0; i<(1<<dim); i++)
1978
for (int k=0; k<dim; k++)
1980
se.coord[k] = this->_it.coord(k)*2+1;
1982
se.coord[k] = this->_it.coord(k)*2;
1987
// make TOS the current element
1990
StackElem se = stack.top();
1993
this->_it.reinit(this->_g.cell_overlap(),se.coord);
1997
//========================================================================
1999
YaspEntitySeed describes the minimal information necessary to create a fully functional YaspEntity
2001
//========================================================================
2002
template<int codim, class GridImp>
2003
class YaspEntitySeed
2005
//! know your own dimension
2006
enum { dim=GridImp::dimension };
2009
//! codimension of entity pointer
2010
enum { codimension = codim };
2013
YaspEntitySeed (int level, FieldVector<int, dim> coord)
2014
: _l(level), _c(coord)
2017
//! copy constructor
2018
YaspEntitySeed (const YaspEntitySeed& rhs)
2019
: _l(rhs._l), _c(rhs._c)
2022
int level () const { return _l; }
2023
const FieldVector<int, dim> & coord() const { return _c; }
2026
int _l; // grid level
2027
FieldVector<int, dim> _c; // coord in the global grid
2030
//========================================================================
2032
YaspEntityPointer serves as a Reference or Pointer to a YaspGrid::Entity.
2033
It can also be initialized from Yasp::LevelIterator, Yasp::LeafIterator,
2034
Yasp::HierarchicIterator and Yasp::IntersectionIterator.
2036
We have specializations for codim==0 (elements) and
2037
codim=dim (vertices).
2038
The general version throws a GridError.
2040
//========================================================================
2041
template<int codim, class GridImp>
2042
class YaspEntityPointer
2044
//! know your own dimension
2045
enum { dim=GridImp::dimension };
2046
//! know your own dimension of world
2047
enum { dimworld=GridImp::dimensionworld };
2048
typedef typename GridImp::ctype ctype;
2050
typedef typename GridImp::template Codim<codim>::Entity Entity;
2051
typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
2052
typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
2053
typedef YaspSpecialEntity<codim,dim,GridImp> SpecialEntity;
2054
typedef YaspEntityPointer<codim,GridImp> EntityPointerImp;
2056
typedef YaspEntity<codim, dim, GridImp> YaspEntityImp;
2059
//! codimension of entity pointer
2060
enum { codimension = codim };
2063
YaspEntityPointer (const GridImp * yg, const YGLI & g, const TSI & it)
2064
: _g(g), _it(it), _entity(yg, _g,_it)
2066
if (codim>0 && codim<dim)
2068
DUNE_THROW(GridError, "YaspEntityPointer: codim not implemented");
2072
//! copy constructor
2073
YaspEntityPointer (const YaspEntityImp& entity)
2074
: _g(entity.gridlevel()),
2075
_it(entity.transformingsubiterator()),
2076
_entity(entity.yaspgrid(),_g,_it)
2078
if (codim>0 && codim<dim)
2080
DUNE_THROW(GridError, "YaspEntityPointer: codim not implemented");
2084
//! copy constructor
2085
YaspEntityPointer (const YaspEntityPointer& rhs)
2086
: _g(rhs._g), _it(rhs._it), _entity(rhs._entity.yaspgrid(),_g,_it)
2088
if (codim>0 && codim<dim)
2090
DUNE_THROW(GridError, "YaspEntityPointer: codim not implemented");
2095
bool equals (const YaspEntityPointer& rhs) const
2097
return (_it==rhs._it && _g == rhs._g);
2101
Entity& dereference() const
2106
//! ask for level of entity
2107
int level () const {return _g.level();}
2109
const YaspEntityPointer&
2110
operator = (const YaspEntityPointer& rhs)
2114
/* _entity = i._entity
2115
* is done implicitely, as the entity is completely
2116
* defined via the interator it belongs to
2121
const TSI& transformingsubiterator () const
2126
const YGLI& gridlevel () const
2131
TSI& transformingsubiterator ()
2142
YGLI _g; // access to grid level
2143
TSI _it; // position in the grid level
2144
mutable SpecialEntity _entity; //!< virtual entity
2147
//========================================================================
2149
YaspLevelIterator enables iteration over entities of one grid level
2151
We have specializations for codim==0 (elements) and
2152
codim=dim (vertices).
2153
The general version throws a GridError.
2155
//========================================================================
2157
template<int codim, PartitionIteratorType pitype, class GridImp>
2158
class YaspLevelIterator :
2159
public YaspEntityPointer<codim,GridImp>
2161
//! know your own dimension
2162
enum { dim=GridImp::dimension };
2163
//! know your own dimension of world
2164
enum { dimworld=GridImp::dimensionworld };
2165
typedef typename GridImp::ctype ctype;
2167
typedef typename GridImp::template Codim<codim>::Entity Entity;
2168
typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
2169
typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
2170
typedef YaspSpecialEntity<codim,dim,GridImp> SpecialEntity;
2173
YaspLevelIterator (const GridImp * yg, const YGLI & g, const TSI & it) :
2174
YaspEntityPointer<codim,GridImp>(yg,g,it) {}
2176
//! copy constructor
2177
YaspLevelIterator (const YaspLevelIterator& i) :
2178
YaspEntityPointer<codim,GridImp>(i) {}
2188
//========================================================================
2190
\brief level-wise, non-persistent, consecutive index
2193
//========================================================================
2195
template<class GridImp>
2196
class YaspLevelIndexSet
2197
: public IndexSet< GridImp, YaspLevelIndexSet< GridImp >, unsigned int >
2199
typedef YaspLevelIndexSet< GridImp > This;
2200
typedef IndexSet< GridImp, This, unsigned int > Base;
2203
typedef typename Base::IndexType IndexType;
2205
using Base::subIndex;
2207
//! constructor stores reference to a grid and level
2208
YaspLevelIndexSet ( const GridImp &g, int l )
2212
// contains a single element type;
2213
for (int codim=0; codim<=GridImp::dimension; codim++)
2214
mytypes[codim].push_back(GeometryType(GeometryType::cube,GridImp::dimension-codim));
2217
//! get index of an entity
2219
IndexType index (const typename GridImp::Traits::template Codim<cc>::Entity& e) const
2221
assert( cc == 0 || cc == GridImp::dimension );
2222
return grid.getRealImplementation(e).compressedIndex();
2225
//! get index of subentity of an entity
2227
IndexType subIndex ( const typename remove_const< GridImp >::type::Traits::template Codim< cc >::Entity &e,
2228
int i, unsigned int codim ) const
2230
assert( cc == 0 || cc == GridImp::dimension );
2231
if( cc == GridImp::dimension )
2232
return grid.getRealImplementation(e).compressedIndex();
2234
return grid.getRealImplementation(e).subCompressedIndex(i,codim);
2237
//! get number of entities of given type and level (the level is known to the object)
2238
int size (GeometryType type) const
2240
return grid.size( level, type );
2243
//! return size of set for a given codim
2244
int size (int codim) const
2246
return grid.size( level, codim );
2249
//! return true if the given entity is contained in \f$E\f$.
2250
template<class EntityType>
2251
bool contains (const EntityType& e) const
2253
return e.level() == level;
2256
//! deliver all geometry types used in this grid
2257
const std::vector<GeometryType>& geomTypes (int codim) const
2259
return mytypes[codim];
2263
const GridImp& grid;
2265
std::vector<GeometryType> mytypes[GridImp::dimension+1];
2271
template<class GridImp>
2272
class YaspLeafIndexSet
2273
: public IndexSet< GridImp, YaspLeafIndexSet< GridImp >, unsigned int >
2275
typedef YaspLeafIndexSet< GridImp > This;
2276
typedef IndexSet< GridImp, This, unsigned int > Base;
2279
typedef typename Base::IndexType IndexType;
2281
using Base::subIndex;
2283
//! constructor stores reference to a grid
2284
explicit YaspLeafIndexSet ( const GridImp &g )
2287
// contains a single element type;
2288
for (int codim=0; codim<=GridImp::dimension; codim++)
2289
mytypes[codim].push_back(GeometryType(GeometryType::cube,GridImp::dimension-codim));
2292
//! get index of an entity
2294
IndexType index (const typename GridImp::Traits::template Codim<cc>::Entity& e) const
2296
assert( cc == 0 || cc == GridImp::dimension );
2297
return grid.getRealImplementation(e).compressedIndex();
2300
//! get index of subentity of an entity
2302
IndexType subIndex ( const typename remove_const< GridImp >::type::Traits::template Codim< cc >::Entity &e,
2303
int i, unsigned int codim ) const
2305
assert( cc == 0 || cc == GridImp::dimension );
2306
if( cc == GridImp::dimension )
2307
return grid.getRealImplementation(e).compressedIndex();
2309
return grid.getRealImplementation(e).subCompressedIndex(i,codim);
2312
//! get number of entities of given type
2313
int size (GeometryType type) const
2315
return grid.size( grid.maxLevel(), type );
2318
//! return size of set for a given codim
2319
int size (int codim) const
2321
return grid.size( grid.maxLevel(), codim );
2324
//! return true if the given entity is contained in \f$E\f$.
2325
template<class EntityType>
2326
bool contains (const EntityType& e) const
2328
//return e.isLeaf();
2329
return (e.level() == grid.maxLevel());
2332
//! deliver all geometry types used in this grid
2333
const std::vector<GeometryType>& geomTypes (int codim) const
2335
return mytypes[codim];
2339
const GridImp& grid;
2340
enum { ncodim = remove_const<GridImp>::type::dimension+1 };
2341
std::vector<GeometryType> mytypes[ncodim];
2347
//========================================================================
2349
\brief persistent, globally unique Ids
2352
//========================================================================
2354
template<class GridImp>
2355
class YaspGlobalIdSet : public IdSet<GridImp,YaspGlobalIdSet<GridImp>,
2356
typename remove_const<GridImp>::type::PersistentIndexType >
2358
We used the remove_const to extract the Type from the mutable class,
2359
because the const class is not instantiated yet.
2362
typedef YaspGlobalIdSet< GridImp > This;
2365
//! define the type used for persisitent indices
2366
typedef typename remove_const<GridImp>::type::PersistentIndexType IdType;
2368
using IdSet<GridImp, This, IdType>::subId;
2370
//! constructor stores reference to a grid
2371
explicit YaspGlobalIdSet ( const GridImp &g )
2375
//! get id of an entity
2377
We use the remove_const to extract the Type from the mutable class,
2378
because the const class is not instantiated yet.
2381
IdType id (const typename remove_const<GridImp>::type::Traits::template Codim<cd>::Entity& e) const
2383
return grid.getRealImplementation(e).persistentIndex();
2386
//! get id of subentity
2388
We use the remove_const to extract the Type from the mutable class,
2389
because the const class is not instantiated yet.
2391
IdType subId (const typename remove_const<GridImp>::type::Traits::template Codim< 0 >::Entity &e,
2392
int i, unsigned int codim ) const
2394
return grid.getRealImplementation(e).subPersistentIndex(i,codim);
2398
const GridImp& grid;
2402
template<int dim, int dimworld>
2403
struct YaspGridFamily
38
YaspGrid stands for yet another structured parallel grid.
39
It will implement the dune grid interface for structured grids with codim 0
40
and dim, with arbitrary overlap, parallel features with two overlap
41
models, periodic boundaries and fast a implementation allowing on-the-fly computations.
46
//************************************************************************
47
/*! define name for floating point type used for coordinates in yaspgrid.
48
You can change the type for coordinates by changing this single typedef.
50
typedef double yaspgrid_ctype;
52
/* some sizes for building global ids
54
const int yaspgrid_dim_bits = 24; // bits for encoding each dimension
55
const int yaspgrid_level_bits = 6; // bits for encoding level number
56
const int yaspgrid_codim_bits = 4; // bits for encoding codimension
59
//************************************************************************
60
// forward declaration of templates
62
template<int dim> class YaspGrid;
63
template<int mydim, int cdim, class GridImp> class YaspGeometry;
64
template<int codim, int dim, class GridImp> class YaspEntity;
65
template<int codim, class GridImp> class YaspEntityPointer;
66
template<int codim, class GridImp> class YaspEntitySeed;
67
template<int codim, PartitionIteratorType pitype, class GridImp> class YaspLevelIterator;
68
template<class GridImp> class YaspIntersectionIterator;
69
template<class GridImp> class YaspIntersection;
70
template<class GridImp> class YaspHierarchicIterator;
71
template<class GridImp, bool isLeafIndexSet> class YaspIndexSet;
72
template<class GridImp> class YaspGlobalIdSet;
74
namespace FacadeOptions
77
template<int dim, int mydim, int cdim>
78
struct StoreGeometryReference<mydim, cdim, YaspGrid<dim>, YaspGeometry>
80
static const bool v = false;
83
template<int dim, int mydim, int cdim>
84
struct StoreGeometryReference<mydim, cdim, const YaspGrid<dim>, YaspGeometry>
86
static const bool v = false;
93
#include <dune/grid/yaspgrid/yaspgridgeometry.hh>
94
#include <dune/grid/yaspgrid/yaspgridentity.hh>
95
#include <dune/grid/yaspgrid/yaspgridintersection.hh>
96
#include <dune/grid/yaspgrid/yaspgridintersectioniterator.hh>
97
#include <dune/grid/yaspgrid/yaspgridhierarchiciterator.hh>
98
#include <dune/grid/yaspgrid/yaspgridentityseed.hh>
99
#include <dune/grid/yaspgrid/yaspgridentitypointer.hh>
100
#include <dune/grid/yaspgrid/yaspgridleveliterator.hh>
101
#include <dune/grid/yaspgrid/yaspgridindexsets.hh>
102
#include <dune/grid/yaspgrid/yaspgrididset.hh>
107
struct YaspGridFamily
2406
typedef CollectiveCommunication<MPI_Comm> CCType;
110
typedef CollectiveCommunication<MPI_Comm> CCType;
2408
typedef CollectiveCommunication<Dune::YaspGrid<dim> > CCType;
112
typedef CollectiveCommunication<Dune::YaspGrid<dim> > CCType;
2411
typedef GridTraits<dim,dimworld,Dune::YaspGrid<dim>,
2412
YaspGeometry,YaspEntity,
2413
YaspEntityPointer,YaspLevelIterator,
2414
YaspIntersection, // leaf intersection
2415
YaspIntersection, // level intersection
2416
YaspIntersectionIterator, // leaf intersection iter
2417
YaspIntersectionIterator, // level intersection iter
2418
YaspHierarchicIterator,
2420
YaspLevelIndexSet< const YaspGrid< dim > >,
2421
YaspLeafIndexSet< const YaspGrid< dim > >,
2422
YaspGlobalIdSet<const YaspGrid<dim> >,
2423
bigunsignedint<dim*yaspgrid_dim_bits+yaspgrid_level_bits+yaspgrid_codim_bits>,
2424
YaspGlobalIdSet<const YaspGrid<dim> >,
2425
bigunsignedint<dim*yaspgrid_dim_bits+yaspgrid_level_bits+yaspgrid_codim_bits>,
2427
DefaultLevelGridViewTraits, DefaultLeafGridViewTraits,
115
typedef GridTraits<dim, // dimension of the grid
116
dim, // dimension of the world space
118
YaspGeometry,YaspEntity,
120
YaspLevelIterator, // type used for the level iterator
121
YaspIntersection, // leaf intersection
122
YaspIntersection, // level intersection
123
YaspIntersectionIterator, // leaf intersection iter
124
YaspIntersectionIterator, // level intersection iter
125
YaspHierarchicIterator,
126
YaspLevelIterator, // type used for the leaf(!) iterator
127
YaspIndexSet< const YaspGrid< dim >, false >, // level index set
128
YaspIndexSet< const YaspGrid< dim >, true >, // leaf index set
129
YaspGlobalIdSet<const YaspGrid<dim> >,
130
bigunsignedint<dim*yaspgrid_dim_bits+yaspgrid_level_bits+yaspgrid_codim_bits>,
131
YaspGlobalIdSet<const YaspGrid<dim> >,
132
bigunsignedint<dim*yaspgrid_dim_bits+yaspgrid_level_bits+yaspgrid_codim_bits>,
134
DefaultLevelGridViewTraits, DefaultLeafGridViewTraits,
2432
template<int dim, int codim>
2433
struct YaspCommunicateMeta {
2434
template<class G, class DataHandle>
2435
static void comm (const G& g, DataHandle& data, InterfaceType iftype, CommunicationDirection dir, int level)
2437
if (data.contains(dim,codim))
139
template<int dim, int codim>
140
struct YaspCommunicateMeta {
141
template<class G, class DataHandle>
142
static void comm (const G& g, DataHandle& data, InterfaceType iftype, CommunicationDirection dir, int level)
144
if (data.contains(dim,codim))
2439
146
DUNE_THROW(GridError, "interface communication not implemented");
2441
YaspCommunicateMeta<dim,codim-1>::comm(g,data,iftype,dir,level);
2446
struct YaspCommunicateMeta<dim,dim> {
2447
template<class G, class DataHandle>
2448
static void comm (const G& g, DataHandle& data, InterfaceType iftype, CommunicationDirection dir, int level)
2450
if (data.contains(dim,dim))
2451
g.template communicateCodim<DataHandle,dim>(data,iftype,dir,level);
2452
YaspCommunicateMeta<dim,dim-1>::comm(g,data,iftype,dir,level);
2457
struct YaspCommunicateMeta<dim,0> {
2458
template<class G, class DataHandle>
2459
static void comm (const G& g, DataHandle& data, InterfaceType iftype, CommunicationDirection dir, int level)
2461
if (data.contains(dim,0))
2462
g.template communicateCodim<DataHandle,0>(data,iftype,dir,level);
2467
//************************************************************************
2469
\brief [<em> provides \ref Dune::Grid </em>]
2470
\brief Provides a distributed structured cube mesh.
2471
\ingroup GridImplementations
2473
YaspGrid stands for yet another structured parallel grid.
2474
It implements the dune grid interface for structured grids with codim 0
2475
and dim, with arbitrary overlap (including zero),
2476
periodic boundaries and fast implementation allowing on-the-fly computations.
2478
\tparam dim The dimension of the grid and its surrounding world
2481
\li started on July 31, 2004 by PB based on abstractions developed in summer 2003
2485
public GridDefaultImplementation<dim,dim,yaspgrid_ctype,YaspGridFamily<dim,dim> >,
2486
public MultiYGrid<dim,yaspgrid_ctype>
2488
typedef const YaspGrid<dim> GridImp;
2493
indexsets.push_back( new YaspLevelIndexSet<const YaspGrid<dim> >(*this,0) );
2494
theleafindexset.push_back( new YaspLeafIndexSet<const YaspGrid<dim> >(*this) );
2495
theglobalidset.push_back( new YaspGlobalIdSet<const YaspGrid<dim> >(*this) );
2496
boundarysegmentssize();
2499
void boundarysegmentssize()
148
YaspCommunicateMeta<dim,codim-1>::comm(g,data,iftype,dir,level);
153
struct YaspCommunicateMeta<dim,dim> {
154
template<class G, class DataHandle>
155
static void comm (const G& g, DataHandle& data, InterfaceType iftype, CommunicationDirection dir, int level)
157
if (data.contains(dim,dim))
158
g.template communicateCodim<DataHandle,dim>(data,iftype,dir,level);
159
YaspCommunicateMeta<dim,dim-1>::comm(g,data,iftype,dir,level);
164
struct YaspCommunicateMeta<dim,0> {
165
template<class G, class DataHandle>
166
static void comm (const G& g, DataHandle& data, InterfaceType iftype, CommunicationDirection dir, int level)
168
if (data.contains(dim,0))
169
g.template communicateCodim<DataHandle,0>(data,iftype,dir,level);
173
//************************************************************************
175
\brief [<em> provides \ref Dune::Grid </em>]
176
\brief Provides a distributed structured cube mesh.
177
\ingroup GridImplementations
180
YaspGrid stands for yet another structured parallel grid.
181
It implements the dune grid interface for structured grids with codim 0
182
and dim, with arbitrary overlap (including zero),
183
periodic boundaries and fast implementation allowing on-the-fly computations.
185
\tparam dim The dimension of the grid and its surrounding world
188
\li started on July 31, 2004 by PB based on abstractions developed in summer 2003
192
: public GridDefaultImplementation<dim,dim,yaspgrid_ctype,YaspGridFamily<dim> >
195
//! Type used for coordinates
196
typedef yaspgrid_ctype ctype;
198
struct Intersection {
199
/** \brief The intersection as a subgrid of the local grid */
200
SubYGrid<dim,ctype> grid;
202
/** \brief Rank of the process where the other grid is stored */
205
/** \brief Manhattan distance to the other grid */
209
/** \brief A single grid level within a YaspGrid
213
/** \brief Level number of this level grid */
219
// cell (codim 0) data
220
YGrid<dim,ctype> cell_global; // the whole cell grid on that level
221
SubYGrid<dim,ctype> cell_overlap; // we have no ghost cells, so our part is overlap completely
222
SubYGrid<dim,ctype> cell_interior; // interior cells are a subgrid of all cells
224
std::deque<Intersection> send_cell_overlap_overlap; // each intersection is a subgrid of overlap
225
std::deque<Intersection> recv_cell_overlap_overlap; // each intersection is a subgrid of overlap
227
std::deque<Intersection> send_cell_interior_overlap; // each intersection is a subgrid of overlap
228
std::deque<Intersection> recv_cell_overlap_interior; // each intersection is a subgrid of overlap
230
// vertex (codim dim) data
231
YGrid<dim,ctype> vertex_global; // the whole vertex grid on that level
232
SubYGrid<dim,ctype> vertex_overlapfront; // all our vertices are overlap and front
233
SubYGrid<dim,ctype> vertex_overlap; // subgrid containing only overlap
234
SubYGrid<dim,ctype> vertex_interiorborder; // subgrid containing only interior and border
235
SubYGrid<dim,ctype> vertex_interior; // subgrid containing only interior
237
std::deque<Intersection> send_vertex_overlapfront_overlapfront; // each intersection is a subgrid of overlapfront
238
std::deque<Intersection> recv_vertex_overlapfront_overlapfront; // each intersection is a subgrid of overlapfront
240
std::deque<Intersection> send_vertex_overlap_overlapfront; // each intersection is a subgrid of overlapfront
241
std::deque<Intersection> recv_vertex_overlapfront_overlap; // each intersection is a subgrid of overlapfront
243
std::deque<Intersection> send_vertex_interiorborder_interiorborder; // each intersection is a subgrid of overlapfront
244
std::deque<Intersection> recv_vertex_interiorborder_interiorborder; // each intersection is a subgrid of overlapfront
246
std::deque<Intersection> send_vertex_interiorborder_overlapfront; // each intersection is a subgrid of overlapfront
247
std::deque<Intersection> recv_vertex_overlapfront_interiorborder; // each intersection is a subgrid of overlapfront
250
YaspGrid<dim>* mg; // each grid level knows its multigrid
251
int overlap; // in mesh cells on this level
252
/** \brief The level number within the YaspGrid level hierarchy */
256
//! define types used for arguments
257
typedef FieldVector<int, dim> iTupel;
258
typedef FieldVector<ctype, dim> fTupel;
260
// communication tag used by multigrid
263
//! return reference to torus
264
const Torus<dim>& torus () const
269
//! Iterator over the grid levels
270
typedef typename ReservedVector<YGridLevel,32>::const_iterator YGridLevelIterator;
272
//! return iterator pointing to coarsest level
273
YGridLevelIterator begin () const
275
return YGridLevelIterator(_levels,0);
278
//! return iterator pointing to given level
279
YGridLevelIterator begin (int i) const
281
if (i<0 || i>maxLevel())
282
DUNE_THROW(GridError, "level not existing");
283
return YGridLevelIterator(_levels,i);
286
//! return iterator pointing to one past the finest level
287
YGridLevelIterator end () const
289
return YGridLevelIterator(_levels,maxLevel()+1);
292
// static method to create the default load balance strategy
293
static const YLoadBalance<dim>* defaultLoadbalancer()
295
static YLoadBalance<dim> lb;
300
/** \brief Make a new YGridLevel structure
302
* \param L size of the whole domain in each direction
303
* \param s number of cells in each direction
304
* \param periodic indicate periodicity for each direction
305
* \param o_interior origin of interior (non-overlapping) cell decomposition
306
* \param s_interior size of interior cell decomposition
307
* \param overlap to be used on this grid level
309
YGridLevel makelevel (int level, fTupel L, iTupel s, std::bitset<dim> periodic, iTupel o_interior, iTupel s_interior, int overlap)
311
// first, lets allocate a new structure
317
// the global cell grid
318
iTupel o = iTupel(0); // logical origin is always 0, that is not a restriction
321
for (int i=0; i<dim; i++) h[i] = L[i]/s[i]; // the mesh size in each direction
322
for (int i=0; i<dim; i++) r[i] = 0.5*h[i]; // the shift for cell centers
323
g.cell_global = YGrid<dim,ctype>(o,s,h,r); // this is the global cell grid
325
// extend the cell interior grid by overlap considering periodicity
328
for (int i=0; i<dim; i++)
332
// easy case, extend by 2 overlaps in total
333
o_overlap[i] = o_interior[i]-overlap; // Note: origin might be negative now
334
s_overlap[i] = s_interior[i]+2*overlap; // Note: might be larger than global size
338
// nonperiodic case, intersect with global size
339
int min = std::max(0,o_interior[i]-overlap);
340
int max = std::min(s[i]-1,o_interior[i]+s_interior[i]-1+overlap);
342
s_overlap[i] = max-min+1;
345
g.cell_overlap = SubYGrid<dim,ctype>(YGrid<dim,ctype>(o_overlap,s_overlap,h,r));
347
// now make the interior grid a subgrid of the overlapping grid
349
for (int i=0; i<dim; i++) offset[i] = o_interior[i]-o_overlap[i];
350
g.cell_interior = SubYGrid<dim,ctype>(o_interior,s_interior,offset,s_overlap,h,r);
352
// compute cell intersections
353
intersections(g.cell_overlap,g.cell_overlap,g.cell_global.size(),g.send_cell_overlap_overlap,g.recv_cell_overlap_overlap);
354
intersections(g.cell_interior,g.cell_overlap,g.cell_global.size(),g.send_cell_interior_overlap,g.recv_cell_overlap_interior);
356
// now we can do the vertex grids. They are derived completely from the cell grids
357
iTupel o_vertex_global, s_vertex_global;
358
for (int i=0; i<dim; i++) r[i] = 0.0; // the shift for vertices is zero, and the mesh size is same as for cells
360
// first let's make the global grid
361
for (int i=0; i<dim; i++) o_vertex_global[i] = g.cell_global.origin(i);
362
for (int i=0; i<dim; i++) s_vertex_global[i] = g.cell_global.size(i)+1; // one more vertices than cells ...
363
g.vertex_global = YGrid<dim,ctype>(o_vertex_global,s_vertex_global,h,r);
365
// now the local grid stored in this processor. All other grids are subgrids of this
366
iTupel o_vertex_overlapfront;
367
iTupel s_vertex_overlapfront;
368
for (int i=0; i<dim; i++) o_vertex_overlapfront[i] = g.cell_overlap.origin(i);
369
for (int i=0; i<dim; i++) s_vertex_overlapfront[i] = g.cell_overlap.size(i)+1; // one more vertices than cells ...
370
g.vertex_overlapfront = SubYGrid<dim,ctype>(YGrid<dim,ctype>(o_vertex_overlapfront,s_vertex_overlapfront,h,r));
372
// now overlap only (i.e. without front), is subgrid of overlapfront
373
iTupel o_vertex_overlap;
374
iTupel s_vertex_overlap;
375
for (int i=0; i<dim; i++)
377
o_vertex_overlap[i] = g.cell_overlap.origin(i);
378
s_vertex_overlap[i] = g.cell_overlap.size(i)+1;
380
if (!periodic[i] && g.cell_overlap.origin(i)>g.cell_global.origin(i))
382
// not at the lower boundary
383
o_vertex_overlap[i] += 1;
384
s_vertex_overlap[i] -= 1;
387
if (!periodic[i] && g.cell_overlap.origin(i)+g.cell_overlap.size(i)<g.cell_global.origin(i)+g.cell_global.size(i))
389
// not at the upper boundary
390
s_vertex_overlap[i] -= 1;
394
offset[i] = o_vertex_overlap[i]-o_vertex_overlapfront[i];
396
g.vertex_overlap = SubYGrid<dim,ctype>(o_vertex_overlap,s_vertex_overlap,offset,s_vertex_overlapfront,h,r);
398
// now interior with border
399
iTupel o_vertex_interiorborder;
400
iTupel s_vertex_interiorborder;
401
for (int i=0; i<dim; i++) o_vertex_interiorborder[i] = g.cell_interior.origin(i);
402
for (int i=0; i<dim; i++) s_vertex_interiorborder[i] = g.cell_interior.size(i)+1;
403
for (int i=0; i<dim; i++) offset[i] = o_vertex_interiorborder[i]-o_vertex_overlapfront[i];
404
g.vertex_interiorborder = SubYGrid<dim,ctype>(o_vertex_interiorborder,s_vertex_interiorborder,offset,s_vertex_overlapfront,h,r);
407
iTupel o_vertex_interior;
408
iTupel s_vertex_interior;
409
for (int i=0; i<dim; i++)
411
o_vertex_interior[i] = g.cell_interior.origin(i);
412
s_vertex_interior[i] = g.cell_interior.size(i)+1;
414
if (!periodic[i] && g.cell_interior.origin(i)>g.cell_global.origin(i))
416
// not at the lower boundary
417
o_vertex_interior[i] += 1;
418
s_vertex_interior[i] -= 1;
421
if (!periodic[i] && g.cell_interior.origin(i)+g.cell_interior.size(i)<g.cell_global.origin(i)+g.cell_global.size(i))
423
// not at the upper boundary
424
s_vertex_interior[i] -= 1;
427
offset[i] = o_vertex_interior[i]-o_vertex_overlapfront[i];
429
g.vertex_interior = SubYGrid<dim,ctype>(o_vertex_interior,s_vertex_interior,offset,s_vertex_overlapfront,h,r);
431
// compute vertex intersections
432
intersections(g.vertex_overlapfront,g.vertex_overlapfront,g.cell_global.size(),
433
g.send_vertex_overlapfront_overlapfront,g.recv_vertex_overlapfront_overlapfront);
434
intersections(g.vertex_overlap,g.vertex_overlapfront,g.cell_global.size(),
435
g.send_vertex_overlap_overlapfront,g.recv_vertex_overlapfront_overlap);
436
intersections(g.vertex_interiorborder,g.vertex_interiorborder,g.cell_global.size(),
437
g.send_vertex_interiorborder_interiorborder,g.recv_vertex_interiorborder_interiorborder);
438
intersections(g.vertex_interiorborder,g.vertex_overlapfront,g.cell_global.size(),
439
g.send_vertex_interiorborder_overlapfront,g.recv_vertex_overlapfront_interiorborder);
441
// return the whole thing
446
struct mpifriendly_ygrid {
448
: origin(0), size(0), h(0.0), r(0.0)
450
mpifriendly_ygrid (const YGrid<dim,ctype>& grid)
451
: origin(grid.origin()), size(grid.size()), h(grid.meshsize()), r(grid.shift())
459
/** \brief Construct list of intersections with neighboring processors
461
* \param recvgrid the grid stored in this processor
462
* \param sendgrid the subgrid to be sent to neighboring processors
463
* \param size needed to shift local grid in periodic case
464
* \returns two lists: Intersections to be sent and Intersections to be received
465
* \note sendgrid/recvgrid may be SubYGrids. Since intersection method is virtual it should work properly
467
void intersections (const SubYGrid<dim,ctype>& sendgrid, const SubYGrid<dim,ctype>& recvgrid, const iTupel& size,
468
std::deque<Intersection>& sendlist, std::deque<Intersection>& recvlist)
470
// the exchange buffers
471
std::vector<YGrid<dim,ctype> > send_recvgrid(_torus.neighbors());
472
std::vector<YGrid<dim,ctype> > recv_recvgrid(_torus.neighbors());
473
std::vector<YGrid<dim,ctype> > send_sendgrid(_torus.neighbors());
474
std::vector<YGrid<dim,ctype> > recv_sendgrid(_torus.neighbors());
476
// new exchange buffers to send simple struct without virtual functions
477
std::vector<mpifriendly_ygrid> mpifriendly_send_recvgrid(_torus.neighbors());
478
std::vector<mpifriendly_ygrid> mpifriendly_recv_recvgrid(_torus.neighbors());
479
std::vector<mpifriendly_ygrid> mpifriendly_send_sendgrid(_torus.neighbors());
480
std::vector<mpifriendly_ygrid> mpifriendly_recv_sendgrid(_torus.neighbors());
482
// fill send buffers; iterate over all neighboring processes
483
// non-periodic case is handled automatically because intersection will be zero
484
for (typename Torus<dim>::ProcListIterator i=_torus.sendbegin(); i!=_torus.sendend(); ++i)
486
// determine if we communicate with this neighbor (and what)
488
iTupel coord = _torus.coord(); // my coordinates
489
iTupel delta = i.delta(); // delta to neighbor
490
iTupel nb = coord; // the neighbor
491
for (int k=0; k<dim; k++) nb[k] += delta[k];
492
iTupel v = iTupel(0); // grid movement
494
for (int k=0; k<dim; k++)
503
if (nb[k]>=_torus.dims(k))
510
// neither might be true, then v=0
513
// store moved grids in send buffers
516
send_sendgrid[i.index()] = sendgrid.move(v);
517
send_recvgrid[i.index()] = recvgrid.move(v);
521
send_sendgrid[i.index()] = YGrid<dim,ctype>(iTupel(0),iTupel(0),fTupel(0.0),fTupel(0.0));
522
send_recvgrid[i.index()] = YGrid<dim,ctype>(iTupel(0),iTupel(0),fTupel(0.0),fTupel(0.0));
526
// issue send requests for sendgrid being sent to all neighbors
527
for (typename Torus<dim>::ProcListIterator i=_torus.sendbegin(); i!=_torus.sendend(); ++i)
529
mpifriendly_send_sendgrid[i.index()] = mpifriendly_ygrid(send_sendgrid[i.index()]);
530
_torus.send(i.rank(), &mpifriendly_send_sendgrid[i.index()], sizeof(mpifriendly_ygrid));
533
// issue recv requests for sendgrids of neighbors
534
for (typename Torus<dim>::ProcListIterator i=_torus.recvbegin(); i!=_torus.recvend(); ++i)
535
_torus.recv(i.rank(), &mpifriendly_recv_sendgrid[i.index()], sizeof(mpifriendly_ygrid));
537
// exchange the sendgrids
540
// issue send requests for recvgrid being sent to all neighbors
541
for (typename Torus<dim>::ProcListIterator i=_torus.sendbegin(); i!=_torus.sendend(); ++i)
543
mpifriendly_send_recvgrid[i.index()] = mpifriendly_ygrid(send_recvgrid[i.index()]);
544
_torus.send(i.rank(), &mpifriendly_send_recvgrid[i.index()], sizeof(mpifriendly_ygrid));
547
// issue recv requests for recvgrid of neighbors
548
for (typename Torus<dim>::ProcListIterator i=_torus.recvbegin(); i!=_torus.recvend(); ++i)
549
_torus.recv(i.rank(), &mpifriendly_recv_recvgrid[i.index()], sizeof(mpifriendly_ygrid));
551
// exchange the recvgrid
554
// process receive buffers and compute intersections
555
for (typename Torus<dim>::ProcListIterator i=_torus.recvbegin(); i!=_torus.recvend(); ++i)
557
// what must be sent to this neighbor
558
Intersection send_intersection;
559
mpifriendly_ygrid yg = mpifriendly_recv_recvgrid[i.index()];
560
recv_recvgrid[i.index()] = YGrid<dim,ctype>(yg.origin,yg.size,yg.h,yg.r);
561
send_intersection.grid = sendgrid.intersection(recv_recvgrid[i.index()]);
562
send_intersection.rank = i.rank();
563
send_intersection.distance = i.distance();
564
if (!send_intersection.grid.empty()) sendlist.push_front(send_intersection);
566
Intersection recv_intersection;
567
yg = mpifriendly_recv_sendgrid[i.index()];
568
recv_sendgrid[i.index()] = YGrid<dim,ctype>(yg.origin,yg.size,yg.h,yg.r);
569
recv_intersection.grid = recvgrid.intersection(recv_sendgrid[i.index()]);
570
recv_intersection.rank = i.rank();
571
recv_intersection.distance = i.distance();
572
if(!recv_intersection.grid.empty()) recvlist.push_back(recv_intersection);
578
typedef const YaspGrid<dim> GridImp;
583
indexsets.push_back( make_shared< YaspIndexSet<const YaspGrid<dim>, false > >(*this,0) );
584
boundarysegmentssize();
587
void boundarysegmentssize()
2501
589
// sizes of local macro grid
2502
const FieldVector<int, dim> & size = MultiYGrid<dim,ctype>::begin().cell_overlap().size();
2503
FieldVector<int, dim> sides;
590
const FieldVector<int, dim> & size = begin()->cell_overlap.size();
591
Dune::array<int, dim> sides;
2505
for (int i=0; i<dim; i++)
2508
((MultiYGrid<dim,ctype>::begin().cell_overlap().origin(i)
2509
== MultiYGrid<dim,ctype>::begin().cell_global().origin(i))+
2510
(MultiYGrid<dim,ctype>::begin().cell_overlap().origin(i) +
2511
MultiYGrid<dim,ctype>::begin().cell_overlap().size(i)
2512
== MultiYGrid<dim,ctype>::begin().cell_global().origin(i) +
2513
MultiYGrid<dim,ctype>::begin().cell_global().size(i)));
593
for (int i=0; i<dim; i++)
596
((begin()->cell_overlap.origin(i) == begin()->cell_global.origin(i))+
597
(begin()->cell_overlap.origin(i) + begin()->cell_overlap.size(i)
598
== begin()->cell_global.origin(i) + begin()->cell_global.size(i)));
2517
602
for (int k=0; k<dim; k++)
2520
for (int l=0; l<dim; l++)
2525
nBSegments += sides[k]*offset;
605
for (int l=0; l<dim; l++)
610
nBSegments += sides[k]*offset;
2531
using MultiYGrid<dim,yaspgrid_ctype>::defaultLoadbalancer;
2533
//! define type used for coordinates in grid module
2534
typedef yaspgrid_ctype ctype;
2536
// define the persistent index type
2537
typedef bigunsignedint<dim*yaspgrid_dim_bits+yaspgrid_level_bits+yaspgrid_codim_bits> PersistentIndexType;
2539
//! the GridFamily of this grid
2540
typedef YaspGridFamily<dim,dim> GridFamily;
2542
typedef typename YaspGridFamily<dim,dim>::Traits Traits;
2544
// need for friend declarations in entity
2545
typedef YaspLevelIndexSet<YaspGrid<dim> > LevelIndexSetType;
2546
typedef YaspLeafIndexSet<YaspGrid<dim> > LeafIndexSetType;
2547
typedef YaspGlobalIdSet<YaspGrid<dim> > GlobalIdSetType;
2549
//! maximum number of levels allowed
2552
//! shorthand for base class data types
2553
typedef MultiYGrid<dim,ctype> YMG;
2554
typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
2555
typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
2556
typedef typename MultiYGrid<dim,ctype>::Intersection IS;
2557
typedef typename std::deque<IS>::const_iterator ISIT;
2559
/*! Constructor for a YaspGrid, they are all forwarded to the base class
2560
@param comm MPI communicator where this mesh is distributed to
2561
@param L extension of the domain
2562
@param s number of cells on coarse mesh in each direction
2563
@param periodic tells if direction is periodic or not
2564
@param overlap size of overlap on coarsest grid (same in all directions)
2565
@param lb pointer to an overloaded YLoadBalance instance
2567
YaspGrid (Dune::MPIHelper::MPICommunicator comm,
2568
Dune::FieldVector<ctype, dim> L,
2569
Dune::FieldVector<int, dim> s,
2570
Dune::FieldVector<bool, dim> periodic, int overlap,
2571
const YLoadBalance<dim>* lb = defaultLoadbalancer())
2573
: YMG(comm,L,s,periodic,overlap,lb), ccobj(comm),
2574
keep_ovlp(true), adaptRefCount(0), adaptActive(false)
2576
: YMG(L,s,periodic,overlap,lb),
2577
keep_ovlp(true), adaptRefCount(0), adaptActive(false)
2584
/*! Constructor for a sequential YaspGrid, they are all forwarded to the base class.
2586
Sequential here means that the whole grid is living on one process even if your program is running
2588
@see YaspGrid(Dune::MPIHelper::MPICommunicator, Dune::FieldVector<ctype, dim>, Dune::FieldVector<int, dim>, Dune::FieldVector<bool, dim>, int)
2589
for constructing one parallel grid decomposed between the processors.
2590
@param L extension of the domain
2591
@param s number of cells on coarse mesh in each direction
2592
@param periodic tells if direction is periodic or not
2593
@param overlap size of overlap on coarsest grid (same in all directions)
2594
@param lb pointer to an overloaded YLoadBalance instance
2596
YaspGrid (Dune::FieldVector<ctype, dim> L,
2597
Dune::FieldVector<int, dim> s,
2598
Dune::FieldVector<bool, dim> periodic, int overlap,
2599
const YLoadBalance<dim>* lb = YMG::defaultLoadbalancer())
2601
: YMG(MPI_COMM_SELF,L,s,periodic,overlap,lb), ccobj(MPI_COMM_SELF),
2602
keep_ovlp(true), adaptRefCount(0), adaptActive(false)
2604
: YMG(L,s,periodic,overlap,lb),
2605
keep_ovlp(true), adaptRefCount(0), adaptActive(false)
2613
deallocatePointers(indexsets);
2614
deallocatePointers(theleafindexset);
2615
deallocatePointers(theglobalidset);
616
// define the persistent index type
617
typedef bigunsignedint<dim*yaspgrid_dim_bits+yaspgrid_level_bits+yaspgrid_codim_bits> PersistentIndexType;
619
//! the GridFamily of this grid
620
typedef YaspGridFamily<dim> GridFamily;
622
typedef typename YaspGridFamily<dim>::Traits Traits;
624
// need for friend declarations in entity
625
typedef YaspIndexSet<YaspGrid<dim>, false > LevelIndexSetType;
626
typedef YaspIndexSet<YaspGrid<dim>, true > LeafIndexSetType;
627
typedef YaspGlobalIdSet<YaspGrid<dim> > GlobalIdSetType;
629
//! shorthand for some data types
630
typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
631
typedef typename std::deque<Intersection>::const_iterator ISIT;
633
//! The constructor of the old MultiYGrid class
634
void MultiYGridSetup (
635
fTupel L, iTupel s, std::bitset<dim> periodic, int overlap, const YLoadBalance<dim>* lb = defaultLoadbalancer())
639
_periodic = periodic;
643
// coarse cell interior grid obtained through partitioning of global grid
647
iTupel o = iTupel(0);
648
array<int,dim> sArray;
649
std::copy(s.begin(), s.end(), sArray.begin());
650
double imbal = _torus.partition(_torus.rank(),o,sArray,o_interior,s_interior);
651
imbal = _torus.global_max(imbal);
653
iTupel o = iTupel(0);
654
iTupel o_interior(o);
655
iTupel s_interior(s);
658
_levels[0] = makelevel(0,L,s,periodic,o_interior,s_interior,overlap);
661
//! The constructor of the old MultiYGrid class
662
void MultiYGridSetup (
664
Dune::array<int,dim> s,
665
std::bitset<dim> periodic,
667
const YLoadBalance<dim>* lb = defaultLoadbalancer())
670
_periodic = periodic;
674
std::copy(s.begin(), s.end(), this->_s.begin());
676
// coarse cell interior grid obtained through partitioning of global grid
677
iTupel o = iTupel(0);
678
iTupel o_interior(o);
680
std::copy(s.begin(), s.end(), s_interior.begin());
682
double imbal = _torus.partition(_torus.rank(),o,s,o_interior,s_interior);
683
imbal = _torus.global_max(imbal);
687
_levels[0] = makelevel(0,L,_s,periodic,o_interior,s_interior,overlap);
691
@param comm MPI communicator where this mesh is distributed to
692
@param L extension of the domain
693
@param s number of cells on coarse mesh in each direction
694
@param periodic tells if direction is periodic or not
695
@param overlap size of overlap on coarsest grid (same in all directions)
696
@param lb pointer to an overloaded YLoadBalance instance
698
\deprecated Will be removed after dune-grid 2.3.
699
Use the corresponding constructor taking array<int> and std::bitset instead.
701
YaspGrid (Dune::MPIHelper::MPICommunicator comm,
702
Dune::FieldVector<ctype, dim> L,
703
Dune::FieldVector<int, dim> s,
704
Dune::FieldVector<bool, dim> periodic, int overlap,
705
const YLoadBalance<dim>* lb = defaultLoadbalancer())
706
DUNE_DEPRECATED_MSG("Use the corresponding constructor taking array<int> and std::bitset")
709
_torus(comm,tag,s,lb),
713
leafIndexSet_(*this),
714
keep_ovlp(true), adaptRefCount(0), adaptActive(false)
716
MultiYGridSetup(L,s,std::bitset<dim>(),overlap,lb);
718
// hack: copy input bitfield (in FieldVector<bool>) into std::bitset
719
for (size_t i=0; i<dim; i++)
720
this->_periodic[i] = periodic[i];
725
/*! Constructor for a sequential YaspGrid
727
Sequential here means that the whole grid is living on one process even if your program is running
729
@see YaspGrid(Dune::MPIHelper::MPICommunicator, Dune::FieldVector<ctype, dim>, Dune::FieldVector<int, dim>, Dune::FieldVector<bool, dim>, int)
730
for constructing one parallel grid decomposed between the processors.
731
@param L extension of the domain
732
@param s number of cells on coarse mesh in each direction
733
@param periodic tells if direction is periodic or not
734
@param overlap size of overlap on coarsest grid (same in all directions)
735
@param lb pointer to an overloaded YLoadBalance instance
737
\deprecated Will be removed after dune-grid 2.3.
738
Use the corresponding constructor taking array<int> and std::bitset instead.
740
YaspGrid (Dune::FieldVector<ctype, dim> L,
741
Dune::FieldVector<int, dim> s,
742
Dune::FieldVector<bool, dim> periodic, int overlap,
743
const YLoadBalance<dim>* lb = defaultLoadbalancer())
744
DUNE_DEPRECATED_MSG("Use the corresponding constructor taking array<int> and std::bitset")
746
: ccobj(MPI_COMM_SELF),
747
_torus(MPI_COMM_SELF,tag,s,lb),
751
leafIndexSet_(*this),
752
keep_ovlp(true), adaptRefCount(0), adaptActive(false)
754
MultiYGridSetup(L,s,std::bitset<dim>(),overlap,lb);
756
// hack: copy input bitfield (in FieldVector<bool>) into std::bitset
757
for (size_t i=0; i<dim; i++)
758
this->_periodic[i] = periodic[i];
763
@param comm MPI communicator where this mesh is distributed to
764
@param L extension of the domain
765
@param s number of cells on coarse mesh in each direction
766
@param periodic tells if direction is periodic or not
767
@param overlap size of overlap on coarsest grid (same in all directions)
768
@param lb pointer to an overloaded YLoadBalance instance
770
YaspGrid (Dune::MPIHelper::MPICommunicator comm,
771
Dune::FieldVector<ctype, dim> L,
772
Dune::array<int, dim> s,
773
std::bitset<dim> periodic,
775
const YLoadBalance<dim>* lb = defaultLoadbalancer())
778
_torus(comm,tag,s,lb),
782
leafIndexSet_(*this),
783
keep_ovlp(true), adaptRefCount(0), adaptActive(false)
785
MultiYGridSetup(L,s,periodic,overlap,lb);
791
/*! Constructor for a sequential YaspGrid
793
Sequential here means that the whole grid is living on one process even if your program is running
795
@see YaspGrid(Dune::MPIHelper::MPICommunicator, Dune::FieldVector<ctype, dim>, Dune::FieldVector<int, dim>, Dune::FieldVector<bool, dim>, int)
796
for constructing one parallel grid decomposed between the processors.
797
@param L extension of the domain
798
@param s number of cells on coarse mesh in each direction
799
@param periodic tells if direction is periodic or not
800
@param overlap size of overlap on coarsest grid (same in all directions)
801
@param lb pointer to an overloaded YLoadBalance instance
803
YaspGrid (Dune::FieldVector<ctype, dim> L,
804
Dune::array<int, dim> s,
805
std::bitset<dim> periodic,
807
const YLoadBalance<dim>* lb = defaultLoadbalancer())
809
: ccobj(MPI_COMM_SELF),
810
_torus(MPI_COMM_SELF,tag,s,lb),
814
leafIndexSet_(*this),
815
keep_ovlp(true), adaptRefCount(0), adaptActive(false)
817
MultiYGridSetup(L,s,periodic,overlap,lb);
822
/*! Constructor for a sequential YaspGrid without periodicity
824
Sequential here means that the whole grid is living on one process even if your program is running
826
@see YaspGrid(Dune::MPIHelper::MPICommunicator, Dune::FieldVector<ctype, dim>, Dune::FieldVector<int, dim>, Dune::FieldVector<bool, dim>, int)
827
for constructing one parallel grid decomposed between the processors.
828
@param L extension of the domain (lower left is always (0,...,0)
829
@param elements number of cells on coarse mesh in each direction
831
YaspGrid (Dune::FieldVector<ctype, dim> L,
832
Dune::array<int, dim> elements)
834
: ccobj(MPI_COMM_SELF),
835
_torus(MPI_COMM_SELF,tag,elements,defaultLoadbalancer()),
837
: _torus(tag,elements,defaultLoadbalancer()),
839
leafIndexSet_(*this),
843
adaptRefCount(0), adaptActive(false)
847
std::copy(elements.begin(), elements.end(), _s.begin());
849
// coarse cell interior grid obtained through partitioning of global grid
850
iTupel o = iTupel(0);
851
iTupel o_interior(o);
853
std::copy(elements.begin(), elements.end(), s_interior.begin());
855
double imbal = _torus.partition(_torus.rank(),o,elements,o_interior,s_interior);
856
imbal = _torus.global_max(imbal);
860
_levels[0] = makelevel(0,L,_s,_periodic,o_interior,s_interior,0);
2619
// do not copy this class
2620
YaspGrid(const YaspGrid&);
866
// do not copy this class
867
YaspGrid(const YaspGrid&);
2624
/*! Return maximum level defined in this grid. Levels are numbered
2625
0 ... maxlevel with 0 the coarsest level.
2627
int maxLevel() const {return MultiYGrid<dim,ctype>::maxlevel();} // delegate
2629
//! refine the grid refCount times. What about overlap?
2630
void globalRefine (int refCount)
2632
if (refCount < -maxLevel())
2633
DUNE_THROW(GridError, "Only " << maxLevel() << " levels left. " <<
2634
"Coarsening " << -refCount << " levels requested!");
2635
for (int k=refCount; k<0; k++)
871
/*! Return maximum level defined in this grid. Levels are numbered
872
0 ... maxlevel with 0 the coarsest level.
876
return _levels.size()-1;
879
//! refine the grid refCount times. What about overlap?
880
void globalRefine (int refCount)
882
if (refCount < -maxLevel())
883
DUNE_THROW(GridError, "Only " << maxLevel() << " levels left. " <<
884
"Coarsening " << -refCount << " levels requested!");
886
// If refCount is negative then coarsen the grid
887
for (int k=refCount; k<0; k++)
2637
MultiYGrid<dim,ctype>::coarsen();
889
// create an empty grid level
891
_levels.back() = empty;
2639
896
indexsets.pop_back();
2641
for (int k=0; k<refCount; k++)
899
// If refCount is positive refine the grid
900
for (int k=0; k<refCount; k++)
2643
MultiYGrid<dim,ctype>::refine(keep_ovlp);
902
// access to coarser grid level
903
YGridLevel& cg = _levels[maxLevel()];
905
// compute size of new global grid
907
for (int i=0; i<dim; i++)
908
s[i] = 2*cg.cell_global.size(i);
911
int overlap = (keep_ovlp) ? 2*cg.overlap : cg.overlap;
913
// the cell interior grid obtained from coarse cell interior grid
916
for (int i=0; i<dim; i++)
917
o_interior[i] = 2*cg.cell_interior.origin(i);
918
for (int i=0; i<dim; i++)
919
s_interior[i] = 2*cg.cell_interior.size(i);
922
_levels.push_back( makelevel(_levels.size(),_LL,s,_periodic,o_interior,s_interior,overlap) );
2645
indexsets.push_back( new YaspLevelIndexSet<const YaspGrid<dim> >(*this,maxLevel()) );
925
indexsets.push_back( make_shared<YaspIndexSet<const YaspGrid<dim>, false > >(*this,maxLevel()) );
2650
\brief set options for refinement
2651
@param keepPhysicalOverlap [true] keep the physical size of the overlap, [false] keep the number of cells in the overlap. Default is [true].
2653
void refineOptions (bool keepPhysicalOverlap)
2655
keep_ovlp = keepPhysicalOverlap;
2658
/** \brief Marks an entity to be refined/coarsened in a subsequent adapt.
2660
\param[in] refCount Number of subdivisions that should be applied. Negative value means coarsening.
2661
\param[in] e Entity to Entity that should be refined
2663
\return true if Entity was marked, false otherwise.
2666
- On yaspgrid marking one element will mark all other elements of the level aswell
2667
- If refCount is lower than refCount of a previous mark-call, nothing is changed
2669
bool mark( int refCount, const typename Traits::template Codim<0>::Entity & e )
2671
assert(adaptActive == false);
2672
if (e.level() != maxLevel()) return false;
2673
adaptRefCount = std::max(adaptRefCount, refCount);
2677
/** \brief returns adaptation mark for given entity
2679
\param[in] e Entity for which adaptation mark should be determined
2681
\return int adaptation mark, here the default value 0 is returned
2683
int getMark ( const typename Traits::template Codim<0>::Entity &e ) const
2685
return ( e.level() == maxLevel() ) ? adaptRefCount : 0;
2688
//! map adapt to global refine
2691
globalRefine(adaptRefCount);
2692
return (adaptRefCount > 0);
2695
//! returns true, if the grid will be coarsened
2699
adaptRefCount = comm().max(adaptRefCount);
2700
return (adaptRefCount < 0);
2703
//! clean up some markers
2706
adaptActive = false;
2710
//! one past the end on this level
2711
template<int cd, PartitionIteratorType pitype>
2712
typename Traits::template Codim<cd>::template Partition<pitype>::LevelIterator lbegin (int level) const
930
\brief set options for refinement
931
@param keepPhysicalOverlap [true] keep the physical size of the overlap, [false] keep the number of cells in the overlap. Default is [true].
933
void refineOptions (bool keepPhysicalOverlap)
935
keep_ovlp = keepPhysicalOverlap;
938
/** \brief Marks an entity to be refined/coarsened in a subsequent adapt.
940
\param[in] refCount Number of subdivisions that should be applied. Negative value means coarsening.
941
\param[in] e Entity to Entity that should be refined
943
\return true if Entity was marked, false otherwise.
946
- On yaspgrid marking one element will mark all other elements of the level as well
947
- If refCount is lower than refCount of a previous mark-call, nothing is changed
949
bool mark( int refCount, const typename Traits::template Codim<0>::Entity & e )
951
assert(adaptActive == false);
952
if (e.level() != maxLevel()) return false;
953
adaptRefCount = std::max(adaptRefCount, refCount);
957
/** \brief returns adaptation mark for given entity
959
\param[in] e Entity for which adaptation mark should be determined
961
\return int adaptation mark, here the default value 0 is returned
963
int getMark ( const typename Traits::template Codim<0>::Entity &e ) const
965
return ( e.level() == maxLevel() ) ? adaptRefCount : 0;
968
//! map adapt to global refine
971
globalRefine(adaptRefCount);
972
return (adaptRefCount > 0);
975
//! returns true, if the grid will be coarsened
979
adaptRefCount = comm().max(adaptRefCount);
980
return (adaptRefCount < 0);
983
//! clean up some markers
990
//! one past the end on this level
991
template<int cd, PartitionIteratorType pitype>
992
typename Traits::template Codim<cd>::template Partition<pitype>::LevelIterator lbegin (int level) const
2714
994
return levelbegin<cd,pitype>(level);
2717
//! Iterator to one past the last entity of given codim on level for partition type
2718
template<int cd, PartitionIteratorType pitype>
2719
typename Traits::template Codim<cd>::template Partition<pitype>::LevelIterator lend (int level) const
997
//! Iterator to one past the last entity of given codim on level for partition type
998
template<int cd, PartitionIteratorType pitype>
999
typename Traits::template Codim<cd>::template Partition<pitype>::LevelIterator lend (int level) const
2721
1001
return levelend<cd,pitype>(level);
2724
//! version without second template parameter for convenience
2726
typename Traits::template Codim<cd>::template Partition<All_Partition>::LevelIterator lbegin (int level) const
1004
//! version without second template parameter for convenience
1006
typename Traits::template Codim<cd>::template Partition<All_Partition>::LevelIterator lbegin (int level) const
2728
1008
return levelbegin<cd,All_Partition>(level);
2731
//! version without second template parameter for convenience
2733
typename Traits::template Codim<cd>::template Partition<All_Partition>::LevelIterator lend (int level) const
1011
//! version without second template parameter for convenience
1013
typename Traits::template Codim<cd>::template Partition<All_Partition>::LevelIterator lend (int level) const
2735
1015
return levelend<cd,All_Partition>(level);
2738
//! return LeafIterator which points to the first entity in maxLevel
2739
template<int cd, PartitionIteratorType pitype>
2740
typename Traits::template Codim<cd>::template Partition<pitype>::LeafIterator leafbegin () const
1018
//! return LeafIterator which points to the first entity in maxLevel
1019
template<int cd, PartitionIteratorType pitype>
1020
typename Traits::template Codim<cd>::template Partition<pitype>::LeafIterator leafbegin () const
2742
1022
return levelbegin<cd,pitype>(maxLevel());
2745
//! return LeafIterator which points behind the last entity in maxLevel
2746
template<int cd, PartitionIteratorType pitype>
2747
typename Traits::template Codim<cd>::template Partition<pitype>::LeafIterator leafend () const
1025
//! return LeafIterator which points behind the last entity in maxLevel
1026
template<int cd, PartitionIteratorType pitype>
1027
typename Traits::template Codim<cd>::template Partition<pitype>::LeafIterator leafend () const
2749
1029
return levelend<cd,pitype>(maxLevel());
2752
//! return LeafIterator which points to the first entity in maxLevel
2754
typename Traits::template Codim<cd>::template Partition<All_Partition>::LeafIterator leafbegin () const
1032
//! return LeafIterator which points to the first entity in maxLevel
1034
typename Traits::template Codim<cd>::template Partition<All_Partition>::LeafIterator leafbegin () const
2756
1036
return levelbegin<cd,All_Partition>(maxLevel());
2759
//! return LeafIterator which points behind the last entity in maxLevel
2761
typename Traits::template Codim<cd>::template Partition<All_Partition>::LeafIterator leafend () const
1039
//! return LeafIterator which points behind the last entity in maxLevel
1041
typename Traits::template Codim<cd>::template Partition<All_Partition>::LeafIterator leafend () const
2763
1043
return levelend<cd,All_Partition>(maxLevel());
2766
// \brief obtain EntityPointer from EntitySeed. */
2767
template <typename Seed>
2768
typename Traits::template Codim<Seed::codimension>::EntityPointer
2769
entityPointer(const Seed& seed) const
2771
const int codim = Seed::codimension;
2772
YGLI g = MultiYGrid<dim,ctype>::begin(seed.level());
1046
// \brief obtain EntityPointer from EntitySeed. */
1047
template <typename Seed>
1048
typename Traits::template Codim<Seed::codimension>::EntityPointer
1049
entityPointer(const Seed& seed) const
2776
return YaspEntityPointer<codim,GridImp>(this,g,
2777
TSI(g.cell_overlap(), seed.coord()));
2779
return YaspEntityPointer<codim,GridImp>(this,g,
2780
TSI(g.vertex_overlap(), seed.coord()));
1051
const int codim = Seed::codimension;
1052
YGridLevelIterator g = begin(this->getRealImplementation(seed).level());
1056
return YaspEntityPointer<codim,GridImp>(this,g,
1057
TSI(g->cell_overlap, this->getRealImplementation(seed).coord()));
1059
return YaspEntityPointer<codim,GridImp>(this,g,
1060
TSI(g->vertex_overlap, this->getRealImplementation(seed).coord()));
2782
1062
DUNE_THROW(GridError, "YaspEntityPointer: codim not implemented");
2786
//! return size (= distance in graph) of overlap region
2787
int overlapSize (int level, int codim) const
2789
YGLI g = MultiYGrid<dim,ctype>::begin(level);
2793
//! return size (= distance in graph) of overlap region
2794
int overlapSize (int codim) const
2796
YGLI g = MultiYGrid<dim,ctype>::begin(maxLevel());
2800
//! return size (= distance in graph) of ghost region
2801
int ghostSize (int level, int codim) const
2806
//! return size (= distance in graph) of ghost region
2807
int ghostSize (int codim) const
2812
//! number of entities per level and codim in this process
2813
int size (int level, int codim) const
1066
//! return size (= distance in graph) of overlap region
1067
int overlapSize (int level, int codim) const
1069
YGridLevelIterator g = begin(level);
1073
//! return size (= distance in graph) of overlap region
1074
int overlapSize (int codim) const
1076
YGridLevelIterator g = begin(maxLevel());
1080
//! return size (= distance in graph) of ghost region
1081
int ghostSize (int level, int codim) const
1086
//! return size (= distance in graph) of ghost region
1087
int ghostSize (int codim) const
1092
//! number of entities per level and codim in this process
1093
int size (int level, int codim) const
2815
1095
return sizes[level][codim];
2818
//! number of leaf entities per codim in this process
2819
int size (int codim) const
1098
//! number of leaf entities per codim in this process
1099
int size (int codim) const
2821
1101
return sizes[maxLevel()][codim];
2824
//! number of entities per level and geometry type in this process
2825
int size (int level, GeometryType type) const
1104
//! number of entities per level and geometry type in this process
1105
int size (int level, GeometryType type) const
2827
1107
return (type.isCube()) ? sizes[level][dim-type.dim()] : 0;
2830
//! number of leaf entities per geometry type in this process
2831
int size (GeometryType type) const
1110
//! number of leaf entities per geometry type in this process
1111
int size (GeometryType type) const
2833
1113
return size(maxLevel(),type);
2836
//! \brief returns the number of boundary segments within the macro grid
2837
size_t numBoundarySegments () const
2842
/*! The new communication interface
2844
communicate objects for all codims on a given level
2846
template<class DataHandleImp, class DataType>
2847
void communicate (CommDataHandleIF<DataHandleImp,DataType> & data, InterfaceType iftype, CommunicationDirection dir, int level) const
2849
YaspCommunicateMeta<dim,dim>::comm(*this,data,iftype,dir,level);
2852
/*! The new communication interface
2854
communicate objects for all codims on the leaf grid
2856
template<class DataHandleImp, class DataType>
2857
void communicate (CommDataHandleIF<DataHandleImp,DataType> & data, InterfaceType iftype, CommunicationDirection dir) const
2859
YaspCommunicateMeta<dim,dim>::comm(*this,data,iftype,dir,this->maxLevel());
2862
/*! The new communication interface
2864
communicate objects for one codim
2866
template<class DataHandle, int codim>
2867
void communicateCodim (DataHandle& data, InterfaceType iftype, CommunicationDirection dir, int level) const
2870
if (!data.contains(dim,codim)) return; // should have been checked outside
2873
typedef typename DataHandle::DataType DataType;
2875
// access to grid level
2876
YGLI g = MultiYGrid<dim,ctype>::begin(level);
2878
// find send/recv lists or throw error
2879
const std::deque<IS>* sendlist=0;
2880
const std::deque<IS>* recvlist=0;
2881
if (codim==0) // the elements
1116
//! \brief returns the number of boundary segments within the macro grid
1117
size_t numBoundarySegments () const
1122
/*! The new communication interface
1124
communicate objects for all codims on a given level
1126
template<class DataHandleImp, class DataType>
1127
void communicate (CommDataHandleIF<DataHandleImp,DataType> & data, InterfaceType iftype, CommunicationDirection dir, int level) const
1129
YaspCommunicateMeta<dim,dim>::comm(*this,data,iftype,dir,level);
1132
/*! The new communication interface
1134
communicate objects for all codims on the leaf grid
1136
template<class DataHandleImp, class DataType>
1137
void communicate (CommDataHandleIF<DataHandleImp,DataType> & data, InterfaceType iftype, CommunicationDirection dir) const
1139
YaspCommunicateMeta<dim,dim>::comm(*this,data,iftype,dir,this->maxLevel());
1142
/*! The new communication interface
1144
communicate objects for one codim
1146
template<class DataHandle, int codim>
1147
void communicateCodim (DataHandle& data, InterfaceType iftype, CommunicationDirection dir, int level) const
1150
if (!data.contains(dim,codim)) return; // should have been checked outside
1153
typedef typename DataHandle::DataType DataType;
1155
// access to grid level
1156
YGridLevelIterator g = begin(level);
1158
// find send/recv lists or throw error
1159
const std::deque<Intersection>* sendlist=0;
1160
const std::deque<Intersection>* recvlist=0;
1161
if (codim==0) // the elements
2883
1163
if (iftype==InteriorBorder_InteriorBorder_Interface)
2884
1164
return; // there is nothing to do in this case
2885
1165
if (iftype==InteriorBorder_All_Interface)
2887
sendlist = &g.send_cell_interior_overlap();
2888
recvlist = &g.recv_cell_overlap_interior();
1167
sendlist = &g->send_cell_interior_overlap;
1168
recvlist = &g->recv_cell_overlap_interior;
2890
1170
if (iftype==Overlap_OverlapFront_Interface || iftype==Overlap_All_Interface || iftype==All_All_Interface)
2892
sendlist = &g.send_cell_overlap_overlap();
2893
recvlist = &g.recv_cell_overlap_overlap();
1172
sendlist = &g->send_cell_overlap_overlap;
1173
recvlist = &g->recv_cell_overlap_overlap;
2896
if (codim==dim) // the vertices
1176
if (codim==dim) // the vertices
2898
1178
if (iftype==InteriorBorder_InteriorBorder_Interface)
2900
sendlist = &g.send_vertex_interiorborder_interiorborder();
2901
recvlist = &g.recv_vertex_interiorborder_interiorborder();
1180
sendlist = &g->send_vertex_interiorborder_interiorborder;
1181
recvlist = &g->recv_vertex_interiorborder_interiorborder;
2904
1184
if (iftype==InteriorBorder_All_Interface)
2906
sendlist = &g.send_vertex_interiorborder_overlapfront();
2907
recvlist = &g.recv_vertex_overlapfront_interiorborder();
1186
sendlist = &g->send_vertex_interiorborder_overlapfront;
1187
recvlist = &g->recv_vertex_overlapfront_interiorborder;
2909
1189
if (iftype==Overlap_OverlapFront_Interface || iftype==Overlap_All_Interface)
2911
sendlist = &g.send_vertex_overlap_overlapfront();
2912
recvlist = &g.recv_vertex_overlapfront_overlap();
1191
sendlist = &g->send_vertex_overlap_overlapfront;
1192
recvlist = &g->recv_vertex_overlapfront_overlap;
2914
1194
if (iftype==All_All_Interface)
2916
sendlist = &g.send_vertex_overlapfront_overlapfront();
2917
recvlist = &g.recv_vertex_overlapfront_overlapfront();
1196
sendlist = &g->send_vertex_overlapfront_overlapfront;
1197
recvlist = &g->recv_vertex_overlapfront_overlapfront;
2921
// change communication direction?
2922
if (dir==BackwardCommunication)
2923
std::swap(sendlist,recvlist);
2927
// Size computation (requires communication if variable size)
2928
std::vector<int> send_size(sendlist->size(),-1); // map rank to total number of objects (of type DataType) to be sent
2929
std::vector<int> recv_size(recvlist->size(),-1); // map rank to total number of objects (of type DataType) to be recvd
2930
std::vector<size_t*> send_sizes(sendlist->size(),static_cast<size_t*>(0)); // map rank to array giving number of objects per entity to be sent
2931
std::vector<size_t*> recv_sizes(recvlist->size(),static_cast<size_t*>(0)); // map rank to array giving number of objects per entity to be recvd
2932
if (data.fixedsize(dim,codim))
1201
// change communication direction?
1202
if (dir==BackwardCommunication)
1203
std::swap(sendlist,recvlist);
1207
// Size computation (requires communication if variable size)
1208
std::vector<int> send_size(sendlist->size(),-1); // map rank to total number of objects (of type DataType) to be sent
1209
std::vector<int> recv_size(recvlist->size(),-1); // map rank to total number of objects (of type DataType) to be recvd
1210
std::vector<size_t*> send_sizes(sendlist->size(),static_cast<size_t*>(0)); // map rank to array giving number of objects per entity to be sent
1211
std::vector<size_t*> recv_sizes(recvlist->size(),static_cast<size_t*>(0)); // map rank to array giving number of objects per entity to be recvd
1212
if (data.fixedsize(dim,codim))
2934
1214
// fixed size: just take a dummy entity, size can be computed without communication
2936
1216
for (ISIT is=sendlist->begin(); is!=sendlist->end(); ++is)
2938
typename Traits::template Codim<codim>::template Partition<All_Partition>::LevelIterator
2939
it(YaspLevelIterator<codim,All_Partition,GridImp>(this,g,is->grid.tsubbegin()));
2940
send_size[cnt] = is->grid.totalsize() * data.size(*it);
1218
typename Traits::template Codim<codim>::template Partition<All_Partition>::LevelIterator
1219
it(YaspLevelIterator<codim,All_Partition,GridImp>(this,g,is->grid.tsubbegin()));
1220
send_size[cnt] = is->grid.totalsize() * data.size(*it);
2944
1224
for (ISIT is=recvlist->begin(); is!=recvlist->end(); ++is)
2946
typename Traits::template Codim<codim>::template Partition<All_Partition>::LevelIterator
2947
it(YaspLevelIterator<codim,All_Partition,GridImp>(this,g,is->grid.tsubbegin()));
2948
recv_size[cnt] = is->grid.totalsize() * data.size(*it);
1226
typename Traits::template Codim<codim>::template Partition<All_Partition>::LevelIterator
1227
it(YaspLevelIterator<codim,All_Partition,GridImp>(this,g,is->grid.tsubbegin()));
1228
recv_size[cnt] = is->grid.totalsize() * data.size(*it);
2954
1234
// variable size case: sender side determines the size
2956
1236
for (ISIT is=sendlist->begin(); is!=sendlist->end(); ++is)
1238
// allocate send buffer for sizes per entitiy
1239
size_t *buf = new size_t[is->grid.totalsize()];
1240
send_sizes[cnt] = buf;
1242
// loop over entities and ask for size
1243
int i=0; size_t n=0;
1244
typename Traits::template Codim<codim>::template Partition<All_Partition>::LevelIterator
1245
it(YaspLevelIterator<codim,All_Partition,GridImp>(this,g,is->grid.tsubbegin()));
1246
typename Traits::template Codim<codim>::template Partition<All_Partition>::LevelIterator
1247
tsubend(YaspLevelIterator<codim,All_Partition,GridImp>(this,g,is->grid.tsubend()));
1248
for ( ; it!=tsubend; ++it)
2958
// allocate send buffer for sizes per entitiy
2959
size_t *buf = new size_t[is->grid.totalsize()];
2960
send_sizes[cnt] = buf;
2962
// loop over entities and ask for size
2963
int i=0; size_t n=0;
2964
typename Traits::template Codim<codim>::template Partition<All_Partition>::LevelIterator
2965
it(YaspLevelIterator<codim,All_Partition,GridImp>(this,g,is->grid.tsubbegin()));
2966
typename Traits::template Codim<codim>::template Partition<All_Partition>::LevelIterator
2967
tsubend(YaspLevelIterator<codim,All_Partition,GridImp>(this,g,is->grid.tsubend()));
2968
for ( ; it!=tsubend; ++it)
2970
buf[i] = data.size(*it);
2975
// now we know the size for this rank
2978
// hand over send request to torus class
2979
MultiYGrid<dim,ctype>::torus().send(is->rank,buf,is->grid.totalsize()*sizeof(size_t));
1250
buf[i] = data.size(*it);
1255
// now we know the size for this rank
1258
// hand over send request to torus class
1259
torus().send(is->rank,buf,is->grid.totalsize()*sizeof(size_t));
2983
1263
// allocate recv buffers for sizes and store receive request
2985
1265
for (ISIT is=recvlist->begin(); is!=recvlist->end(); ++is)
2987
// allocate recv buffer
2988
size_t *buf = new size_t[is->grid.totalsize()];
2989
recv_sizes[cnt] = buf;
2991
// hand over recv request to torus class
2992
MultiYGrid<dim,ctype>::torus().recv(is->rank,buf,is->grid.totalsize()*sizeof(size_t));
1267
// allocate recv buffer
1268
size_t *buf = new size_t[is->grid.totalsize()];
1269
recv_sizes[cnt] = buf;
1271
// hand over recv request to torus class
1272
torus().recv(is->rank,buf,is->grid.totalsize()*sizeof(size_t));
2996
1276
// exchange all size buffers now
2997
MultiYGrid<dim,ctype>::torus().exchange();
2999
1279
// release send size buffers
3001
1281
for (ISIT is=sendlist->begin(); is!=sendlist->end(); ++is)
3003
delete[] send_sizes[cnt];
3004
send_sizes[cnt] = 0;
1283
delete[] send_sizes[cnt];
1284
send_sizes[cnt] = 0;
3008
1288
// process receive size buffers
3010
1290
for (ISIT is=recvlist->begin(); is!=recvlist->end(); ++is)
3013
size_t *buf = recv_sizes[cnt];
3015
// compute total size
3017
for (int i=0; i<is->grid.totalsize(); ++i)
1293
size_t *buf = recv_sizes[cnt];
1295
// compute total size
1297
for (int i=0; i<is->grid.totalsize(); ++i)
3027
// allocate & fill the send buffers & store send request
3028
std::vector<DataType*> sends(sendlist->size(), static_cast<DataType*>(0)); // store pointers to send buffers
3030
for (ISIT is=sendlist->begin(); is!=sendlist->end(); ++is)
1307
// allocate & fill the send buffers & store send request
1308
std::vector<DataType*> sends(sendlist->size(), static_cast<DataType*>(0)); // store pointers to send buffers
1310
for (ISIT is=sendlist->begin(); is!=sendlist->end(); ++is)
3032
// std::cout << "[" << this->comm().rank() << "] "
3033
// << " send " << " dest=" << is->rank
3034
// << " size=" << send_size[cnt]
3037
1312
// allocate send buffer
3038
1313
DataType *buf = new DataType[send_size[cnt]];