dgfyasp.hh

Go to the documentation of this file.
00001 #ifndef DUNE_DGFPARSERYASP_HH
00002 #define DUNE_DGFPARSERYASP_HH
00003 
00004 #include <dune/grid/yaspgrid.hh>
00005 #include "dgfparser.hh"
00006 
00007 namespace Dune
00008 {
00009 
00010   namespace dgf
00011   {
00012 
00026     class YaspGridParameterBlock
00027     : public GridParameterBlock
00028     {
00029     protected:
00030       int _overlap;     // overlap for YaspGrid
00031 
00032     public:
00034       YaspGridParameterBlock( std::istream &in )
00035         : GridParameterBlock( in ),
00036           _overlap( 0 )  // default value
00037       {
00038         // check overlap
00039         if( findtoken( "overlap" ) )
00040         {
00041           int x;
00042           if( getnextentry(x) ) _overlap = x;
00043           else 
00044           {
00045             dwarn << "GridParameterBlock: found keyword `overlap' but no value, defaulting to `" <<  _overlap  <<"' !\n";
00046           }
00047 
00048           if (_overlap < 0) 
00049           {
00050             DUNE_THROW(DGFException,"Negative overlap specified!");
00051           }
00052         }
00053         else
00054         {
00055           dwarn << "YaspGridParameterBlock: Parameter 'overlap' not specified, "
00056                 << "defaulting to '" << _overlap << "'." << std::endl;
00057         }
00058         
00059       }
00060 
00062       int overlap () const
00063       {
00064         return _overlap;
00065       }
00066 
00067     };
00068 
00069   }
00070 
00071   template <int dim>
00072   struct DGFGridFactory< YaspGrid<dim> >
00073   {
00074     typedef YaspGrid<dim> Grid;
00075     const static int dimension = Grid::dimension;
00076     typedef MPIHelper::MPICommunicator MPICommunicatorType;
00077 
00078     explicit DGFGridFactory ( std::istream &input,
00079                               MPICommunicatorType comm = MPIHelper::getCommunicator() )
00080     {
00081       generate( input, comm );
00082     }
00083 
00084     explicit DGFGridFactory ( const std::string &filename,
00085                               MPICommunicatorType comm = MPIHelper::getCommunicator() )
00086     {
00087       std::ifstream input( filename.c_str() );
00088       generate( input, comm );
00089     }
00090 
00091     Grid *grid() const
00092     {
00093       return grid_;
00094     }
00095 
00096     template <class Intersection>
00097     bool wasInserted(const Intersection &intersection) const
00098     {
00099       return false;
00100     }
00101     template <class Intersection>
00102     int boundaryId(const Intersection &intersection) const
00103     {
00104       return intersection.boundaryId();
00105     }
00106 
00107     template< int codim >
00108     int numParameters () const
00109     {
00110       return 0;
00111     }
00112 
00113     template< class Entity >
00114     std::vector<double> &parameter ( const Entity &entity )
00115     {
00116       return emptyParam;
00117     }
00118 
00119   private:
00120     void generate( std::istream &gridin, MPICommunicatorType comm );
00121 
00122     Grid *grid_;
00123     std::vector<double> emptyParam;
00124   };
00125 
00126   template< int dim >
00127   inline void DGFGridFactory< YaspGrid< dim > >
00128     ::generate ( std::istream &gridin, MPICommunicatorType comm )
00129   {
00130     dgf::IntervalBlock intervalBlock( gridin );
00131 
00132     if( !intervalBlock.isactive() )
00133       DUNE_THROW( DGFException, "YaspGrid can only be created from an interval block." );
00134 
00135     if( intervalBlock.numIntervals() != 1 )
00136       DUNE_THROW( DGFException, "YaspGrid can only handle 1 interval block." );
00137 
00138     if( intervalBlock.dimw() != dim )
00139     {
00140       DUNE_THROW( DGFException,
00141                   "Cannot read an interval of dimension " << intervalBlock.dimw()
00142                   << "into a YaspGrid< " << dim << " >." );
00143     }
00144     
00145     const dgf::IntervalBlock::Interval &interval = intervalBlock.get( 0 );
00146 
00147     FieldVector<double,dim> lang;
00148     FieldVector<int,dim>    anz;
00149     for( int i = 0; i < dim; ++i )
00150     {
00151       // check that start point is 0.0
00152       if( fabs( interval.p[ 0 ][ i ] ) > 1e-10 )
00153       {
00154         DUNE_THROW( DGFException,
00155                     "YaspGrid cannot handle grids with non-zero left lower corner." );
00156       }
00157 
00158       lang[ i ] = interval.p[ 1 ][ i ] - interval.p[ 0 ][ i ];
00159       anz[ i ]  = interval.n[ i ];
00160     }
00161 
00162     typedef dgf::PeriodicFaceTransformationBlock::AffineTransformation Transformation;
00163     dgf::PeriodicFaceTransformationBlock trafoBlock( gridin, dim );
00164     FieldVector< bool, dim > per( false );
00165     const int numTrafos = trafoBlock.numTransformations();
00166     for( int k = 0; k < numTrafos; ++k )
00167     {
00168       const Transformation &trafo = trafoBlock.transformation( k );
00169 
00170       bool identity = true;
00171       for( int i = 0; i < dim; ++i )
00172         for( int j = 0; j < dim; ++j )
00173           identity &= (fabs( (i == j ? 1.0 : 0.0) - trafo.matrix( i, j ) ) < 1e-10);
00174       if( !identity )
00175         DUNE_THROW( DGFException, "YaspGrid can only handle shifts as periodic face transformations." );
00176 
00177       int numDirs = 0;
00178       int dir = -1;
00179       for( int i = 0; i < dim; ++i )
00180       {
00181         if( fabs( trafo.shift[ i ] ) < 1e-10 )
00182           continue;
00183         dir = i;
00184         ++numDirs;
00185       }
00186       if( (numDirs != 1) || (fabs( fabs( trafo.shift[ dir ] ) - lang[ dir ] ) >= 1e-10) )
00187       {
00188         std::cerr << "Tranformation '" << trafo
00189                   << "' does not map boundaries on boundaries." << std::endl;
00190       }
00191       else
00192         per[ dir ] = true;
00193     }
00194 
00195     // get grid parameters 
00196     dgf::YaspGridParameterBlock grdParam( gridin );
00197 
00198 #if HAVE_MPI
00199     grid_ = new YaspGrid< dim >( comm, lang, anz, per, grdParam.overlap() );
00200 #else
00201     grid_ = new YaspGrid< dim >( lang, anz, per, grdParam.overlap() );
00202 #endif
00203   }
00204 
00205   template <int dim>
00206   struct DGFGridInfo< YaspGrid<dim> > {
00207       static int refineStepsForHalf() {return 1;}
00208       static double refineWeight() {return pow(0.5,dim);}
00209   };
00210 
00211 
00212 }
00213 #endif

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].