dune-grid  2.2.0
dgfgeogrid.hh
Go to the documentation of this file.
00001 #ifndef DUNE_DGFGEOGRID_HH
00002 #define DUNE_DGFGEOGRID_HH
00003 
00004 #include <dune/common/typetraits.hh>
00005 
00006 #include <dune/grid/geometrygrid.hh>
00007 #include <dune/grid/io/file/dgfparser/dgfparser.hh>
00008 #include <dune/grid/io/file/dgfparser/blocks/projection.hh>
00009 #include <dune/grid/utility/hostgridaccess.hh>
00010 #include <dune/grid/common/intersection.hh>
00011 
00012 #include <dune/grid/io/file/dgfparser/parser.hh>
00013 
00014 
00015 namespace Dune
00016 {
00017   /************************************************************************
00018    * Warning:
00019    * Reading DGF files directly into a GeometryGrid is a dirty hack for
00020    * two reasons:
00021    *   1) The host grid and coordinate function are never deleted (dangling
00022    *      pointers).
00023    *   2) The coordinate function has to provide a default constructor
00024    ************************************************************************/
00025 
00026   // forward declaration
00027   // -------------------
00028   template < class GridImp, template < class > class IntersectionImp >
00029   class Intersection;
00030 
00031   // DGFCoordFunction
00032   // ----------------
00033 
00034   template< int dimD, int dimR > 
00035   class DGFCoordFunction
00036   : public AnalyticalCoordFunction< double, dimD, dimR, DGFCoordFunction< dimD, dimR > >
00037   {
00038     typedef DGFCoordFunction< dimD, dimR > This;
00039     typedef AnalyticalCoordFunction< double, dimD, dimR, This > Base;
00040 
00041   public:
00042     typedef typename Base::DomainVector DomainVector;
00043     typedef typename Base::RangeVector RangeVector;
00044 
00045     typedef dgf::ProjectionBlock::Expression Expression;
00046 
00047     DGFCoordFunction ( const Expression *expression )
00048     : expression_( expression )
00049     {}
00050 
00051     void evaluate ( const DomainVector &x, RangeVector &y ) const
00052     {
00053       std::vector< double > vx( dimD );
00054       std::vector< double > vy;
00055       for( int i = 0; i < dimD; ++i )
00056         vx[ i ] = x[ i ];
00057       expression_->evaluate( vx, vy );
00058       assert( vy.size() == size_t( dimR ) );
00059       for( int i = 0; i < dimR; ++i )
00060         y[ i ] = vy[ i ];
00061     }
00062 
00063   private:
00064     const Expression *expression_;
00065   };
00066 
00067 
00068 
00069   // DGFCoordFunctionFactory
00070   // -----------------------
00071 
00072   template< class HostGrid, class CoordFunction,
00073             bool discrete = GeoGrid::isDiscreteCoordFunctionInterface< typename CoordFunction::Interface >::value >
00074   struct DGFCoordFunctionFactory;
00075 
00076 
00077   template< class HostGrid, class CoordFunction >
00078   struct DGFCoordFunctionFactory< HostGrid, CoordFunction, false >
00079   {
00080     static CoordFunction *create ( std::istream &input, const HostGrid &hostGrid )
00081     {
00082       return new CoordFunction;
00083     }
00084   };
00085 
00086 
00087   template< class HostGrid, class CoordFunction >
00088   struct DGFCoordFunctionFactory< HostGrid, CoordFunction, true >
00089   {
00090     static CoordFunction *create ( std::istream &input, const HostGrid &hostGrid )
00091     {
00092       return new CoordFunction( hostGrid );
00093     }
00094   };
00095 
00096 
00097   template< class HostGrid, int dimD, int dimR > 
00098   struct DGFCoordFunctionFactory< HostGrid, DGFCoordFunction< dimD, dimR >, false >
00099   {
00100     typedef DGFCoordFunction< dimD, dimR > CoordFunction;
00101 
00102     static CoordFunction *create ( std::istream &input, const HostGrid &hostGrid )
00103     {
00104       dgf::ProjectionBlock projectionBlock( input, dimR );
00105       const typename CoordFunction::Expression *expression = projectionBlock.function( "coordfunction" );
00106       if( expression == 0 )
00107         DUNE_THROW( DGFException, "no coordfunction specified in DGF file." );
00108       return new CoordFunction( expression );
00109     }
00110   };
00111 
00112 
00113 
00114   // DGFGridFactory for GeometryGrid
00115   // -------------------------------
00116 
00117   template< class HostGrid, class CoordFunction, class Allocator >
00118   struct DGFGridFactory< GeometryGrid< HostGrid, CoordFunction, Allocator > >
00119   {
00120     typedef GeometryGrid< HostGrid, CoordFunction, Allocator > Grid;
00121 
00122     const static int dimension = Grid::dimension;
00123     typedef MPIHelper::MPICommunicator MPICommunicator;
00124     typedef typename Grid::template Codim<0>::Entity Element;
00125     typedef typename Grid::template Codim<dimension>::Entity Vertex;
00126 
00127     typedef DGFCoordFunctionFactory< HostGrid, CoordFunction > CoordFunctionFactory;
00128 
00129     explicit DGFGridFactory ( std::istream &input,
00130                               MPICommunicator comm = MPIHelper::getCommunicator() )
00131     : dgfHostFactory_( input, comm ),
00132       grid_( 0 )
00133     {
00134       HostGrid *hostGrid = dgfHostFactory_.grid();
00135       assert( hostGrid != 0 );
00136       CoordFunction *coordFunction = CoordFunctionFactory::create( input, *hostGrid );
00137       grid_ = new Grid( hostGrid, coordFunction );
00138     }
00139 
00140     explicit DGFGridFactory ( const std::string &filename, 
00141                               MPICommunicator comm = MPIHelper::getCommunicator() )
00142     : dgfHostFactory_( filename, comm ),
00143       grid_( 0 )
00144     {
00145       HostGrid *hostGrid = dgfHostFactory_.grid();
00146       assert( hostGrid != 0 );
00147       std::ifstream input( filename.c_str() );
00148       CoordFunction *coordFunction = CoordFunctionFactory::create( input, *hostGrid );
00149       grid_ = new Grid( hostGrid, coordFunction );
00150     }
00151 
00152     Grid *grid () const
00153     {
00154       return grid_;
00155     }
00156 
00157     template< class Intersection >
00158     bool wasInserted ( const Intersection &intersection ) const
00159     {
00160       return dgfHostFactory_.wasInserted( HostGridAccess< Grid >::hostIntersection( intersection ) ); 
00161     }
00162 
00163     template< class Intersection >
00164     int boundaryId ( const Intersection &intersection ) const
00165     {
00166       return dgfHostFactory_.boundaryId( HostGridAccess< Grid >::hostIntersection( intersection ) ); 
00167     }
00168 
00169     template< int codim >
00170     int numParameters () const
00171     {
00172       return dgfHostFactory_.template numParameters< codim >();
00173     }
00174 
00175     // return true if boundary parameters found
00176     bool haveBoundaryParameters () const
00177     {
00178       return dgfHostFactory_.haveBoundaryParameters();
00179     }
00180 
00181     template< class GG, template< class > class II >
00182     const typename DGFBoundaryParameter::type &
00183       boundaryParameter ( const Dune::Intersection< GG, II > & intersection ) const
00184     {
00185       return dgfHostFactory_.boundaryParameter( HostGridAccess< Grid >::hostIntersection( intersection ) );
00186     }
00187 
00188     template< class Entity >
00189     std::vector< double > &parameter ( const Entity &entity )
00190     {
00191       return dgfHostFactory_.parameter( HostGridAccess< Grid >::hostEntity( entity ) );
00192     }
00193 
00194   private:
00195     DGFGridFactory< HostGrid > dgfHostFactory_;
00196     Grid *grid_;
00197   };
00198 
00199 
00200 
00201   // DGFGridInfo for GeometryGrid
00202   // ----------------------------
00203 
00204   template< class HostGrid, class CoordFunction, class Allocator >
00205   struct DGFGridInfo< GeometryGrid< HostGrid, CoordFunction, Allocator > >
00206   {
00207     static int refineStepsForHalf ()
00208     {
00209       return DGFGridInfo< HostGrid >::refineStepsForHalf();
00210     }
00211 
00212     static double refineWeight ()
00213     {
00214       return -1.0;
00215     }
00216   };
00217   
00218 }
00219 
00220 #endif // #ifndef DUNE_DGFGEOGRID_HH