cornermapping.hh

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

Generated on Tue Jul 28 22:28:15 2009 for dune-grid by  doxygen 1.5.6