3#ifndef DUNE_PYTHON_MMESH_JACOBIAN_HH
4#define DUNE_PYTHON_MMESH_JACOBIAN_HH
6#include <dune/python/pybind11/functional.h>
7#include <dune/python/pybind11/numpy.h>
8#include <dune/python/pybind11/pybind11.h>
9#include <dune/python/pybind11/stl.h>
29template <
class Gr
idPart,
class Intersection,
class Entity>
30const typename GridPart::IntersectionType
convert(
31 const GridPart&
gridPart,
const Intersection& intersection,
36 if (is.outside() == outside) return is;
37 DUNE_THROW(InvalidStateException,
"Intersection not found!");
41template <
class Gr
idPart,
class Intersection,
class Entity>
43 std::is_convertible_v<Intersection, typename GridPart::IntersectionType>,
44 const typename GridPart::IntersectionType>
51template <
class Gr
idPart,
class Intersection,
class Entity>
52const typename GridPart::IntersectionType
convert(
53 const GridPart&
gridPart,
const Intersection& intersection,
62template <
class DomainSpace,
class RangeSpace,
64struct NeighborInterfaceStencil :
public Fem::Stencil<DomainSpace, RangeSpace> {
77 const auto& mmesh = domainGridPart_.grid().getMMesh();
78 for (
const auto&
entity : elements(domainGridPart_, Partition{})) {
79 const auto mmeshIntersection = mmesh.asIntersection(
entity);
80 const auto inside = rangeGridPart_.convert(mmeshIntersection.inside());
81 const auto intersection =
82 convert(rangeGridPart_, mmeshIntersection, inside);
98template <
class DomainSpace,
class RangeSpace,
100struct InterfaceNeighborStencil :
public Fem::Stencil<DomainSpace, RangeSpace> {
110 rangeGridPart_(rSpace.
gridPart()) {}
113 for (
const auto&
entity : elements(domainGridPart_, Partition{})) {
114 for (
const auto& intersection : intersections(domainGridPart_,
entity)) {
115 if (intersection.neighbor() &&
116 domainGridPart_.grid().isInterface(intersection)) {
117 auto ientity = domainGridPart_.grid().asInterfaceEntity(intersection);
129template <
class X,
class BulkDF,
class InterfaceDF>
137 : u(uh), v(uh), t(th), s(th) {}
140 u.blockVector() = x[_0];
141 t.blockVector() = x[_1];
142 v.blockVector() = y[_0];
143 s.blockVector() = y[_1];
144 return u.scalarProductDofs(v) + t.scalarProductDofs(s);
148 u.blockVector() = x[_0];
149 t.blockVector() = x[_1];
150 return std::sqrt(u.scalarProductDofs(u) +
151 t.scalarProductDofs(t));
156 mutable InterfaceDF t, s;
159template <
class M,
class X,
class Y,
class BulkDF,
class InterfaceDF>
170 const InterfaceDF& th)
174 void apply(
const X& x, Y& y)
const override {
181 _A_->usmv(
alpha, x, y);
186 const M&
getmat()
const override {
return *_A_; }
194 void communicate(Y& y)
const {
195 u.blockVector() = y[_0];
196 t.blockVector() = y[_1];
199 y[_0] = u.blockVector();
200 y[_1] = t.blockVector();
205 mutable InterfaceDF t;
208template <
class Sch,
class ISch,
class Sol,
class ISol>
210 using ThisType = Jacobian<Sch, ISch, Sol, ISol>;
218 using AType =
typename Scheme::JacobianOperatorType;
219 using BType = Dune::Fem::ISTLLinearOperator<ISolution, Solution>;
220 using CType = Dune::Fem::ISTLLinearOperator<Solution, ISolution>;
221 using DType =
typename IScheme::JacobianOperatorType;
241 typename IScheme::LinearInverseOperatorType::SolverParameterType>;
256 x_[_0] = uh.blockVector();
257 x_[_1] = th.blockVector();
264 if (n_ == 0 || m_ == 0)
return;
268 stencilB.setupStencil();
273 stencilC.setupStencil();
278 scheme_.jacobian(uh, A_);
279 ischeme_.jacobian(th, D_);
281 if (n_ > 0 && m_ > 0) {
284 assembleB(scheme_, th, uh);
285 assembleC(ischeme_, uh, th);
290 auto setBlock = [
this](
const auto& block,
const auto blockrow,
291 const auto blockcol) {
292 this->M_[blockrow][blockcol] = block.exportMatrix();
295 if (n_ > 0) setBlock(A_, _0, _0);
296 if (n_ > 0 && m_ > 0) {
297 setBlock(B_, _0, _1);
298 setBlock(C_, _1, _0);
300 if (m_ > 0) setBlock(D_, _1, _1);
302 b_[_0] = f.blockVector();
303 b_[_1] = g.blockVector();
305 auto params = std::make_shared<Fem::ISTLSolverParameter>(
307 const size_t numIterations = params->preconditionerIteration();
308 const double relaxFactor = params->relaxation();
310 using SolverAdapterType = Fem::ISTLSolverAdapter<-1,
BlockVector>;
311 using ReductionType =
typename SolverAdapterType::ReductionType;
312 SolverAdapterType solver(ReductionType(params), params);
313 solver.setMaxIterations(params->maxIterations());
322 solver(linop, scp, prec, b_, x_, res);
324 u.blockVector() = x_[_0];
325 t.blockVector() = x_[_1];
331 template <
class Scheme,
class DomainGr
idFunction,
class RangeGr
idFunction>
332 void assembleB(
const Scheme&
scheme,
const DomainGridFunction& t,
333 const RangeGridFunction& u) {
338 TemporaryLocalMatrixType;
339 typedef typename RangeGridFunction::DiscreteFunctionSpaceType
340 DiscreteFunctionSpaceType;
342 const auto&
gridPart = t.gridPart();
344 const auto& mmesh = grid.getMMesh();
369 for (
const auto& interface : elements(
gridPart, Partitions::all)) {
370 tLocal.bind(interface);
371 auto& tDof = tLocal.localDofVector();
373 const auto mmeshIntersection = mmesh.asIntersection(interface);
374 const auto inside = u.gridPart().convert(mmeshIntersection.inside());
375 const auto intersection =
376 convert(u.gridPart(), mmeshIntersection, inside);
378 const auto& outside = intersection.outside();
380 FmTmpIn.bind(inside);
381 FmTmpOut.bind(outside);
382 FpTmpIn.bind(inside);
383 FpTmpOut.bind(outside);
385 uInside.bind(inside);
386 uOutside.bind(outside);
388 dFLocalIn.bind(inside);
389 dFLocalOut.bind(outside);
391 localMatrixIn.init(interface, inside);
392 localMatrixOut.init(interface, outside);
394 localMatrixIn.clear();
395 localMatrixOut.clear();
406 double h =
std::max(tDof[i] * eps_, eps_);
409 scheme.fullOperator().impl().addSkeletonIntegral(
410 intersection, uInside, uOutside, FmTmpIn, FmTmpOut);
413 dFIn.addLocalDofs(inside, FmTmpIn.localDofVector());
414 dFOut.addLocalDofs(outside, FmTmpOut.localDofVector());
421 scheme.fullOperator().impl().addSkeletonIntegral(
422 intersection, uInside, uOutside, FpTmpIn, FpTmpOut);
425 dFIn.addLocalDofs(inside, FpTmpIn.localDofVector());
426 dFOut.addLocalDofs(outside, FpTmpOut.localDofVector());
432 localMatrixIn.set(j, i, dFLocalIn[j]);
435 localMatrixOut.set(j, i, dFLocalOut[j]);
444 template <
class Scheme,
class DomainGr
idFunction,
class RangeGr
idFunction>
445 void assembleC(
const Scheme& ischeme,
const DomainGridFunction& u,
446 const RangeGridFunction& t) {
450 typedef Fem::TemporaryLocalMatrix<DomainSpaceType, RangeSpaceType>
451 TemporaryLocalMatrixType;
452 typedef typename RangeGridFunction::DiscreteFunctionSpaceType
453 DiscreteFunctionSpaceType;
455 const auto&
gridPart = u.gridPart();
472 for (
const auto& element : elements(
gridPart, Partitions::all)) {
473 for (
const auto& intersection : intersections(
gridPart, element)) {
474 if (grid.isInterface(intersection)) {
475 const auto&
interface = grid.asInterfaceEntity(intersection);
477 uLocal.bind(element);
478 auto& uDof = uLocal.localDofVector();
480 GmTmp.bind(interface);
481 GpTmp.bind(interface);
482 tInterface.bind(interface);
484 dGLocal.bind(interface);
485 localMatrix.init(element, interface);
494 double h =
std::max(uDof[i] * eps_, eps_);
497 ischeme.fullOperator().impl().addInteriorIntegral(tInterface,
501 dG.addLocalDofs(interface, GmTmp.localDofVector());
506 ischeme.fullOperator().impl().addInteriorIntegral(tInterface,
510 dG.addLocalDofs(interface, GpTmp.localDofVector());
514 localMatrix.set(j, i, dGLocal[j]);
537template <
class Jacobian,
class...
options>
539 pybind11::handle scope, pybind11::class_<Jacobian, options...> cls) {
544 "init", [](
Jacobian& self) { self.init(); },
546 Initialize the mixed-dimensional jacobian.
551 [](
Jacobian& self,
const Solution& uh,
const ISolution& th) {
555 Update the mixed-dimensional jacobian.
560 [](
Jacobian& self,
const Solution& f,
const ISolution& g, Solution& ux,
561 ISolution& tx) { self.solve(f, g, ux, tx); },
563 Solve the mixed-dimensional jacobian.
Dune::ParameterTree options
static auto registerJacobian(pybind11::handle scope, pybind11::class_< Jacobian, options... > cls)
Definition jacobian.hh:464
const GridPart::IntersectionType convert(const GridPart &gridPart, const Intersection &intersection, const Entity &inside, Dune::PriorityTag< 0 >)
Convert intersection if gridPart is wrapped, e.g. geometryGridPart.
Definition jacobian.hh:29
static constexpr size_type M()
#define DUNE_THROW(E,...)
std::shared_ptr< T > stackobject_to_shared_ptr(T &t)
constexpr index_constant< 0 > _0
constexpr index_constant< 1 > _1
IteratorRange<... > intersections(const GV &gv, const Entity &e)
const GridPartType & gridPart() const
const DiscreteFunctionSpaceType & space() const
const EntityType & entity() const
typename Impl::ConstLocalFunction< GridFunction >::Type ConstLocalFunction
GridImp::template Codim< cd >::Entity Entity
void fill(const DomainEntityType &dEntity, const RangeEntityType &rEntity, bool fillGhost=true) const
const DomainSpaceType & domainSpace() const
void reserve(const std::vector< Set > &sparsityPattern)
void addLocalMatrix(const DomainEntityType &domainEntity, const RangeEntityType &rangeEntity, const LocalMatrix &localMat)
const RangeSpaceType & rangeSpace() const
Stencil contaning the entries (ien,en) for all interface entities ien and adjacent bulk entities en.
Definition jacobian.hh:64
NeighborInterfaceStencil(const DomainSpace &dSpace, const RangeSpace &rSpace)
Definition jacobian_iterative.hh:71
Fem::Stencil< DomainSpace, RangeSpace > BaseType
Definition jacobian_iterative.hh:65
DomainSpace::GridPartType DomainGridPart
Definition jacobian_iterative.hh:67
void setupStencil() const
Definition jacobian_iterative.hh:76
RangeSpace::GridPartType RangeGridPart
Definition jacobian_iterative.hh:68
Stencil contaning the entries (en,ien) for all entities en in the bulk and interface edges ien.
Definition jacobian.hh:100
RangeSpace::GridPartType RangeGridPart
Definition jacobian_iterative.hh:104
DomainSpace::GridPartType DomainGridPart
Definition jacobian_iterative.hh:103
Fem::Stencil< DomainSpace, RangeSpace > BaseType
Definition jacobian_iterative.hh:101
InterfaceNeighborStencil(const DomainSpace &dSpace, const RangeSpace &rSpace)
Definition jacobian_iterative.hh:107
void setupStencil() const
Definition jacobian_iterative.hh:112
Definition jacobian.hh:130
void solve(const Solution &f, const ISolution &g, Solution &u, ISolution &t)
Definition jacobian_iterative.hh:289
void update(const Solution &uh, const ISolution &th)
Definition jacobian_iterative.hh:277
typename AType::ColumnBlockVectorType AVectorBlock
Definition jacobian_iterative.hh:234
ISch IScheme
Definition jacobian.hh:133
DType::DomainSpaceType InterfaceSpaceType
Definition jacobian_iterative.hh:239
Dune::MultiTypeBlockMatrix< ABRowType, CDRowType > BlockMatrix
Definition jacobian_iterative.hh:231
typename Scheme::JacobianOperatorType AType
Definition jacobian.hh:139
typename DType::ColumnBlockVectorType DVectorBlock
Definition jacobian_iterative.hh:235
Sol Solution
Definition jacobian.hh:134
const BlockMatrix & M() const
Definition jacobian_iterative.hh:261
Dune::Fem::SparseRowLinearOperator< ISolution, Solution, SparseMatrix > BType
Definition jacobian.hh:141
Jacobian(const Scheme &scheme, const IScheme &ischeme, const Solution &uh, const ISolution &th, const double eps, const std::function< void()> &callback)
Definition jacobian_iterative.hh:243
typename IScheme::JacobianOperatorType DType
Definition jacobian.hh:144
ISol ISolution
Definition jacobian.hh:135
void init()
Definition jacobian_iterative.hh:263
const Scheme & scheme() const
Definition jacobian_iterative.hh:260
AType::DomainSpaceType BulkSpaceType
Definition jacobian_iterative.hh:238
Fem::NewtonParameter< typename IScheme::LinearInverseOperatorType::SolverParameterType > ParameterType
Definition jacobian_iterative.hh:241
Sch Scheme
Definition jacobian.hh:132
Dune::Fem::SparseRowLinearOperator< Solution, ISolution, SparseMatrix > CType
Definition jacobian.hh:143
Dune::MultiTypeBlockVector< AVectorBlock, DVectorBlock > BlockVector
Definition jacobian_iterative.hh:236
Definition jacobian_iterative.hh:130
X::field_type field_type
Definition jacobian_iterative.hh:133
virtual field_type dot(const X &x, const X &y) const
Definition jacobian_iterative.hh:139
ParallelizedScalarProduct(const BulkDF &uh, const InterfaceDF &th)
Definition jacobian_iterative.hh:136
X domain_type
Definition jacobian_iterative.hh:132
FieldTraits< field_type >::real_type real_type
Definition jacobian_iterative.hh:134
virtual real_type norm(const X &x) const
Definition jacobian_iterative.hh:147
Definition jacobian_iterative.hh:160
M matrix_type
export types
Definition jacobian_iterative.hh:163
void apply(const X &x, Y &y) const override
apply operator to x:
Definition jacobian_iterative.hh:174
Y range_type
Definition jacobian_iterative.hh:165
X::field_type field_type
Definition jacobian_iterative.hh:166
SolverCategory::Category category() const override
Category of the solver (see SolverCategory::Category)
Definition jacobian_iterative.hh:189
X domain_type
Definition jacobian_iterative.hh:164
const M & getmat() const override
get matrix via *
Definition jacobian_iterative.hh:186
void applyscaleadd(field_type alpha, const X &x, Y &y) const override
apply operator to x, scale and add:
Definition jacobian_iterative.hh:180
ParallelizedMatrixAdapter(const M &A, const BulkDF &uh, const InterfaceDF &th)
constructor: just store a reference to a matrix
Definition jacobian_iterative.hh:169