DUNE-ACFEM (2.5.1)

ellipticmodel.hh
1 #ifndef ELLIPTC_MODEL_HH
2 #define ELLIPTC_MODEL_HH
3 
4 #include <cassert>
5 #include <cmath>
6 
7 #include <dune/fem/solver/timeprovider.hh>
8 #include <dune/fem/io/parameter.hh>
9 
10 #include "modelinterface.hh"
11 #include "probleminterface.hh"
12 #include "../functions/gridfunctionexpression.hh"
13 #include "../functions/gridfunctionwrapper.hh"
14 
15 namespace Dune {
16 
17  namespace ACFem {
18 
27  // DiffusionModel
28  // --------------
29 
75  template<class FunctionSpace, class GridPart, class Problem = ProblemInterface<FunctionSpace> >
77  : public DefaultModel<EllipticModel<FunctionSpace, GridPart, Problem> >
78  {
79  private:
80  typedef EllipticModel ThisType;
84  public:
85  typedef typename InterfaceType::FunctionSpaceType FunctionSpaceType;
86  typedef typename InterfaceType::GridPartType GridPartType;
87  typedef typename InterfaceType::EntityType EntityType;
88  typedef typename InterfaceType::IntersectionType IntersectionType;
89 
90  typedef typename FunctionSpaceType::DomainType DomainType;
91  typedef typename FunctionSpaceType::RangeType RangeType;
92  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
93  typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
94 
95  typedef typename FunctionSpaceType::DomainFieldType DomainFieldType;
96  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
97 
98  typedef Problem ProblemType ;
99 
100  typedef typename ProblemType::DirichletBoundaryType DirichletBoundaryType;
101  typedef typename ProblemType::NeumannBoundaryType NeumannBoundaryType;
102  typedef typename ProblemType::RightHandSideType BulkForcesType;
103  typedef typename ProblemType::ExactSolutionType ExactSolutionType; // not part of the ModelInterface
104 
105  typedef typename InterfaceType::DirichletBoundaryFunctionType DirichletBoundaryFunctionType;
106  typedef typename InterfaceType::DirichletWeightFunctionType DirichletWeightFunctionType;
107  typedef typename InterfaceType::NeumannBoundaryFunctionType NeumannBoundaryFunctionType;
108  typedef typename InterfaceType::BulkForcesFunctionType BulkForcesFunctionType;
109  typedef typename TraitsType::ExactSolutionFunctionType ExactSolutionFunctionType; // not part of the ModelInterface
110 
111  typedef typename TraitsType::DirichletIndicatorType DirichletIndicatorType;
112  typedef typename TraitsType::NeumannIndicatorType NeumannIndicatorType;
113  typedef typename TraitsType::RobinIndicatorType RobinIndicatorType;
114 
119  EllipticModel(const ProblemType& problem)
120  : problem_(problem),
121  dirichletFunction_(problem_),
122  neumannFunction_(problem_),
123  bulkForcesFunction_(problem_),
124  solutionFunction_(problem_),
125  dirichletIndicator_(*this),
126  neumannIndicator_(*this),
127  robinIndicator_(*this),
128  lastRobinIndication_(false)
129  {}
130 
131  void setEntity(const EntityType& entity) const
132  {
133  // just here to remind us ...
134  }
135 
136  bool setIntersection(const IntersectionType& intersection) const
137  {
138  lastRobinIndication_ = robinIndicator_.applies(intersection);
139  return lastRobinIndication_;
140  }
141 
143  template<class Entity, class Point>
144  void flux(const Entity& entity,
145  const Point &x,
146  const RangeType& value,
147  const JacobianRangeType& jacobian,
148  JacobianRangeType& flux) const
149  {
150  // Default is a linear model
151  linearizedFlux(value, jacobian, entity, x, value, jacobian, flux);
152  }
153 
155  template<class Entity, class Point>
156  void linearizedFlux(const RangeType& uBar,
157  const JacobianRangeType& DuBar,
158  const Entity& entity,
159  const Point &x,
160  const RangeType& value,
161  const JacobianRangeType& jacobian,
162  JacobianRangeType& flux) const
163  {
164  // The default model does not have a non-linearity.
165  const DomainType xGlobal = entity.geometry().global(coordinate(x));
166  problem_.secondOrderCoefficient(xGlobal, jacobian, flux);
167  }
168 
170  template<class Entity, class Point>
171  void source(const Entity& entity,
172  const Point &x,
173  const RangeType& value,
174  const JacobianRangeType& jacobian,
175  RangeType& result) const
176  {
177  linearizedSource(value, jacobian, entity, x, value, jacobian, result);
178  }
179 
181  template<class Entity, class Point>
182  void linearizedSource(const RangeType& uBar,
183  const JacobianRangeType& DuBar,
184  const Entity& entity,
185  const Point &x,
186  const RangeType& value,
187  const JacobianRangeType& jacobian,
188  RangeType& result) const
189  {
190  const DomainType xGlobal = entity.geometry().global(coordinate(x));
191  result = 0;
192  if (problem_.has(ProblemType::ZeroOrderCoefficient)) {
193  RangeType tmp;
194  problem_.zeroOrderCoefficient(xGlobal, value, tmp);
195  result += tmp;
196  }
197  if (problem_.has(ProblemType::FirstOrderCoefficient)) {
198  RangeType tmp;
199  problem_.firstOrderCoefficient(xGlobal, value, jacobian, tmp);
200  result += tmp;
201  }
202  }
203 
205  template<class Intersection, class Point>
206  void robinFlux(const Intersection& intersection,
207  const Point& x,
208  const DomainType& unitOuterNormal,
209  const RangeType& value,
210  RangeType& result) const
211  {
212  linearizedRobinFlux(value, intersection, x, unitOuterNormal, value, result);
213  }
214 
216  template<class Intersection, class Point>
217  void linearizedRobinFlux(const RangeType& uBar,
218  const Intersection& intersection,
219  const Point& x,
220  const DomainType& unitOuterNormal,
221  const RangeType& value,
222  RangeType& result) const
223  {
224  if (!lastRobinIndication_) {
225  result = 0;
226  return;
227  }
228  const DomainType xGlobal = intersection.inside()->geometry().global(coordinate(x));
229 
230  problem_.robinData(xGlobal, value, result);
231  }
232 
234  template<class Entity, class Point>
235  void fluxDivergence(const Entity& entity,
236  const Point &x,
237  const RangeType& value,
238  const JacobianRangeType& jacobian,
239  const HessianRangeType& hessian,
240  RangeType& result) const
241  {
242  const DomainType xGlobal = entity.geometry().global(coordinate(x));
243 
244  result = 0;
245  if (problem_.has(ProblemType::SecondOrderCoefficient)) {
246  problem_.secondOrderCoefficient(xGlobal, jacobian, hessian, result);
247  }
248  }
249 
250  public:
254  BulkForcesFunctionType bulkForcesFunction(const GridPartType& gridPart) const
255  {
256  typedef BulkForcesFunctionType FunctionType;
257 
258  return FunctionType("Bulk Forces", bulkForcesFunction_, gridPart);
259  }
260 
264  DirichletBoundaryFunctionType dirichletBoundaryFunction(const GridPartType& gridPart) const
265  {
266  typedef typename TraitsType::DirichletBoundaryGridFunctionType GridFunctionType;
267  typedef DirichletBoundaryFunctionType FunctionType;
268 
269  auto gridFunction = GridFunctionType("Dirichlet Boundary Values", dirichletFunction_, gridPart);
270 
271  return FunctionType(gridFunction, dirichletIndicator_);
272  }
273 
276  DirichletWeightFunctionType dirichletWeightFunction(const GridPartType& gridPart) const
277  {
278  typedef DirichletWeightFunctionType FunctionType;
279 
280  auto gridFunction = oneFunction(dirichletBoundaryFunction(gridPart));
281 
282  return FunctionType(gridFunction, dirichletIndicator_);
283  }
284 
288  NeumannBoundaryFunctionType
289  neumannBoundaryFunction(const GridPartType& gridPart) const
290  {
291  typedef typename TraitsType::NeumannBoundaryGridFunctionType GridFunctionType;
292  typedef NeumannBoundaryFunctionType FunctionType;
293 
294  auto gridFunction = GridFunctionType("Neumann Boundary Values", neumannFunction_, gridPart);
295 
296  return FunctionType(gridFunction, neumannIndicator_);
297  }
298 
302  ExactSolutionFunctionType
303  exactSolutionFunction(const GridPartType& gridPart) const
304  {
305  typedef ExactSolutionFunctionType FunctionType;
306 
307  return FunctionType("Exact Solution", solutionFunction_, gridPart);
308  }
309 
310  DirichletIndicatorType dirichletIndicator() const {
311  return dirichletIndicator_;
312  }
313 
314  NeumannIndicatorType neumannIndicator() const {
315  return neumannIndicator_;
316  }
317 
318  RobinIndicatorType robinIndicator() const {
319  return robinIndicator_;
320  }
321 
323  const ProblemType& problem() const { return problem_; }
324 
325  protected:
326  const ProblemType& problem_;
336  DirichletBoundaryType dirichletFunction_;
337  NeumannBoundaryType neumannFunction_;
338  BulkForcesType bulkForcesFunction_;
339  ExactSolutionType solutionFunction_;
340 
341  DirichletIndicatorType dirichletIndicator_;
342  NeumannIndicatorType neumannIndicator_;
343  RobinIndicatorType robinIndicator_;
345  mutable bool lastRobinIndication_;
346  };
347 
348  template<class FunctionSpace, class GridPart, class Problem>
349  struct ModelTraits<EllipticModel<FunctionSpace, GridPart, Problem> >
350  : public DefaultModelTraits<FunctionSpace, GridPart>
351  {
352  private:
354  typedef Problem ProblemType;
355 
356  typedef typename ProblemType::DirichletBoundaryType DirichletBoundaryType;
357  typedef typename ProblemType::NeumannBoundaryType NeumannBoundaryType;
358  typedef typename ProblemType::RightHandSideType BulkForcesType;
359  typedef typename ProblemType::ExactSolutionType ExactSolutionType;
360 
361  typedef typename FunctionSpace::DomainType DomainType;
362  public:
363  enum {
364  isLinear = true, // The ProblemInterface only models linear operators
365  isSymmetric = true, // really?
366  isSemiDefinite = true // really?
367  };
368 
370  hasFlux = true,
371  hasSources = true,
372  };
373 
374  typedef FunctionSpace FunctionSpaceType;
375  typedef typename FunctionSpace::ScalarFunctionSpaceType ScalarFunctionSpaceType;
376  typedef GridPart GridPartType;
377 
378  struct DirichletIndicator
379  : DefaultBoundaryIndicator<DirichletIndicator>
380  {
381  DirichletIndicator(const ModelType& model) : model_(model)
382  {}
383 
384  template<class Intersection>
385  bool applies(const Intersection& intersection) const
386  {
387  const int bndId = intersection.boundaryId();
388  const DomainType center = intersection.geometry().center();
389 
390  return model_.problem().isDirichletSegment(bndId, center);
391  }
392  private:
393  const ModelType& model_;
394  };
395 
396  typedef DirichletIndicator DirichletIndicatorType;
397 
398  struct NeumannIndicator
399  : DefaultBoundaryIndicator<NeumannIndicator>
400  {
401  NeumannIndicator(const ModelType& model) : model_(model)
402  {}
403 
404  template<class Intersection>
405  bool applies(const Intersection& intersection) const
406  {
407  const int bndId = intersection.boundaryId();
408  const DomainType center = intersection.geometry().center();
409 
410  return model_.problem().isNeumannSegment(bndId, center);
411  }
412  private:
413  const ModelType& model_;
414  };
415  typedef NeumannIndicator NeumannIndicatorType;
416 
417  struct RobinIndicator
418  : DefaultBoundaryIndicator<RobinIndicator>
419  {
420  RobinIndicator(const ModelType& model) : model_(model)
421  {}
422 
423  template<class Intersection>
424  bool applies(const Intersection& intersection) const
425  {
426  const int bndId = intersection.boundaryId();
427  const DomainType center = intersection.geometry().center();
428 
429  return model_.problem().isRobinSegment(bndId, center);
430  }
431  private:
432  const ModelType& model_;
433  };
434  typedef RobinIndicator RobinIndicatorType;
435 
436  typedef GridFunctionAdapter<BulkForcesType, GridPartType> BulkForcesFunctionType;
437  typedef GridFunctionAdapter<ExactSolutionType, GridPartType> ExactSolutionFunctionType;
438 
439  typedef GridFunctionAdapter<DirichletBoundaryType, GridPartType> DirichletBoundaryGridFunctionType;
440  typedef
441  BoundarySupportedFunction<DirichletBoundaryGridFunctionType, DirichletIndicatorType>
442  DirichletBoundaryFunctionType;
443  typedef
444  BoundarySupportedFunction<FractionGridFunction<ScalarFunctionSpaceType, GridPartType, 1L, 1UL>,
445  DirichletIndicatorType>
446  DirichletWeightFunctionType;
447 
448  typedef GridFunctionAdapter<NeumannBoundaryType, GridPartType> NeumannBoundaryGridFunctionType;
449  typedef
450  BoundarySupportedFunction<NeumannBoundaryGridFunctionType, NeumannIndicatorType>
451  NeumannBoundaryFunctionType;
452  };
453 
455 
457 
458  } // ACFem
459 
460 } // Dune
461 
462 #endif // #ifndef ELLIPTC_MODEL_HH
Default model implementation.
Definition: modelinterface.hh:330
Interface class for second order elliptic models.
Definition: modelinterface.hh:192
TraitsType::DirichletBoundaryFunctionType DirichletBoundaryFunctionType
A BoundarySupportedFunction which must be sub-ordinate to the DirichletIndicatorType.
Definition: modelinterface.hh:241
TraitsType::BulkForcesFunctionType BulkForcesFunctionType
A function modelling "force" terms in the bulk-phase.
Definition: modelinterface.hh:226
TraitsType::DirichletWeightFunctionType DirichletWeightFunctionType
A BoundarySupportedFunction which must be sub-ordinate to the DirichletIndicatorType.
Definition: modelinterface.hh:242
TraitsType::NeumannBoundaryFunctionType NeumannBoundaryFunctionType
A function modelling "force" terms in the bulk-phase.
Definition: modelinterface.hh:227
BulkForcesFunctionType bulkForcesFunction(const GridPartType &gridPart) const
Return a grid functin adapter for the external forces, see class Dune::Fem::GridFunctionAdapter.
Definition: ellipticmodel.hh:254
void fluxDivergence(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, const HessianRangeType &hessian, RangeType &result) const
Definition: ellipticmodel.hh:235
ExactSolutionFunctionType exactSolutionFunction(const GridPartType &gridPart) const
Return a grid function for a "exact solution" for experimental convergence tests.
Definition: ellipticmodel.hh:303
const ProblemType & problem() const
return reference to problem
Definition: ellipticmodel.hh:323
void robinFlux(const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: ellipticmodel.hh:206
const ProblemType & problem_
Pointer to the underlying problem.
Definition: ellipticmodel.hh:326
void linearizedFlux(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
Definition: ellipticmodel.hh:156
DirichletBoundaryFunctionType dirichletBoundaryFunction(const GridPartType &gridPart) const
Return a grid functin adapter for the Dirichlet boundary values, see class Dune::Fem::GridFunctionAda...
Definition: ellipticmodel.hh:264
EllipticModel(const ProblemType &problem)
Constructor taking problem reference.
Definition: ellipticmodel.hh:119
DirichletWeightFunctionType dirichletWeightFunction(const GridPartType &gridPart) const
Return the trivial constant one function as Dirichlet weight.
Definition: ellipticmodel.hh:276
void linearizedSource(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, RangeType &result) const
Definition: ellipticmodel.hh:182
void source(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, RangeType &result) const
Definition: ellipticmodel.hh:171
void linearizedRobinFlux(const RangeType &uBar, const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: ellipticmodel.hh:217
NeumannBoundaryFunctionType neumannBoundaryFunction(const GridPartType &gridPart) const
Return a grid functin adapter for the Neumann boundary values, see class Dune::Fem::GridFunctionAdapt...
Definition: ellipticmodel.hh:289
void flux(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
Definition: ellipticmodel.hh:144
FractionGridFunction< typename FunctionSpace::FunctionSpaceType::ScalarFunctionSpaceType, GridPart, 1L, 1UL > oneFunction(const FunctionSpace &space, const GridPart &gridPart)
Generate a proper constant-one function from the given Fem::FunctionSpace and Fem::GridPart.
Definition: gridfunctionexpression.hh:157
Default boundary indicator: like EntireBoundaryIndicator<false>
Definition: boundaryindicator.hh:76
A structure defining some trivial default values for the template structure ModelTraits<ModelType>,...
Definition: modelinterface.hh:57
A model for a second order elliptic operator.
Definition: ellipticmodel.hh:78
Traits-template which has to be specialized for each individual model.
Definition: modelinterface.hh:48
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 2, 22:35, 2024)