Loading [MathJax]/extensions/tex2jax.js

dune-mmesh (1.4)

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