1 #ifndef DUNE_FEM_FUNCTION_LOCALFUNCTION_CONST_HH 2 #define DUNE_FEM_FUNCTION_LOCALFUNCTION_CONST_HH 3 4 #include <algorithm> 5 #include <type_traits> 6 #include <utility> 7 8 #include <dune/common/dynvector.hh> 9 10 #include <dune/fem/function/localfunction/mutable.hh> 11 #include <dune/fem/function/localfunction/localfunction.hh> 12 #include <dune/fem/common/intersectionside.hh> 13 14 namespace Dune 15 { 16 17 namespace Fem 18 { 19 20 // External Forward Declerations 21 // ----------------------------- 22 23 template< class > 24 struct DiscreteFunctionTraits; 25 26 class HasLocalFunction; 27 class IsDiscreteFunction; 28 struct BindableFunction; 29 30 // BasicConstLocalFunction 31 // ----------------------- 32 33 template < class BasisFunctionSet, class LocalDofVector > 34 class BasicConstLocalFunction 35 : public LocalFunction< BasisFunctionSet, LocalDofVector > 36 { 37 typedef BasicConstLocalFunction< BasisFunctionSet, LocalDofVector > ThisType; 38 typedef LocalFunction< BasisFunctionSet, LocalDofVector > BaseType; 39 40 public: 41 //! type of Dof 42 typedef typename BaseType::DofType DofType; 43 44 //! type of Entity 45 typedef typename BaseType :: EntityType EntityType; 46 47 //! type of BasisFunctionSet 48 typedef typename BaseType :: BasisFunctionSetType BasisFunctionSetType; 49 50 //! type of LocalDofVector 51 typedef typename BaseType :: LocalDofVectorType LocalDofVectorType; 52 53 //! type of SizeType 54 typedef typename BaseType::SizeType SizeType; 55 56 //! default ctor BasicConstLocalFunction()57 BasicConstLocalFunction () {} 58 BasicConstLocalFunction(const BasisFunctionSetType & basisFunctionSet)59 explicit BasicConstLocalFunction ( const BasisFunctionSetType & basisFunctionSet ) : BaseType( basisFunctionSet ) {} 60 BasicConstLocalFunction(const LocalDofVectorType & localDofVector)61 explicit BasicConstLocalFunction ( const LocalDofVectorType &localDofVector ) : BaseType( localDofVector ) {} 62 BasicConstLocalFunction(const BasisFunctionSetType & basisFunctionSet,const LocalDofVectorType & localDofVector)63 BasicConstLocalFunction ( const BasisFunctionSetType &basisFunctionSet, const LocalDofVectorType &localDofVector ) 64 : BaseType( basisFunctionSet, localDofVector ) 65 {} 66 BasicConstLocalFunction(LocalDofVectorType && localDofVector)67 explicit BasicConstLocalFunction ( LocalDofVectorType &&localDofVector ) : BaseType( localDofVector ) {} 68 BasicConstLocalFunction(const BasisFunctionSetType & basisFunctionSet,LocalDofVectorType && localDofVector)69 BasicConstLocalFunction ( const BasisFunctionSetType &basisFunctionSet, LocalDofVectorType &&localDofVector ) 70 : BaseType( basisFunctionSet, localDofVector ) 71 {} 72 BasicConstLocalFunction(const BaseType & other)73 BasicConstLocalFunction ( const BaseType &other ) : BaseType( other ) {} 74 BasicConstLocalFunction(const ThisType & other)75 BasicConstLocalFunction ( const ThisType &other ) : BaseType( static_cast<const BaseType &>( other ) ) {} BasicConstLocalFunction(ThisType && other)76 BasicConstLocalFunction ( ThisType && other ) : BaseType( static_cast<BaseType&&>(other) ) {} 77 operator [](SizeType i) const78 const DofType &operator[] ( SizeType i ) const { return static_cast< const BaseType & >( *this )[ i ]; } operator [](SizeType i)79 const DofType &operator[] ( SizeType i ) { return static_cast< const BaseType & >( *this )[ i ]; } 80 81 using BaseType::localDofVector; 82 83 protected: 84 using BaseType::clear; 85 using BaseType::assign; 86 using BaseType::operator +=; 87 using BaseType::operator -=; 88 using BaseType::axpy; 89 }; 90 91 /** \ingroup LocalFunction 92 \class ConstLocalDiscreteFunction 93 \brief A constant local function carrying values for one entity 94 95 A ConstLocalDiscreteFunction is a LocalFunction which is basically doing the same as the 96 LocalFunction of a discrete function. The difference is that the local dofs 97 are not kept as references but are copied to a local storage. 98 Therefore, this is a const local function and any modification of dofs is not 99 allowed. 100 101 \note Local DoF numbers correspond directly to array indices. Hence it 102 may be more cache efficient to generate a ConstLocalFunction when only a 103 const access to the local function is needed. 104 105 \param DiscreteFunction type of the discrete function, the 106 local function shall belong to 107 */ 108 template< class DiscreteFunction > 109 class ConstLocalDiscreteFunction 110 : public BasicConstLocalFunction< 111 typename DiscreteFunctionTraits< std::remove_const_t< DiscreteFunction > >::DiscreteFunctionSpaceType::BasisFunctionSetType, 112 Dune::DynamicVector< typename DiscreteFunctionTraits< std::remove_const_t< DiscreteFunction > >::DofType, 113 typename DiscreteFunctionTraits< std::remove_const_t< DiscreteFunction > >::LocalDofVectorAllocatorType 114 :: template rebind< typename DiscreteFunctionTraits< std::remove_const_t< DiscreteFunction > > ::DofType > ::other > > 115 { 116 typedef ConstLocalDiscreteFunction< DiscreteFunction > ThisType; 117 typedef BasicConstLocalFunction< typename DiscreteFunctionTraits< std::remove_const_t< DiscreteFunction > >::DiscreteFunctionSpaceType::BasisFunctionSetType, 118 Dune::DynamicVector< typename DiscreteFunctionTraits< std::remove_const_t< DiscreteFunction > >::DofType, 119 typename DiscreteFunctionTraits< std::remove_const_t< DiscreteFunction > > :: LocalDofVectorAllocatorType 120 :: template rebind< typename DiscreteFunctionTraits< std::remove_const_t< DiscreteFunction > >::DofType >::other > > 121 BaseType; 122 123 public: 124 typedef std::remove_const_t< DiscreteFunction > DiscreteFunctionType; 125 typedef typename DiscreteFunctionType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType; 126 typedef typename DiscreteFunctionSpaceType::GridPartType GridPartType; 127 typedef typename DiscreteFunctionSpaceType::FunctionSpaceType FunctionSpaceType; 128 129 typedef DiscreteFunctionType GridFunctionType; 130 131 typedef typename BaseType::DofType DofType; 132 typedef typename BaseType::EntityType EntityType; 133 typedef typename GridPartType::IntersectionType IntersectionType; 134 typedef typename BaseType::BasisFunctionSetType BasisFunctionSetType; 135 typedef typename BaseType::LocalDofVectorType LocalDofVectorType; 136 typedef typename BaseType::DomainType DomainType; 137 typedef typename BaseType::RangeType RangeType; 138 typedef typename BaseType::JacobianRangeType JacobianRangeType; 139 typedef typename BaseType::HessianRangeType HessianRangeType; 140 141 /** \brief constructor creating a local function without binding it to an 142 entity 143 144 Creates the local function without initializing the fields depending on 145 the current entity. 146 147 \note Before using the local function it must be initilized by 148 \code 149 localFunction.init( entity ); 150 \endcode 151 152 \param[in] df discrete function the local function shall belong to 153 */ ConstLocalDiscreteFunction(const DiscreteFunctionType & df)154 explicit ConstLocalDiscreteFunction ( const DiscreteFunctionType &df ) 155 : BaseType( LocalDofVectorType( df.localDofVectorAllocator() ) ), 156 discreteFunction_( &df ) 157 { 158 } 159 160 //! cast a MutableLocalFunction into this one !!! expensive !!! ConstLocalDiscreteFunction(const typename DiscreteFunctionType::LocalFunctionType & localFunction)161 ConstLocalDiscreteFunction ( const typename DiscreteFunctionType::LocalFunctionType &localFunction ) 162 : BaseType( localFunction.basisFunctionSet(), LocalDofVectorType( localFunction.size(), localFunction.discreteFunction().localDofVectorAllocator() ) ), 163 discreteFunction_( &localFunction.discreteFunction() ) 164 { 165 std::copy( localFunction.localDofVector().begin(), localFunction.localDofVector().end(), localDofVector().begin() ); 166 } 167 168 /** \brief constructor creating a local function and binding it to an 169 entity 170 171 Creates the local function and initilizes the fields depending on the 172 current entity. It is not necessary, though allowed, to call init 173 before using the discrete function. 174 175 \note The degrees of freedom are not initialized by this function. 176 177 \param[in] df discrete function the local function shall 178 belong to 179 \param[in] entity entity for initialize the local function to 180 */ ConstLocalDiscreteFunction(const DiscreteFunctionType & df,const EntityType & entity)181 ConstLocalDiscreteFunction ( const DiscreteFunctionType &df, const EntityType &entity ) 182 : BaseType( df.space().basisFunctionSet( entity ), LocalDofVectorType( df.localDofVectorAllocator() ) ), 183 discreteFunction_( &df ) 184 { 185 discreteFunction().getLocalDofs( entity, localDofVector() ); 186 } ConstLocalDiscreteFunction(const EntityType & entity,const DiscreteFunctionType & df)187 ConstLocalDiscreteFunction ( const EntityType &entity, const DiscreteFunctionType &df ) 188 : BaseType( df.space().basisFunctionSet( entity ), LocalDofVectorType( df.localDofVectorAllocator() ) ), 189 discreteFunction_( &df ) 190 { 191 discreteFunction().getLocalDofs( entity, localDofVector() ); 192 } 193 194 //! copy constructor ConstLocalDiscreteFunction(const ThisType & other)195 ConstLocalDiscreteFunction ( const ThisType &other ) 196 : BaseType( static_cast<const BaseType &>( other ) ), 197 discreteFunction_( other.discreteFunction_ ) 198 {} 199 200 //! move constructor ConstLocalDiscreteFunction(ThisType && other)201 ConstLocalDiscreteFunction ( ThisType &&other ) 202 : BaseType( static_cast< BaseType &&>( other ) ), 203 discreteFunction_( other.discreteFunction_ ) 204 {} 205 206 using BaseType::localDofVector; 207 208 using BaseType::evaluate; 209 using BaseType::jacobian; 210 using BaseType::hessian; 211 212 /** \brief evaluate the local function 213 * 214 * \param[in] x evaluation point in local coordinates 215 * \returns value of the function in the given point 216 */ 217 template< class Point > evaluate(const Point & p) const218 RangeType evaluate ( const Point &p ) const 219 { 220 RangeType val; 221 evaluate( p, val ); 222 return val; 223 } 224 225 /** \brief evaluate Jacobian of the local function 226 * 227 * \note Though the Jacobian is evaluated on the reference element, the 228 * return value is the Jacobian with respect to the actual entity. 229 * 230 * \param[in] x evaluation point in local coordinates 231 * \returns Jacobian of the function in the evaluation point 232 */ 233 template< class Point > jacobian(const Point & p) const234 JacobianRangeType jacobian ( const Point &p ) const 235 { 236 JacobianRangeType jac; 237 jacobian( p, jac ); 238 return jac; 239 } 240 241 /** \brief evaluate Hessian of the local function 242 * 243 * \note Though the Hessian is evaluated on the reference element, the 244 * return value is the Hessian with respect to the actual entity. 245 * 246 * \param[in] x evaluation point in local coordinates 247 * \returns Hessian of the function in the evaluation point 248 */ 249 template< class Point > hessian(const Point & p) const250 HessianRangeType hessian ( const Point &p ) const 251 { 252 HessianRangeType h; 253 hessian( p, h ); 254 return h; 255 } 256 257 /** \copydoc Dune::Fem::LocalFunction :: init */ init(const EntityType & entity)258 void init ( const EntityType &entity ) 259 { 260 BaseType::init( discreteFunction().space().basisFunctionSet( entity ) ); 261 discreteFunction().getLocalDofs( entity, localDofVector() ); 262 } 263 bind(const EntityType & entity)264 void bind ( const EntityType &entity ) { init( entity ); } unbind()265 void unbind () {} bind(const IntersectionType & intersection,IntersectionSide side)266 void bind(const IntersectionType &intersection, IntersectionSide side) 267 { 268 bind( side==IntersectionSide::in? 269 intersection.inside(): intersection.outside() ); 270 } 271 discreteFunction() const272 const DiscreteFunctionType &discreteFunction() const { return *discreteFunction_; } gridFunction() const273 const GridFunctionType &gridFunction() const { return discreteFunction(); } 274 275 protected: 276 const DiscreteFunctionType* discreteFunction_; 277 }; 278 279 280 281 // ConstLocalFunction 282 // ------------------ 283 284 namespace Impl 285 { 286 287 template< class GF, class = void > 288 struct ConstLocalFunction; 289 290 template< class GF > 291 struct ConstLocalFunction< GF, std::enable_if_t< std::is_base_of< Fem::HasLocalFunction, GF >::value && std::is_base_of< Fem::IsDiscreteFunction, GF >::value > > 292 { 293 typedef ConstLocalDiscreteFunction< GF > Type; 294 }; 295 296 template< class GF > 297 struct ConstLocalFunction< GF, std::enable_if_t< std::is_base_of< Fem::HasLocalFunction, GF >::value && !std::is_base_of< Fem::IsDiscreteFunction, GF >::value && std::is_class< typename GF::LocalFunctionType >::value > > 298 { 299 struct Type 300 : public GF::LocalFunctionType 301 { 302 typedef GF GridFunctionType; 303 typedef typename GridFunctionType::LocalFunctionType::EntityType EntityType; 304 305 typedef typename GF::LocalFunctionType::DomainType DomainType; 306 typedef typename GF::LocalFunctionType::RangeType RangeType; 307 typedef typename GF::LocalFunctionType::JacobianRangeType JacobianRangeType; 308 typedef typename GF::LocalFunctionType::HessianRangeType HessianRangeType; 309 TypeDune::Fem::Impl::ConstLocalFunction::Type310 explicit Type ( const GridFunctionType &gridFunction ) 311 : GridFunctionType::LocalFunctionType( gridFunction ), 312 gridFunction_( gridFunction ) 313 {} TypeDune::Fem::Impl::ConstLocalFunction::Type314 explicit Type ( const EntityType &entity, const GridFunctionType &gridFunction ) 315 : GridFunctionType::LocalFunctionType( gridFunction ), 316 gridFunction_( gridFunction ) 317 { bind(entity); } 318 319 using GF::LocalFunctionType::evaluate; 320 using GF::LocalFunctionType::jacobian; 321 using GF::LocalFunctionType::hessian; 322 using GF::LocalFunctionType::init; 323 using GF::LocalFunctionType::entity; 324 325 //! evaluate local function 326 template< class Point > evaluateDune::Fem::Impl::ConstLocalFunction::Type327 RangeType evaluate ( const Point &p ) const 328 { 329 RangeType val; 330 evaluate( p, val ); 331 return val; 332 } 333 334 //! jacobian of local function 335 template< class Point > jacobianDune::Fem::Impl::ConstLocalFunction::Type336 JacobianRangeType jacobian ( const Point &p ) const 337 { 338 JacobianRangeType jac; 339 jacobian( p, jac ); 340 return jac; 341 } 342 343 //! hessian of local function 344 template< class Point > hessianDune::Fem::Impl::ConstLocalFunction::Type345 HessianRangeType hessian ( const Point &p ) const 346 { 347 HessianRangeType h; 348 hessian( p, h ); 349 return h; 350 } 351 bindDune::Fem::Impl::ConstLocalFunction::Type352 void bind ( const EntityType &entity ) { init( entity ); } unbindDune::Fem::Impl::ConstLocalFunction::Type353 void unbind () {} 354 template <class IntersectionType> bindDune::Fem::Impl::ConstLocalFunction::Type355 void bind(const IntersectionType &intersection, IntersectionSide side) 356 { 357 bind( side==IntersectionSide::in? 358 intersection.inside(): intersection.outside() ); 359 } 360 gridFunctionDune::Fem::Impl::ConstLocalFunction::Type361 const GridFunctionType &gridFunction () const { return gridFunction_; } 362 363 private: 364 const GridFunctionType &gridFunction_; 365 }; 366 }; 367 368 template< class GF > 369 struct ConstLocalFunction< GF, std::enable_if_t< std::is_base_of< Fem::BindableFunction, std::decay_t<GF> >::value && !std::is_base_of< Fem::IsDiscreteFunction, std::decay_t<GF> >::value > > 370 { 371 struct Type 372 { 373 typedef GF GridFunctionType; 374 typedef std::decay_t<GF> GridFunctionDecayType; 375 typedef typename GridFunctionDecayType::GridPartType GridPartType; 376 typedef typename GridFunctionDecayType::EntityType EntityType; 377 typedef typename GridFunctionDecayType::RangeFieldType RangeFieldType; 378 typedef typename GridFunctionDecayType::DomainType DomainType; 379 typedef typename GridFunctionDecayType::RangeType RangeType; 380 typedef typename GridFunctionDecayType::JacobianRangeType JacobianRangeType; 381 typedef typename GridFunctionDecayType::HessianRangeType HessianRangeType; 382 typedef typename GridFunctionDecayType::FunctionSpaceType FunctionSpaceType; 383 384 template<class Arg, std::enable_if_t<std::is_constructible<GF, Arg>::value, int> = 0> TypeDune::Fem::Impl::ConstLocalFunction::Type385 explicit Type ( Arg&& gridFunction ) 386 : gridFunction_( std::forward<Arg>(gridFunction) ) 387 {} 388 template<class Arg, std::enable_if_t<std::is_constructible<GF, Arg>::value, int> = 0> TypeDune::Fem::Impl::ConstLocalFunction::Type389 explicit Type ( const EntityType &entity, Arg&& gridFunction ) 390 : gridFunction_( std::forward<Arg>(gridFunction) ) 391 { bind(entity); } 392 393 template <class Point> evaluateDune::Fem::Impl::ConstLocalFunction::Type394 void evaluate(const Point &x, RangeType &ret) const 395 { 396 gridFunction().evaluate(x,ret); 397 } 398 template <class Point> jacobianDune::Fem::Impl::ConstLocalFunction::Type399 void jacobian(const Point &x, JacobianRangeType &ret) const 400 { 401 gridFunction().jacobian(x,ret); 402 } 403 template <class Point> hessianDune::Fem::Impl::ConstLocalFunction::Type404 void hessian(const Point &x, HessianRangeType &ret) const 405 { 406 gridFunction().hessian(x,ret); 407 } orderDune::Fem::Impl::ConstLocalFunction::Type408 unsigned int order() const { return gridFunction().order(); } 409 410 //! evaluate local function 411 template< class Point > evaluateDune::Fem::Impl::ConstLocalFunction::Type412 RangeType evaluate ( const Point &p ) const 413 { 414 RangeType val; 415 evaluate( p, val ); 416 return val; 417 } 418 419 //! jacobian of local function 420 template< class Point > jacobianDune::Fem::Impl::ConstLocalFunction::Type421 JacobianRangeType jacobian ( const Point &p ) const 422 { 423 JacobianRangeType jac; 424 jacobian( p, jac ); 425 return jac; 426 } 427 428 //! hessian of local function 429 template< class Point > hessianDune::Fem::Impl::ConstLocalFunction::Type430 HessianRangeType hessian ( const Point &p ) const 431 { 432 HessianRangeType h; 433 hessian( p, h ); 434 return h; 435 } 436 437 template< class Quadrature, class ... Vectors > evaluateQuadratureDune::Fem::Impl::ConstLocalFunction::Type438 void evaluateQuadrature ( const Quadrature &quad, Vectors & ... values ) const 439 { 440 static_assert( sizeof...( Vectors ) > 0, "evaluateQuadrature needs to be called with at least one vector." ); 441 evaluateFullQuadrature( PriorityTag<42>(), quad, values... ); 442 } 443 template< class Quadrature, class Jacobians > jacobianQuadratureDune::Fem::Impl::ConstLocalFunction::Type444 void jacobianQuadrature ( const Quadrature &quadrature, Jacobians &jacobians ) const 445 { jacobianQuadrature(quadrature,jacobians, PriorityTag<42>() ); } 446 template< class Quadrature, class Hessians > hessianQuadratureDune::Fem::Impl::ConstLocalFunction::Type447 void hessianQuadrature ( const Quadrature &quadrature, Hessians &hessians ) const 448 { hessianQuadrature(quadrature,hessians, PriorityTag<42>() ); } 449 bindDune::Fem::Impl::ConstLocalFunction::Type450 void bind ( const EntityType &entity ) { gridFunction_.bind( entity ); } unbindDune::Fem::Impl::ConstLocalFunction::Type451 void unbind () { gridFunction_.unbind(); } 452 template <class IntersectionType> bindDune::Fem::Impl::ConstLocalFunction::Type453 void bind(const IntersectionType &intersection, IntersectionSide side) 454 { defaultIntersectionBind(gridFunction_,intersection, side); } 455 entityDune::Fem::Impl::ConstLocalFunction::Type456 const EntityType& entity() const 457 { 458 return gridFunction_.entity(); 459 } 460 gridFunctionDune::Fem::Impl::ConstLocalFunction::Type461 const GridFunctionDecayType &gridFunction () const { return gridFunction_; } 462 463 private: 464 template< class Quadrature, class ... Vectors, class GF_=GridFunctionDecayType > evaluateFullQuadratureDune::Fem::Impl::ConstLocalFunction::Type465 auto evaluateFullQuadrature ( PriorityTag<1>, const Quadrature &quad, Vectors & ... values ) const 466 -> std::enable_if_t< std::is_void< decltype( std::declval< const GF_& >().evaluateQuadrature(quad,values...))>::value > 467 { gridFunction().evaluateQuadrature(quad,values...); } 468 template< class Quadrature, class ... Vectors > evaluateFullQuadratureDune::Fem::Impl::ConstLocalFunction::Type469 void evaluateFullQuadrature ( PriorityTag<0>, const Quadrature &quad, Vectors & ... values ) const 470 { std::ignore = std::make_tuple( ( evaluateSingleQuadrature( quad, values ), 1 ) ... ); } 471 472 template< class Quadrature, class Jacobians, class GF_=GridFunctionDecayType> jacobianQuadratureDune::Fem::Impl::ConstLocalFunction::Type473 auto jacobianQuadrature ( const Quadrature &quadrature, Jacobians &jacobians, PriorityTag<1> ) const 474 -> std::enable_if_t< std::is_void< decltype( std::declval< const GF_& >().jacobianQuadrature(quadrature,jacobians))>::value > 475 { gridFunction().jacobianQuadrature(quadrature,jacobians); } 476 template< class Quadrature, class Jacobians > jacobianQuadratureDune::Fem::Impl::ConstLocalFunction::Type477 void jacobianQuadrature ( const Quadrature &quadrature, Jacobians &jacobians, PriorityTag<0> ) const 478 { 479 for( const auto qp : quadrature ) 480 jacobians[ qp.index() ] = jacobian( qp ); 481 } 482 483 template< class Quadrature, class Hessians, class GF_=GridFunctionDecayType > hessianQuadratureDune::Fem::Impl::ConstLocalFunction::Type484 auto hessianQuadrature ( const Quadrature &quadrature, Hessians &hessians, PriorityTag<1> ) const 485 -> std::enable_if_t< std::is_void< decltype( std::declval< const GF_& >().hessianQuadrature(quadrature,hessians))>::value > 486 { gridFunction().hessianQuadrature(quadrature,hessians); } 487 template< class Quadrature, class Hessians > hessianQuadratureDune::Fem::Impl::ConstLocalFunction::Type488 void hessianQuadrature ( const Quadrature &quadrature, Hessians &hessians, PriorityTag<0> ) const 489 { 490 for( const auto qp : quadrature ) 491 hessians[ qp.index() ] = hessian( qp ); 492 } 493 494 template< class Quadrature, class Vector > evaluateSingleQuadratureDune::Fem::Impl::ConstLocalFunction::Type495 auto evaluateSingleQuadrature ( const Quadrature &quad, Vector &v ) const 496 -> std::enable_if_t< std::is_same< std::decay_t< decltype(v[ 0 ]) >, RangeType >::value > 497 { 498 for( const auto qp : quad ) 499 v[ qp.index() ] = evaluate( qp ); 500 } 501 template< class Quadrature, class Vector > evaluateSingleQuadratureDune::Fem::Impl::ConstLocalFunction::Type502 auto evaluateSingleQuadrature ( const Quadrature &quad, Vector &v ) const 503 -> std::enable_if_t< std::is_same< std::decay_t< decltype(v[ 0 ]) >, JacobianRangeType >::value > 504 { jacobianQuadrature(quad,v); } 505 template< class Quadrature, class Vector > evaluateSingleQuadratureDune::Fem::Impl::ConstLocalFunction::Type506 auto evaluateSingleQuadrature ( const Quadrature &quad, Vector &v ) const 507 -> std::enable_if_t< std::is_same< std::decay_t< decltype(v[ 0 ]) >, HessianRangeType >::value > 508 { hessianQuadrature(quad,v); } 509 510 GridFunctionType gridFunction_; 511 }; 512 }; 513 } // namespace Impl 514 515 516 template< class GridFunction > 517 using ConstLocalFunction = typename Impl::ConstLocalFunction< GridFunction >::Type; 518 /**@internal Default FalseType.*/ 519 template<class T, class SFINAE = void> 520 struct IsConstLocalFunction 521 : std::false_type 522 {}; 523 524 /**@internal Forward to decay_t.*/ 525 template<class T> 526 struct IsConstLocalFunction<T, std::enable_if_t<!std::is_same<T, std::decay_t<T> >{}> > 527 : IsConstLocalFunction<std::decay_t<T> > 528 {}; 529 530 /**TrueType if a T can be wrapped into a Fem::ConstLocalFunction.*/ 531 template<class T> 532 struct IsConstLocalFunction< 533 T, 534 std::enable_if_t<(std::is_same<T, std::decay_t<T> >{} 535 && std::is_same<T, Fem::ConstLocalFunction<typename T::GridFunctionType> >{} 536 )> > 537 : std::true_type 538 {}; 539 540 541 /**Wrap an F into a Fem::ConstLocalFunction if directly allowed 542 * by Fem::ConstLocalFunction. 543 */ 544 template<class F, std::enable_if_t<!IsConstLocalFunction<F>::value, int> = 0> constLocalFunction(F && f)545 constexpr auto constLocalFunction(F&& f) 546 { 547 return Fem::ConstLocalFunction<std::decay_t<F> >(std::forward<F>(f)); 548 } 549 550 /**@internal Forward a Fem::ConstLocalFunction as is.*/ 551 template<class F, std::enable_if_t<IsConstLocalFunction<F>::value, int> = 0> constLocalFunction(F && f)552 constexpr decltype(auto) constLocalFunction(F&& f) 553 { 554 return std::forward<F>(f); 555 } 556 557 template<class F, class Entity> constLocalFunction(F && f,const Entity & entity)558 constexpr auto constLocalFunction(F&& f, const Entity &entity) 559 { 560 return Dune::Fem::ConstLocalFunction<std::decay_t<F> >(entity,std::forward<F>(f)); 561 } 562 563 } // namespace Fem 564 565 } // namespace Dune 566 567 #endif // #ifndef DUNE_FEM_FUNCTION_LOCALFUNCTION_CONST_HH 568