dune-mmesh (unstable)

massoperator.hh
1#ifndef MASSOPERATOR_HH
2#define MASSOPERATOR_HH
3
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>
14
15template <class DiscreteFunction, class LinearOperator>
16class MassOperator : public LinearOperator {
17 typedef MassOperator<DiscreteFunction, LinearOperator> ThisType;
18 typedef LinearOperator BaseType;
19
20 typedef DiscreteFunction DiscreteFunctionType;
21 typedef typename DiscreteFunctionType::DiscreteFunctionSpaceType
22 DiscreteFunctionSpaceType;
23
24 typedef typename DiscreteFunctionSpaceType::DomainType DomainType;
25 typedef typename DiscreteFunctionSpaceType::RangeType RangeType;
26
27 typedef Dune::Fem::CachingQuadrature<
28 typename DiscreteFunctionSpaceType::GridPartType, 0>
29 QuadratureType;
30
31 public:
32 explicit MassOperator(const DiscreteFunctionSpaceType &dfSpace)
33 : BaseType("mass operator", dfSpace, dfSpace), dfSpace_(dfSpace) {
34 assemble(*this);
35 }
36
37 template <class Function>
38 void assembleRHS(const Function &u, DiscreteFunctionType &w) const;
39 void assemble(LinearOperator &matrix) const;
40
41 private:
42 const DiscreteFunctionSpaceType &dfSpace_;
43};
44
45template <class DiscreteFunction, class LinearOperator>
46class AffineMassOperator
47 : public Dune::Fem::DifferentiableOperator<LinearOperator> {
48 public:
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,
55 const Function &u)
56 : matrix_(dfSpace), rhs_("rhs", dfSpace) {
57 matrix_.assembleRHS(u, rhs_);
58 }
59 const DiscreteFunctionType rhs() const { return rhs_; }
60 virtual void operator()(const DiscreteFunctionType &u,
61 DiscreteFunctionType &w) const {
62 matrix_(u, w);
63 w -= rhs_;
64 }
65 virtual void jacobian(const DiscreteFunctionType &u,
66 JacobianOperatorType &jOp) const {
67 matrix_.assemble(jOp);
68 }
69
70 private:
71 MassOperator<DiscreteFunction, LinearOperator> matrix_;
72 DiscreteFunction rhs_;
73};
74
75template <class DiscreteFunction, class LinearOperator>
76template <class Function>
77void MassOperator<DiscreteFunction, LinearOperator>::assembleRHS(
78 const Function &u, DiscreteFunctionType &w) const {
79 // clear result
80 w.clear();
81
82 Dune::Fem::ConstLocalFunction<Function> uLocal(u);
83 Dune::Fem::AddLocalContribution<DiscreteFunctionType> wLocal(w);
84
85 // run over entities
86 for (const auto &entity :
87 elements(dfSpace_.gridPart(), Dune::Partitions::interiorBorder)) {
88 const auto geometry = entity.geometry();
89
90 auto guard = bindGuard(std::tie(uLocal, wLocal), entity);
91
92 // run over quadrature points
93 for (const auto qp :
94 QuadratureType(entity, uLocal.order() + wLocal.order())) {
95 // evaluate u
96 RangeType uValue = uLocal.evaluate(qp);
97
98 // apply quadrature weight
99 uValue *= qp.weight() * geometry.integrationElement(qp.position());
100
101 // add to local function
102 wLocal.axpy(qp, uValue);
103 }
104 }
105}
106
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_));
113 matrix.clear();
114
115 Dune::Fem::AddLocalContribution<LinearOperator> localMatrix(matrix);
116 Dune::DynamicVector<typename DiscreteFunctionSpaceType::RangeType> values;
117
118 // run over entities
119 for (const auto &entity :
120 elements(dfSpace_.gridPart(), Dune::Partitions::interiorBorder)) {
121 const auto geometry = entity.geometry();
122
123 auto guard = bindGuard(localMatrix, entity, entity);
124
125 const auto &basis = localMatrix.domainBasisFunctionSet();
126 const unsigned int numBasisFunctions = basis.size();
127 values.resize(numBasisFunctions);
128
129 // run over quadrature points
130 for (const auto qp : QuadratureType(entity, localMatrix.order())) {
131 // evaluate base functions
132 basis.evaluateAll(qp, values);
133
134 // apply quadrature weight
135 const auto weight =
136 qp.weight() * geometry.integrationElement(qp.position());
137 std::for_each(values.begin(), values.end(),
138 [weight](auto &a) { a *= weight; });
139
140 // update system matrix
141 localMatrix.axpy(qp, values);
142 }
143 }
144}
145
146#endif // #ifndef MASSOPERATOR_HH
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Sep 4, 22:38, 2025)