Loading [MathJax]/extensions/tex2jax.js

DUNE-FEM (unstable)

orthonormal.hh
1#ifndef DUNE_FEM_SPACE_SHAPEFUNCTIONSET_ORTHONORMAL_HH
2#define DUNE_FEM_SPACE_SHAPEFUNCTIONSET_ORTHONORMAL_HH
3
4#include <cassert>
5#include <cstddef>
6#include <memory>
7
9
10#include <dune/fem/common/coordinate.hh>
11#include <dune/fem/quadrature/quadrature.hh>
12
13#include <dune/fem/space/common/functionspace.hh>
14#include <dune/fem/space/shapefunctionset/orthonormal/orthonormalbase_1d.hh>
15#include <dune/fem/space/shapefunctionset/orthonormal/orthonormalbase_2d.hh>
16#include <dune/fem/space/shapefunctionset/orthonormal/orthonormalbase_3d.hh>
17
18#if HAVE_DUNE_LOCALFUNCTIONS
19#include <dune/localfunctions/orthonormal.hh>
20#endif
21
22namespace Dune
23{
24
25 namespace Fem
26 {
27
28#ifndef DOXYGEN
29
30 // OrthonormalShapeFunctions
31 // -------------------------
32
33 template< int dimension >
34 struct OrthonormalShapeFunctions;
35
36 template<>
37 struct OrthonormalShapeFunctions< 1 >
38 {
39 static constexpr std::size_t size ( int order )
40 {
41 return static_cast< std::size_t >( order+1 );
42 }
43 };
44
45 template<>
46 struct OrthonormalShapeFunctions< 2 >
47 {
48 static constexpr std::size_t size ( int order )
49 {
50 return static_cast< std::size_t >( (order+2)*(order+1)/2 );
51 }
52 };
53
54 template<>
55 struct OrthonormalShapeFunctions< 3 >
56 {
57 static constexpr std::size_t size ( int order )
58 {
59 return static_cast< std::size_t >( ((order+1)*(order+2)*(2*order+3)/6+(order+1)*(order+2)/2)/2 );
60 }
61 };
62
63#endif // #ifndef DOXYGEN
64
65
66
67 // OrthonormalShapeFunctionSet
68 // ---------------------------
69
70 template< class FunctionSpace >
71 class OrthonormalShapeFunctionSet
72 {
73 typedef OrthonormalShapeFunctionSet< FunctionSpace > ThisType;
74
75 static_assert( FunctionSpace::dimDomain <= 3, "OrthonormalShapeFunctionSet only implemented up to domain dimension 3" );
76 static_assert( FunctionSpace::dimRange == 1, "OrthonormalShapeFunctionSet only implemented for scalar function spaces" );
77
78 public:
80 typedef FunctionSpace FunctionSpaceType;
81
82 private:
83 typedef typename FunctionSpaceType::DomainFieldType DomainFieldType;
84 typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
85
86 typedef RangeFieldType (*Evaluate) ( const int, const DomainFieldType * );
87 typedef void (*Jacobian) ( const int i, const DomainFieldType *, RangeFieldType * );
88
89 // hessian is only available for 2d-simplices (aka triangles)
90 typedef RangeFieldType Array[ 3 ];
91 typedef void (*Hessian) ( const int i, const DomainFieldType *, Array & );
92
93 typedef OrthonormalBase_1D< DomainFieldType, RangeFieldType > OrthonormalBase1d;
94 typedef OrthonormalBase_2D< DomainFieldType, RangeFieldType > OrthonormalBase2d;
95 typedef OrthonormalBase_3D< DomainFieldType, RangeFieldType > OrthonormalBase3d;
96
97 static void setFunctionPointers(const Dune::GeometryType& geomType,
98 Evaluate &evaluate, Jacobian &jacobian )
99 {
100 if( geomType.isLine() )
101 {
102 evaluate = OrthonormalBase1d::eval_line;
103 jacobian = OrthonormalBase1d::grad_line;
104 return ;
105 }
106 else if( geomType.isQuadrilateral() )
107 {
108 evaluate = OrthonormalBase2d::eval_quadrilateral_2d;
109 jacobian = OrthonormalBase2d::grad_quadrilateral_2d;
110 return ;
111 }
112 else if( geomType.isTriangle() )
113 {
114 evaluate = OrthonormalBase2d::eval_triangle_2d;
115 jacobian = OrthonormalBase2d::grad_triangle_2d;
116 return ;
117 }
118 else if( geomType.isHexahedron() )
119 {
120 evaluate = OrthonormalBase3d::eval_hexahedron_3d;
121 jacobian = OrthonormalBase3d::grad_hexahedron_3d;
122 return ;
123 }
124 else if ( geomType.isTetrahedron() )
125 {
126 evaluate = OrthonormalBase3d::eval_tetrahedron_3d;
127 jacobian = OrthonormalBase3d::grad_tetrahedron_3d;
128 return ;
129 }
130 else if( geomType.isPrism() )
131 {
132 evaluate = OrthonormalBase3d::eval_prism_3d;
133 jacobian = OrthonormalBase3d::grad_prism_3d;
134 return ;
135 }
136 else if ( geomType.isPyramid() )
137 {
138 evaluate = OrthonormalBase3d::eval_pyramid_3d;
139 jacobian = OrthonormalBase3d::grad_pyramid_3d;
140 return ;
141 }
142
143 DUNE_THROW(InvalidStateException,"Invalid geometry type " << geomType );
144 }
145
146 public:
148 static const int dimension = FunctionSpaceType::dimDomain;
149
151 typedef typename FunctionSpaceType::DomainType DomainType;
153 typedef typename FunctionSpaceType::RangeType RangeType;
155 typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
157 typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
158
159#if HAVE_DUNE_LOCALFUNCTIONS
160 typedef OrthonormalLocalFiniteElement< dimension,
161 typename DomainType::field_type, typename RangeType::field_type> OrthonormalLocalFiniteElementType;
162 static const bool haveLocalFunctions_ = true;
163#else
164 typedef int OrthonormalLocalFiniteElementType;
165 static const bool haveLocalFunctions_ = false;
166#endif
171 OrthonormalShapeFunctionSet () = default;
172
173 OrthonormalShapeFunctionSet ( GeometryType type, int order )
174 : order_( order ),
175 evaluate_( nullptr ),
176 jacobian_( nullptr ),
177 hessian_( nullptr ),
178 onbElem_()
179 {
180 // for type none simply create cube basis function set.
181 if( type.isNone() )
182 type = Dune::GeometryTypes::cube(type.dim());
183
184 // set functions pointers for evaluate and jacobian
185 // depending on geometry type
186 setFunctionPointers( type, evaluate_, jacobian_ );
187 assert( evaluate_ );
188 assert( jacobian_ );
189
190 if constexpr ( dimension == 2 )
191 {
192 if( type.isTriangle() )
193 hessian_ = OrthonormalBase2d::hess_triangle_2d;
194 else if( type.isQuadrilateral() )
195 hessian_ = OrthonormalBase2d::hess_quadrilateral_2d;
196 }
197 else if constexpr ( dimension == 3 && haveLocalFunctions_ )
198 onbElem_.reset( new OrthonormalLocalFiniteElementType( type, order ) );
199
200 }
201
202 OrthonormalShapeFunctionSet ( const ThisType & ) = default;
203
204 OrthonormalShapeFunctionSet ( ThisType && ) = default;
205
212 OrthonormalShapeFunctionSet &operator= ( const ThisType & ) = default;
213
214 OrthonormalShapeFunctionSet &operator= ( ThisType && ) = default;
215
223 int order () const { return order_; }
224
226 std::size_t constexpr size () const { return size( order() ); }
227
229 static std::size_t constexpr size ( int order )
230 {
231 return OrthonormalShapeFunctions< dimension >::size( order );
232 }
233
235 template< class Point, class Functor >
236 void evaluateEach ( const Point &x, Functor functor ) const
237 {
238 const DomainType y = Dune::Fem::coordinate( x );
239 RangeType value;
240 const std::size_t size = this->size();
241 for( std::size_t i = 0; i < size; ++i )
242 {
243 evaluate( i, y, value );
244 functor( i, value );
245 }
246 }
247
249 template< class Point, class Functor >
250 void jacobianEach ( const Point &x, Functor functor ) const
251 {
252 const DomainType y = Dune::Fem::coordinate( x );
253 JacobianRangeType jacobian;
254 const std::size_t size = this->size();
255 for( std::size_t i = 0; i < size; ++i )
256 {
257 this->jacobian( i, y, jacobian );
258 functor( i, jacobian );
259 }
260 }
261
263 template< class Point, class Functor >
264 void hessianEach ( const Point &x, Functor functor ) const
265 {
266 const DomainType y = Dune::Fem::coordinate( x );
267 if constexpr ( dimension == 2 )
268 {
269 HessianRangeType hessian;
270 const std::size_t size = this->size();
271 for( std::size_t i = 0; i < size; ++i )
272 {
273 this->hessian( i, y, hessian );
274 functor( i, hessian );
275 }
276 }
277 else if constexpr( dimension == 3 && haveLocalFunctions_ )
278 {
279 const std::size_t size = this->size();
280 // for p < 2 this is simply zero
281 if ( order_ < 2 )
282 {
283 HessianRangeType hessian(0);
284 for( std::size_t i = 0; i < size; ++i )
285 {
286 // convert to our own data type to avoid
287 // conversion conflicts in functor call
288 functor( i, hessian );
289 }
290 return ;
291 }
292
293 typedef typename OrthonormalLocalFiniteElementType::Traits::LocalBasisType::HessianType HessianType;
294 std::vector< HessianType > hessians;
295 onbElem_->localBasis().evaluateHessian( y, hessians );
296 HessianRangeType hessian;
297 for( std::size_t i = 0; i < size; ++i )
298 {
299 // convert to our own data type to avoid
300 // conversion conflicts in functor call
301 hessian = hessians[ i ];
302 functor( i, hessian );
303 }
304 }
305 else
306 {
307 std::abort();
308 }
309 }
310
313 private:
314 void evaluate ( std::size_t i, const DomainType &x, RangeType &value ) const
315 {
316 value[ 0 ] = evaluate_( i, &x[ 0 ] );
317 }
318
319 void jacobian ( std::size_t i, const DomainType &x, JacobianRangeType &jacobian ) const
320 {
321 jacobian_( i, &x[ 0 ], &jacobian[ 0 ][ 0 ] );
322 }
323
324 void hessian ( std::size_t i, const DomainType &x, HessianRangeType &hessian ) const
325 {
326 assert( hessian_ );
327 if constexpr (dimension == 2 )
328 {
329 RangeFieldType values[] = { 0, 0, 0 };
330 hessian_( i , &x[ 0 ], values );
331 for( unsigned int j = 0; j < FunctionSpaceType::dimDomain; ++j )
332 for( unsigned int k = 0; k < FunctionSpaceType::dimDomain; ++k )
333 hessian[ 0 ][ j ][ k ] = values[ j + k ];
334 }
335 else
336 {
337 std::abort();
338 }
339 }
340
341 int order_;
342 Evaluate evaluate_;
343 Jacobian jacobian_;
344 Hessian hessian_;
345
346 mutable std::shared_ptr< OrthonormalLocalFiniteElementType > onbElem_;
347 };
348
349
350 } // namespace Fem
351
352} // namespace Dune
353
354#endif // #ifndef DUNE_FEM_SPACE_SHAPEFUNCTIONSET_ORTHONORMAL_HH
Definition: explicitfieldvector.hh:75
FunctionSpaceTraits::DomainFieldType DomainFieldType
Intrinsic type used for values in the domain field (usually a double)
Definition: functionspaceinterface.hh:60
FunctionSpaceTraits::RangeType RangeType
Type of range vector (using type of range field) has a Dune::FieldVector type interface.
Definition: functionspaceinterface.hh:71
@ dimDomain
dimension of domain vector space
Definition: functionspaceinterface.hh:46
@ dimRange
dimension of range vector space
Definition: functionspaceinterface.hh:48
FunctionSpaceTraits::LinearMappingType JacobianRangeType
Intrinsic type used for the jacobian values has a Dune::FieldMatrix type interface.
Definition: functionspaceinterface.hh:75
FunctionSpaceTraits::DomainType DomainType
Type of domain vector (using type of domain field) has a Dune::FieldVector type interface.
Definition: functionspaceinterface.hh:67
FunctionSpaceTraits::RangeFieldType RangeFieldType
Intrinsic type used for values in the range field (usually a double)
Definition: functionspaceinterface.hh:63
A vector valued function space.
Definition: functionspace.hh:60
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:114
constexpr bool isPyramid() const
Return true if entity is a pyramid.
Definition: type.hh:304
constexpr bool isTetrahedron() const
Return true if entity is a tetrahedron.
Definition: type.hh:299
constexpr bool isPrism() const
Return true if entity is a prism.
Definition: type.hh:309
constexpr bool isTriangle() const
Return true if entity is a triangle.
Definition: type.hh:289
constexpr bool isLine() const
Return true if entity is a line segment.
Definition: type.hh:284
constexpr bool isQuadrilateral() const
Return true if entity is a quadrilateral.
Definition: type.hh:294
constexpr bool isHexahedron() const
Return true if entity is a hexahedron.
Definition: type.hh:314
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:462
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
A unique label for each type of element that can occur in a grid.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Apr 28, 22:35, 2025)