1 #ifndef DUNE_FEM_FUNCTION_LOCALFUNCTION_CONVERTER_HH 2 #define DUNE_FEM_FUNCTION_LOCALFUNCTION_CONVERTER_HH 3 4 #include <functional> 5 #include <type_traits> 6 #include <utility> 7 8 #include <dune/fem/function/common/function.hh> 9 #include <dune/fem/function/common/instationary.hh> 10 #include <dune/fem/space/common/functionspace.hh> 11 12 13 namespace Dune 14 { 15 16 namespace Fem 17 { 18 19 // LocalFunctionConverter 20 // -------------------- 21 22 /** \brief implementation of a Dune::Fem::LocalFunction on a FunctionSpace V restircted/prolongated from an other 23 * function space W. 24 * 25 * The HostLocalFunction is assumed to fulfill the LocalFunctioninterface. 26 * Basically the following functions are implemented on the HostLocalFunction: 27 * \code 28 * template< class Point > 29 * void evaluate ( const Point &x, RangeType &ret ) const; 30 * 31 * template< class Point > 32 * void jacobian ( const Point &x, JacobianRangeType &jac ) const; 33 * 34 * tempalte< class Point > 35 * void hessian ( const Point &x, HessianRangeType &hess ) const; 36 * 37 * const EntityType &entity () const; 38 * 39 * int size() const; 40 * 41 * void init ( const EntityType & entity ); 42 * \endcode 43 * 44 * The template paramter Converter, is used to get the restriction/prolongation onto the space V. 45 * Converter is expected to provide the method 46 * {Hessian,Jacobian,.}RangeType converter( Host{Hessian,Jacobian,. }RangeType ); 47 * which does the acctual mapping onto V. 48 * The dimension of the new Range is obtained from the method Convertor::operator( HostRangeType )::dimension. 49 * 50 * Users may prescribe how the parameter localFunction is stored by providing a 51 * fourth template parameter, the storage policy. Further informations on the storage policy can be found in 52 * the file dune/fem/function/common/instationary.hh. 53 * 54 * The free-standing function 55 * \code 56 * Dune::Fem::localFunctionConverter 57 * \endcode 58 * may be used to conveniently create a new instance of a LocalFunctionConverter. Use 59 * \code 60 * auto g = localFunctionConverter( localFunction, Converter ) 61 * \endcode 62 * to create an converted local function. 63 * 64 * \tparam HostLocalFunction original local function 65 * \tparam Converter structure which provides the restirction/prolongation from W to V 66 * \tparam StoragePolicy storage policy 67 * 68 * \ingroup LocalFunction 69 */ 70 71 template< class HostLocalFunction, class Converter, template< class > class Storage = __InstationaryFunction::HoldCopy > 72 class LocalFunctionConverter 73 : private Storage< HostLocalFunction > 74 { 75 typedef LocalFunctionConverter< HostLocalFunction, Converter, Storage > ThisType; 76 typedef Storage< HostLocalFunction > BaseType; 77 78 typedef typename HostLocalFunction::RangeType HostRangeType; 79 typedef typename HostLocalFunction::JacobianRangeType HostJacobianRangeType; 80 typedef typename HostLocalFunction::HessianRangeType HostHessianRangeType; 81 82 public: 83 // obtain new dimRange from Converter 84 static const int dimRange = decltype( std::declval< Converter >() ( std::declval< HostRangeType >() ) ) ::dimension; 85 86 // define new FunctionSpace 87 typedef typename ToNewDimRangeFunctionSpace< typename HostLocalFunction::FunctionSpaceType, dimRange >::Type FunctionSpaceType; 88 89 // types from HostLocalFunction 90 typedef typename HostLocalFunction::EntityType EntityType; 91 92 // types from FunctionSpace 93 typedef typename FunctionSpaceType::DomainType DomainType; 94 typedef typename FunctionSpaceType::RangeType RangeType; 95 typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType; 96 typedef typename FunctionSpaceType::HessianRangeType HessianRangeType; 97 typedef typename FunctionSpaceType::DomainFieldType DomainFieldType; 98 typedef typename FunctionSpaceType::RangeFieldType RangeFieldType; 99 100 static const int dimDomain = FunctionSpaceType::dimDomain; 101 102 struct Traits 103 { 104 typedef typename FunctionSpaceType::DomainType DomainType; 105 typedef typename FunctionSpaceType::RangeType RangeType; 106 typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType; 107 typedef typename FunctionSpaceType::HessianRangeType HessianRangeType; 108 typedef typename FunctionSpaceType::DomainFieldType DomainFieldType; 109 typedef typename FunctionSpaceType::RangeFieldType RangeFieldType; 110 }; 111 LocalFunctionConverter(const HostLocalFunction & hostLocalFunction,const Converter & converter=Converter ())112 LocalFunctionConverter ( const HostLocalFunction &hostLocalFunction, const Converter &converter = Converter() ) 113 : BaseType( hostLocalFunction ), converter_( converter ) 114 {} 115 LocalFunctionConverter(HostLocalFunction && hostLocalFunction,const Converter & converter=Converter ())116 LocalFunctionConverter ( HostLocalFunction &&hostLocalFunction, const Converter &converter = Converter() ) 117 : BaseType( std::move( hostLocalFunction ) ), converter_( converter ) 118 {} 119 120 template< class Point > evaluate(const Point & p,RangeType & ret) const121 void evaluate ( const Point &p, RangeType &ret ) const 122 { 123 HostRangeType hRet; 124 this->get().evaluate( p, hRet ); 125 ret = converter_( hRet ); 126 } 127 template< class Point > operator ()(const Point & p) const128 RangeType operator()( const Point &p ) const 129 { 130 RangeType ret; 131 evaluate(p,ret); 132 return ret; 133 } 134 135 template< class Point > jacobian(const Point & p,JacobianRangeType & jac) const136 void jacobian ( const Point &p, JacobianRangeType &jac ) const 137 { 138 HostJacobianRangeType hJac; 139 this->get().jacobian( p, hJac ); 140 jac = converter_( hJac ); 141 } 142 143 template< class Point > hessian(const Point & p,HessianRangeType & hes) const144 void hessian ( const Point &p, HessianRangeType &hes ) const 145 { 146 HostHessianRangeType hHes; 147 this->get().hessian( p, hHes ); 148 hes = converter_( hHes ); 149 } 150 151 template< class Quadrature, class ... Vectors > evaluateQuadrature(const Quadrature & quad,Vectors &...vector) const152 void evaluateQuadrature ( const Quadrature &quad, Vectors& ... vector ) const 153 { 154 std::ignore = std::make_tuple( 155 ( evaluateQuadratureImp( quad, vector, vector[ 0 ] ), 1 )... ); 156 } 157 order() const158 int order () const { return this->get().order(); } 159 entity() const160 EntityType entity () const { return this->get().entity(); } 161 init(const EntityType & entity)162 void init ( const EntityType &entity ) { this->get().init( entity ); } 163 164 protected: 165 template< class QuadratureType, class VectorType > evaluateQuadratureImp(const QuadratureType & quadrature,VectorType & values,const RangeType &) const166 void evaluateQuadratureImp ( const QuadratureType &quadrature, VectorType &values, const RangeType & ) const 167 { 168 const unsigned int nop = quadrature.nop(); 169 for( unsigned int qp = 0; qp < nop; ++qp ) 170 evaluate( quadrature[ qp ], values[ qp ] ); 171 } 172 173 template< class QuadratureType, class VectorType > evaluateQuadratureImp(const QuadratureType & quadrature,VectorType & values,const JacobianRangeType &) const174 void evaluateQuadratureImp ( const QuadratureType &quadrature, VectorType &values, const JacobianRangeType & ) const 175 { 176 const unsigned int nop = quadrature.nop(); 177 for( unsigned int qp = 0; qp < nop; ++qp ) 178 jacobian( quadrature[ qp ], values[ qp ] ); 179 } 180 181 template< class QuadratureType, class VectorType > evaluateQuadratureImp(const QuadratureType & quadrature,VectorType & values,const HessianRangeType &) const182 void evaluateQuadratureImp ( const QuadratureType &quadrature, VectorType &values, const HessianRangeType & ) const 183 { 184 const unsigned int nop = quadrature.nop(); 185 for( unsigned int qp = 0; qp < nop; ++qp ) 186 hessian( quadrature[ qp ], values[ qp ] ); 187 } 188 189 Converter converter_; 190 }; 191 192 193 194 // localFunctionConverter 195 // ---------------------- 196 197 template< class HostLocalFunction, class Converter > 198 LocalFunctionConverter< HostLocalFunction, Converter, __InstationaryFunction::HoldCopy > localFunctionConverter(HostLocalFunction hostLocalFunction,const Converter & converter=Converter ())199 localFunctionConverter ( HostLocalFunction hostLocalFunction, const Converter &converter = Converter() ) 200 { 201 typedef LocalFunctionConverter< HostLocalFunction, Converter, __InstationaryFunction::HoldCopy > LocalFunctionConverterType; 202 return LocalFunctionConverterType( std::move( hostLocalFunction ), converter ); 203 } 204 205 template< class HostLocalFunction, class Converter > 206 LocalFunctionConverter< typename std::remove_const< HostLocalFunction >::type, Converter, __InstationaryFunction::HoldReference > localFunctionConverter(std::reference_wrapper<HostLocalFunction> hostLocalFunction,const Converter & converter=Converter ())207 localFunctionConverter ( std::reference_wrapper< HostLocalFunction > hostLocalFunction, const Converter &converter = Converter() ) 208 { 209 typedef LocalFunctionConverter< typename std::remove_const< HostLocalFunction >::type, Converter, __InstationaryFunction::HoldReference > LocalFunctionConverterType; 210 return LocalFunctionConverterType( hostLocalFunction.get(), converter ); 211 } 212 213 } // namespace Fem 214 215 } // namespace Dune 216 217 #endif // #ifndef DUNE_FEM_FUNCTION_LOCALFUNCTION_CONVERTER_HH 218