00001 #ifndef DUNE_ALBERTAGRIDINDEXSETS_HH
00002 #define DUNE_ALBERTAGRIDINDEXSETS_HH
00003
00004
00005
00006
00007 #include <dune/common/stdstreams.hh>
00008 #include <dune/grid/common/grid.hh>
00009 #include <dune/grid/common/indexidset.hh>
00010
00011
00012
00013 namespace Dune {
00014
00016 template <class GridImp>
00017 struct AlbertaGridHierarchicIteratorTypes
00018 {
00020 template<int cd>
00021 struct Codim
00022 {
00023 template<PartitionIteratorType pitype>
00024 struct Partition
00025 {
00026
00027
00028
00029
00030 typedef typename RemoveConst<GridImp>::Type::Traits::template Codim<cd>::template Partition<pitype>::LeafIterator Iterator;
00031 };
00032 };
00033 };
00034
00035
00036 template <int dim, int dimworld> class AlbertaGrid;
00037 template<int cd, int dim, class GridImp> class AlbertaGridEntity;
00038 template <class GridType, int dim> struct MarkEdges;
00039
00040 template <int dim, int dimworld>
00041 class AlbertaGridHierarchicIndexSet :
00042 public IndexSetDefaultImplementation<AlbertaGrid<dim,dimworld>,
00043 AlbertaGridHierarchicIndexSet<dim,dimworld>,
00044 AlbertaGridHierarchicIteratorTypes<AlbertaGrid<dim,dimworld> > >
00045
00046 {
00047 typedef AlbertaGrid<dim,dimworld> GridType;
00048
00049
00050
00051
00052 typedef typename RemoveConst<GridType>::Type::Traits::template Codim<0>::Entity EntityCodim0Type;
00053 enum { numVecs = AlbertHelp::numOfElNumVec };
00054 enum { numCodim = dim + 1 };
00055
00056
00057 friend class AlbertaGrid<dim,dimworld>;
00058 friend class MarkEdges<GridType,3>;
00059 friend class MarkEdges<const GridType,3>;
00060
00061
00062 AlbertaGridHierarchicIndexSet(const GridType & grid) : grid_( grid ) {}
00063 public:
00064 enum { ncodim = numCodim };
00065
00067 template <class EntityType>
00068 bool contains(const EntityType &) const
00069 {
00070
00071 return true;
00072 }
00073
00075 template <class EntityType>
00076 int index (const EntityType & ep) const
00077 {
00078 enum { cd = EntityType :: codimension };
00079
00080 const AlbertaGridEntity<cd,dim,const GridType> & en = (grid_.template getRealEntity<cd>(ep));
00081 return getIndex(en.getElInfo()->el, en.getFEVnum(),Int2Type<dim-cd>());
00082 }
00083
00085 template <int cd>
00086 int subIndex (const EntityCodim0Type & en, int i) const
00087 {
00088 return getIndex((grid_.template getRealEntity<0>(en)).getElInfo()->el
00089 ,i,Int2Type<dim-cd>());
00090 }
00091
00093 int size (GeometryType type) const
00094 {
00095 if( !type.isSimplex() ) return 0;
00096 return this->size(GridType::dimension-type.dim());
00097 }
00098
00100 int size (int codim) const
00101 {
00102 return grid_.global_size(codim);
00103 }
00104
00106 const std::vector< GeometryType > & geomTypes(int codim) const
00107 {
00108
00109 return grid_.geomTypes(codim);
00110 }
00111
00114 template<int cd, PartitionIteratorType pitype>
00115 typename AlbertaGridHierarchicIteratorTypes<GridType>::template Codim<cd>::
00116 template Partition<pitype>::Iterator end () const
00117 {
00118 return grid_.template leafend<cd,pitype> ();
00119 }
00120
00123 template<int cd, PartitionIteratorType pitype>
00124 typename AlbertaGridHierarchicIteratorTypes<GridType>::template Codim<cd>::
00125 template Partition<pitype>::Iterator begin () const
00126 {
00127 return grid_.template leafbegin<cd,pitype> ();
00128 }
00129
00130 private:
00131
00132 const GridType & grid_;
00133
00134 const ALBERTA AlbertHelp :: AlbertaGridReferenceTopology<dim> refTopo_;
00135
00136 const int * elNumVec_[numVecs];
00137
00138
00139 int nv_[numVecs];
00140 int dof_[numVecs];
00141
00142
00143 void updatePointers(ALBERTA AlbertHelp::DOFVEC_STACK & dofvecs)
00144 {
00145 for(int i=0; i<numVecs; i++)
00146 {
00147 elNumVec_[i] = (dofvecs.elNumbers[i])->vec;
00148 assert(elNumVec_[i]);
00149 }
00150
00151 setDofIdentifier<0> (dofvecs);
00152 if(numVecs > 1) setDofIdentifier<1> (dofvecs);
00153 if(numVecs > 2) setDofIdentifier<2> (dofvecs);
00154 if(numVecs > 3) setDofIdentifier<3> (dofvecs);
00155 }
00156
00157 template <int cd>
00158 void setDofIdentifier (ALBERTA AlbertHelp::DOFVEC_STACK & dofvecs)
00159 {
00160 const ALBERTA DOF_ADMIN * elAdmin_ = dofvecs.elNumbers[cd]->fe_space->admin;
00161
00162
00163 nv_ [cd] = elAdmin_->n0_dof [ALBERTA AlbertHelp::AlbertaDofType<dim,cd>::type];
00164 assert( nv_ [cd] == 0);
00165 dof_[cd] = elAdmin_->mesh->node[ALBERTA AlbertHelp::AlbertaDofType<dim,cd>::type];
00166 }
00167
00168
00169
00170
00171 int getIndex ( const ALBERTA EL * el, int i , Int2Type<dim> fake ) const
00172 {
00173 enum { cd = 0 };
00174 assert(el);
00175 return elNumVec_[cd][ el->dof[ dof_[cd] ][nv_[cd]] ];
00176 }
00177
00178 enum { cd1 = (dim == 2) ? 1 : 2 };
00179
00180
00181
00182 int getIndex ( const ALBERTA EL * el, int i , Int2Type<cd1> fake ) const
00183 {
00184 enum { cd = 1 };
00185 assert(el);
00186 assert( (dim == 2) || (dim == 3));
00187
00188
00189 return elNumVec_[cd][ el->dof[ dof_[cd] + i ][ nv_[cd] ] ];
00190 }
00191
00192 enum { cd2 = (dim > 2) ? 1 : 6 };
00193
00194
00195
00196 int getIndex ( const ALBERTA EL * el, int i , Int2Type<cd2> fake ) const
00197 {
00198 enum { cd = 2 };
00199 assert(el);
00200
00201
00202
00203
00204 return elNumVec_[cd][ el->dof[ dof_[cd] + refTopo_.dune2albertaEdge(i) ][ nv_[cd] ] ];
00205 }
00206
00207
00208
00209
00210 int getIndex ( const ALBERTA EL * el, int i , Int2Type<0> fake ) const
00211 {
00212 assert(el);
00213 return (el->dof[i][0]);
00214 }
00215
00216 int getIndex ( const ALBERTA EL * el, int i , Int2Type<-1> fake ) const
00217 {
00218 assert(false);
00219 DUNE_THROW(AlbertaError,"Error, wrong codimension!\n");
00220 return -1;
00221 }
00222 };
00223
00224
00226 template <int dim, int dimworld>
00227 class AlbertaGridIdSet :
00228 public IdSetDefaultImplementation < AlbertaGrid<dim,dimworld> ,
00229 AlbertaGridIdSet<dim,dimworld> , int >
00230 {
00231 typedef AlbertaGrid<dim,dimworld> GridType;
00232 typedef typename GridType :: HierarchicIndexSet HierarchicIndexSetType;
00233
00234
00235 enum { codimMultiplier = 300000000 };
00236
00237
00238
00239
00240 typedef typename RemoveConst<GridType>::Type::Traits::template Codim<0>::Entity EntityCodim0Type;
00241
00243 AlbertaGridIdSet(const GridType & grid) : hset_(grid.hierarchicIndexSet())
00244 {
00245 for(int i=0; i<dim+1; i++)
00246 codimStart_[i] = i*codimMultiplier;
00247 }
00248
00249 friend class AlbertaGrid<dim,dimworld>;
00250 public:
00252 typedef int IdType;
00253
00255 template <class EntityType>
00256 int id (const EntityType & ep) const
00257 {
00258 enum { cd = EntityType :: codimension };
00259 assert( hset_.size(cd) < codimMultiplier );
00260 return codimStart_[cd] + hset_.index(ep);
00261 }
00262
00264 template <int codim>
00265 int id (const typename GridType::template Codim<codim>::Entity& ep) const
00266 {
00267
00268 assert( hset_.size(codim) < codimMultiplier );
00269 return codimStart_[codim] + hset_.index(ep);
00270 }
00271
00273 template <int cd>
00274 int subId (const EntityCodim0Type & ep, int i) const
00275 {
00276 assert( hset_.size(cd) < codimMultiplier );
00277 return codimStart_[cd] + hset_.template subIndex<cd>(ep,i);
00278 }
00279
00280 private:
00281
00282 const HierarchicIndexSetType & hset_;
00283
00284
00285 int codimStart_[dim+1];
00286 };
00287 }
00288
00289 #endif