1#ifndef DUNE_FEM_SPACE_FOURIER_FUNCTIONSET_HH
2#define DUNE_FEM_SPACE_FOURIER_FUNCTIONSET_HH
13#include <dune/fem/space/common/functionspace.hh>
14#include <dune/fem/version.hh>
26 template<
int dimension,
int Order >
27 struct FourierFunctionSetSize
29 static constexpr int v =
Dune::power( (2*Order+1), dimension );
37 template<
class FunctionSpace,
int Order >
38 class FourierFunctionSet;
45 template<
class DomainFieldType,
class RangeFieldType,
int Order >
46 class FourierFunctionSet< FunctionSpace< DomainFieldType, RangeFieldType, 1, 1 >, Order >
48 typedef FourierFunctionSet< FunctionSpace< DomainFieldType, RangeFieldType, 1, 1 >, Order > ThisType;
58 typedef std::size_t SizeType;
60 explicit FourierFunctionSet (
int order ) : order_( order ) {}
62 int order ()
const {
return order_; }
64 static SizeType
size () {
return FourierFunctionSetSize< 1, Order >::v; }
66 template<
class Functor >
67 static void evaluateEach (
const DomainType &x, Functor functor )
71 functor( 0, RangeType( RangeFieldType( 1 ) / RangeFieldType( 2 ) ) );
75 SizeType basisFunction = 1;
76 for(
int n = 1; n <= Order; ++n )
78 functor( basisFunction++, RangeType( cos( n*x[ 0 ] ) ) );
79 functor( basisFunction++, RangeType( sin( n*x[ 0 ] ) ) );
83 template<
class Functor >
84 static void jacobianEach (
const DomainType &x, Functor functor )
88 functor( 0, JacobianRangeType( RangeFieldType( 0 ) ) );
89 SizeType basisFunction = 1;
90 for(
int n = 1; n <= Order; ++n )
92 functor( basisFunction++, JacobianRangeType( -n*sin( n*x[ 0 ] ) ) );
93 functor( basisFunction++, JacobianRangeType( n*cos( n*x[ 0 ] ) ) );
97 template<
class Functor >
98 static void hessianEach (
const DomainType &x, Functor functor )
102 functor( 0, HessianRangeType( RangeFieldType( 0 ) ) );
103 SizeType basisFunction = 1;
104 for(
int n = 1; n <= Order; ++n )
106 functor( basisFunction++, HessianRangeType( -(n*n)*cos( n*x[ 0 ] ) ) );
107 functor( basisFunction++, HessianRangeType( -(n*n)*sin( n*x[ 0 ] ) ) );
119 template<
class DomainFieldType,
class RangeFieldType,
int dimDomain,
int Order >
120 class FourierFunctionSet< FunctionSpace< DomainFieldType, RangeFieldType, dimDomain, 1 >, Order >
122 typedef FourierFunctionSet< FunctionSpace< DomainFieldType, RangeFieldType, dimDomain, 1 >, Order > ThisType;
125 typedef FunctionSpace< DomainFieldType, RangeFieldType, dimDomain, 1 >
FunctionSpaceType;
132 typedef std::size_t SizeType;
136 static const int buffer_size = FourierFunctionSetSize< 1, Order >::v;
150 struct MultiIndexIterator;
151 typedef MultiIndexIterator IteratorType;
152 static IteratorType begin () {
return IteratorType::begin(); }
153 static IteratorType end () {
return IteratorType::end(); }
156 explicit FourierFunctionSet (
int order ) : order_( order ) {}
158 int order ()
const {
return order_; }
160 static SizeType
size () {
return FourierFunctionSetSize< dimDomain, Order >::v; }
162 template<
class Functor >
163 void evaluateEach (
const DomainType &x, Functor functor )
const
165 prepare( Evaluate(), x );
167 const IteratorType end = ThisType::end();
168 for( IteratorType it = ThisType::begin(); it != end; ++it, ++index )
171 evaluate( *it, value );
172 assert( index == IteratorType::index( *it ) );
173 functor( index, value );
175 assert( index ==
size() );
178 template<
class Functor >
179 void jacobianEach (
const DomainType &x, Functor functor )
const
181 prepare( Jacobian(), x );
183 const IteratorType end = ThisType::end();
184 for( IteratorType it = ThisType::begin(); it != end; ++it, ++index )
186 JacobianRangeType jacobian;
187 evaluate( *it, jacobian );
188 assert( index == IteratorType::index( *it ) );
189 functor( index, jacobian );
191 assert( index ==
size() );
194 template<
class Functor >
195 void hessianEach (
const DomainType &x, Functor functor )
const
197 prepare( Hessian(), x );
199 const IteratorType end = ThisType::end();
200 for( IteratorType it = ThisType::begin(); it != end; ++it, ++index )
202 HessianRangeType hessian;
203 evaluate( *it, hessian );
204 assert( index == IteratorType::index( *it ) );
205 functor( index, hessian );
207 assert( index ==
size() );
212 void evaluate (
const MultiIndexType &multiIndex, RangeType &value )
const
214 value = RangeType( RangeFieldType( 1 ) );
215 for( SizeType i = 0; i < dimDomain; ++i )
216 value *= buffer_[ i ][ multiIndex[ i ] ];
220 void evaluate (
const MultiIndexType &multiIndex, JacobianRangeType &jacobian )
const
222 jacobian = JacobianRangeType( 1 );
223 for(
int k = 0; k < dimDomain; ++k )
225 const RangeFieldType phi = buffer_[ k ][ multiIndex[ k ] ];
226 const RangeFieldType dphi = buffer_[ k ][ buffer_size + multiIndex[ k ] ];
227 for(
int i = 0; i < dimDomain; ++i )
228 jacobian[ 0 ][ i ] *= (k == i ? dphi : phi);
233 void evaluate (
const MultiIndexType &multiIndex, HessianRangeType &hessian )
const
235 for(
int i = 0; i < dimDomain; ++i )
236 for(
int j = 0; j < dimDomain; ++j )
237 hessian[ 0 ][ i ][ j ] = RangeFieldType( 1 );
239 for(
int k = 0; k < dimDomain; ++k )
241 const RangeFieldType phi = buffer_[ k ][ multiIndex[ k ] ];
242 const RangeFieldType dphi = buffer_[ k ][ buffer_size + multiIndex[ k ] ];
243 for(
int i = 0; i < dimDomain; ++i )
245 hessian[ 0 ][ i ][ i ] *= (k == i ? buffer_[ i ][ 2*buffer_size + multiIndex[ i ] ] : phi);
246 for(
int j = i+1; j < dimDomain; ++j )
248 RangeFieldType tmp = ( k == i || k == j ) ? dphi : phi;
249 hessian[ 0 ][ i ][ j ] *= tmp;
250 hessian[ 0 ][ j ][ i ] *= tmp;
257 void prepare (
const Evaluate &,
const DomainType &x )
const;
258 void prepare (
const Jacobian &,
const DomainType &x )
const;
259 void prepare (
const Hessian &,
const DomainType &x )
const;
264 mutable std::array< std::array< RangeFieldType, 3*buffer_size>, dimDomain > buffer_;
272 template<
class DomainFieldType,
class RangeFieldType,
int dimDomain,
int Order >
273 struct FourierFunctionSet< FunctionSpace< DomainFieldType, RangeFieldType, dimDomain, 1 >, Order >::Assign
275 explicit Assign ( RangeFieldType *buffer ) : buffer_( buffer ) {}
277 void operator() (
const std::size_t i,
const RangeFieldType &value )
279 buffer_[ i ] = value;
283 void operator() (
const std::size_t i,
const FieldVector< T, 1 > &value )
285 (*this)( i, value[ 0 ] );
289 void operator() (
const std::size_t i,
const FieldMatrix< T, 1, 1 > &value )
291 (*this)( i, value[ 0 ][ 0 ] );
295 RangeFieldType *buffer_;
303 template<
class DomainFieldType,
class RangeFieldType,
int dimDomain,
int Order >
304 struct FourierFunctionSet< FunctionSpace< DomainFieldType, RangeFieldType, dimDomain, 1 >, Order >::MultiIndexIterator
306 typedef MultiIndexIterator ThisType;
309 typedef int IndexType;
311 explicit MultiIndexIterator ( IndexType n ) : multiIndex_( n ) {}
315 static const int N = FourierFunctionSetSize< 1, Order >::v;
318 static ThisType begin () {
return ThisType( 0 ); }
319 static ThisType end () {
return ThisType( invalidIndex() ); }
321 ThisType operator++ ()
324 for(
int i = 0; i < dimDomain; ++i )
326 const int j = dimDomain-i-1;
327 if( ++multiIndex_[ j ] < N )
329 multiIndex_[ j ] = 0;
337 bool operator== (
const ThisType &other )
const {
return ( multiIndex_ == other.multiIndex_ ); }
339 bool operator!= (
const ThisType &other )
const {
return !( *
this == other ); }
341 const MultiIndexType &operator* ()
const {
return multiIndex_; }
343 const MultiIndexType *operator-> ()
const {
return &multiIndex_; }
345 SizeType index ()
const {
return index( multiIndex_ ); }
347 static SizeType index (
const MultiIndexType &multiIndex )
349 SizeType index = 0, factor = 1;
350 for(
int i = dimDomain-1; i >= 0; --i )
352 index += multiIndex[ i ]*factor;
355 assert( index <
size() );
360 MultiIndexType multiIndex_;
368 template<
class DomainFieldType,
class RangeFieldType,
int dimDomain,
int Order >
369 void FourierFunctionSet< FunctionSpace< DomainFieldType, RangeFieldType, dimDomain, 1 >, Order >
370 ::prepare (
const Evaluate &,
const DomainType &x )
const
372 typedef FourierFunctionSet< FunctionSpace< DomainFieldType, RangeFieldType, 1, 1 >, Order > FunctionSetImp;
373 for( SizeType i = 0; i < dimDomain; ++i )
375 RangeFieldType *it = &buffer_[ i ][ 0 ];
377 FunctionSetImp::evaluateEach( y, Assign( it ) );
382 template<
class DomainFieldType,
class RangeFieldType,
int dimDomain,
int Order >
383 void FourierFunctionSet< FunctionSpace< DomainFieldType, RangeFieldType, dimDomain, 1 >, Order >
384 ::prepare (
const Jacobian &,
const DomainType &x )
const
386 typedef FourierFunctionSet< FunctionSpace< DomainFieldType, RangeFieldType, 1, 1 >, Order > FunctionSetImp;
387 for( SizeType i = 0; i < dimDomain; ++i )
389 RangeFieldType *it = &buffer_[ i ][ 0 ];
391 FunctionSetImp::evaluateEach( y, Assign( it ) );
392 FunctionSetImp::jacobianEach( y, Assign( it+buffer_size ) );
397 template<
class DomainFieldType,
class RangeFieldType,
int dimDomain,
int Order >
398 void FourierFunctionSet< FunctionSpace< DomainFieldType, RangeFieldType, dimDomain, 1 >, Order >
399 ::prepare (
const Hessian &,
const DomainType &x )
const
401 typedef FourierFunctionSet< FunctionSpace< DomainFieldType, RangeFieldType, 1, 1 >, Order > FunctionSetImp;
402 for( SizeType i = 0; i < dimDomain; ++i )
404 RangeFieldType *it = &buffer_[ i ][ 0 ];
406 FunctionSetImp::evaluateEach( y, Assign( it ) );
407 FunctionSetImp::jacobianEach( y, Assign( it+buffer_size) );
408 FunctionSetImp::hessianEach( y, Assign( it+2*buffer_size ) );
Definition: explicitfieldvector.hh:75
FunctionSpaceTraits::RangeType RangeType
Type of range vector (using type of range field) has a Dune::FieldVector type interface.
Definition: functionspaceinterface.hh:71
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
A vector valued function space.
Definition: functionspace.hh:60
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Implements a vector constructed from a given type representing a field and a compile-time given size.
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:238
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:260
Some useful basic math stuff.
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
constexpr Base power(Base m, Exponent p)
Power method for integer exponents.
Definition: math.hh:75