cachedmapping.hh

00001 #ifndef DUNE_GENERICGEOMETRY_MAPPINGS_HH
00002 #define DUNE_GENERICGEOMETRY_MAPPINGS_HH
00003 
00004 #include <dune/common/smallobject.hh>
00005 
00006 #include <dune/grid/genericgeometry/misc.hh>
00007 #include <dune/grid/genericgeometry/topologytypes.hh>
00008 #include <dune/grid/genericgeometry/referenceelements.hh>
00009 #include <dune/grid/genericgeometry/matrix.hh>
00010 #include <dune/grid/genericgeometry/mapping.hh>
00011 #include <dune/grid/genericgeometry/hybridmapping.hh>
00012 #include <dune/grid/genericgeometry/traceprovider.hh>
00013 
00014 namespace Dune
00015 {
00016 
00017   namespace GenericGeometry
00018   {
00019 
00020     // CachedMapping
00021     // -------------
00022 
00023     template< class Topology, class GeometryTraits >
00024     class CachedMapping
00025     : public SmallObject
00026     {
00027       typedef CachedMapping< Topology, GeometryTraits > This;
00028 
00029       typedef typename GeometryTraits :: template Mapping< Topology > :: type
00030         MappingImpl;
00031 
00032     public:
00033       typedef MappingTraits
00034         < typename GeometryTraits :: CoordTraits,
00035           Topology :: dimension, GeometryTraits :: dimWorld >
00036         Traits;
00037 
00038       typedef GenericGeometry :: Mapping
00039         < typename GeometryTraits :: CoordTraits,
00040           Topology, GeometryTraits :: dimWorld, MappingImpl >
00041         Mapping;
00042 
00043       static const unsigned int dimension = Traits :: dimension;
00044       static const unsigned int dimWorld = Traits :: dimWorld;
00045 
00046       typedef typename Traits :: FieldType FieldType;           
00047       typedef typename Traits :: LocalCoordType LocalCoordType;
00048       typedef typename Traits :: GlobalCoordType GlobalCoordType;
00049       typedef typename Traits :: JacobianType JacobianType;
00050       typedef typename Traits :: JacobianTransposedType JacobianTransposedType;
00051 
00052       typedef GenericGeometry :: ReferenceElement< Topology, FieldType > ReferenceElement;
00053 
00054       static const bool alwaysAffine = Mapping :: alwaysAffine;
00055 
00056       template< unsigned int codim >
00057       struct Codim
00058       {
00059         typedef typename TraceProvider< Topology, GeometryTraits, codim, false > :: Trace
00060           Trace;
00061       };
00062   
00063     private:
00064       typedef typename GeometryTraits :: Caching Caching;
00065       typedef typename Traits :: MatrixHelper MatrixHelper;
00066 
00067     public:
00068       unsigned int referenceCount;
00069       
00070     private:
00071       static const unsigned int numNormals = ReferenceElement :: numNormals;
00072 
00073       Mapping mapping_;
00074 
00075       mutable JacobianTransposedType jacobianTransposed_;
00076       mutable JacobianType jacobianInverseTransposed_;
00077       mutable FieldType integrationElement_;
00078       mutable array< GlobalCoordType, numNormals > normal_;
00079 
00080       mutable bool affine_;
00081 
00082       mutable bool jacobianTransposedComputed_;
00083       mutable bool jacobianInverseTransposedComputed_;
00084       mutable bool integrationElementComputed_;
00085       mutable array< bool, numNormals > normalComputed_;
00086 
00087     public:
00088       template< class CoordVector >
00089       explicit CachedMapping ( const CoordVector &coords )
00090       : mapping_( coords ),
00091         jacobianTransposedComputed_( false ),
00092         jacobianInverseTransposedComputed_( false ),
00093         integrationElementComputed_( false )
00094       {
00095         for( unsigned int i = 0; i < numNormals; ++i )
00096           normalComputed_[ i ] = false;
00097 
00098         if( alwaysAffine )
00099           affine_ = true;
00100         else
00101           computeJacobianTransposed( baryCenter() );
00102 
00103         if( affine() )
00104         {
00105           if( (Caching :: evaluateJacobianTransposed == PreCompute) && !jacobianTransposedComputed_ )
00106             computeJacobianTransposed( baryCenter() );
00107 
00108           if( Caching :: evaluateJacobianInverseTransposed == PreCompute )
00109             computeJacobianInverseTransposed( baryCenter() );
00110           else if( Caching :: evaluateIntegrationElement == PreCompute )
00111             computeIntegrationElement( baryCenter() );
00112         }
00113       }
00114 
00115       unsigned int topologyId () const
00116       {
00117         return ReferenceElement :: topologyId;
00118       }
00119 
00120       const GlobalCoordType &corner ( int i ) const
00121       {
00122         return mapping_.corner( i );
00123       }
00124 
00125       int numCorners () const
00126       {
00127         return ReferenceElement :: numCorners;
00128       }
00129 
00130       static bool checkInside ( const LocalCoordType &x )
00131       {
00132         return ReferenceElement :: checkInside( x );
00133       }
00134 
00135       bool affine () const
00136       {
00137         return (alwaysAffine || affine_);
00138       }
00139 
00140       GlobalCoordType global ( const LocalCoordType &x ) const
00141       {
00142         GlobalCoordType y;
00143         if( jacobianTransposedComputed_ )
00144         {
00145           MatrixHelper :: template ATx< dimension, dimWorld >( jacobianTransposed_, x, y );
00146           y += corner( 0 );
00147         }
00148         else
00149           mapping_.global( x, y );
00150         return y;
00151       }
00152 
00153       LocalCoordType local ( const GlobalCoordType &y ) const
00154       {
00155         LocalCoordType x;
00156         if( jacobianInverseTransposedComputed_ )
00157         {
00158           GlobalCoordType z = y - corner( 0 );
00159           MatrixHelper :: template ATx< dimWorld, dimension >( jacobianInverseTransposed_, z, x );
00160         }
00161         else if( affine() )
00162         {
00163           const JacobianTransposedType &JT = jacobianTransposed( baryCenter() );
00164           GlobalCoordType z = y - corner( 0 );
00165           MatrixHelper :: template xTRightInvA< dimension, dimWorld >( JT, z, x );
00166         }
00167         else
00168           mapping_.local( y, x );
00169         return x;
00170       }
00171 
00172       const JacobianTransposedType &jacobianTransposed ( const LocalCoordType &x ) const
00173       {
00174         const EvaluationType evaluate = Caching :: evaluateJacobianTransposed;
00175         if( (evaluate == PreCompute) && alwaysAffine )
00176           return jacobianTransposed_;
00177 
00178         if( !jacobianTransposedComputed_ )
00179           computeJacobianTransposed( x );
00180         return jacobianTransposed_;
00181       }
00182       
00183       FieldType integrationElement ( const LocalCoordType &x ) const
00184       {
00185         const EvaluationType evaluateI = Caching :: evaluateIntegrationElement;
00186         const EvaluationType evaluateJ = Caching :: evaluateJacobianInverseTransposed;
00187         if( ((evaluateI == PreCompute) || (evaluateJ == PreCompute)) && alwaysAffine )
00188           return integrationElement_;
00189 
00190         if( !integrationElementComputed_ )
00191           computeIntegrationElement( x );
00192         return integrationElement_;
00193       }
00194 
00195       const JacobianType &jacobianInverseTransposed ( const LocalCoordType &x ) const
00196       {
00197         const EvaluationType evaluate = Caching :: evaluateJacobianInverseTransposed;
00198         if( (evaluate == PreCompute) && alwaysAffine )
00199           return jacobianInverseTransposed_;
00200 
00201         if( !jacobianInverseTransposedComputed_ )
00202           computeJacobianInverseTransposed( x );
00203         return jacobianInverseTransposed_;
00204       }
00205 
00206       FieldType volume () const
00207       {
00208         const FieldType refVolume = ReferenceElement :: volume();
00209         return refVolume * integrationElement( baryCenter() );
00210       }
00211 
00212       const GlobalCoordType &normal ( int face, const LocalCoordType &x ) const
00213       {
00214         assert( (unsigned int)face < numNormals );
00215         if( !normalComputed_[ face ] )
00216         {
00217           const JacobianType &JT = jacobianInverseTransposed( x );
00218           const LocalCoordType &refNormal =  ReferenceElement :: integrationOuterNormal( face );
00219           MatrixHelper :: template Ax< dimWorld, dimension >( JT, refNormal, normal_[ face ] );
00220           normal_[ face ] *= integrationElement_;
00221           normalComputed_[ face ] = affine();
00222         }
00223         return normal_[ face ];
00224       }
00225 
00226       template< unsigned int codim, bool hybrid >
00227       typename TraceProvider< Topology, GeometryTraits, codim, hybrid > :: Trace *
00228       trace ( unsigned int i ) const
00229       {
00230         typedef TraceProvider< Topology, GeometryTraits, codim, hybrid > Provider;
00231         return Provider :: trace( mapping_, i );
00232       }
00233 
00234       template< unsigned int codim >
00235       typename Codim< codim > :: Trace *trace ( unsigned int i ) const
00236       {
00237         return trace< codim, false >( i );
00238       }
00239 
00240     private:
00241       static const LocalCoordType &baryCenter ()
00242       {
00243         return ReferenceElement :: template baryCenter< 0 >( 0 );
00244       }
00245 
00246       void computeJacobianTransposed ( const LocalCoordType &x ) const
00247       {
00248         affine_ = mapping_.jacobianTransposed( x, jacobianTransposed_ );
00249         jacobianTransposedComputed_ = affine_;
00250       }
00251 
00252       void computeJacobianInverseTransposed ( const LocalCoordType &x ) const
00253       {
00254         integrationElement_ = mapping_.jacobianInverseTransposed( x, jacobianInverseTransposed_ );
00255         integrationElementComputed_ = jacobianInverseTransposedComputed_ = affine();
00256       }
00257 
00258       void computeIntegrationElement ( const LocalCoordType &x ) const
00259       {
00260         integrationElement_ = mapping_.integrationElement( x );
00261         integrationElementComputed_ = affine();
00262       }
00263     };
00264 
00265   }
00266 
00267 }
00268 
00269 #endif

Generated on Sun Nov 15 22:28:39 2009 for dune-grid by  doxygen 1.5.6