1#ifndef __DUNE_ACFEM_FUNCTIONS_MODULES_MODELDIRICHLETVALUES_HH__
2#define __DUNE_ACFEM_FUNCTIONS_MODULES_MODELDIRICHLETVALUES_HH__
4#include <dune/fem/function/localfunction/bindable.hh>
5#include "../../models/modelfacade.hh"
6#include "../../models/modelboundaryindicators.hh"
14 namespace GridFunction {
27 template<
class Model,
class Gr
idPart>
29 :
public Fem::BindableGridFunction<GridPart, typename ModelTraits<Model>::RangeType>
32 "Model better would be a proper PDE-model ...");
33 using BaseType = Fem::BindableGridFunction<GridPart, typename ModelTraits<Model>::RangeType>;
35 using GridPartType = GridPart;
36 using ModelType = std::decay_t<Model>;
37 using ModelTraits = ModelIntrospection::Traits<Model>;
38 using typename BaseType::EntityType;
39 using typename BaseType::RangeFieldType;
40 using RealType =
typename Dune::FieldTraits<RangeFieldType>::real_type;
41 using typename BaseType::DomainType;
42 using typename BaseType::RangeType;
43 using typename BaseType::JacobianRangeType;
44 using HessianRangeType =
typename ModelType::HessianRangeType;
45 static constexpr std::size_t dimRange = ModelType::dimRange;
46 static constexpr std::size_t dimDomain = ModelType::dimDomain;
47 static constexpr std::size_t dirichlet = ModelIntrospection::dirichlet;
48 static constexpr std::size_t linearizedDirichlet = ModelIntrospection::linearizedDirichlet;
49 static constexpr bool precomputeJacobian =
50 ModelTraits::template IsPiecewiseConstant<linearizedDirichlet>::value
52 ModelTraits::template IsAffineLinear<dirichlet>::value;
53 using DirichletJacobianRangeType = FieldMatrix<RangeFieldType, dimRange, dimRange>;
65 const GridPartType& gridPart,
66 const std::string& name =
"")
70 , linearizedDirichlet_(model_)
71 , name_(name ==
"" ?
"Dirichlet("+model_.name()+
")" : name)
72 , tolerance_(Fem::Parameter::getValue<RealType>(
"acfem.dirichlet.newton.tolerance", 2.0*
std::numeric_limits<RangeFieldType>::epsilon()))
73 , maxIter_(Fem::Parameter::getValue<RealType>(
"acfem.dirichlet.newton.iterationLimit", 100))
78 , model_(other.model_)
80 , linearizedDirichlet_(model_)
82 , tolerance_(other.tolerance_)
83 , maxIter_(other.maxIter_)
88 , model_(
std::move(other.model_))
90 , linearizedDirichlet_(model_)
91 , name_(
std::move(other.name_))
92 , tolerance_(other.tolerance_)
93 , maxIter_(other.maxIter_)
96 using BaseType::entity;
97 using BaseType::gridPart;
99 const std::string& name()
const {
return name_; }
102 void bind(
const EntityType& entity)
104 BaseType::bind(entity);
105 model_.bind(BaseType::entity());
116 template<
class Intersection>
119 auto supported = model_.classifyBoundary(intersection);
120 if constexpr (precomputeJacobian) {
122 jacobian_ = computeJacobian(RangeType(), quadraturePoint(DomainType()));
129 return std::numeric_limits<int>::max();
134 template<
class Point,
148 auto values = RangeType(0.5);
150 for (
int k = 0; k <= maxIter_; ++k) {
152 assert(k < maxIter_);
154 auto G = dirichlet_(x, values);
157 if constexpr (precomputeJacobian) {
158 jacobian_.solve(d, G);
160 computeJacobian(values, x).solve(d, G);
164 static_assert(ModelTraits::template IsAffineLinear<dirichlet>::value,
165 "non-linear Dirichlet values");
168 if constexpr (ModelTraits::template IsAffineLinear<dirichlet>::value) {
173 if (d.two_norm2() < tolerance_ * tolerance_) {
184 template<
class Point,
186 void evaluate(
const Point& point, RangeType& result)
const
192 template<
class Point,
196#if !__DUNE_ACFEM_MAKE_CHECK__
197 static_assert(
sizeof(Point) != 0,
"It does not make sense to differentiate Dirichlet values.");
199 return JacobianRangeType(0);
203 template<
class Point,
205 void jacobian(
const Point& x, JacobianRangeType& result)
const
207#if !__DUNE_ACFEM_MAKE_CHECK__
208 static_assert(
sizeof(Point) != 0,
"It does not make sense to differentiate Dirichlet values.");
214 template<
class Point,
216 auto hessian(
const Point& x)
const
218#if !__DUNE_ACFEM_MAKE_CHECK__
219 static_assert(
sizeof(Point) != 0,
"It does not make sense to differentiate Dirichlet values.");
221 return HessianRangeType(0);
225 template<
class Point,
227 void hessian(
const Point& x, HessianRangeType& ret)
const
229#if !__DUNE_ACFEM_MAKE_CHECK__
230 static_assert(
sizeof(Point) != 0,
"It does not make sense to differentiate Dirichlet values.");
235 const ModelType& model()
const {
return model_; }
236 ModelType& model() {
return model_; }
239 template<
class Quadrature>
240 auto computeJacobian(
const RangeType& values,
const QuadraturePoint<Quadrature>& x)
const
242 DirichletJacobianRangeType
jacobian;
244 forLoop<dimRange>([&](
auto j) {
245 using J =
decltype(j);
246 auto ej = kroneckerDelta<J::value>(IndexSequence<dimRange>{});
247 auto tmp = linearizedDirichlet_(values, x, ej);
248 for (
unsigned i = 0; i < dimRange; ++i) {
257 ModelClosureMethod<ModelType, dirichlet> dirichlet_;
258 ModelClosureMethod<ModelType, linearizedDirichlet> linearizedDirichlet_;
262 DirichletJacobianRangeType jacobian_;
268 template<
class Model,
class GridPart,
269 std::enable_if_t<EffectiveModelTraits<Model>::template Exists<PDEModel::dirichlet>::value,
int> = 0>
271 const GridPart& gridPart,
272 const std::string& name =
"")
281 template<
class Model,
class GridPart,
282 std::enable_if_t<!EffectiveModelTraits<Model>::template Exists<PDEModel::dirichlet>::value,
int> = 0>
284 const GridPart& gridPart,
285 const std::string& name =
"")
288 return GridFunction::zeros<typename std::decay_t<Model>::FunctionSpaceType>(gridPart);
An adapter class which takes any ACFem-PDE model and extracts its Dirichlet values as a BoundarySuppo...
Definition: modeldirichletvalues.hh:30
auto classifyIntersection(const Intersection &intersection)
Bind to the given intersection and classify the components w.r.t.
Definition: modeldirichletvalues.hh:117
auto evaluate(Point &x) const
evaluate local function evaluate local function
Definition: modeldirichletvalues.hh:136
auto jacobian(const Point &x) const
jacobian of local function
Definition: modeldirichletvalues.hh:194
ModelDirichletValues(Model &&model, const GridPartType &gridPart, const std::string &name="")
Extract the Dirichlet values from the given model.
Definition: modeldirichletvalues.hh:64
void evaluate(const Point &point, RangeType &result) const
evaluate local function
Definition: modeldirichletvalues.hh:186
void jacobian(const Point &x, JacobianRangeType &result) const
jacobian of local function
Definition: modeldirichletvalues.hh:205
auto modelDirichletValues(Model &&model, const GridPart &gridPart, const std::string &name="")
Generate a representation of the Dirichlet values associated to the model as Fem::BindableGridFunctio...
Definition: modeldirichletvalues.hh:270
ModelIntrospection::template IsModel< Model > IsPDEModel
std::true_type if Model is derived from ModelBase.
Definition: modeltraits.hh:894
Definition: quadraturepoint.hh:29