DUNE-FEM (unstable)

checkbasisfunctionset.hh
1#ifndef DUNE_FEM_SPACE_TEST_CHECKBASISFUNCTIONSET_HH
2#define DUNE_FEM_SPACE_TEST_CHECKBASISFUNCTIONSET_HH
3
4#include <algorithm>
5#include <functional>
6#include <iostream>
7#include <random>
8
10#include <dune/fem/common/coordinate.hh>
11
12namespace Dune
13{
14
15 namespace Fem
16 {
17
18 // checkQuadratureConsistency
19 // --------------------------
20
21 template< class BasisFunctionSet, class Quadrature >
23 checkQuadratureConsistency ( const BasisFunctionSet &basisFunctionSet, const Quadrature &quadrature,
24 bool supportsHessians = false )
25 {
26 // get types
28 typedef typename BasisFunctionSet::DomainType DomainType;
29 typedef typename BasisFunctionSet::RangeType RangeType;
30 typedef typename BasisFunctionSet::JacobianRangeType JacobianRangeType;
31 typedef typename BasisFunctionSet::HessianRangeType HessianRangeType;
32 typedef typename BasisFunctionSet::EntityType EntityType;
33
34 typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
35
36 static const int dimRange = FunctionSpaceType::dimRange;
37
38 const EntityType &entity = basisFunctionSet.entity();
39 const auto refElement = basisFunctionSet.referenceElement();
40
41 if( entity.type() != refElement.type() )
42 DUNE_THROW( Dune::InvalidStateException, "GeometryType of referenceElement and entity mismatch for this basisFunctionSet" );
43
44 int order = basisFunctionSet.order();
45 // prevent warning about unused params
46 (void) order;
47
48 const std::size_t size = basisFunctionSet.size();
49
50 // init random dof vectors
51 std::uniform_real_distribution< RangeFieldType > distribution( 1e-3, 1e3 );
52 std::default_random_engine randomEngine;
53 auto random = std::bind( distribution, randomEngine );
54
55 std::vector< RangeFieldType > dofs( size );
56 for( RangeFieldType &dof : dofs )
57 dof = random();
58
59 RangeType valueFactor;
60 for( RangeFieldType &v : valueFactor )
61 v = random();
62
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();
67
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();
73
74 // return value
76
77 const std::size_t nop = quadrature.nop();
78
79 std::vector< RangeType > aVec( nop );
80 std::vector< JacobianRangeType > aJac( nop );
81
82 basisFunctionSet.evaluateAll( quadrature, dofs, aVec );
83 basisFunctionSet.jacobianAll( quadrature, dofs, aJac );
84
85 for( std::size_t qp = 0; qp < nop; ++qp )
86 {
87 // check evaluate methods
88 {
89 RangeType b;
90 RangeType& a = aVec[ qp ];
91
92 std::vector< RangeType > values( basisFunctionSet.size() );
93 basisFunctionSet.evaluateAll( quadrature[ qp ], values );
94 for( std::size_t i = 0; i < values.size(); ++i )
95 {
96 b.axpy( dofs[ i ], values[ i ] );
97 }
98
99 ret[ 0 ] = std::max( ret[ 0 ], (a - b).two_norm() );
100 }
101
102 // check jacobian methods
103 {
104 JacobianRangeType b;
105 JacobianRangeType& a = aJac[ qp ];
106
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 ] );
111
112 a -= b;
113 ret[ 1 ] = std::max( ret[ 1 ], a.frobenius_norm() );
114 }
115
116 // check hessian methods
117 if( supportsHessians )
118 {
119 HessianRangeType a, b;
120
121 basisFunctionSet.hessianAll( quadrature[ qp ], dofs, a );
122
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 ] );
128
129 RangeFieldType error( 0 );
130 for( int r = 0; r < dimRange; ++r )
131 a[ r ] -= b[ r ];
132 for( int r = 0; r < dimRange; ++r )
133 error += a[ r ].frobenius_norm2();
134
135 ret[ 2 ] = std::max( ret[ 2 ], std::sqrt( error ) );
136 }
137
138 // check value axpy method
139 {
140 std::vector< RangeFieldType > r1( dofs );
141 std::vector< RangeFieldType > r2( dofs );
142
143 basisFunctionSet.axpy( quadrature[ qp ], valueFactor, r1 );
144
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 ];
149
150 RangeFieldType error = 0;
151 for( std::size_t i = 0; i < values.size(); ++i )
152 error += std::abs( r2[ i ] - r1[ i ] );
153
154 ret[ 3 ] = std::max( ret[ 3 ], error );
155 }
156
157 // check jacobian axpy method
158 {
159 DomainType x = coordinate( quadrature[ qp ] );
160 std::vector< RangeFieldType > r1( dofs );
161 std::vector< RangeFieldType > r2( dofs );
162
163 basisFunctionSet.axpy( x, jacobianFactor, r1 );
164
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 ];
170
171 RangeFieldType error = 0;
172 for( std::size_t i = 0; i < values.size(); ++i )
173 error += std::abs( r2[ i ] - r1[ i ] );
174
175 ret[ 4 ] = std::max( ret[ 4 ], error );
176 }
177
178
179 // check hessian axpy method
180 if( supportsHessians )
181 {
182 DomainType x = coordinate( quadrature[ qp ] );
183 std::vector< RangeFieldType > r1( dofs );
184 std::vector< RangeFieldType > r2( dofs );
185
186 basisFunctionSet.axpy( x, hessianFactor, r1 );
187
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 ];
195
196 RangeFieldType error = 0;
197 for( std::size_t i = 0; i < values.size(); ++i )
198 error += std::abs( r2[ i ] - r1[ i ] );
199
200 ret[ 5 ] = std::max( ret[ 5 ], error );
201 }
202
203 // check value, jaacobian axpy method
204 {
205 DomainType x = coordinate( quadrature[ qp ] );
206 std::vector< RangeFieldType > r1( dofs );
207 std::vector< RangeFieldType > r2( dofs );
208
209 basisFunctionSet.axpy( x, valueFactor, jacobianFactor, r1 );
210
211 std::vector< RangeType > values( basisFunctionSet.size() );
212 std::vector< JacobianRangeType > jacobians( basisFunctionSet.size() );
213
214 basisFunctionSet.evaluateAll( x, values );
215 basisFunctionSet.jacobianAll( x, jacobians );
216
217 for( std::size_t i = 0; i < values.size(); ++i )
218 {
219 r2[ i ] += valueFactor * values[ i ];
220 for( int j = 0; j < JacobianRangeType::rows; ++j )
221 r2[ i ] += jacobianFactor[ j ] * jacobians[ i ][ j ];
222 }
223
224 RangeFieldType error = 0;
225 for( std::size_t i = 0; i < values.size(); ++i )
226 error += std::abs( r2[ i ] - r1[ i ] );
227
228 ret[ 6 ] = std::max( ret[ 6 ], error );
229 }
230 }
231
232 return ret;
233 }
234
235 } // namespace Fem
236
237} // namespace Dune
238
239#endif // #ifndef DUNE_FEM_SPACE_TEST_CHECKBASISFUNCTIONSET_HH
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:95
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
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 27, 22:29, 2024)