dune-grid  2.2.0
geometrygrid/geometry.hh
Go to the documentation of this file.
00001 #ifndef DUNE_GEOGRID_GEOMETRY_HH
00002 #define DUNE_GEOGRID_GEOMETRY_HH
00003 
00004 #include <dune/common/nullptr.hh>
00005 #include <dune/common/typetraits.hh>
00006 
00007 #include <dune/geometry/referenceelements.hh>
00008 #include <dune/geometry/genericgeometry/mappingprovider.hh>
00009 
00010 #include <dune/grid/common/capabilities.hh>
00011 #include <dune/grid/geometrygrid/cornerstorage.hh>
00012 
00013 namespace Dune
00014 {
00015 
00016   namespace GeoGrid
00017   {
00018 
00019     // GeometryTraits
00020     // --------------
00021 
00022     template< int cdim, class Grid >
00023     struct GeometryTraits
00024     {
00025       typedef typename remove_const< Grid >::type::Traits Traits;
00026 
00027       typedef GenericGeometry::DuneCoordTraits< typename Traits::ctype > CoordTraits;
00028 
00029       static const int dimWorld = cdim;
00030 
00031       template< class Topology >
00032       struct Mapping
00033       {
00034         typedef GeoGrid::CornerStorage< Topology, const Grid > CornerStorage;
00035         typedef GenericGeometry::CornerMapping< CoordTraits, Topology, dimWorld, CornerStorage > type;
00036       };
00037 
00038       struct Caching
00039       {
00040         static const GenericGeometry::EvaluationType evaluateJacobianTransposed = GenericGeometry::ComputeOnDemand;
00041         static const GenericGeometry::EvaluationType evaluateJacobianInverseTransposed = GenericGeometry::ComputeOnDemand;
00042         static const GenericGeometry::EvaluationType evaluateIntegrationElement = GenericGeometry::ComputeOnDemand;
00043         static const GenericGeometry::EvaluationType evaluateNormal = GenericGeometry::ComputeOnDemand;
00044       };
00045 
00046       struct UserData
00047       {
00048         UserData () : refCount_( 0 ) {}
00049 
00050         void addReference () { ++refCount_; }
00051         bool removeReference () { return (--refCount_ == 0); }
00052 
00053       private:
00054         unsigned int refCount_;
00055       };
00056     };
00057 
00058 
00059 
00060     // MappingFamily
00061     // -------------
00062     
00063     template< int cdim, class Grid >
00064     class MappingFamily
00065     {
00066       typedef typename remove_const< Grid >::type::Traits Traits;
00067 
00068     public:
00069       typedef GeoGrid::GeometryTraits< cdim, Grid > GeometryTraits;
00070 
00071       static const int dimension = Traits::dimension;
00072 
00073     private:
00074       template< bool >
00075       struct Hybrid
00076       {
00077         typedef GenericGeometry::HybridMapping< dimension, GeometryTraits > ElementMapping;
00078       };
00079 
00080       template< bool >
00081       struct NonHybrid
00082       {
00083         static const unsigned int topologyId = Capabilities::hasSingleGeometryType< Grid >::topologyId;
00084         typedef typename GenericGeometry::Topology< topologyId, dimension >::type Topology;
00085         typedef GenericGeometry::NonHybridMapping< Topology, GeometryTraits > ElementMapping;
00086       };
00087 
00088     public:
00089       typedef typename SelectType< Capabilities::hasSingleGeometryType< Grid >::v, NonHybrid< true >, Hybrid< false > >::Type::ElementMapping ElementMapping;
00090 
00091       template< int codim >
00092       struct Codim
00093       {
00094         typedef GenericGeometry::MappingProvider< ElementMapping, codim > MappingProvider;
00095         typedef typename MappingProvider::Mapping Mapping;
00096 
00097         static const unsigned int maxMappingSize = MappingProvider::maxMappingSize;
00098       };
00099     };
00100 
00101 
00102 
00103     // Geometry
00104     // --------
00105 
00106     template< int mydim, int cdim, class Grid >
00107     class Geometry
00108     {
00109       typedef Geometry< mydim, cdim, Grid > This;
00110 
00111       typedef GeoGrid::MappingFamily< cdim, Grid > MappingFamily;
00112       typedef typename remove_const< Grid >::type::Traits Traits;
00113 
00114       template< int, int, class > friend class Geometry;
00115 
00116     public:
00117       static const int mydimension = mydim;
00118       static const int coorddimension = cdim;
00119       static const int dimension = MappingFamily::dimension;
00120       static const int codimension = dimension - mydimension;
00121 
00122     protected:
00123       typedef typename MappingFamily::template Codim< codimension >::MappingProvider MappingProvider;
00124       typedef typename MappingFamily::template Codim< codimension >::Mapping Mapping;
00125 
00126     public:
00127       typedef typename Mapping::FieldType ctype;
00128 
00129       typedef FieldVector< ctype, mydimension > LocalCoordinate;
00130       typedef FieldVector< ctype, coorddimension > GlobalCoordinate;
00131 
00132       typedef typename Mapping::JacobianTransposed JacobianTransposed;
00133       typedef typename Mapping::JacobianInverseTransposed JacobianInverseTransposed;
00134 
00135       // for cenvencience: Jacobian is the name of the type in the geometry interface
00136       typedef JacobianInverseTransposed Jacobian;
00137 
00138       Geometry ( const Grid &grid )
00139       : grid_( &grid ),
00140         mapping_( nullptr )
00141       {}
00142 
00143       template< class CoordVector >
00144       Geometry ( const Grid &grid, const GeometryType &type, const CoordVector &coords )
00145       : grid_( &grid )
00146       {
00147         char *mappingStorage = grid.template allocateMappingStorage< codimension >( type );
00148         mapping_ = MappingProvider::construct( type.id(), coords, mappingStorage );
00149         mapping_->userData().addReference();
00150       }
00151       
00152       template< int fatherdim >
00153       Geometry ( const Geometry< fatherdim, cdim, Grid > &father, int i )
00154       : grid_( father.grid_ )
00155       {
00156         const unsigned int codim = fatherdim - mydim;
00157         char *mappingStorage = grid().template allocateMappingStorage< codimension >( type );
00158         mapping_ = father.mapping_->template trace< codim >( i, mappingStorage );
00159         mapping_->userData().addReference();
00160       }
00161 
00162       Geometry ( const This &other )
00163       : grid_( other.grid_ ),
00164         mapping_( other.mapping_ )
00165       {
00166         if( mapping_ )
00167           mapping_->userData().addReference();
00168       }
00169 
00170       ~Geometry ()
00171       {
00172         if( mapping_ && mapping_->userData().removeReference() )
00173           destroyMapping();
00174       }
00175       
00176       const This &operator= ( const This &other )
00177       {
00178         if( other.mapping_ )
00179           other.mapping_->userData().addReference();
00180         if( mapping_ && mapping_->userData().removeReference() )
00181           destroyMapping();
00182         grid_ = other.grid_;
00183         mapping_ = other.mapping_;
00184         return *this;
00185       }
00186 
00187       operator bool () const { return bool( mapping_ ); }
00188 
00189       bool affine () const { return mapping_->affine(); }
00190       GeometryType type () const { return mapping_->type(); }
00191 
00192       int corners () const { return mapping_->numCorners(); }
00193       GlobalCoordinate corner ( const int i ) const { return mapping_->corner( i ); }
00194       GlobalCoordinate center () const { return mapping_->center(); }
00195 
00196       GlobalCoordinate global ( const LocalCoordinate &local ) const { return mapping_->global( local ); }
00197       LocalCoordinate local ( const GlobalCoordinate &global ) const { return mapping_->local( global ); }
00198 
00199       ctype integrationElement ( const LocalCoordinate &local ) const { return mapping_->integrationElement( local ); }
00200       ctype volume () const { return mapping_->volume(); }
00201 
00202       const JacobianTransposed &jacobianTransposed ( const LocalCoordinate &local ) const { return mapping_->jacobianTransposed( local ); }
00203       const JacobianInverseTransposed &jacobianInverseTransposed ( const LocalCoordinate &local ) const { return mapping_->jacobianInverseTransposed( local ); }
00204 
00205       const Grid &grid () const { return *grid_; }
00206 
00207     private:
00208       void destroyMapping ()
00209       {
00210         const GeometryType gt = type();
00211         mapping_->~Mapping();
00212         grid().template deallocateMappingStorage< codimension >( gt, (char *)mapping_ );
00213       }
00214 
00215       const Grid *grid_;
00216       Mapping* mapping_;
00217     };
00218 
00219   } // namespace GeoGrid
00220 
00221 
00222 
00223   // FacadeOptions
00224   // -------------
00225 
00226   namespace FacadeOptions
00227   {
00228 
00229     template< int mydim, int cdim, class Grid >
00230     struct StoreGeometryReference< mydim, cdim, Grid, GeoGrid::Geometry >
00231     {
00232       static const bool v = false;
00233     };
00234 
00235   } // namespace FacadeOptions
00236 
00237 } // namespace Dune
00238 
00239 #endif // #ifndef DUNE_GEOGRID_GEOMETRY_HH