1#ifndef DUNE_MMESH_PYSKELETONTRACE
2#define DUNE_MMESH_PYSKELETONTRACE
6#include <dune/common/exceptions.hh>
7#include <dune/python/common/typeregistry.hh>
8#include <dune/fem/common/intersectionside.hh>
9#include <dune/fem/function/localfunction/const.hh>
10#include <dune/fem/function/localfunction/bindable.hh>
11#include <dune/fempy/py/grid/gridpart.hh>
12#include <dune/fempy/py/grid/function.hh>
24 template <
class BulkGV,
class InterfaceGr
idFunction>
26 :
public BindableGridFunctionWithSpace<FemPy::GridPart<BulkGV>,
27 typename InterfaceGridFunction::RangeType>
29 using GridView = BulkGV;
30 using GridPart = FemPy::GridPart<BulkGV>;
31 using Base = BindableGridFunctionWithSpace<GridPart, typename InterfaceGridFunction::RangeType>;
32 using ILocalFunction = ConstLocalFunction<InterfaceGridFunction>;
33 using SideGeometry =
typename GridPart::GridType::Intersection::LocalGeometry::Implementation;
34 static constexpr bool scalar = (InterfaceGridFunction::RangeType::dimension == 1);
36 SkeletonGF(
const BulkGV &bulkGV,
const InterfaceGridFunction &igf)
37 : Base(FemPy::gridPart<BulkGV>(bulkGV),
"skeleton_"+igf.name(), igf.order()),
38 ilf_(igf), onInterface_(false)
41 void bind(
const typename Base::EntityType &entity)
46 void bind(
const typename BulkGV::Intersection &intersection,
47 IntersectionSide side)
49 if( Base::gridPart().grid().isInterface( intersection ) )
52 ilf_.bind( Base::gridPart().grid().asInterfaceEntity( intersection ) );
53 sideGeometry_ = (side == IntersectionSide::in)
54 ? intersection.geometryInInside().impl() : intersection.geometryInOutside().impl();
56 else onInterface_ =
false;
60 template <
class Po
int>
61 void evaluate(
const Point &x,
typename Base::RangeType &ret)
const
65 auto xLocal = Dune::Fem::coordinate(x);
66 auto ix = sideGeometry_.local( xLocal );
67 ilf_.evaluate(ix,ret);
68 }
else ret =
typename Base::RangeType(0);
71 template <
class Po
int>
72 void jacobian(
const Point &x,
typename Base::JacobianRangeType &ret)
const
76 auto xLocal = Dune::Fem::coordinate(x);
77 auto ix = sideGeometry_.local( xLocal );
78 ilf_.jacobian(ix,ret);
79 }
else ret =
typename Base::JacobianRangeType(0);
82 template <
class Po
int>
83 void hessian(
const Point &x,
typename Base::HessianRangeType &ret)
const
87 auto xLocal = Dune::Fem::coordinate(x);
88 auto ix = sideGeometry_.local( xLocal );
90 }
else ret =
typename Base::HessianRangeType(0);
96 SideGeometry sideGeometry_;
99 template<
class BulkGV,
class InterfaceGr
idFunction >
100 inline static void registerSkeletonGF(pybind11::module module, pybind11::class_< SkeletonGF<BulkGV, InterfaceGridFunction> > cls)
102 using pybind11::operator
""_a;
104 cls.def( pybind11::init( [] (
const BulkGV &bulkGV,
const InterfaceGridFunction &bgf ) {
105 return SkeletonGF<BulkGV, InterfaceGridFunction> ( bulkGV, bgf );
106 } ),
"bulkGV"_a,
"igf"_a, pybind11::keep_alive< 1, 2 >(), pybind11::keep_alive< 1, 3 >() );
108 cls.def_property_readonly(
"scalar", [] ( SkeletonGF<BulkGV, InterfaceGridFunction> &self ) {
return self.scalar; } );
110 Dune::FemPy::registerGridFunction( module, cls );
118 template <
class IGV,
class BulkGr
idFunction, Dune::Fem::IntersectionS
ide s
ide>
120 :
public Dune::Fem::BindableGridFunctionWithSpace<Dune::FemPy::GridPart<IGV>,
121 typename BulkGridFunction::RangeType>
123 using GridView = IGV;
124 using GridPart = Dune::FemPy::GridPart<IGV>;
125 using Base = Dune::Fem::BindableGridFunctionWithSpace<GridPart,typename BulkGridFunction::RangeType>;
126 using BLocalFunction = Dune::Fem::ConstLocalFunction<BulkGridFunction>;
127 using BulkGridPart =
typename BulkGridFunction::GridPartType;
128 using SideGeometry =
typename GridPart::GridType::MMeshType::Intersection::LocalGeometry::Implementation;
129 static constexpr bool scalar = (BulkGridFunction::RangeType::dimension == 1);
131 TraceGF(
const IGV &iGV,
const BulkGridFunction &bgf)
132 : Base(Dune::FemPy::gridPart<IGV>(iGV),
"trace_"+bgf.name(), bgf.order() ),
133 bulkGridPart_(bgf.gridPart()),
137 void bind(
const typename Base::EntityType &entity)
140 const auto intersection = Base::gridPart().grid().getMMesh().asIntersection( entity );
142 if constexpr (side == Dune::Fem::IntersectionSide::in)
143 blf_.bind(bulkGridPart_.convert(intersection.inside()));
144 else if (intersection.neighbor())
145 blf_.bind(bulkGridPart_.convert(intersection.outside()));
147 DUNE_THROW( Dune::NotImplemented,
"TraceFunction on boundary can no be used with outside entity" );
148 sideGeometry_ = (side == IntersectionSide::in)
149 ? intersection.geometryInInside().impl() : intersection.geometryInOutside().impl();
152 template <
class Po
int>
153 void evaluate(
const Point &x,
typename Base::RangeType &ret)
const
156 auto xLocal = Dune::Fem::coordinate(x);
157 auto bx = sideGeometry_.global( xLocal );
158 blf_.evaluate(bx,ret);
162 template <
class Po
int>
163 void jacobian(
const Point &x,
typename Base::JacobianRangeType &ret)
const
166 auto xLocal = Dune::Fem::coordinate(x);
167 auto bx = sideGeometry_.global( xLocal );
168 typename BulkGridFunction::JacobianRangeType bulkJac;
169 blf_.jacobian(bx,bulkJac);
173 template <
class Po
int>
174 void hessian(
const Point &x,
typename Base::HessianRangeType &ret)
const
177 auto xLocal = Dune::Fem::coordinate(x);
178 auto bx = sideGeometry_.global( xLocal );
179 typename BulkGridFunction::HessianRangeType bulkHessian;
180 blf_.hessian(bx,bulkHessian);
186 const BulkGridPart& bulkGridPart_;
187 SideGeometry sideGeometry_;
190 template<
class IGV,
class BulkGr
idFunction, Dune::Fem::IntersectionS
ide s
ide >
191 inline static void registerTraceGF(pybind11::module module, pybind11::class_< TraceGF<IGV, BulkGridFunction, side> > cls)
193 using pybind11::operator
""_a;
195 cls.def( pybind11::init( [] (
const IGV &iGV,
const BulkGridFunction &bgf ) {
196 return TraceGF<IGV, BulkGridFunction, side> ( iGV, bgf );
197 } ),
"iGV"_a,
"bgf"_a, pybind11::keep_alive< 1, 2 >(), pybind11::keep_alive< 1, 3 >() );
199 cls.def_property_readonly(
"scalar", [] ( TraceGF<IGV, BulkGridFunction, side> &self ) {
return self.scalar; } );
201 Dune::FemPy::registerGridFunction( module, cls );