albertagrid/indexsets.hh

00001 #ifndef DUNE_ALBERTAGRIDINDEXSETS_HH
00002 #define DUNE_ALBERTAGRIDINDEXSETS_HH
00003 
00004 //- System includes
00005 
00006 //- Dune includes
00007 #include <dune/common/stdstreams.hh>
00008 #include <dune/grid/common/grid.hh>
00009 #include <dune/grid/common/indexidset.hh>
00010 
00011 //- Local includes
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           We use the RemoveConst to extract the Type from the mutable class,
00028           because the const class is not instantiated yet.
00029         */
00030         typedef typename RemoveConst<GridImp>::Type::Traits::template Codim<cd>::template Partition<pitype>::LeafIterator Iterator;
00031       };
00032     };
00033   };
00034 
00035   // Forward declarations
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       We use the RemoveConst to extract the Type from the mutable class,
00050       because the const class is not instantiated yet.
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     // all classes that are allowed to call private functions 
00057     friend class AlbertaGrid<dim,dimworld>;
00058     friend class MarkEdges<GridType,3>; 
00059     friend class MarkEdges<const GridType,3>; 
00060 
00061     // only  AlbertaGrid is allowed to create this class 
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       // always true for this set 
00071       return true; 
00072     }
00073 
00075     template <class EntityType>
00076     int index (const EntityType & ep) const
00077     {
00078       enum { cd = EntityType :: codimension };
00079       // get real entity 
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       // returns all simplex 
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     // out grid 
00132     const GridType & grid_;
00133     // constains the mapping from dune to alberta numbers  
00134     const ALBERTA AlbertHelp :: AlbertaGridReferenceTopology<dim> refTopo_;
00135     // the vectors containing the numbers
00136     const int * elNumVec_[numVecs];
00137    
00138     // stores offset of dof numbers on given elements 
00139     int nv_[numVecs];
00140     int dof_[numVecs];
00141 
00142     // update vec pointer of the DOF_INT_VECs, which can change during resize 
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       // see Albert Doc. , should stay the same 
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     // codim = 0 means we get from dim-cd = dim 
00169     // this is the method for the element numbers 
00170     // --element
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     // method for face numbers 
00180     // codim = 0 means we get from dim-cd = dim 
00181     // --face
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       // dof_[cd] marks the insertion point form which this dofs start
00188       // then i is the i-th dof
00189       return elNumVec_[cd][ el->dof[ dof_[cd] + i ][ nv_[cd] ] ];
00190     }
00191     
00192     enum { cd2 = (dim > 2) ? 1 : 6 };
00193     // codim = 0 means we get from dim-cd = dim 
00194     // this method we have only in 3d, for edges 
00195     // --edges 
00196     int getIndex ( const ALBERTA EL * el, int i , Int2Type<cd2> fake ) const
00197     {
00198       enum { cd = 2 }; 
00199       assert(el);
00200 
00201       // dof_[cd] marks the insertion point form which this dofs start
00202       // then i is the i-th dof, here we addionally have to use the edge
00203       // mapping 
00204       return elNumVec_[cd][ el->dof[ dof_[cd] + refTopo_.dune2albertaEdge(i) ][ nv_[cd] ] ];
00205     }
00206 
00207     // codim = dim  means we get from dim-cd = 0 
00208     // return index of vertices 
00209     // --vertex
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   }; // end class AlbertaGridHierarchicIndexSet
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     // this means that only up to 300000000 entities are allowed 
00235     enum { codimMultiplier = 300000000 };
00236     /*
00237       We use the RemoveConst to extract the Type from the mutable class,
00238       because the const class is not instantiated yet.
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       //enum { cd = EntityType :: codimension };
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     // our Grid 
00282     const HierarchicIndexSetType & hset_;
00283 
00284     // store start of each codim numbers 
00285     int codimStart_[dim+1]; 
00286   };
00287 } // namespace Dune
00288 
00289 #endif

Generated on 12 Dec 2007 with Doxygen (ver 1.5.1)