- Home
- About DUNE
- Download
- Documentation
- Community
- Development
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 // vi: set et ts=8 sw=2 sts=2: 00003 00004 #ifndef DUNE_GENERICREFERENCEELEMENTS_HH 00005 #define DUNE_GENERICREFERENCEELEMENTS_HH 00006 00007 #include <dune/common/forloop.hh> 00008 #include <dune/common/typetraits.hh> 00009 00010 #include <dune/grid/genericgeometry/subtopologies.hh> 00011 #include <dune/grid/genericgeometry/referencedomain.hh> 00012 #include <dune/grid/genericgeometry/conversion.hh> 00013 #include <dune/grid/genericgeometry/hybridmapping.hh> 00014 #include <dune/grid/genericgeometry/mappingprovider.hh> 00015 00016 namespace Dune 00017 { 00018 00019 // forward declaration, needed for friend decl 00020 template< class ctype, int dim > 00021 class GenericReferenceElementContainer; 00022 00023 // GenericReferenceElement 00024 // ----------------------- 00025 00042 template< class ctype, int dim > 00043 class GenericReferenceElement 00044 { 00045 typedef GenericReferenceElement< ctype, dim > This; 00046 00047 friend class GenericReferenceElementContainer< ctype, dim >; 00048 00049 // make copy constructor private 00050 GenericReferenceElement(const GenericReferenceElement &); 00051 00052 // make empty constructor 00053 GenericReferenceElement() {}; 00054 00055 ~GenericReferenceElement () 00056 { 00057 ForLoop< Destroy, 0, dim >::apply( mappings_ ); 00058 } 00059 00060 class SubEntityInfo; 00061 template< class Topology > class CornerStorage; 00062 template< class Topology > struct Initialize; 00063 template< int codim > struct Destroy; 00064 00065 struct GeometryTraits 00066 : public GenericGeometry::DefaultGeometryTraits< ctype, dim, dim > 00067 { 00068 typedef GenericGeometry::DefaultGeometryTraits< ctype, dim, dim > Base; 00069 00070 typedef typename Base::CoordTraits CoordTraits; 00071 00072 template< class Topology > 00073 struct Mapping 00074 { 00075 typedef GenericGeometry::CornerMapping< CoordTraits, Topology, dim, CornerStorage< Topology >, true > type; 00076 }; 00077 00078 struct Caching 00079 { 00080 static const GenericGeometry::EvaluationType evaluateJacobianTransposed = GenericGeometry::PreCompute; 00081 static const GenericGeometry::EvaluationType evaluateJacobianInverseTransposed = GenericGeometry::PreCompute; 00082 static const GenericGeometry::EvaluationType evaluateIntegrationElement = GenericGeometry::PreCompute; 00083 static const GenericGeometry::EvaluationType evaluateNormal = GenericGeometry::PreCompute; 00084 }; 00085 00086 }; 00087 00088 public: 00090 template< int codim > 00091 struct Codim 00092 { 00094 typedef GenericGeometry::HybridMapping< dim-codim, GeometryTraits > Mapping; 00095 }; 00096 00097 private: 00098 00100 template< int codim > 00101 struct MappingArray 00102 : public std::vector< typename Codim< codim >::Mapping * > 00103 {}; 00104 00106 typedef GenericGeometry::CodimTable< MappingArray, dim > MappingsTable; 00107 00108 std::vector< SubEntityInfo > info_[ dim+1 ]; 00109 00111 double volume_; 00112 std::vector< FieldVector< ctype, dim > > volumeNormals_; 00113 00115 MappingsTable mappings_; 00116 00117 public: 00122 int size ( int c ) const 00123 { 00124 assert( (c >= 0) && (c <= dim) ); 00125 return info_[ c ].size(); 00126 } 00127 00139 int size ( int i, int c, int cc ) const 00140 { 00141 assert( (c >= 0) && (c <= dim) ); 00142 return info_[ c ][ i ].size( cc ); 00143 } 00144 00158 int subEntity ( int i, int c, int ii, int cc ) const 00159 { 00160 assert( (c >= 0) && (c <= dim) ); 00161 return info_[ c ][ i ].number( ii, cc ); 00162 } 00163 00173 const FieldVector< ctype, dim > &position( int i, int c ) const 00174 { 00175 assert( (c >= 0) && (c <= dim) ); 00176 return info_[ c ][ i ].position(); 00177 } 00178 00186 bool checkInside ( const FieldVector< ctype, dim > &local ) const 00187 { 00188 return checkInside< 0 >( local, 0 ); 00189 } 00190 00205 template< int codim > 00206 bool checkInside ( const FieldVector< ctype, dim-codim > &local, int i ) const 00207 { 00208 return mapping< codim >( i ).checkInside( local ); 00209 } 00210 00232 template< int codim > 00233 FieldVector< ctype, dim > 00234 global( const FieldVector< ctype, dim-codim > &local, int i, int c ) const 00235 { 00236 if( c != codim ) 00237 DUNE_THROW( Exception, "Local Coordinate Type does not correspond to codimension c." ); 00238 assert( c == codim ); 00239 return mapping< codim >( i ).global( local ); 00240 } 00241 00260 template< int codim > 00261 FieldVector< ctype, dim > 00262 global( const FieldVector< ctype, dim-codim > &local, int i ) const 00263 { 00264 return mapping< codim >( i ).global( local ); 00265 } 00266 00282 template< int codim > 00283 typename Codim< codim >::Mapping &mapping( int i ) const 00284 { 00285 integral_constant< int, codim > codimVariable; 00286 return *(mappings_[ codimVariable ][ i ]); 00287 } 00288 00297 const GeometryType &type ( int i, int c ) const 00298 { 00299 assert( (c >= 0) && (c <= dim) ); 00300 return info_[ c ][ i ].type(); 00301 } 00302 00303 unsigned int topologyId ( int i, int c ) const DUNE_DEPRECATED 00304 { 00305 assert( (c >= 0) && (c <= dim) ); 00306 return info_[ c ][ i ].topologyId(); 00307 } 00308 00310 double volume () const 00311 { 00312 return volume_; 00313 } 00314 00322 const FieldVector< ctype, dim > &volumeOuterNormal ( int face ) const 00323 { 00324 assert( (face >= 0) && (face < int( volumeNormals_.size())) ); 00325 return volumeNormals_[ face ]; 00326 } 00327 00334 template< class Topology > 00335 void initializeTopology () 00336 { 00337 dune_static_assert( (Topology::dimension == dim), 00338 "Cannot initialize reference element for different dimension." ); 00339 typedef Initialize< Topology > Init; 00340 typedef GenericGeometry::VirtualMapping< Topology, GeometryTraits > VirtualMapping; 00341 00342 // set up subentities 00343 integral_constant< int, 0 > codim0Variable; 00344 mappings_[ codim0Variable ].resize( 1 ); 00345 mappings_[ codim0Variable ][ 0 ] = new VirtualMapping( codim0Variable ); 00346 00347 Dune::ForLoop< Init::template Codim, 0, dim >::apply( info_, mappings_ ); 00348 00349 // compute reference element volume 00350 typedef GenericGeometry::ReferenceDomain< Topology > ReferenceDomain; 00351 volume_ = ReferenceDomain::template volume< double >(); 00352 00353 // compute normals 00354 volumeNormals_.resize( ReferenceDomain::numNormals ); 00355 for( unsigned int i = 0; i < ReferenceDomain::numNormals; ++i ) 00356 ReferenceDomain::integrationOuterNormal( i ,volumeNormals_[ i ] ); 00357 } 00358 }; 00359 00360 00364 template< class ctype, int dim > 00365 class GenericReferenceElement< ctype, dim >::SubEntityInfo 00366 { 00367 template< class Topology, int codim > struct Initialize 00368 { 00369 template< int subcodim > struct SubCodim; 00370 }; 00371 00372 int codim_; 00373 std::vector< int > numbering_[ dim+1 ]; 00374 FieldVector< ctype, dim > baryCenter_; 00375 GeometryType type_; 00376 00377 public: 00378 int size ( int cc ) const 00379 { 00380 assert( (cc >= codim_) && (cc <= dim) ); 00381 return numbering_[ cc ].size(); 00382 } 00383 00384 int number ( int ii, int cc ) const 00385 { 00386 assert( (cc >= codim_) && (cc <= dim) ); 00387 return numbering_[ cc ][ ii ]; 00388 } 00389 00390 const FieldVector< ctype, dim > &position () const 00391 { 00392 return baryCenter_; 00393 } 00394 00395 const GeometryType &type () const 00396 { 00397 return type_; 00398 } 00399 00400 unsigned int topologyId () const DUNE_DEPRECATED 00401 { 00402 return type_.id(); 00403 } 00404 00405 template< class Topology, unsigned int codim, unsigned int i > 00406 void initialize () 00407 { 00408 typedef Initialize< Topology, codim > Init; 00409 typedef GenericGeometry::ReferenceDomain< Topology > RefDomain; 00410 00411 codim_ = codim; 00412 00413 const unsigned int iVariable = i; 00414 Dune::ForLoop< Init::template SubCodim, 0, dim-codim >::apply( iVariable, numbering_ ); 00415 00416 baryCenter_ = ctype( 0 ); 00417 static const unsigned int numCorners = size( dim ); 00418 for( unsigned int j = 0; j < numCorners; ++j ) 00419 { 00420 FieldVector< ctype, dim > corner; 00421 RefDomain::corner( number( j, dim ), corner ); 00422 baryCenter_ += corner; 00423 } 00424 baryCenter_ *= ctype( 1 ) / ctype( numCorners ); 00425 00426 typedef typename GenericGeometry::SubTopology< Topology, codim, i >::type SubTopology; 00427 type_ = GeometryType( SubTopology::id, SubTopology::dimension ); 00428 // type_ = GenericGeometry::DuneGeometryType< SubTopology, GeometryType::simplex >::type(); 00429 } 00430 }; 00431 00432 00433 template< class ctype, int dim > 00434 template< class Topology > 00435 class GenericReferenceElement< ctype, dim >::CornerStorage 00436 { 00437 typedef GenericGeometry::ReferenceDomain< Topology > RefDomain; 00438 00439 public: 00440 static const unsigned int size = Topology::numCorners; 00441 00442 template< class SubTopology > 00443 struct SubStorage 00444 { 00445 typedef CornerStorage< SubTopology > type; 00446 }; 00447 00448 explicit CornerStorage ( const integral_constant< int, 0 > & ) 00449 { 00450 for( unsigned int i = 0; i < size; ++i ) 00451 RefDomain::corner( i, coords_[ i ] ); 00452 } 00453 00454 template< class Mapping, unsigned int codim > 00455 explicit 00456 CornerStorage ( const GenericGeometry::SubMappingCoords< Mapping, codim > &coords ) 00457 { 00458 for( unsigned int i = 0; i < size; ++i ) 00459 coords_[ i ] = coords[ i ]; 00460 } 00461 00462 const FieldVector< ctype, dim > &operator[] ( unsigned int i ) const 00463 { 00464 return coords_[ i ]; 00465 } 00466 00467 private: 00468 FieldVector< ctype, dim > coords_[ size ]; 00469 }; 00470 00471 00472 template< class ctype, int dim > 00473 template< class Topology, int codim > 00474 template< int subcodim > 00475 struct GenericReferenceElement< ctype, dim >::SubEntityInfo::Initialize< Topology, codim >::SubCodim 00476 { 00477 typedef GenericGeometry::SubTopologySize< Topology, codim, subcodim > SubSize; 00478 typedef GenericGeometry::GenericSubTopologyNumbering< Topology, codim, subcodim > SubNumbering; 00479 00480 static void apply ( unsigned int i, std::vector< int > (&numbering)[ dim+1 ] ) 00481 { 00482 const unsigned int size = SubSize::size( i ); 00483 numbering[ codim+subcodim ].resize( size ); 00484 for( unsigned int j = 0; j < size; ++j ) 00485 numbering[ codim+subcodim ][ j ] = SubNumbering::number( i, j ); 00486 } 00487 }; 00488 00489 00490 template< class ctype, int dim > 00491 template< class Topology > 00492 struct GenericReferenceElement< ctype, dim >::Initialize 00493 { 00494 typedef Dune::GenericReferenceElement< ctype, dim > GenericReferenceElement; 00495 00496 typedef typename GenericReferenceElement::template Codim< 0 >::Mapping ReferenceMapping; 00497 00498 template< int codim > 00499 struct Codim 00500 { 00501 template< int i > 00502 struct SubTopology 00503 { 00504 static void apply ( std::vector< SubEntityInfo > &info ) 00505 { 00506 info[ i ].template initialize< Topology, codim, i >(); 00507 } 00508 }; 00509 00510 static void 00511 apply ( std::vector< SubEntityInfo > (&info)[ dim+1 ], 00512 MappingsTable &mappings ) 00513 { 00514 const unsigned int size = GenericGeometry::Size< Topology, codim >::value; 00515 info[ codim ].resize( size ); 00516 Dune::ForLoop< SubTopology, 0, size-1 >::apply( info[ codim ] ); 00517 00518 if( codim > 0 ) 00519 { 00520 integral_constant< int, 0 > codim0Variable; 00521 const ReferenceMapping &refMapping = *(mappings[ codim0Variable ][ 0 ]); 00522 00523 typedef typename GenericGeometry::MappingProvider< ReferenceMapping, codim > MappingProvider; 00524 00525 integral_constant< int, codim > codimVariable; 00526 mappings[ codimVariable ].resize( size ); 00527 for( unsigned int i = 0; i < size; ++i ) { 00528 char* storage = new char[MappingProvider::maxMappingSize]; 00529 mappings[ codimVariable ][ i ] = refMapping.template trace< codim >( i, storage ); 00530 } 00531 } 00532 } 00533 }; 00534 }; 00535 00536 00537 00538 template< class ctype, int dim > 00539 template< int codim > 00540 struct GenericReferenceElement< ctype, dim >::Destroy 00541 { 00542 static void apply ( MappingsTable &mappings ) 00543 { 00544 if (codim > 0 ) 00545 { 00546 integral_constant< int, codim > codimVariable; 00547 for( size_t i = 0; i < mappings[ codimVariable ].size(); ++i ) { 00548 typedef typename Codim<codim>::Mapping Mapping; 00549 mappings[ codimVariable ][ i ]->~Mapping(); 00550 char* storage = (char*)mappings[ codimVariable ][ i ]; 00551 delete[](storage); 00552 } 00553 } 00554 } 00555 }; 00556 00557 00558 00559 // GenericReferenceElementContainer 00560 // -------------------------------- 00561 00562 template< class ctype, int dim > 00563 class GenericReferenceElementContainer 00564 { 00565 static const unsigned int numTopologies = (1u << dim); 00566 00567 public: 00568 typedef GenericReferenceElement< ctype, dim > value_type; 00569 00570 const value_type &operator() ( const unsigned int topologyId ) const DUNE_DEPRECATED 00571 { 00572 return values_[ topologyId ]; 00573 } 00574 00575 const value_type &operator() ( const GeometryType &type ) const 00576 { 00577 assert( type.dim() == dim ); 00578 return values_[ type.id() ]; 00579 } 00580 00581 const value_type &simplex () const 00582 { 00583 return values_[ GenericGeometry::SimplexTopology< dim >::type::id ]; 00584 } 00585 00586 const value_type &cube () const 00587 { 00588 return values_[ GenericGeometry::CubeTopology< dim >::type::id ]; 00589 } 00590 00591 const value_type &pyramid () const 00592 { 00593 return values_[ GenericGeometry::PyramidTopology< dim >::type::id ]; 00594 } 00595 00596 const value_type &prism () const 00597 { 00598 return values_[ GenericGeometry::PrismTopology< dim >::type::id ]; 00599 } 00600 00601 static const GenericReferenceElementContainer &instance () 00602 { 00603 static GenericReferenceElementContainer inst; 00604 return inst; 00605 } 00606 00607 private: 00608 template< int topologyId > 00609 struct Builder 00610 { 00611 static void apply ( value_type (&values)[ numTopologies ] ) 00612 { 00613 typedef typename GenericGeometry::Topology< topologyId, dim >::type Topology; 00614 values[ topologyId ].template initializeTopology< Topology >(); 00615 } 00616 }; 00617 00618 GenericReferenceElementContainer () 00619 { 00620 ForLoop< Builder, 0, numTopologies-1 >::apply( values_ ); 00621 } 00622 00623 value_type values_[ numTopologies ]; 00624 }; 00625 00626 00627 // GenericReferenceElements 00628 // ------------------------ 00629 00638 template< class ctype, int dim > 00639 struct GenericReferenceElements 00640 { 00642 static const GenericReferenceElement< ctype, dim > & 00643 general ( const GeometryType &type ) 00644 { 00645 return GenericReferenceElementContainer< ctype, dim >::instance()( type ); 00646 } 00647 00649 static const GenericReferenceElement< ctype, dim > &simplex () 00650 { 00651 return GenericReferenceElementContainer< ctype, dim >::instance().simplex(); 00652 } 00653 00655 static const GenericReferenceElement< ctype, dim > &cube () 00656 { 00657 return GenericReferenceElementContainer< ctype, dim >::instance().cube(); 00658 } 00659 }; 00660 00661 } 00662 00663 #endif // #ifndef DUNE_GENERICREFERENCEELEMENTS_HH
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].