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 
9 namespace 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  {
173  typedef LocalRightHandSideAdapter<OperatorParts, Solution> LocalFunctionType;
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.80.0 (May 16, 22:29, 2024)