4#include <dune/common/dynvector.hh>
5#include <dune/fem/common/bindguard.hh>
6#include <dune/fem/function/common/localcontribution.hh>
7#include <dune/fem/function/localfunction/const.hh>
8#include <dune/fem/operator/common/differentiableoperator.hh>
9#include <dune/fem/operator/common/localcontribution.hh>
10#include <dune/fem/operator/common/operator.hh>
11#include <dune/fem/operator/common/stencil.hh>
12#include <dune/fem/quadrature/cachingquadrature.hh>
13#include <dune/grid/common/rangegenerators.hh>
15template <
class DiscreteFunction,
class LinearOperator>
16class MassOperator :
public LinearOperator {
17 typedef MassOperator<DiscreteFunction, LinearOperator> ThisType;
18 typedef LinearOperator BaseType;
20 typedef DiscreteFunction DiscreteFunctionType;
21 typedef typename DiscreteFunctionType::DiscreteFunctionSpaceType
22 DiscreteFunctionSpaceType;
24 typedef typename DiscreteFunctionSpaceType::DomainType DomainType;
25 typedef typename DiscreteFunctionSpaceType::RangeType RangeType;
27 typedef Dune::Fem::CachingQuadrature<
28 typename DiscreteFunctionSpaceType::GridPartType, 0>
32 explicit MassOperator(
const DiscreteFunctionSpaceType &dfSpace)
33 : BaseType(
"mass operator", dfSpace, dfSpace), dfSpace_(dfSpace) {
37 template <
class Function>
38 void assembleRHS(
const Function &u, DiscreteFunctionType &w)
const;
39 void assemble(LinearOperator &matrix)
const;
42 const DiscreteFunctionSpaceType &dfSpace_;
45template <
class DiscreteFunction,
class LinearOperator>
46class AffineMassOperator
47 :
public Dune::Fem::DifferentiableOperator<LinearOperator> {
49 typedef DiscreteFunction DiscreteFunctionType;
50 typedef typename DiscreteFunctionType::DiscreteFunctionSpaceType
51 DiscreteFunctionSpaceType;
52 typedef LinearOperator JacobianOperatorType;
53 template <
class Function>
54 explicit AffineMassOperator(
const DiscreteFunctionSpaceType &dfSpace,
56 : matrix_(dfSpace), rhs_(
"rhs", dfSpace) {
57 matrix_.assembleRHS(u, rhs_);
59 const DiscreteFunctionType rhs()
const {
return rhs_; }
60 virtual void operator()(
const DiscreteFunctionType &u,
61 DiscreteFunctionType &w)
const {
65 virtual void jacobian(
const DiscreteFunctionType &u,
66 JacobianOperatorType &jOp)
const {
67 matrix_.assemble(jOp);
71 MassOperator<DiscreteFunction, LinearOperator> matrix_;
72 DiscreteFunction rhs_;
75template <
class DiscreteFunction,
class LinearOperator>
76template <
class Function>
77void MassOperator<DiscreteFunction, LinearOperator>::assembleRHS(
78 const Function &u, DiscreteFunctionType &w)
const {
82 Dune::Fem::ConstLocalFunction<Function> uLocal(u);
83 Dune::Fem::AddLocalContribution<DiscreteFunctionType> wLocal(w);
86 for (
const auto &entity :
87 elements(dfSpace_.gridPart(), Dune::Partitions::interiorBorder)) {
88 const auto geometry = entity.geometry();
90 auto guard = bindGuard(std::tie(uLocal, wLocal), entity);
94 QuadratureType(entity, uLocal.order() + wLocal.order())) {
96 RangeType uValue = uLocal.evaluate(qp);
99 uValue *= qp.weight() * geometry.integrationElement(qp.position());
102 wLocal.axpy(qp, uValue);
107template <
class DiscreteFunction,
class LinearOperator>
108void MassOperator<DiscreteFunction, LinearOperator>::assemble(
109 LinearOperator &matrix)
const {
110 matrix.reserve(Dune::Fem::DiagonalStencil<DiscreteFunctionSpaceType,
111 DiscreteFunctionSpaceType>(
112 dfSpace_, dfSpace_));
115 Dune::Fem::AddLocalContribution<LinearOperator> localMatrix(matrix);
116 Dune::DynamicVector<typename DiscreteFunctionSpaceType::RangeType> values;
119 for (
const auto &entity :
120 elements(dfSpace_.gridPart(), Dune::Partitions::interiorBorder)) {
121 const auto geometry = entity.geometry();
123 auto guard = bindGuard(localMatrix, entity, entity);
125 const auto &basis = localMatrix.domainBasisFunctionSet();
126 const unsigned int numBasisFunctions = basis.size();
127 values.resize(numBasisFunctions);
130 for (
const auto qp : QuadratureType(entity, localMatrix.order())) {
132 basis.evaluateAll(qp, values);
136 qp.weight() * geometry.integrationElement(qp.position());
137 std::for_each(values.begin(), values.end(),
138 [weight](
auto &a) { a *= weight; });
141 localMatrix.axpy(qp, values);