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