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
15namespace 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
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
const ProblemType & problem() const
return reference to problem
Definition: ellipticmodel.hh:323
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.111.3 (Aug 13, 22:30, 2024)