dune-grid  2.2.0
io/file/dgfparser/blocks/projection.hh
Go to the documentation of this file.
00001 #ifndef DUNE_DGF_PROJECTIONBLOCK_HH
00002 #define DUNE_DGF_PROJECTIONBLOCK_HH
00003 
00004 #include <map>
00005 
00006 #include <dune/grid/common/boundaryprojection.hh>
00007 #include <dune/grid/io/file/dgfparser/blocks/basic.hh>
00008 
00009 namespace Dune
00010 {
00011 
00012   namespace dgf
00013   {
00014 
00015     // ProjectionBlock
00016     // ---------------
00017 
00018     class ProjectionBlock
00019     : public BasicBlock
00020     {
00021       struct Token
00022       {
00023         friend std::ostream &operator<< ( std::ostream &, const Token & );
00024         
00025         enum Type
00026         {
00027           string, number,
00028           defaultKeyword, functionKeyword, segmentKeyword,
00029           sqrtKeyword, sinKeyword, cosKeyword, piKeyword,
00030           comma,
00031           equals,
00032           openingParen, closingParen, openingBracket, closingBracket, normDelim,
00033           additiveOperator, multiplicativeOperator, powerOperator,
00034           endOfLine
00035         };
00036 
00037         Type type;
00038         char symbol;
00039         std::string literal;
00040         double value;
00041 
00042         void setSymbol ( const Type &t, char c )
00043         {
00044           type = t;
00045           symbol = c;
00046         }
00047       };
00048 
00049       friend std::ostream &operator<< ( std::ostream &, const Token & );
00050 
00051     public:
00052       struct Expression;
00053 
00054     private:
00055       template< int dimworld >
00056       struct BoundaryProjection;
00057 
00058     public:
00059       ProjectionBlock ( std::istream &in, int dimworld );
00060 
00061       template< int dimworld >
00062       const DuneBoundaryProjection< dimworld > *defaultProjection () const
00063       {
00064         if( defaultFunction_ != 0 )
00065           return new BoundaryProjection< dimworld >( defaultFunction_ );
00066         else
00067           return 0;
00068       }
00069 
00070       size_t numBoundaryProjections () const
00071       {
00072         return boundaryFunctions_.size();
00073       }
00074 
00075       const std::vector< unsigned int > &boundaryFace ( const size_t i ) const
00076       {
00077         assert( i < numBoundaryProjections() );
00078         return boundaryFunctions_[ i ].first;
00079       }
00080 
00081       template< int dimworld >
00082       const DuneBoundaryProjection< dimworld > *boundaryProjection ( const size_t i ) const
00083       {
00084         assert( i < numBoundaryProjections() );
00085         return new BoundaryProjection< dimworld >( boundaryFunctions_[ i ].second );
00086       }
00087 
00088       const Expression *function ( const std::string &name ) const
00089       {
00090         const FunctionMap::const_iterator it = functions_.find( name );
00091         return (it != functions_.end() ? it->second : 0);
00092       }
00093 
00094     private:
00095       void parseFunction ();
00096       const Expression *parseBasicExpression ( const std::string &variableName );
00097       const Expression *parsePostfixExpression ( const std::string &variableName );
00098       const Expression *parseUnaryExpression ( const std::string &variableName );
00099       const Expression *parsePowerExpression ( const std::string &variableName );
00100       const Expression *parseMultiplicativeExpression ( const std::string &variableName );
00101       const Expression *parseExpression ( const std::string &variableName );
00102       void parseDefault ();
00103       void parseSegment ();
00104 
00105       void matchToken ( const Token::Type &type, const std::string &message );
00106       void nextToken ();
00107 
00108       static char lowerCase ( char c )
00109       {
00110         return ((c >= 'A') && (c <= 'Z') ? c + ('a' - 'A') : c);
00111       }
00112 
00113     protected:
00114       typedef std::map< std::string, const Expression * > FunctionMap;
00115       typedef std::pair< std::vector< unsigned int >, const Expression * > BoundaryFunction;
00116 
00117       using BasicBlock::line;
00118 
00119       Token token;
00120       FunctionMap functions_;
00121       const Expression *defaultFunction_;
00122       std::vector< BoundaryFunction > boundaryFunctions_;
00123     };
00124 
00125 
00126     std::ostream &operator<< ( std::ostream &out, const ProjectionBlock::Token &token );
00127 
00128 
00129     struct ProjectionBlock::Expression
00130     {
00131       typedef std::vector< double > Vector;
00132 
00133       virtual ~Expression ()
00134       {}
00135 
00136       virtual void evaluate ( const Vector &argument, Vector &result ) const = 0;
00137     };
00138 
00139 
00140     template< int dimworld >
00141     class ProjectionBlock::BoundaryProjection
00142     : public DuneBoundaryProjection< dimworld >
00143     {
00144       typedef DuneBoundaryProjection< dimworld > Base;
00145 
00146     public:
00147       typedef typename Base::CoordinateType CoordinateType;
00148 
00149       BoundaryProjection ( const Expression *expression )
00150       : expression_( expression )
00151       {}
00152 
00153       virtual CoordinateType operator() ( const CoordinateType &global ) const
00154       {
00155         std::vector< double > x( dimworld );
00156         for( int i = 0; i < dimworld; ++i )
00157           x[ i ] = global[ i ];
00158         std::vector< double > y;
00159         expression_->evaluate( x, y );
00160         CoordinateType result;
00161         for( int i = 0; i < dimworld; ++i )
00162           result[ i ] = y[ i ];
00163         return result;
00164       }
00165 
00166     private:
00167       const Expression *expression_;
00168     };
00169 
00170   }
00171 
00172 }
00173 
00174 #endif // #ifndef DUNE_DGF_PROJECTIONBLOCK_HH