dune-mmesh 1.4.1-git
Loading...
Searching...
No Matches
pyskeletontrace.hh
Go to the documentation of this file.
1#ifndef DUNE_MMESH_PYSKELETONTRACE
2#define DUNE_MMESH_PYSKELETONTRACE
3
4#if HAVE_DUNE_FEM
5
10#include <dune/fempy/py/grid/function.hh>
11#include <dune/fempy/py/grid/gridpart.hh>
12#include <dune/python/common/typeregistry.hh>
13
14namespace Dune {
15
16namespace Fem {
17
19// Skeleton function //
21
22template <class BulkGV, class InterfaceGridFunction>
23struct SkeletonGF
24 : public BindableGridFunctionWithSpace<
25 FemPy::GridPart<BulkGV>, typename InterfaceGridFunction::RangeType> {
26 using GridView = BulkGV;
27 using GridPart = FemPy::GridPart<BulkGV>;
28 using Base =
29 BindableGridFunctionWithSpace<GridPart,
30 typename InterfaceGridFunction::RangeType>;
31 using ILocalFunction = ConstLocalFunction<InterfaceGridFunction>;
32 using SideGeometry =
33 typename GridPart::GridType::Intersection::LocalGeometry::Implementation;
34 static constexpr bool scalar =
35 (InterfaceGridFunction::RangeType::dimension == 1);
36
37 SkeletonGF(const BulkGV &bulkGV, const InterfaceGridFunction &igf)
38 : Base(FemPy::gridPart<BulkGV>(bulkGV), "skeleton_" + igf.name(),
39 igf.order()),
40 ilf_(igf),
41 onInterface_(false) {}
42
43 void bind(const typename Base::EntityType &entity) { Base::bind(entity); }
44
45 void bind(const typename BulkGV::Intersection &intersection,
46 IntersectionSide side) {
47 if (Base::gridPart().grid().isInterface(intersection)) {
48 onInterface_ = true;
49 ilf_.bind(Base::gridPart().grid().asInterfaceEntity(intersection));
50 sideGeometry_ = (side == IntersectionSide::in)
51 ? intersection.geometryInInside().impl()
52 : intersection.geometryInOutside().impl();
53 } else
54 onInterface_ = false;
55 }
56
57 public:
58 template <class Point>
59 void evaluate(const Point &x, typename Base::RangeType &ret) const {
60 if (onInterface_) {
61 auto xLocal = Dune::Fem::coordinate(x);
62 auto ix = sideGeometry_.local(xLocal);
63 ilf_.evaluate(ix, ret);
64 } else
65 ret = typename Base::RangeType(0);
66 }
67
68 template <class Point>
69 void jacobian(const Point &x, typename Base::JacobianRangeType &ret) const {
70 if (onInterface_) {
71 auto xLocal = Dune::Fem::coordinate(x);
72 auto ix = sideGeometry_.local(xLocal);
73 ilf_.jacobian(ix, ret);
74 } else
75 ret = typename Base::JacobianRangeType(0);
76 }
77
78 template <class Point>
79 void hessian(const Point &x, typename Base::HessianRangeType &ret) const {
80 if (onInterface_) {
81 auto xLocal = Dune::Fem::coordinate(x);
82 auto ix = sideGeometry_.local(xLocal);
83 ilf_.hessian(ix, ret);
84 } else
85 ret = typename Base::HessianRangeType(0);
86 }
87
88 private:
89 ILocalFunction ilf_;
90 bool onInterface_;
91 SideGeometry sideGeometry_;
92};
93
94template <class BulkGV, class InterfaceGridFunction>
95inline static void registerSkeletonGF(
96 pybind11::module module,
97 pybind11::class_<SkeletonGF<BulkGV, InterfaceGridFunction> > cls) {
98 using pybind11::operator""_a;
99
100 cls.def(pybind11::init(
101 [](const BulkGV &bulkGV, const InterfaceGridFunction &bgf) {
102 return SkeletonGF<BulkGV, InterfaceGridFunction>(bulkGV, bgf);
103 }),
104 "bulkGV"_a, "igf"_a, pybind11::keep_alive<1, 2>(),
105 pybind11::keep_alive<1, 3>());
106
107 cls.def_property_readonly(
108 "scalar", [](SkeletonGF<BulkGV, InterfaceGridFunction> &self) {
109 return self.scalar;
110 });
111
112 Dune::FemPy::registerGridFunction(module, cls);
113}
114
116// Trace function //
118
119template <class IGV, class BulkGridFunction, Dune::Fem::IntersectionSide side>
120struct TraceGF
122 Dune::FemPy::GridPart<IGV>, typename BulkGridFunction::RangeType> {
123 using GridView = IGV;
124 using GridPart = Dune::FemPy::GridPart<IGV>;
126 GridPart, typename BulkGridFunction::RangeType>;
128 using BulkGridPart = typename BulkGridFunction::GridPartType;
129 using SideGeometry = typename GridPart::GridType::MMeshType::Intersection::
130 LocalGeometry::Implementation;
131 static constexpr bool scalar = (BulkGridFunction::RangeType::dimension == 1);
132
133 TraceGF(const IGV &iGV, const BulkGridFunction &bgf)
134 : Base(Dune::FemPy::gridPart<IGV>(iGV), "trace_" + bgf.name(),
135 bgf.order()),
136 bulkGridPart_(bgf.gridPart()),
137 blf_(bgf) {}
138
139 void bind(const typename Base::EntityType &entity) {
140 Base::bind(entity);
141 const auto intersection =
142 Base::gridPart().grid().getMMesh().asIntersection(entity);
143
144 if constexpr (side == Dune::Fem::IntersectionSide::in)
145 blf_.bind(bulkGridPart_.convert(intersection.inside()));
146 else if (intersection.neighbor())
147 blf_.bind(bulkGridPart_.convert(intersection.outside()));
148 else // is this the best we can do?
151 "TraceFunction on boundary can no be used with outside entity");
152 sideGeometry_ = (side == IntersectionSide::in)
153 ? intersection.geometryInInside().impl()
154 : intersection.geometryInOutside().impl();
155 }
156
157 template <class Point>
158 void evaluate(const Point &x, typename Base::RangeType &ret) const {
159 // again need to transfer the x (in this case on the interface) to an x in
160 // bulk
161 auto xLocal = Dune::Fem::coordinate(x);
162 auto bx = sideGeometry_.global(xLocal);
163 blf_.evaluate(bx, ret);
164 }
165
166 // need to implement jacobian and hessian as their tangential components
167 template <class Point>
168 void jacobian(const Point &x, typename Base::JacobianRangeType &ret) const {
169 // again need to transfer the x (in this case on the interface) to an x in
170 // bulk
171 auto xLocal = Dune::Fem::coordinate(x);
172 auto bx = sideGeometry_.global(xLocal);
173 typename BulkGridFunction::JacobianRangeType bulkJac;
174 blf_.jacobian(bx, bulkJac);
175 ret = bulkJac; // could decide to remove normal component - but perhaps
176 // don't have to?
177 }
178
179 template <class Point>
180 void hessian(const Point &x, typename Base::HessianRangeType &ret) const {
181 // again need to transfer the x (in this case on the interface) to an x in
182 // bulk
183 auto xLocal = Dune::Fem::coordinate(x);
184 auto bx = sideGeometry_.global(xLocal);
185 typename BulkGridFunction::HessianRangeType bulkHessian;
186 blf_.hessian(bx, bulkHessian);
187 ret = bulkHessian;
188 }
189
190 private:
191 BLocalFunction blf_;
192 const BulkGridPart &bulkGridPart_;
193 SideGeometry sideGeometry_;
194};
195
196template <class IGV, class BulkGridFunction, Dune::Fem::IntersectionSide side>
197inline static void registerTraceGF(
198 pybind11::module module,
199 pybind11::class_<TraceGF<IGV, BulkGridFunction, side> > cls) {
200 using pybind11::operator""_a;
201
202 cls.def(pybind11::init([](const IGV &iGV, const BulkGridFunction &bgf) {
203 return TraceGF<IGV, BulkGridFunction, side>(iGV, bgf);
204 }),
205 "iGV"_a, "bgf"_a, pybind11::keep_alive<1, 2>(),
206 pybind11::keep_alive<1, 3>());
207
208 cls.def_property_readonly(
209 "scalar",
210 [](TraceGF<IGV, BulkGridFunction, side> &self) { return self.scalar; });
211
212 Dune::FemPy::registerGridFunction(module, cls);
213}
214
215} // namespace Fem
216
217} // namespace Dune
218
219#endif // HAVE_DUNE_FEM
220
221#endif // DUNE_MMESH_PYSKELETONTRACE
const char * name()
#define DUNE_THROW(E,...)
const Grid & grid() const
GridView(const Implementation &imp)
const GridPartType & gridPart() const
void evaluate(const DomainType &global, RangeType &result) const
int order() const
AnalyticalJacobianType & jacobian()
const EntityType & entity() const
AnalyticalHessianType & hessian()
typename Impl::ConstLocalFunction< GridFunction >::Type ConstLocalFunction
static const Point & coordinate(const Point &x)
T bind(T... args)