- Home
- About DUNE
- Download
- Documentation
- Community
- Development
00001 #ifndef DUNE_GENERICGEOMETRY_CORNERMAPPING_HH 00002 #define DUNE_GENERICGEOMETRY_CORNERMAPPING_HH 00003 00004 #include <dune/grid/genericgeometry/topologytypes.hh> 00005 #include <dune/grid/genericgeometry/referenceelements.hh> 00006 #include <dune/grid/genericgeometry/matrixhelper.hh> 00007 00008 namespace Dune 00009 { 00010 00011 namespace GenericGeometry 00012 { 00013 00014 // External Forward Declarations 00015 // ----------------------------- 00016 00017 template< class CT, unsigned int dim, unsigned int dimW > 00018 struct MappingTraits; 00019 00020 00021 00022 00023 // GenericCornerMapping 00024 // -------------------- 00025 00026 template< class Topology, class Traits, bool affine, unsigned int offset = 0 > 00027 class GenericCornerMapping; 00028 00029 template< class Traits, bool affine, unsigned int offset > 00030 class GenericCornerMapping < Point, Traits, affine, offset > 00031 { 00032 typedef Point Topology; 00033 00034 public: 00035 static const unsigned int dim = Topology :: dimension; 00036 static const unsigned int dimW = Traits :: dimWorld; 00037 00038 typedef typename Traits :: FieldType FieldType; 00039 typedef typename Traits :: LocalCoordinate LocalCoordinate; 00040 typedef typename Traits :: GlobalCoordinate GlobalCoordinate; 00041 typedef typename Traits :: JacobianTransposedType JacobianTransposedType; 00042 00043 static const bool alwaysAffine = true; 00044 00045 template< class CoordStorage > 00046 static const GlobalCoordinate &origin ( const CoordStorage &coords ) 00047 { 00048 dune_static_assert( CoordStorage :: size, "Invalid offset." ); 00049 return coords[ offset ]; 00050 } 00051 00052 template< class CoordStorage > 00053 static void phi_set ( const CoordStorage &coords, 00054 const LocalCoordinate &x, 00055 const FieldType &factor, 00056 GlobalCoordinate &p ) 00057 { 00058 const GlobalCoordinate &y = origin( coords ); 00059 for( unsigned int i = 0; i < dimW; ++i ) 00060 p[ i ] = factor * y[ i ]; 00061 } 00062 00063 template< class CoordStorage > 00064 static void phi_add ( const CoordStorage &coords, 00065 const LocalCoordinate &x, 00066 const FieldType &factor, 00067 GlobalCoordinate &p ) 00068 { 00069 const GlobalCoordinate &y = origin( coords ); 00070 for( unsigned int i = 0; i < dimW; ++i ) 00071 p[ i ] += factor * y[ i ]; 00072 } 00073 00074 template< class CoordStorage > 00075 static bool Dphi_set ( const CoordStorage &coords, 00076 const LocalCoordinate &x, 00077 const FieldType &factor, 00078 JacobianTransposedType &J ) 00079 { 00080 return true; 00081 } 00082 00083 template< class CoordStorage > 00084 static bool Dphi_add ( const CoordStorage &coords, 00085 const LocalCoordinate &x, 00086 const FieldType &factor, 00087 JacobianTransposedType &J ) 00088 { 00089 return true; 00090 } 00091 }; 00092 00093 00094 template< class BaseTopology, class Traits, bool affine, unsigned int offset > 00095 class GenericCornerMapping< Prism< BaseTopology >, Traits, affine, offset > 00096 { 00097 typedef Prism< BaseTopology > Topology; 00098 00099 typedef GenericCornerMapping< BaseTopology, Traits, affine, offset > 00100 BottomMapping; 00101 typedef GenericCornerMapping 00102 < BaseTopology, Traits, affine, offset + BaseTopology :: numCorners > 00103 TopMapping; 00104 00105 public: 00106 static const unsigned int dim = Topology :: dimension; 00107 static const unsigned int dimW = Traits :: dimWorld; 00108 00109 typedef typename Traits :: FieldType FieldType; 00110 typedef typename Traits :: LocalCoordinate LocalCoordinate; 00111 typedef typename Traits :: GlobalCoordinate GlobalCoordinate; 00112 typedef typename Traits :: JacobianTransposedType JacobianTransposedType; 00113 00114 static const bool alwaysAffine = ((dim < 2) || affine); 00115 00116 template< class CoordStorage > 00117 static const GlobalCoordinate &origin ( const CoordStorage &coords ) 00118 { 00119 return BottomMapping :: origin( coords ); 00120 } 00121 00122 template< class CoordStorage > 00123 static void phi_set ( const CoordStorage &coords, 00124 const LocalCoordinate &x, 00125 const FieldType &factor, 00126 GlobalCoordinate &p ) 00127 { 00128 const FieldType xn = x[ dim-1 ]; 00129 const FieldType cxn = FieldType( 1 ) - xn; 00130 BottomMapping :: phi_set( coords, x, factor * cxn, p ); 00131 TopMapping :: phi_add( coords, x, factor * xn, p ); 00132 } 00133 00134 template< class CoordStorage > 00135 static void phi_add ( const CoordStorage &coords, 00136 const LocalCoordinate &x, 00137 const FieldType &factor, 00138 GlobalCoordinate &p ) 00139 { 00140 const FieldType xn = x[ dim-1 ]; 00141 const FieldType cxn = FieldType( 1 ) - xn; 00142 BottomMapping :: phi_add( coords, x, factor * cxn, p ); 00143 TopMapping :: phi_add( coords, x, factor * xn, p ); 00144 } 00145 00146 template< class CoordStorage > 00147 static bool Dphi_set ( const CoordStorage &coords, 00148 const LocalCoordinate &x, 00149 const FieldType &factor, 00150 JacobianTransposedType &J ) 00151 { 00152 const FieldType xn = x[ dim-1 ]; 00153 bool isAffine = true; 00154 if( alwaysAffine ) 00155 { 00156 const FieldType cxn = FieldType( 1 ) - xn; 00157 BottomMapping :: Dphi_set( coords, x, factor * cxn, J ); 00158 TopMapping :: Dphi_add( coords, x, factor * xn, J ); 00159 } 00160 else 00161 { 00162 JacobianTransposedType Jtop; 00163 isAffine &= BottomMapping :: Dphi_set( coords, x, factor, J ); 00164 isAffine &= TopMapping :: Dphi_set( coords, x, factor, Jtop ); 00165 00166 FieldType norm = FieldType( 0 ); 00167 for( unsigned int i = 0; i < dim-1; ++i ) 00168 { 00169 Jtop[ i ] -= J[ i ]; 00170 norm += Jtop[ i ].two_norm2(); 00171 J[ i ].axpy( xn, Jtop[ i ] ); 00172 } 00173 isAffine &= (norm < 1e-12); 00174 } 00175 BottomMapping :: phi_set( coords, x, -factor, J[ dim-1 ] ); 00176 TopMapping :: phi_add( coords, x, factor, J[ dim-1 ] ); 00177 return isAffine; 00178 } 00179 00180 template< class CoordStorage > 00181 static bool Dphi_add ( const CoordStorage &coords, 00182 const LocalCoordinate &x, 00183 const FieldType &factor, 00184 JacobianTransposedType &J ) 00185 { 00186 const FieldType xn = x[ dim-1 ]; 00187 bool isAffine = true; 00188 if( alwaysAffine ) 00189 { 00190 const FieldType cxn = FieldType( 1 ) - xn; 00191 BottomMapping :: Dphi_add( coords, x, factor * cxn, J ); 00192 TopMapping :: Dphi_add( coords, x, factor * xn, J ); 00193 } 00194 else 00195 { 00196 JacobianTransposedType Jbottom, Jtop; 00197 isAffine &= BottomMapping :: Dphi_set( coords, x, FieldType( 1 ), Jbottom ); 00198 isAffine &= TopMapping :: Dphi_set( coords, x, FieldType( 1 ), Jtop ); 00199 00200 FieldType norm = FieldType( 0 ); 00201 for( unsigned int i = 0; i < dim-1; ++i ) 00202 { 00203 Jtop[ i ] -= Jbottom[ i ]; 00204 norm += Jtop[ i ].two_norm2(); 00205 J[ i ].axpy( factor, Jbottom[ i ] ); 00206 J[ i ].axpy( factor*xn, Jtop[ i ] ); 00207 } 00208 isAffine &= (norm < 1e-12); 00209 } 00210 BottomMapping :: phi_add( coords, x, -factor, J[ dim-1 ] ); 00211 TopMapping :: phi_add( coords, x, factor, J[ dim-1 ] ); 00212 return isAffine; 00213 } 00214 }; 00215 00216 00217 template< class BaseTopology, class Traits, bool affine, unsigned int offset > 00218 class GenericCornerMapping < Pyramid< BaseTopology >, Traits, affine, offset > 00219 { 00220 typedef Pyramid< BaseTopology > Topology; 00221 00222 typedef GenericCornerMapping< BaseTopology, Traits, affine, offset > 00223 BottomMapping; 00224 typedef GenericCornerMapping 00225 < Point, Traits, affine, offset + BaseTopology :: numCorners > 00226 TopMapping; 00227 00228 public: 00229 static const unsigned int dim = Topology :: dimension; 00230 static const unsigned int dimW = Traits :: dimWorld; 00231 00232 typedef typename Traits :: FieldType FieldType; 00233 typedef typename Traits :: LocalCoordinate LocalCoordinate; 00234 typedef typename Traits :: GlobalCoordinate GlobalCoordinate; 00235 typedef typename Traits :: JacobianTransposedType JacobianTransposedType; 00236 00237 static const bool alwaysAffine = (BottomMapping :: alwaysAffine || affine); 00238 00239 template< class CoordStorage > 00240 static const GlobalCoordinate &origin ( const CoordStorage &coords ) 00241 { 00242 return BottomMapping :: origin( coords ); 00243 } 00244 00245 template< class CoordStorage > 00246 static void phi_set ( const CoordStorage &coords, 00247 const LocalCoordinate &x, 00248 const FieldType &factor, 00249 GlobalCoordinate &p ) 00250 { 00251 const FieldType xn = x[ dim-1 ]; 00252 if( alwaysAffine ) 00253 { 00254 const GlobalCoordinate &top = TopMapping :: origin( coords ); 00255 const GlobalCoordinate &bottom = BottomMapping :: origin( coords ); 00256 00257 BottomMapping :: phi_set( coords, x, factor, p ); 00258 for( unsigned int i = 0; i < dimW; ++i ) 00259 p[ i ] += (factor * xn) * (top[ i ] - bottom[ i ]); 00260 } 00261 else 00262 { 00263 TopMapping :: phi_set( coords, x, factor * xn, p ); 00264 const FieldType cxn = FieldType( 1 ) - xn; 00265 if( cxn > 1e-12 ) 00266 { 00267 const FieldType icxn = FieldType( 1 ) / cxn; 00268 LocalCoordinate xb; 00269 for( unsigned int i = 0; i < dim-1; ++i ) 00270 xb[ i ] = icxn * x[ i ]; 00271 00272 BottomMapping :: phi_add( coords, xb, factor * cxn, p ); 00273 } 00274 } 00275 } 00276 00277 template< class CoordStorage > 00278 static void phi_add ( const CoordStorage &coords, 00279 const LocalCoordinate &x, 00280 const FieldType &factor, 00281 GlobalCoordinate &p ) 00282 { 00283 const FieldType xn = x[ dim-1 ]; 00284 if( alwaysAffine ) 00285 { 00286 const GlobalCoordinate &top = TopMapping :: origin( coords ); 00287 const GlobalCoordinate &bottom = BottomMapping :: origin( coords ); 00288 00289 BottomMapping :: phi_add( coords, x, factor, p ); 00290 for( unsigned int i = 0; i < dimW; ++i ) 00291 p[ i ] += (factor * xn) * (top[ i ] - bottom[ i ]); 00292 } 00293 else 00294 { 00295 TopMapping :: phi_add( coords, x, factor * xn, p ); 00296 const FieldType cxn = FieldType( 1 ) - xn; 00297 if( cxn > 1e-12 ) 00298 { 00299 const FieldType icxn = FieldType( 1 ) / cxn; 00300 LocalCoordinate xb; 00301 for( unsigned int i = 0; i < dim-1; ++i ) 00302 xb[ i ] = icxn * x[ i ]; 00303 00304 BottomMapping :: phi_add( coords, xb, factor * cxn, p ); 00305 } 00306 } 00307 } 00308 00309 template< class CoordStorage > 00310 static bool Dphi_set ( const CoordStorage &coords, 00311 const LocalCoordinate &x, 00312 const FieldType &factor, 00313 JacobianTransposedType &J ) 00314 { 00315 GlobalCoordinate &q = J[ dim-1 ]; 00316 bool isAffine; 00317 if( alwaysAffine ) 00318 { 00319 const GlobalCoordinate &top = TopMapping :: origin( coords ); 00320 const GlobalCoordinate &bottom = BottomMapping :: origin( coords ); 00321 00322 isAffine = BottomMapping :: Dphi_set( coords, x, factor, J ); 00323 for( unsigned int i = 0; i < dimW; ++i ) 00324 q[ i ] = factor * (top[ i ] - bottom[ i ]); 00325 } 00326 else 00327 { 00328 const FieldType xn = x[ dim-1 ]; 00329 const FieldType cxn = FieldType( 1 ) - xn; 00330 const FieldType icxn = FieldType( 1 ) / cxn; 00331 LocalCoordinate xb; 00332 for( unsigned int i = 0; i < dim-1; ++i ) 00333 xb[ i ] = icxn * x[ i ]; 00334 isAffine = BottomMapping :: Dphi_set( coords, xb, factor, J ); 00335 00336 TopMapping :: phi_set( coords, x, factor, q ); 00337 BottomMapping :: phi_add( coords, xb, -factor, q ); 00338 xb *= factor; 00339 for( unsigned int j = 0; j < dim-1; ++j ) 00340 { 00341 for( unsigned int i = 0; i < dimW; ++i ) 00342 q[ i ] += J[ j ][ i ] * xb[ j ]; 00343 } 00344 } 00345 return isAffine; 00346 } 00347 00348 template< class CoordStorage > 00349 static bool Dphi_add ( const CoordStorage &coords, 00350 const LocalCoordinate &x, 00351 const FieldType &factor, 00352 JacobianTransposedType &J ) 00353 { 00354 GlobalCoordinate &q = J[ dim-1 ]; 00355 bool isAffine; 00356 if( alwaysAffine ) 00357 { 00358 const GlobalCoordinate &top = TopMapping :: origin( coords ); 00359 const GlobalCoordinate &bottom = BottomMapping :: origin( coords ); 00360 00361 isAffine = BottomMapping :: Dphi_add( coords, x, factor, J ); 00362 for( unsigned int i = 0; i < dimW; ++i ) 00363 q[ i ] += factor * (top[ i ] - bottom[ i ]); 00364 } 00365 else 00366 { 00367 const FieldType xn = x[ dim-1 ]; 00368 const FieldType cxn = FieldType( 1 ) - xn; 00369 const FieldType icxn = FieldType( 1 ) / cxn; 00370 LocalCoordinate xb; 00371 for( unsigned int i = 0; i < dim-1; ++i ) 00372 xb[ i ] = icxn * x[ i ]; 00373 isAffine = BottomMapping :: Dphi_add( coords, xb, factor, J ); 00374 00375 TopMapping :: phi_add( coords, x, factor, q ); 00376 BottomMapping :: phi_add( coords, xb, -factor, q ); 00377 xb *= factor; 00378 for( unsigned int j = 0; j < dim-1; ++j ) 00379 { 00380 for( unsigned int i = 0; i < dimW; ++i ) 00381 q[ i ] += J[ j ][ i ] * xb[ j ]; 00382 } 00383 } 00384 return isAffine; 00385 } 00386 }; 00387 00388 00389 00390 // SubMappingCoords 00391 // ---------------- 00392 00393 template< class Mapping, unsigned int codim > 00394 class SubMappingCoords 00395 { 00396 typedef typename Mapping :: GlobalCoordinate GlobalCoordinate; 00397 typedef typename Mapping :: ReferenceElement ReferenceElement; 00398 00399 static const unsigned int dimension = ReferenceElement :: dimension; 00400 00401 const Mapping &mapping_; 00402 const unsigned int i_; 00403 00404 public: 00405 SubMappingCoords ( const Mapping &mapping, unsigned int i ) 00406 : mapping_( mapping ), i_( i ) 00407 {} 00408 00409 const GlobalCoordinate &operator[] ( unsigned int j ) const 00410 { 00411 const unsigned int k 00412 = ReferenceElement :: template subNumbering< codim, dimension - codim >( i_, j ); 00413 return mapping_.corner( k ); 00414 } 00415 }; 00416 00417 00418 00419 // CoordStorage 00420 // ------------ 00421 00426 template< class CoordTraits, class Topology, unsigned int dimW > 00427 class CoordStorage 00428 { 00429 typedef CoordStorage< CoordTraits, Topology, dimW > This; 00430 00431 public: 00432 static const unsigned int size = Topology :: numCorners; 00433 00434 static const unsigned int dimWorld = dimW; 00435 00436 typedef typename CoordTraits :: template Vector< dimWorld > :: type 00437 GlobalCoordinate; 00438 00439 template< class SubTopology > 00440 struct SubStorage 00441 { 00442 typedef CoordStorage< CoordTraits, SubTopology, dimWorld > type; 00443 }; 00444 00445 private: 00446 GlobalCoordinate coords_[ size ]; 00447 00448 public: 00449 template< class CoordVector > 00450 explicit CoordStorage ( const CoordVector &coords ) 00451 { 00452 for( unsigned int i = 0; i < size; ++i ) 00453 coords_[ i ] = coords[ i ]; 00454 } 00455 00456 const GlobalCoordinate &operator[] ( unsigned int i ) const 00457 { 00458 return coords_[ i ]; 00459 } 00460 }; 00461 00462 00463 00464 // CoordPointerStorage 00465 // ------------------- 00466 00471 template< class CoordTraits, class Topology, unsigned int dimW > 00472 class CoordPointerStorage 00473 { 00474 typedef CoordPointerStorage< CoordTraits, Topology, dimW > This; 00475 00476 public: 00477 static const unsigned int size = Topology :: numCorners; 00478 00479 static const unsigned int dimWorld = dimW; 00480 00481 typedef typename CoordTraits :: template Vector< dimWorld > :: type 00482 GlobalCoordinate; 00483 00484 template< class SubTopology > 00485 struct SubStorage 00486 { 00487 typedef CoordPointerStorage< CoordTraits, SubTopology, dimWorld > type; 00488 }; 00489 00490 private: 00491 const GlobalCoordinate *coords_[ size ]; 00492 00493 public: 00494 template< class CoordVector > 00495 explicit CoordPointerStorage ( const CoordVector &coords ) 00496 { 00497 for( unsigned int i = 0; i < size; ++i ) 00498 coords_[ i ] = &(coords[ i ]); 00499 } 00500 00501 const GlobalCoordinate &operator[] ( unsigned int i ) const 00502 { 00503 return *(coords_[ i ]); 00504 } 00505 }; 00506 00507 00508 00509 // CornerMapping 00510 // ------------- 00511 00517 template< class CoordTraits, class Topo, unsigned int dimW, 00518 class CStorage = CoordStorage< CoordTraits, Topo, dimW >, 00519 bool affine = false > 00520 class CornerMapping 00521 { 00522 typedef CornerMapping< CoordTraits, Topo, dimW, CStorage, affine > This; 00523 00524 public: 00525 typedef Topo Topology; 00526 typedef CStorage CornerStorage; 00527 typedef MappingTraits< CoordTraits, Topology :: dimension, dimW > Traits; 00528 00529 static const unsigned int dimension = Traits :: dimension; 00530 static const unsigned int dimWorld = Traits :: dimWorld; 00531 00532 typedef typename Traits :: FieldType FieldType; 00533 typedef typename Traits :: LocalCoordinate LocalCoordinate; 00534 typedef typename Traits :: GlobalCoordinate GlobalCoordinate; 00535 typedef typename Traits :: JacobianType JacobianType; 00536 typedef typename Traits :: JacobianTransposedType JacobianTransposedType; 00537 00538 typedef GenericGeometry :: ReferenceElement< Topology, FieldType > ReferenceElement; 00539 00540 template< unsigned int codim, unsigned int i > 00541 struct SubTopology 00542 { 00543 typedef typename GenericGeometry :: SubTopology< Topo, codim, i > :: type Topology; 00544 typedef typename CStorage::template SubStorage< Topology >::type CornerStorage; 00545 typedef CornerMapping< CoordTraits, Topology, dimWorld, CornerStorage, affine > Trace; 00546 }; 00547 00548 private: 00549 typedef GenericGeometry :: GenericCornerMapping< Topology, Traits, affine > GenericMapping; 00550 00551 public: 00552 static const bool alwaysAffine = GenericMapping :: alwaysAffine; 00553 00554 protected: 00555 CornerStorage coords_; 00556 00557 public: 00558 template< class CoordVector > 00559 explicit CornerMapping ( const CoordVector &coords ) 00560 : coords_( coords ) 00561 {} 00562 00563 const GlobalCoordinate &corner ( int i ) const 00564 { 00565 return coords_[ i ]; 00566 } 00567 00568 void global ( const LocalCoordinate &x, GlobalCoordinate &y ) const 00569 { 00570 GenericMapping :: phi_set( coords_, x, FieldType( 1 ), y ); 00571 } 00572 00573 bool jacobianTransposed ( const LocalCoordinate &x, 00574 JacobianTransposedType &JT ) const 00575 { 00576 return GenericMapping :: Dphi_set( coords_, x, FieldType( 1 ), JT ); 00577 } 00578 00579 template< unsigned int codim, unsigned int i > 00580 typename SubTopology< codim, i > :: Trace trace () const 00581 { 00582 typedef typename SubTopology< codim, i > :: Trace Trace; 00583 typedef SubMappingCoords< This, codim > CoordVector; 00584 return Trace( CoordVector( *this, i ) ); 00585 } 00586 }; 00587 00588 } 00589 00590 } 00591 00592 #endif
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].