cornermapping.hh

Go to the documentation of this file.
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].