DUNE-ACFEM (2.5.1)

righthandsidefunction.hh
1#ifndef DUNE_ACFEM_RIGHTHANDSIDEFUNCTION_HH
2#define DUNE_ACFEM_RIGHTHANDSIDEFUNCTION_HH
3
4#include "../functions/localfunctionwrapper.hh"
5#include "../functions/gridfunctionexpression.hh"
6#include "../models/operatorparts/operatorpartsexpression.hh"
7#include "../models/modelinterface.hh"
8
9namespace Dune {
10 namespace ACFem {
11
26 template<class OperatorParts, class Solution>
28 {
29 public:
31 typedef OperatorParts OperatorPartsType;
32 typedef Solution SolutionType;
33 protected:
34 typedef typename OperatorPartsType::FunctionSpaceType OperatorPartsFunctionSpaceType;
35 typedef typename SolutionType::FunctionSpaceType SolutionFunctionSpaceType;
36 typedef typename SolutionType::LocalFunctionType LocalSolutionType;
37
38 static_assert(std::is_same<OperatorPartsFunctionSpaceType, SolutionFunctionSpaceType>::value,
39 "OperatorParts and \"exact\" solution must live in the same function space");
40
41 public:
42 typedef OperatorPartsFunctionSpaceType FunctionSpaceType; // ahem, make change in the future, maybe ...
43 typedef typename SolutionType::GridPartType GridPartType;
44 typedef typename GridPartType::template Codim<0>::EntityType EntityType;
45
46 typedef typename FunctionSpaceType::RangeType RangeType;
47 typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
48 typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
49
54 const Fem::Function<FunctionSpaceType, SolutionType>& solution,
55 const std::string& name = "")
56 : operatorParts_(operatorParts),
57 solution_(solution),
58 localSolution_(solution_()),
59 name_(name == "" ? operatorParts_().name() + "(" + solution_().name() + ", . )" : name)
60 {}
61
66 : operatorParts_(other.operatorParts_()),
67 solution_(other.solution_()),
68 localSolution_(solution_()),
69 name_(other.name_)
70 {}
71
72 const std::string& name() const { return name_; }
73
74 // Implement needed interface method for the adapter class
75 void init(const EntityType& entity)
76 {
77 operatorParts_().setEntity(entity);
78 localSolution_.init(entity);
79 }
80
81 int order () const
82 {
83 return localSolution_.order();
84 }
85
87 template<class PointType>
88 void evaluate(const PointType& x, RangeType& result) const
89 {
90 // Now do the stuff ... we need the source term and the
91 // fluxDivergence(). For the latter we need to remember the
92 // sign convention we chose ages ago ... actually
93 // fluxDivergence really is MINUS the divergence, i.e. we have
94 // the correct sign as obtained when deriving the weak
95 // formulation with integration by parts.
96
97 RangeType value;
98 JacobianRangeType jacobian;
99 HessianRangeType hessian;
100
101 localSolution_.evaluate(x, value);
102 localSolution_.jacobian(x, jacobian);
103 localSolution_.hessian(x, hessian);
104
105 result = RangeType(0);
106
107 if (OperatorPartsType::hasFlux) {
108 // take the principal part ...
109 operatorParts_().fluxDivergence(localSolution_.entity(), x,
110 value, jacobian, hessian,
111 result);
112 }
113
114 if (OperatorPartsType::hasSources) {
115 // add the source terms
116 RangeType source;
117 operatorParts_().source(localSolution_.entity(), x,
118 value, jacobian,
119 source);
120 result += source;
121 }
122
123 }
124
126 template<class PointType>
127 void jacobian(const PointType& x, JacobianRangeType& ret) const
128 {
129#if __DUNE_ACFEM_MAKE_CHECK__
130 // in order not to disturb the test-suite, which greedily takes hessians from anything
131 ret = 0;
132#else
133 DUNE_THROW(NotImplemented, "Jacobian of an automatic RHS force density just cannot be computed.");
134#endif
135 }
136
137 // hessian of local function
138 template<class PointType>
139 void hessian(const PointType& x, HessianRangeType& ret) const
140 {
141#if __DUNE_ACFEM_MAKE_CHECK__
142 // in order not to disturb the test-suite, which greedily takes hessians from anything
143 ret = 0;
144#else
145 DUNE_THROW(NotImplemented, "Hessian of an automatic RHS force density just cannot be computed.");
146#endif
147 }
148
149 protected:
150 ExpressionStorage<OperatorPartsType> operatorParts_;
151 ExpressionStorage<SolutionType> solution_;
152 mutable LocalSolutionType localSolution_;
153 const std::string name_;
154 };
155
157
167 template<class OperatorParts, class Solution>
168 LocalFunctionWrapper<LocalRightHandSideAdapter<OperatorParts, Solution>, typename Solution::GridPartType>
170 const Fem::Function<typename Solution::FunctionSpaceType, Solution>& solution_,
171 const std::string& name = "")
172 {
175
176 const Solution& solution(static_cast<const Solution&>(solution_));
177 LocalFunctionType L_f_dot(operatorParts, solution, name);
178
179 return GridFunctionType(L_f_dot.name(), L_f_dot, solution.space().gridPart(), solution.space().order());
180 }
181
182 template<class Model, class Solution>
183 LocalFunctionWrapper<LocalRightHandSideAdapter<typename Model::OperatorPartsType, Solution>,
184 typename Solution::GridPartType>
185 rightHandSide(const ModelInterface<Model>& model,
186 const Fem::Function<typename Solution::FunctionSpaceType, Solution>& solution_,
187 const std::string& name = "")
188 {
189 typedef LocalRightHandSideAdapter<typename Model::OperatorPartsType, Solution> LocalFunctionType;
190 typedef LocalFunctionWrapper<LocalFunctionType, typename Solution::GridPartType> GridFunctionType;
191
192 const Solution& solution(static_cast<const Solution&>(solution_));
193 LocalFunctionType L_f_dot(model.operatorParts(), solution, name);
194
195 return GridFunctionType(L_f_dot.name(), L_f_dot, solution.space().gridPart(), solution.space().order());
196 }
197
199
201
202 } // ACFem::
203
204} // Dune::
205
206
207#endif // DUNE_ACFEM_RIGHTHANDSIDEFUNCTION_HH
LocalFunctionWrapper wraps a class with a local evaluate method into a grid function.
Definition: localfunctionwrapper.hh:71
An adapter class which takes any ACFem-PDE model and computes from its bulk contributions and any giv...
Definition: righthandsidefunction.hh:28
void evaluate(const PointType &x, RangeType &result) const
evaluate local function
Definition: righthandsidefunction.hh:88
LocalRightHandSideAdapter(const OperatorPartsInterfaceType &operatorParts, const Fem::Function< FunctionSpaceType, SolutionType > &solution, const std::string &name="")
Construct the right hand side function from a given PDE model and a given – potentially non-discrete ...
Definition: righthandsidefunction.hh:53
LocalRightHandSideAdapter(const LocalRightHandSideAdapter &other)
Definition: righthandsidefunction.hh:65
void jacobian(const PointType &x, JacobianRangeType &ret) const
jacobian of local function
Definition: righthandsidefunction.hh:127
Interface class for second order elliptic models.
Definition: operatorparts.hh:92
LocalFunctionWrapper< LocalRightHandSideAdapter< OperatorParts, Solution >, typename Solution::GridPartType > rightHandSide(const OperatorPartsInterface< OperatorParts > &operatorParts, const Fem::Function< typename Solution::FunctionSpaceType, Solution > &solution_, const std::string &name="")
Take any PDE operatorparts and an "exact solutio" and generate a right-hand-side force-density such t...
Definition: righthandsidefunction.hh:169
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Aug 13, 22:30, 2024)