1#ifndef DUNE_FEM_SPACE_TEST_CHECKBASISFUNCTIONSET_HH
2#define DUNE_FEM_SPACE_TEST_CHECKBASISFUNCTIONSET_HH
10#include <dune/fem/common/coordinate.hh>
21 template<
class BasisFunctionSet,
class Quadrature >
23 checkQuadratureConsistency (
const BasisFunctionSet &basisFunctionSet,
const Quadrature &quadrature,
24 bool supportsHessians =
false )
38 const EntityType &entity = basisFunctionSet.entity();
39 const auto refElement = basisFunctionSet.referenceElement();
41 if( entity.type() != refElement.type() )
44 int order = basisFunctionSet.order();
48 const std::size_t
size = basisFunctionSet.size();
51 std::uniform_real_distribution< RangeFieldType > distribution( 1e-3, 1e3 );
52 std::default_random_engine randomEngine;
53 auto random = std::bind( distribution, randomEngine );
55 std::vector< RangeFieldType > dofs(
size );
56 for( RangeFieldType &dof : dofs )
59 RangeType valueFactor;
60 for( RangeFieldType &v : valueFactor )
63 JacobianRangeType jacobianFactor;
64 for( std::size_t j = 0; j < JacobianRangeType::rows; ++j )
65 for( std::size_t k = 0; k < JacobianRangeType::cols; ++k )
66 jacobianFactor[ j ][ k ] = random();
68 HessianRangeType hessianFactor;
69 for( std::size_t j = 0; j < JacobianRangeType::rows; ++j )
70 for( std::size_t k = 0; k < JacobianRangeType::cols; ++k )
71 for( std::size_t l = 0; l < JacobianRangeType::cols; ++l )
72 hessianFactor[ j ][ k ][ l ] = random();
77 const std::size_t nop = quadrature.nop();
79 std::vector< RangeType > aVec( nop );
80 std::vector< JacobianRangeType > aJac( nop );
82 basisFunctionSet.evaluateAll( quadrature, dofs, aVec );
83 basisFunctionSet.jacobianAll( quadrature, dofs, aJac );
85 for( std::size_t qp = 0; qp < nop; ++qp )
90 RangeType& a = aVec[ qp ];
92 std::vector< RangeType > values( basisFunctionSet.size() );
93 basisFunctionSet.evaluateAll( quadrature[ qp ], values );
94 for( std::size_t i = 0; i < values.size(); ++i )
96 b.axpy( dofs[ i ], values[ i ] );
99 ret[ 0 ] = std::max( ret[ 0 ], (a - b).two_norm() );
105 JacobianRangeType& a = aJac[ qp ];
107 std::vector< JacobianRangeType > values( basisFunctionSet.size() );
108 basisFunctionSet.jacobianAll( quadrature[ qp ], values );
109 for( std::size_t i = 0; i < values.size(); ++i )
110 b.axpy( dofs[ i ], values[ i ] );
113 ret[ 1 ] = std::max( ret[ 1 ], a.frobenius_norm() );
117 if( supportsHessians )
119 HessianRangeType a, b;
121 basisFunctionSet.hessianAll( quadrature[ qp ], dofs, a );
123 std::vector< HessianRangeType > values( basisFunctionSet.size() );
124 basisFunctionSet.hessianAll( quadrature[ qp ], values );
125 for(
int r = 0; r < dimRange; ++r )
126 for( std::size_t i = 0; i < values.size(); ++i )
127 b[ r ].axpy( dofs[ i ], values[ i ][ r ] );
129 RangeFieldType error( 0 );
130 for(
int r = 0; r < dimRange; ++r )
132 for(
int r = 0; r < dimRange; ++r )
133 error += a[ r ].frobenius_norm2();
135 ret[ 2 ] = std::max( ret[ 2 ], std::sqrt( error ) );
140 std::vector< RangeFieldType > r1( dofs );
141 std::vector< RangeFieldType > r2( dofs );
143 basisFunctionSet.axpy( quadrature[ qp ], valueFactor, r1 );
145 std::vector< RangeType > values( basisFunctionSet.size() );
146 basisFunctionSet.evaluateAll( quadrature[ qp ], values );
147 for( std::size_t i = 0; i < values.size(); ++i )
148 r2[ i ] += valueFactor * values[ i ];
150 RangeFieldType error = 0;
151 for( std::size_t i = 0; i < values.size(); ++i )
152 error += std::abs( r2[ i ] - r1[ i ] );
154 ret[ 3 ] = std::max( ret[ 3 ], error );
159 DomainType x = coordinate( quadrature[ qp ] );
160 std::vector< RangeFieldType > r1( dofs );
161 std::vector< RangeFieldType > r2( dofs );
163 basisFunctionSet.axpy( x, jacobianFactor, r1 );
165 std::vector< JacobianRangeType > values( basisFunctionSet.size() );
166 basisFunctionSet.jacobianAll( x, values );
167 for( std::size_t i = 0; i < values.size(); ++i )
168 for(
int j = 0; j < JacobianRangeType::rows; ++j )
169 r2[ i ] += jacobianFactor[ j ] * values[ i ][ j ];
171 RangeFieldType error = 0;
172 for( std::size_t i = 0; i < values.size(); ++i )
173 error += std::abs( r2[ i ] - r1[ i ] );
175 ret[ 4 ] = std::max( ret[ 4 ], error );
180 if( supportsHessians )
182 DomainType x = coordinate( quadrature[ qp ] );
183 std::vector< RangeFieldType > r1( dofs );
184 std::vector< RangeFieldType > r2( dofs );
186 basisFunctionSet.axpy( x, hessianFactor, r1 );
188 std::vector< HessianRangeType > values( basisFunctionSet.size() );
189 basisFunctionSet.hessianAll( x, values );
190 for( std::size_t i = 0; i < values.size(); ++i )
191 for(
int j = 0; j < JacobianRangeType::rows; ++j )
192 for( std::size_t k = 0; k < JacobianRangeType::cols; ++k )
193 for( std::size_t l = 0; l < JacobianRangeType::cols; ++l )
194 r2[ i ] += hessianFactor[ j ][ k ][ l ] * values[ i ][ j ][ k ][ l ];
196 RangeFieldType error = 0;
197 for( std::size_t i = 0; i < values.size(); ++i )
198 error += std::abs( r2[ i ] - r1[ i ] );
200 ret[ 5 ] = std::max( ret[ 5 ], error );
205 DomainType x = coordinate( quadrature[ qp ] );
206 std::vector< RangeFieldType > r1( dofs );
207 std::vector< RangeFieldType > r2( dofs );
209 basisFunctionSet.axpy( x, valueFactor, jacobianFactor, r1 );
211 std::vector< RangeType > values( basisFunctionSet.size() );
212 std::vector< JacobianRangeType > jacobians( basisFunctionSet.size() );
214 basisFunctionSet.evaluateAll( x, values );
215 basisFunctionSet.jacobianAll( x, jacobians );
217 for( std::size_t i = 0; i < values.size(); ++i )
219 r2[ i ] += valueFactor * values[ i ];
220 for(
int j = 0; j < JacobianRangeType::rows; ++j )
221 r2[ i ] += jacobianFactor[ j ] * jacobians[ i ][ j ];
224 RangeFieldType error = 0;
225 for( std::size_t i = 0; i < values.size(); ++i )
226 error += std::abs( r2[ i ] - r1[ i ] );
228 ret[ 6 ] = std::max( ret[ 6 ], error );
Entity EntityType
entity type
Definition: basisfunctionset.hh:35
FunctionSpace< typename Entity::Geometry::ctype, typename Range::value_type, Entity::Geometry::coorddimension, Range::dimension > FunctionSpaceType
function space type
Definition: basisfunctionset.hh:40
FunctionSpaceType::DomainType DomainType
range type
Definition: basisfunctionset.hh:43
FunctionSpaceType::JacobianRangeType JacobianRangeType
jacobian range type
Definition: basisfunctionset.hh:47
FunctionSpaceType::HessianRangeType HessianRangeType
hessian range type
Definition: basisfunctionset.hh:49
FunctionSpaceType::RangeType RangeType
range type
Definition: basisfunctionset.hh:45
@ dimRange
dimension of range vector space
Definition: functionspaceinterface.hh:48
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
vector space out of a tensor product of fields.
Definition: fvector.hh:91
Default exception if a function was called while the object is not in a valid state for that function...
Definition: exceptions.hh:281
Implements a vector constructed from a given type representing a field and a compile-time given size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
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