1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 // vi: set et ts=4 sw=2 sts=2: 3 #ifndef DUNE_DGF_PROJECTIONBLOCK_HH 4 #define DUNE_DGF_PROJECTIONBLOCK_HH 5 6 #include <map> 7 8 #include <dune/grid/common/boundaryprojection.hh> 9 #include <dune/grid/io/file/dgfparser/blocks/basic.hh> 10 11 namespace Dune 12 { 13 14 namespace dgf 15 { 16 17 // ProjectionBlock 18 // --------------- 19 20 class ProjectionBlock 21 : public BasicBlock 22 { 23 struct Token 24 { 25 friend std::ostream &operator<< ( std::ostream &, const Token & ); 26 27 enum Type 28 { 29 string, number, 30 defaultKeyword, functionKeyword, segmentKeyword, 31 sqrtKeyword, sinKeyword, cosKeyword, piKeyword, 32 comma, 33 equals, 34 openingParen, closingParen, openingBracket, closingBracket, normDelim, 35 additiveOperator, multiplicativeOperator, powerOperator, 36 endOfLine 37 }; 38 39 Type type; 40 char symbol; 41 std::string literal; 42 double value; 43 setSymbolDune::dgf::ProjectionBlock::Token44 void setSymbol ( const Type &t, char c ) 45 { 46 type = t; 47 symbol = c; 48 } 49 }; 50 51 friend std::ostream &operator<< ( std::ostream &, const Token & ); 52 53 public: 54 struct Expression; 55 56 typedef std::shared_ptr< Expression > ExpressionPointer; 57 typedef std::pair< ExpressionPointer, std::string > ExpressionPair ; 58 59 private: 60 template< int dimworld > 61 class BoundaryProjection; 62 63 void registerProjectionFactory( const int dimworld ); 64 blockId()65 static const char* blockId() { return "Projection"; } 66 public: 67 ProjectionBlock ( std::istream &in, int dimworld ); 68 69 template< int dimworld > defaultProjection() const70 const DuneBoundaryProjection< dimworld > *defaultProjection () const 71 { 72 if( defaultFunction_.first ) 73 { 74 return new BoundaryProjection< dimworld >( defaultFunction_ ); 75 } 76 else 77 return 0; 78 } 79 numBoundaryProjections() const80 size_t numBoundaryProjections () const 81 { 82 return boundaryFunctions_.size(); 83 } 84 boundaryFace(const size_t i) const85 const std::vector< unsigned int > &boundaryFace ( const size_t i ) const 86 { 87 assert( i < numBoundaryProjections() ); 88 return boundaryFunctions_[ i ].first; 89 } 90 91 template< int dimworld > boundaryProjection(const size_t i) const92 const DuneBoundaryProjection< dimworld > *boundaryProjection ( const size_t i ) const 93 { 94 assert( i < numBoundaryProjections() ); 95 return new BoundaryProjection< dimworld >( boundaryFunctions_[ i ].second ); 96 } 97 function(const std::string & name) const98 ExpressionPointer function ( const std::string &name ) const 99 { 100 const FunctionMap::const_iterator it = functions_.find( name ); 101 return (it != functions_.end() ? it->second.first : 0); 102 } 103 lastFunctionInserted() const104 ExpressionPair lastFunctionInserted () const 105 { 106 assert( ! functions_.empty() ); 107 return functions_.begin()->second; 108 } 109 createExpression(const std::string & funcexpr,const int dimworld)110 static ProjectionBlock::ExpressionPair createExpression( const std::string& funcexpr, const int dimworld ) 111 { 112 std::stringstream str; 113 str << blockId() << std::endl; 114 str << funcexpr << std::endl; 115 str << "#" << std::endl; 116 ProjectionBlock problock( str, dimworld ); 117 return problock.lastFunctionInserted(); 118 } 119 120 121 122 private: 123 void parseFunction ( const std::string& exprname ); 124 ExpressionPointer parseBasicExpression ( const std::string &variableName ); 125 ExpressionPointer parsePostfixExpression ( const std::string &variableName ); 126 ExpressionPointer parseUnaryExpression ( const std::string &variableName ); 127 ExpressionPointer parsePowerExpression ( const std::string &variableName ); 128 ExpressionPointer parseMultiplicativeExpression ( const std::string &variableName ); 129 ExpressionPointer parseExpression ( const std::string &variableName ); 130 void parseDefault (); 131 void parseSegment (); 132 133 void matchToken ( const Token::Type &type, const std::string &message ); 134 void nextToken (); 135 lowerCase(char c)136 static char lowerCase ( char c ) 137 { 138 return ((c >= 'A') && (c <= 'Z') ? c + ('a' - 'A') : c); 139 } 140 141 protected: 142 typedef std::map< std::string, ExpressionPair > FunctionMap; 143 typedef std::pair< std::vector< unsigned int >, ExpressionPair > BoundaryFunction; 144 145 using BasicBlock::line; 146 147 Token token; 148 FunctionMap functions_; 149 ExpressionPair defaultFunction_; 150 std::vector< BoundaryFunction > boundaryFunctions_; 151 }; 152 153 154 std::ostream &operator<< ( std::ostream &out, const ProjectionBlock::Token &token ); 155 156 157 struct ProjectionBlock::Expression 158 { 159 typedef std::vector< double > Vector; 160 ~ExpressionDune::dgf::ProjectionBlock::Expression161 virtual ~Expression () 162 {} 163 164 virtual void evaluate ( const Vector &argument, Vector &result ) const = 0; 165 }; 166 167 168 template< int dimworld > 169 class ProjectionBlock::BoundaryProjection 170 : public DuneBoundaryProjection< dimworld > 171 { 172 typedef DuneBoundaryProjection< dimworld > Base; 173 typedef BoundaryProjection < dimworld > This; 174 typedef typename Base :: ObjectStreamType ObjectStreamType; 175 176 public: 177 typedef typename Base::CoordinateType CoordinateType; 178 BoundaryProjection(const ExpressionPair & exprpair)179 BoundaryProjection ( const ExpressionPair& exprpair ) 180 : expression_( exprpair.first ), 181 expressionName_( exprpair.second ) 182 {} 183 BoundaryProjection(ObjectStreamType & buffer)184 BoundaryProjection( ObjectStreamType& buffer ) 185 { 186 int size = 0; 187 buffer.read( (char *) &size, sizeof(int) ); 188 expressionName_.resize( size ); 189 buffer.read( (char *) expressionName_.c_str(), size ); 190 expression_ = ProjectionBlock::createExpression( expressionName_, dimworld ).first; 191 } 192 operator ()(const CoordinateType & global) const193 virtual CoordinateType operator() ( const CoordinateType &global ) const override 194 { 195 std::vector< double > x( dimworld ); 196 for( int i = 0; i < dimworld; ++i ) 197 x[ i ] = global[ i ]; 198 std::vector< double > y; 199 expression_->evaluate( x, y ); 200 CoordinateType result; 201 for( int i = 0; i < dimworld; ++i ) 202 result[ i ] = y[ i ]; 203 return result; 204 } 205 206 // backup name of expression that should allow to recreate this class backup(std::stringstream & buffer) const207 virtual void backup( std::stringstream& buffer ) const override 208 { 209 buffer.write( (const char *) &key(), sizeof( int )); 210 int size = expressionName_.size(); 211 buffer.write( (const char *) &size, sizeof(int) ); 212 buffer.write( expressionName_.c_str(), size ); 213 } 214 registerFactory()215 static void registerFactory() 216 { 217 if( key() < 0 ) 218 { 219 key() = Base::template registerFactory< This >(); 220 } 221 } 222 223 protected: key()224 static int& key () 225 { 226 static int k = -1; 227 return k; 228 } 229 230 ExpressionPointer expression_; 231 std::string expressionName_; 232 }; 233 registerProjectionFactory(const int dimworld)234 inline void ProjectionBlock::registerProjectionFactory( const int dimworld ) 235 { 236 if( dimworld == 3 ) { 237 BoundaryProjection< 3 > :: registerFactory(); 238 } 239 else if ( dimworld == 2 ) { 240 BoundaryProjection< 2 > :: registerFactory(); 241 } 242 else if ( dimworld == 1 ) { 243 BoundaryProjection< 1 > :: registerFactory(); 244 } 245 else { 246 DUNE_THROW(NotImplemented,"ProjectionBlock::registerProjectionFactory not implemented for dimworld = " << dimworld); 247 } 248 } 249 250 } 251 252 } 253 254 #endif // #ifndef DUNE_DGF_PROJECTIONBLOCK_HH 255