version 0.4
utils/dirichletvalues.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2024 The Ikarus Developers mueller@ibb.uni-stuttgart.de
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
10#pragma once
11#include <algorithm>
12#include <concepts>
13#include <cstddef>
14#include <functional>
15#include <type_traits>
16#include <utility>
17#include <vector>
18
19#include <dune/functions/backends/istlvectorbackend.hh>
20#include <dune/functions/functionspacebases/boundarydofs.hh>
21
22#include <Eigen/Core>
23
24#include <autodiff/forward/real/real.hpp>
25
27
28namespace Dune {
29 template <class K, int N>
30 class FieldVector;
31}
32
33namespace Ikarus {
34
45 template <typename Basis_, typename FlagsType_ = std::vector<bool>>
47 public:
48 using Basis = std::remove_cvref_t<Basis_>;
49 using FlagsType = FlagsType_;
50 static constexpr int worldDimension = Basis::GridView::dimensionworld;
51 using BackendType = decltype(Dune::Functions::istlVectorBackend(std::declval<FlagsType&>()));
52 explicit DirichletValues(const Basis_& p_basis) : basis_{p_basis}, dirichletFlagsBackend{dirichletFlags} {
53 dirichletFlagsBackend.resize(basis_);
54 std::fill(dirichletFlags.begin(), dirichletFlags.end(), false);
55 inhomogeneousBoundaryVectorDummy.setZero(static_cast<Eigen::Index>(basis_.size()));
56 }
57
66 template <typename F>
67 void fixBoundaryDOFs(F&& f) {
69 auto lambda = [&](auto&& indexGlobal) { f(dirichletFlagsBackend, indexGlobal); };
70 Dune::Functions::forEachBoundaryDOF(basis_, lambda);
72 auto lambda = [&](auto&& localIndex, auto&& localView) { f(dirichletFlagsBackend, localIndex, localView); };
73 Dune::Functions::forEachBoundaryDOF(basis_, lambda);
74 } else if constexpr (Concepts::IsFunctorWithArgs<F, BackendType, int, typename Basis::LocalView,
75 typename Basis::GridView::Intersection>) {
76 auto lambda = [&](auto&& localIndex, auto&& localView, auto&& intersection) {
77 f(dirichletFlagsBackend, localIndex, localView, intersection);
78 };
79 Dune::Functions::forEachBoundaryDOF(basis_, lambda);
80 }
81 }
82
91 template <typename F>
92 void fixDOFs(F&& f) {
93 f(basis_, dirichletFlagsBackend);
94 }
95
101 void fixIthDOF(typename Basis::MultiIndex i) { dirichletFlagsBackend[i] = true; }
102
103 /* \brief Returns the local basis object */
104 const auto& basis() const { return basis_; }
105
106 /* \brief Returns a boolean values, if the give multiIndex is constrained */
107 template <typename MultiIndex>
108 requires(not std::integral<MultiIndex>) [[nodiscard]] bool isConstrained(const MultiIndex& multiIndex) const {
109 return dirichletFlagsBackend[multiIndex];
110 }
111
112 /* \brief Returns a boolean values, if the i-th degree of freedom is constrained */
113 [[nodiscard]] bool isConstrained(std::size_t i) const { return dirichletFlags[i]; }
114
115 /* \brief Returns how many degrees of freedoms are fixed */
116 auto fixedDOFsize() const { return std::ranges::count(dirichletFlags, true); }
117
118 /* \brief Returns how many degrees of freedom there are */
119 auto size() const { return dirichletFlags.size(); }
120
121 /* \brief Returns the underlying dof flag container */
122 auto& container() const { return dirichletFlags; }
123
133 template <typename F>
135 auto derivativeLambda = [&](const auto& globalCoord, const double& lambda) {
136 autodiff::real lambdaDual = lambda;
137 lambdaDual[1] = 1; // Setting the derivative in lambda direction to 1
138 return derivative(f(globalCoord, lambdaDual));
139 };
140 dirichletFunctions.push_back({f, derivativeLambda});
141 }
142
152 void evaluateInhomogeneousBoundaryCondition(Eigen::VectorXd& xIh, const double& lambda) {
153 inhomogeneousBoundaryVectorDummy.setZero();
154 xIh.resizeLike(inhomogeneousBoundaryVectorDummy);
155 xIh.setZero();
156 for (auto& f : dirichletFunctions) {
157 interpolate(
158 basis_, inhomogeneousBoundaryVectorDummy,
159 [&](const auto& globalCoord) { return f.value(globalCoord, lambda); }, dirichletFlagsBackend);
160 xIh += inhomogeneousBoundaryVectorDummy;
161 }
162 }
163
173 void evaluateInhomogeneousBoundaryConditionDerivative(Eigen::VectorXd& xIh, const double& lambda) {
174 inhomogeneousBoundaryVectorDummy.setZero();
175 xIh.resizeLike(inhomogeneousBoundaryVectorDummy);
176 xIh.setZero();
177 for (auto& f : dirichletFunctions) {
178 interpolate(
179 basis_, inhomogeneousBoundaryVectorDummy,
180 [&](const auto& globalCoord) { return f.derivative(globalCoord, lambda); }, dirichletFlagsBackend);
181 xIh += inhomogeneousBoundaryVectorDummy;
182 }
183 }
184
185 private:
186 Eigen::VectorXd inhomogeneousBoundaryVectorDummy;
187 Basis basis_;
188 FlagsType dirichletFlags;
189 BackendType dirichletFlagsBackend;
190 struct DirichletFunctions {
191 using Signature = std::function<Eigen::Vector<double, worldDimension>(
192 const Dune::FieldVector<double, worldDimension>&, const double&)>;
193 Signature value;
194 Signature derivative;
195 };
196 std::vector<DirichletFunctions> dirichletFunctions;
197 };
198
199} // namespace Ikarus
Several concepts.
Definition: simpleassemblers.hh:21
Definition: resultevaluators.hh:17
Definition: resultevaluators.hh:20
Wrapper class for a hierarchical basis constructed from a pre-basis.
Definition: utils/basis.hh:29
Class for handling Dirichlet boundary conditions in Ikarus.
Definition: utils/dirichletvalues.hh:46
auto fixedDOFsize() const
Definition: utils/dirichletvalues.hh:116
decltype(Dune::Functions::istlVectorBackend(std::declval< FlagsType & >())) BackendType
Definition: utils/dirichletvalues.hh:51
DirichletValues(const Basis_ &p_basis)
Definition: utils/dirichletvalues.hh:52
void fixBoundaryDOFs(F &&f)
Function to fix (set boolean values to true or false) degrees of freedom on the boundary.
Definition: utils/dirichletvalues.hh:67
FlagsType_ FlagsType
Definition: utils/dirichletvalues.hh:49
std::remove_cvref_t< Basis_ > Basis
Definition: utils/dirichletvalues.hh:48
const auto & basis() const
Definition: utils/dirichletvalues.hh:104
void storeInhomogeneousBoundaryCondition(F &&f)
Function to insert a function for inhomogeneous Dirichlet boundary conditions.
Definition: utils/dirichletvalues.hh:134
bool isConstrained(const MultiIndex &multiIndex) const
Definition: utils/dirichletvalues.hh:108
static constexpr int worldDimension
Definition: utils/dirichletvalues.hh:50
void evaluateInhomogeneousBoundaryCondition(Eigen::VectorXd &xIh, const double &lambda)
Function to evaluate all stored inhomogeneous Dirichlet boundary functions.
Definition: utils/dirichletvalues.hh:152
bool isConstrained(std::size_t i) const
Definition: utils/dirichletvalues.hh:113
void fixDOFs(F &&f)
Function to fix (set boolean values to true or false) degrees of freedom.
Definition: utils/dirichletvalues.hh:92
void evaluateInhomogeneousBoundaryConditionDerivative(Eigen::VectorXd &xIh, const double &lambda)
Function to evaluate all stored inhomogeneous Dirichlet boundary derivative functions.
Definition: utils/dirichletvalues.hh:173
auto size() const
Definition: utils/dirichletvalues.hh:119
auto & container() const
Definition: utils/dirichletvalues.hh:122
void fixIthDOF(typename Basis::MultiIndex i)
Function to fix (set boolean values to true or false) of degrees of freedom.
Definition: utils/dirichletvalues.hh:101
Concept defining the requirements for functors with arguments.
Definition: concepts.hh:369