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>
28template <
class Gr
idPart,
class Intersection,
class Entity>
29const typename GridPart::IntersectionType
convert(
34 for (
auto is : intersections(
gridPart, inside))
36 if (is.outside() == outside)
return is;
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(
62template <
class DomainSpace,
class 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,
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 Sch,
class ISch,
class Sol,
class ISol>
139 using AType =
typename Scheme::JacobianOperatorType;
144 using DType =
typename IScheme::JacobianOperatorType;
162 callback_(callback) {}
177 scheme_.jacobian(uh, A_);
178 ischeme_.jacobian(th, D_);
181 assembleB(scheme_, th, uh);
184 assembleC(ischeme_, uh, th);
193 auto setBlock = [
this](
const auto& block,
std::size_t row0,
195 auto crs = block.exportMatrix().exportCRS();
196 const auto& val = std::get<0>(crs);
197 const auto&
col = std::get<1>(crs);
198 const auto& row = std::get<2>(crs);
202 this->M_[row0 + i][col0 +
col[j]] = val[j];
210 for (
std::size_t i = 0; i < n; ++i) b_[i] = f.leakPointer()[i];
211 for (
std::size_t i = 0; i < m; ++i) b_[i + n] = g.leakPointer()[i];
215 solver.
apply(x_, b_, res);
218 for (
std::size_t i = 0; i < u.size(); ++i) u.leakPointer()[i] = x_[i];
219 for (
std::size_t i = 0; i < t.size(); ++i) t.leakPointer()[i] = x_[i + n];
231 A_.exportMatrix().maxNzPerRow() + B_.
exportMatrix().maxNzPerRow(),
232 C_.
exportMatrix().maxNzPerRow() + D_.exportMatrix().maxNzPerRow());
237 auto addBlock = [
this](
const auto& block,
std::size_t row0,
239 auto crs = block.exportMatrix().exportCRS();
240 const auto& val = std::get<0>(crs);
241 const auto&
col = std::get<1>(crs);
242 const auto& row = std::get<2>(crs);
246 this->M_.
entry(row0 + i, col0 + col[j]) = val[j];
257 template <
class Scheme,
class DomainGr
idFunction,
class RangeGr
idFunction>
258 void assembleB(
const Scheme&
scheme,
const DomainGridFunction& t,
259 const RangeGridFunction& u) {
264 TemporaryLocalMatrixType;
265 typedef typename RangeGridFunction::DiscreteFunctionSpaceType
266 DiscreteFunctionSpaceType;
268 const auto&
gridPart = t.gridPart();
270 const auto& mmesh = grid.getMMesh();
295 for (
const auto& interface :
296 elements(
gridPart, Partitions::interiorBorder)) {
297 tLocal.bind(interface);
298 auto& tDof = tLocal.localDofVector();
300 const auto mmeshIntersection = mmesh.asIntersection(interface);
301 const auto inside = u.gridPart().convert(mmeshIntersection.inside());
302 const auto intersection =
303 convert(u.gridPart(), mmeshIntersection, inside);
305 const auto& outside = intersection.outside();
307 FmTmpIn.bind(inside);
308 FmTmpOut.bind(outside);
309 FpTmpIn.bind(inside);
310 FpTmpOut.bind(outside);
312 uInside.bind(inside);
313 uOutside.bind(outside);
315 dFLocalIn.bind(inside);
316 dFLocalOut.bind(outside);
318 localMatrixIn.init(interface, inside);
319 localMatrixOut.init(interface, outside);
321 localMatrixIn.clear();
322 localMatrixOut.clear();
333 double h =
std::max(tDof[i] * eps_, eps_);
336 scheme.fullOperator().impl().addSkeletonIntegral(
337 intersection, uInside, uOutside, FmTmpIn, FmTmpOut);
340 dFIn.addLocalDofs(inside, FmTmpIn.localDofVector());
341 dFOut.addLocalDofs(outside, FmTmpOut.localDofVector());
348 scheme.fullOperator().impl().addSkeletonIntegral(
349 intersection, uInside, uOutside, FpTmpIn, FpTmpOut);
352 dFIn.addLocalDofs(inside, FpTmpIn.localDofVector());
353 dFOut.addLocalDofs(outside, FpTmpOut.localDofVector());
359 localMatrixIn.set(j, i, dFLocalIn[j]);
362 localMatrixOut.set(j, i, dFLocalOut[j]);
371 template <
class Scheme,
class DomainGr
idFunction,
class RangeGr
idFunction>
372 void assembleC(
const Scheme& ischeme,
const DomainGridFunction& u,
373 const RangeGridFunction& t) {
377 typedef Fem::TemporaryLocalMatrix<DomainSpaceType, RangeSpaceType>
378 TemporaryLocalMatrixType;
379 typedef typename RangeGridFunction::DiscreteFunctionSpaceType
380 DiscreteFunctionSpaceType;
382 const auto&
gridPart = u.gridPart();
401 if (
grid.isInterface(intersection)) {
402 const auto&
interface = grid.asInterfaceEntity(intersection);
404 uLocal.bind(element);
405 auto& uDof = uLocal.localDofVector();
407 GmTmp.bind(interface);
408 GpTmp.bind(interface);
409 tInterface.bind(interface);
411 dGLocal.bind(interface);
412 localMatrix.init(element, interface);
421 double h =
std::max(uDof[i] * eps_, eps_);
424 ischeme.fullOperator().impl().addInteriorIntegral(tInterface,
428 dG.addLocalDofs(interface, GmTmp.localDofVector());
433 ischeme.fullOperator().impl().addInteriorIntegral(tInterface,
437 dG.addLocalDofs(interface, GpTmp.localDofVector());
441 localMatrix.set(j, i, dGLocal[j]);
463template <
class Jacobian,
class...
options>
465 pybind11::handle scope, pybind11::class_<Jacobian, options...> cls) {
472 Initialize the mixed-dimensional jacobian.
477 [](
Jacobian& self,
const Solution& uh,
const ISolution& th) {
481 Update the mixed-dimensional jacobian.
486 [](
Jacobian& self,
const Solution& f,
const ISolution& g, Solution& ux,
487 ISolution& tx) { self.
solve(f, g, ux, tx); },
489 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
void apply(domain_type &x, range_type &b, InverseOperatorResult &res) override
#define DUNE_THROW(E,...)
const Grid & grid() const
IteratorRange<... > intersections(const GV &gv, const Entity &e)
IteratorRange<... > elements(const GV &gv)
constexpr InteriorBorder interiorBorder
const GridPartType & gridPart() const
const DiscreteFunctionSpaceType & space() const
const EntityType & entity() const
typename Impl::ConstLocalFunction< GridFunction >::Type ConstLocalFunction
BuildStage buildStage() const
B & entry(size_type row, size_type col)
void setImplicitBuildModeParameters(size_type _avg, double compressionBufferSize)
CompressionStatistics compress()
void setBuildMode(BuildMode bm)
void setSize(size_type rows, size_type columns, size_type nnz=0)
void resize(size_type size)
void fill(const DomainEntityType &dEntity, const RangeEntityType &rEntity, bool fillGhost=true) const
MatrixType & exportMatrix() 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
The MMesh class templatized by the CGAL host grid type and the dimension. .
Definition grid/mmesh.hh:158
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.hh:71
Fem::Stencil< DomainSpace, RangeSpace > BaseType
Definition jacobian.hh:65
DomainSpace::GridPartType DomainGridPart
Definition jacobian.hh:67
void setupStencil() const
Definition jacobian.hh:76
RangeSpace::GridPartType RangeGridPart
Definition jacobian.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.hh:104
DomainSpace::GridPartType DomainGridPart
Definition jacobian.hh:103
Fem::Stencil< DomainSpace, RangeSpace > BaseType
Definition jacobian.hh:101
InterfaceNeighborStencil(const DomainSpace &dSpace, const RangeSpace &rSpace)
Definition jacobian.hh:107
void setupStencil() const
Definition jacobian.hh:112
Definition jacobian.hh:130
void solve(const Solution &f, const ISolution &g, Solution &u, ISolution &t)
Definition jacobian.hh:187
void update(const Solution &uh, const ISolution &th)
Definition jacobian.hh:176
ISch IScheme
Definition jacobian.hh:133
DType::DomainSpaceType InterfaceSpaceType
Definition jacobian.hh:150
typename Scheme::JacobianOperatorType AType
Definition jacobian.hh:139
Sol Solution
Definition jacobian.hh:134
Dune::Fem::SparseRowLinearOperator< ISolution, Solution, SparseMatrix > BType
Definition jacobian.hh:141
Dune::BlockVector< double > UMFPackVector
Definition jacobian.hh:147
Jacobian(const Scheme &scheme, const IScheme &ischeme, const Solution &uh, const ISolution &th, const double eps, const std::function< void()> &callback)
Definition jacobian.hh:152
typename IScheme::JacobianOperatorType DType
Definition jacobian.hh:144
Dune::BCRSMatrix< double > UMFPackMatrix
Definition jacobian.hh:146
ISol ISolution
Definition jacobian.hh:135
void init()
Definition jacobian.hh:164
const Scheme & scheme() const
Definition jacobian_iterative.hh:260
AType::DomainSpaceType BulkSpaceType
Definition jacobian.hh:149
Sch Scheme
Definition jacobian.hh:132
Dune::Fem::SparseRowLinearOperator< Solution, ISolution, SparseMatrix > CType
Definition jacobian.hh:143