1 #ifndef DUNE_FEM_FUNCTION_LOCALFUNCTION_BINDABLE_HH 2 #define DUNE_FEM_FUNCTION_LOCALFUNCTION_BINDABLE_HH 3 4 #include <dune/fem/space/common/discretefunctionspace.hh> 5 #include <dune/fem/function/common/discretefunction.hh> 6 #include <dune/fem/common/coordinate.hh> 7 #include <dune/fem/quadrature/quadrature.hh> // shouldn't be here (but otherwise the coordinate method doesn't work) 8 #include <dune/fem/common/intersectionside.hh> 9 10 namespace Dune 11 { 12 namespace Fem 13 { 14 struct BindableFunction : public HasLocalFunction {}; 15 16 template <class GridPart, class Range> 17 struct BindableGridFunction : public BindableFunction 18 { 19 typedef GridPart GridPartType; 20 typedef typename GridPart::template Codim<0>::EntityType EntityType; 21 typedef typename GridPart::IntersectionType IntersectionType; 22 typedef typename EntityType::Geometry Geometry; 23 typedef typename Geometry::GlobalCoordinate DomainType; 24 typedef Dune::Fem::GridFunctionSpace<GridPartType, Range> FunctionSpaceType; 25 typedef typename FunctionSpaceType::RangeFieldType RangeFieldType; 26 typedef typename FunctionSpaceType::RangeType RangeType; 27 typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType; 28 typedef typename FunctionSpaceType::HessianRangeType HessianRangeType; BindableGridFunctionDune::Fem::BindableGridFunction29 BindableGridFunction(const GridPart &gridPart) 30 : gridPart_(gridPart) {} 31 bindDune::Fem::BindableGridFunction32 void bind(const EntityType &entity) 33 { 34 unbind(); 35 36 entity_.emplace( entity ); 37 geometry_.emplace( this->entity().geometry() ); 38 } 39 unbindDune::Fem::BindableGridFunction40 void unbind() 41 { 42 geometry_.reset(); 43 entity_.reset(); 44 } 45 bindDune::Fem::BindableGridFunction46 void bind(const IntersectionType &intersection, IntersectionSide side) 47 { 48 bind( side==IntersectionSide::in? 49 intersection.inside(): intersection.outside() ); 50 } 51 continuousDune::Fem::BindableGridFunction52 bool continuous() const { return true; } 53 template <class Point> globalDune::Fem::BindableGridFunction54 DomainType global(const Point &x) const 55 { 56 return geometry_.value().global( Dune::Fem::coordinate(x) ); 57 } 58 59 // this method needs to be overloaded in the derived class 60 template <class Point> 61 void evaluate( const Point& x, RangeType& ret ) const; 62 63 template <class Quadrature, class RangeArray> evaluateDune::Fem::BindableGridFunction64 void evaluate( const Quadrature& quadrature, RangeArray& values ) const 65 { 66 const unsigned int nop = quadrature.nop(); 67 values.resize( nop ); 68 for( unsigned int qp=0; qp<nop; ++qp) 69 { 70 evaluate( quadrature[ qp ], values[ qp ]); 71 } 72 } 73 gridPartDune::Fem::BindableGridFunction74 const GridPart& gridPart() const { return gridPart_; } entityDune::Fem::BindableGridFunction75 const EntityType &entity() const { return entity_.value(); } geometryDune::Fem::BindableGridFunction76 const Geometry& geometry() const { return geometry_.value(); } 77 78 protected: 79 std::optional< EntityType > entity_; 80 std::optional< Geometry > geometry_; 81 const GridPart &gridPart_; 82 }; 83 84 template <class GridPart, class Range> 85 struct BindableGridFunctionWithSpace : public BindableGridFunction<GridPart,Range> 86 { 87 typedef BindableGridFunction<GridPart,Range> Base; 88 typedef GridPart GridPartType; 89 typedef typename GridPart::template Codim<0>::EntityType EntityType; 90 typedef typename EntityType::Geometry::GlobalCoordinate DomainType; 91 typedef Dune::Fem::GridFunctionSpace<GridPartType, Range> FunctionSpaceType; 92 typedef typename FunctionSpaceType::RangeFieldType RangeFieldType; 93 typedef typename FunctionSpaceType::RangeType RangeType; 94 typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType; 95 typedef typename FunctionSpaceType::HessianRangeType HessianRangeType; 96 typedef DiscreteFunctionSpaceAdapter< FunctionSpaceType, GridPartType > DiscreteFunctionSpaceType; BindableGridFunctionWithSpaceDune::Fem::BindableGridFunctionWithSpace97 BindableGridFunctionWithSpace(const GridPart &gridPart, const std::string &name, int order) 98 : Base(gridPart), 99 space_( gridPart, order ), 100 name_(name) 101 {} 102 //! return the order of the space orderDune::Fem::BindableGridFunctionWithSpace103 unsigned int order() const 104 { 105 return space().order(); 106 } nameDune::Fem::BindableGridFunctionWithSpace107 const std::string &name() const 108 { 109 return name_; 110 } spaceDune::Fem::BindableGridFunctionWithSpace111 const DiscreteFunctionSpaceType &space () const 112 { 113 return space_; 114 } 115 private: 116 DiscreteFunctionSpaceType space_; 117 const std::string name_; 118 }; 119 120 namespace detail 121 { 122 template <class,class,class> 123 struct canBind 124 : std::false_type {}; 125 template <class GP,class LF> 126 struct canBind<GP,LF, 127 std::void_t< decltype( std::declval<LF>(). 128 bind(std::declval<const typename GP::template Codim<0>::EntityType&>())) >> 129 : std::true_type {}; 130 template <class GP,class LF> 131 using canBind_t = canBind<GP,LF,void>; 132 } 133 134 template <class GP,class LF> checkGridPartValid()135 constexpr detail::canBind_t<GP,LF> checkGridPartValid() { return {}; } 136 137 } // namespace Fem 138 } // namespace Dune 139 #endif // DUNE_FEM_FUNCTION_LOCALFUNCTION_BINDABLE_HH 140