1#ifndef DUNE_ACFEM_RIGHTHANDSIDEFUNCTION_HH
2#define DUNE_ACFEM_RIGHTHANDSIDEFUNCTION_HH
4#include "../functions/localfunctionwrapper.hh"
5#include "../functions/gridfunctionexpression.hh"
6#include "../models/operatorparts/operatorpartsexpression.hh"
7#include "../models/modelinterface.hh"
26 template<
class OperatorParts,
class Solution>
31 typedef OperatorParts OperatorPartsType;
32 typedef Solution SolutionType;
34 typedef typename OperatorPartsType::FunctionSpaceType OperatorPartsFunctionSpaceType;
35 typedef typename SolutionType::FunctionSpaceType SolutionFunctionSpaceType;
36 typedef typename SolutionType::LocalFunctionType LocalSolutionType;
38 static_assert(std::is_same<OperatorPartsFunctionSpaceType, SolutionFunctionSpaceType>::value,
39 "OperatorParts and \"exact\" solution must live in the same function space");
42 typedef OperatorPartsFunctionSpaceType FunctionSpaceType;
43 typedef typename SolutionType::GridPartType GridPartType;
44 typedef typename GridPartType::template Codim<0>::EntityType EntityType;
46 typedef typename FunctionSpaceType::RangeType RangeType;
47 typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
48 typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
54 const Fem::Function<FunctionSpaceType, SolutionType>& solution,
55 const std::string& name =
"")
56 : operatorParts_(operatorParts),
58 localSolution_(solution_()),
59 name_(name ==
"" ? operatorParts_().name() +
"(" + solution_().name() +
", . )" : name)
66 : operatorParts_(other.operatorParts_()),
67 solution_(other.solution_()),
68 localSolution_(solution_()),
72 const std::string& name()
const {
return name_; }
75 void init(
const EntityType& entity)
77 operatorParts_().setEntity(entity);
78 localSolution_.init(entity);
83 return localSolution_.order();
87 template<
class Po
intType>
88 void evaluate(
const PointType& x, RangeType& result)
const
99 HessianRangeType hessian;
101 localSolution_.evaluate(x, value);
102 localSolution_.jacobian(x,
jacobian);
103 localSolution_.hessian(x, hessian);
105 result = RangeType(0);
107 if (OperatorPartsType::hasFlux) {
109 operatorParts_().fluxDivergence(localSolution_.entity(), x,
114 if (OperatorPartsType::hasSources) {
117 operatorParts_().source(localSolution_.entity(), x,
126 template<
class Po
intType>
127 void jacobian(
const PointType& x, JacobianRangeType& ret)
const
129#if __DUNE_ACFEM_MAKE_CHECK__
133 DUNE_THROW(NotImplemented,
"Jacobian of an automatic RHS force density just cannot be computed.");
138 template<
class Po
intType>
139 void hessian(
const PointType& x, HessianRangeType& ret)
const
141#if __DUNE_ACFEM_MAKE_CHECK__
145 DUNE_THROW(NotImplemented,
"Hessian of an automatic RHS force density just cannot be computed.");
150 ExpressionStorage<OperatorPartsType> operatorParts_;
151 ExpressionStorage<SolutionType> solution_;
152 mutable LocalSolutionType localSolution_;
153 const std::string name_;
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 =
"")
176 const Solution& solution(
static_cast<const Solution&
>(solution_));
177 LocalFunctionType L_f_dot(operatorParts, solution, name);
179 return GridFunctionType(L_f_dot.name(), L_f_dot, solution.space().gridPart(), solution.space().order());
182 template<
class Model,
class Solution>
183 LocalFunctionWrapper<LocalRightHandSideAdapter<typename Model::OperatorPartsType, Solution>,
184 typename Solution::GridPartType>
186 const Fem::Function<typename Solution::FunctionSpaceType, Solution>& solution_,
187 const std::string& name =
"")
189 typedef LocalRightHandSideAdapter<typename Model::OperatorPartsType, Solution> LocalFunctionType;
190 typedef LocalFunctionWrapper<LocalFunctionType, typename Solution::GridPartType> GridFunctionType;
192 const Solution& solution(
static_cast<const Solution&
>(solution_));
193 LocalFunctionType L_f_dot(model.operatorParts(), solution, name);
195 return GridFunctionType(L_f_dot.name(), L_f_dot, solution.space().gridPart(), solution.space().order());
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