dune-grid  2.1.1
geostorage.hh
Go to the documentation of this file.
00001 #ifndef DUNE_ALUGRIDGEOMETRYSTORAGE_HH
00002 #define DUNE_ALUGRIDGEOMETRYSTORAGE_HH
00003 
00004 // Dune includes
00005 #include <dune/common/misc.hh>
00006 #include <dune/grid/common/grid.hh>
00007 #include <dune/grid/common/gridfactory.hh>
00008 
00009 #if HAVE_ALUGRID
00010 
00011 #include <dune/grid/alugrid/3d/alu3dinclude.hh>
00012 #include <dune/grid/alugrid/2d/alu2dinclude.hh>
00013 
00014 namespace Dune
00015 {
00016   template<int dim, int dimw>
00017   class ALUCubeGrid;
00018 
00019   template<int dim, int dimw>
00020   class ALUSimplexGrid;
00021 
00022   template<int dim, int dimw>
00023   class ALUConformGrid;
00024 
00025   template <class GridImp, 
00026             class GeometryImp, 
00027             int nChild>
00028   class ALULocalGeometryStorage 
00029   {
00030     // array with pointers to the geometries
00031     std::vector < GeometryImp * > geoms_;
00032     // count local geometry creation
00033     int count_;
00034 
00035     static const int aluTriangle = ALU2DSPACE triangle;
00036     static const int aluQuad     = ALU2DSPACE quadrilateral;
00037     static const int aluTetra    = ALU3DSPACE tetra; 
00038     static const int aluHexa     = ALU3DSPACE hexa;
00039 
00040     // type of grid impl 
00041     typedef typename GridImp :: ctype ctype; 
00042     enum{ dimension       = GridImp :: dimension };
00043     enum{ dimensionworld  = GridImp :: dimensionworld };
00044 
00045     template <int dummy, int dim, int dimworld, int > 
00046     struct CreateGeometries;
00047 
00048     template <int dummy, int dimworld> 
00049     struct CreateGeometries<dummy, 2, dimworld, aluTriangle >
00050     {
00051       template <class Storage> 
00052       static void createGeometries(Storage& storage, 
00053                                    const GeometryType& type,
00054                                    const bool nonConform )
00055       {
00056         if( nonConform ) 
00057         {
00058           typedef ALUSimplexGrid< 2, dimworld > Grid;
00059           storage.template createGeometries< Grid > (type);
00060         }
00061         else 
00062         {
00063           typedef ALUConformGrid< 2, dimworld > Grid;
00064           storage.template createGeometries< Grid > (type);
00065         }
00066       }
00067     };
00068 
00069     template <int dummy> 
00070     struct CreateGeometries<dummy, 3, 3, aluTetra >
00071     {
00072       template <class Storage> 
00073       static void createGeometries(Storage& storage, 
00074                                    const GeometryType& type,
00075                                    const bool nonConform )
00076       {
00077         assert( nonConform );
00078         {
00079           typedef ALUSimplexGrid< 3, 3 > Grid;
00080           storage.template createGeometries< Grid > (type);
00081         }
00082       }
00083     };
00084 
00085     template <int dummy, int dimworld> 
00086     struct CreateGeometries<dummy, 2, dimworld, aluQuad >
00087     {
00088       template <class Storage> 
00089       static void createGeometries(Storage& storage, 
00090                                    const GeometryType& type,
00091                                    const bool nonConform )
00092       {
00093         assert ( nonConform ) ;
00094         {
00095           typedef ALUCubeGrid< 2, dimworld > Grid;
00096           storage.template createGeometries< Grid > (type);
00097         }
00098       }
00099     };
00100 
00101     template <int dummy> 
00102     struct CreateGeometries<dummy, 3, 3, aluHexa >
00103     {
00104       template <class Storage> 
00105       static void createGeometries(Storage& storage, 
00106                                    const GeometryType& type,
00107                                    const bool nonConform )
00108       {
00109         assert( nonConform );
00110         {
00111           typedef ALUCubeGrid< 3, 3 > Grid;
00112           storage.template createGeometries< Grid > (type);
00113         }
00114       }
00115     };
00116 
00117   public:
00118     // create empty storage
00119     ALULocalGeometryStorage (const GeometryType type, const bool nonConform) 
00120       : geoms_ (nChild, (GeometryImp *) 0 ) , count_ (0) 
00121     {
00122       // the idea is to create a grid containing the reference element,
00123       // refine once and the store the father - child relations 
00124       CreateGeometries<0, dimension, dimensionworld, GridImp :: elementType >
00125         ::createGeometries(*this, type, nonConform);
00126     }
00127 
00128     // desctructor deleteing geometries
00129     ~ALULocalGeometryStorage () 
00130     {
00131       for(size_t i=0; i<geoms_.size(); ++i)
00132         if(geoms_[i]) delete geoms_[i];
00133     }
00134 
00135     // check if geometry has been created
00136     bool geomCreated(int child) const { return geoms_[child] != 0; }
00137 
00138     // return reference to local geometry
00139     const GeometryImp & operator [] (int child) const
00140     {
00141       assert( geomCreated(child) );
00142       return *(geoms_[child]);
00143     }
00144 
00145     template < class Grid >
00146     void createGeometries(const GeometryType& type) 
00147     {
00148       // create factory without verbosity 
00149       GridFactory< Grid > factory( false );
00150 
00151       const Dune::GenericReferenceElement< ctype, dimension > &refElem
00152         = Dune::GenericReferenceElements< ctype, dimension >::general( type );
00153 
00154       // insert vertices 
00155       FieldVector<ctype, dimensionworld> pos( 0 );
00156       const int vxSize = refElem.size(dimension);  
00157       for(int i=0; i<vxSize; ++i)
00158       {
00159         FieldVector<ctype, dimension> position = refElem.position(i, dimension );
00160         // copy position 
00161         for(int d = 0; d<dimension; ++d )
00162           pos[ d ] = position[ d ];
00163 
00164         factory.insertVertex( pos );
00165       }
00166 
00167       std::vector< unsigned int > vertices( vxSize );
00168       // create grid with reference element
00169       for(size_t i=0; i<vertices.size(); ++i) vertices[ i ] = i;
00170       factory.insertElement(type, vertices);
00171 
00172       // save original sbuf
00173       std::streambuf* cerr_sbuf = std::cerr.rdbuf();
00174       std::stringstream tempout; 
00175       // redirect 'cerr' to a 'fout' to avoid unnecessary output in constructors 
00176       std::cerr.rdbuf(tempout.rdbuf()); 
00177 
00178       Grid* gridPtr = factory.createGrid();
00179       Grid& grid    = *gridPtr; 
00180 
00181       // restore the original stream buffer
00182       std::cerr.rdbuf(cerr_sbuf); 
00183 
00184       //std::cerr = savecerr;
00185       
00186       // refine once to get children 
00187       const int level = 1;
00188       grid.globalRefine( level );
00189 
00190       {
00191         typedef typename Grid :: template Partition< All_Partition >:: LevelGridView MacroGridView;
00192         MacroGridView macroView = grid.template levelView< All_Partition > ( 0 );
00193         typedef typename MacroGridView :: template Codim< 0 > :: Iterator Iterator;
00194 
00195         Iterator it = macroView.template begin<0> (); 
00196 
00197         if( it == macroView.template end<0>() ) 
00198           DUNE_THROW(InvalidStateException,"Empty Grid, should contain at least 1 element");
00199 
00200         typedef typename Iterator :: Entity EntityType;
00201 
00202         const EntityType& entity = *it;
00203         const typename EntityType :: Geometry& geo = entity.geometry();
00204         typedef typename EntityType :: HierarchicIterator HierarchicIteratorType;
00205         const HierarchicIteratorType end = entity.hend( level );
00206 
00207         int childNum = 0;
00208         for( HierarchicIteratorType child = entity.hbegin( level ); 
00209              child != end; ++child, ++childNum ) 
00210         {
00211           create( geo, child->geometry(), childNum );
00212         }
00213       }
00214 
00215       // delete grid 
00216       delete gridPtr;
00217     }
00218 
00219   protected:  
00220     // create local geometry
00221     template <class Geometry>
00222     void create (const Geometry & father, 
00223                  const Geometry & son, 
00224                  const int child)
00225     {
00226       assert( !geomCreated(child) );
00227       assert( child >=0 && child < nChild );
00228 
00229       assert( count_ < nChild );
00230       ++count_;
00231 
00232       typedef typename GeometryImp :: ImplementationType ImplType;
00233       ImplType geoImp;
00234       geoImp.buildGeomInFather( father, son );
00235       geoms_[child] = new GeometryImp( geoImp );
00236     }
00237   };  
00238 
00239 } // end namespace Dune
00240 
00241 #endif // end HAVE_ALUGRID
00242 
00243 #endif