version 0.4.1
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 {
29template <class K, int N>
31}
32
33namespace Ikarus {
34
45template <typename B, typename FC = std::vector<bool>>
47{
48public:
49 using Basis = std::remove_cvref_t<B>;
50 using FlagsType = FC;
51 static constexpr int worldDimension = Basis::GridView::dimensionworld;
52 using BackendType = decltype(Dune::Functions::istlVectorBackend(std::declval<FlagsType&>()));
53 explicit DirichletValues(const B& basis)
54 : basis_{basis},
55 dirichletFlagsBackend_{dirichletFlags_} {
56 dirichletFlagsBackend_.resize(basis_);
57 std::fill(dirichletFlags_.begin(), dirichletFlags_.end(), false);
58 inhomogeneousBoundaryVectorDummy_.setZero(static_cast<Eigen::Index>(basis_.size()));
59 }
60
69 template <typename F>
70 void fixBoundaryDOFs(F&& f) {
72 auto lambda = [&](auto&& indexGlobal) { f(dirichletFlagsBackend_, indexGlobal); };
73 Dune::Functions::forEachBoundaryDOF(basis_, lambda);
75 auto lambda = [&](auto&& localIndex, auto&& localView) { f(dirichletFlagsBackend_, localIndex, localView); };
76 Dune::Functions::forEachBoundaryDOF(basis_, lambda);
77 } else if constexpr (Concepts::IsFunctorWithArgs<F, BackendType, int, typename Basis::LocalView,
78 typename Basis::GridView::Intersection>) {
79 auto lambda = [&](auto&& localIndex, auto&& localView, auto&& intersection) {
80 f(dirichletFlagsBackend_, localIndex, localView, intersection);
81 };
82 Dune::Functions::forEachBoundaryDOF(basis_, lambda);
83 }
84 }
85
94 template <typename F>
95 void fixDOFs(F&& f) {
96 f(basis_, dirichletFlagsBackend_);
97 }
98
104 void fixIthDOF(typename Basis::MultiIndex i) { dirichletFlagsBackend_[i] = true; }
105
106 /* \brief Returns the local basis object */
107 const auto& basis() const { return basis_; }
108
109 /* \brief Returns a boolean values, if the give multiIndex is constrained */
110 template <typename MultiIndex>
111 requires(not std::integral<MultiIndex>)
112 [[nodiscard]] bool isConstrained(const MultiIndex& multiIndex) const {
113 return dirichletFlagsBackend_[multiIndex];
114 }
115
116 /* \brief Returns a boolean values, if the i-th degree of freedom is constrained */
117 [[nodiscard]] bool isConstrained(std::size_t i) const { return dirichletFlags_[i]; }
118
119 /* \brief Returns how many degrees of freedoms are fixed */
120 auto fixedDOFsize() const { return std::ranges::count(dirichletFlags_, true); }
121
122 /* \brief Returns how many degrees of freedom there are */
123 auto size() const { return dirichletFlags_.size(); }
124
125 /* \brief Returns the underlying dof flag container */
126 auto& container() const { return dirichletFlags_; }
127
137 template <typename F>
139 auto derivativeLambda = [&](const auto& globalCoord, const double& lambda) {
140 autodiff::real lambdaDual = lambda;
141 lambdaDual[1] = 1; // Setting the derivative in lambda direction to 1
142 return derivative(f(globalCoord, lambdaDual));
143 };
144 dirichletFunctions_.push_back({f, derivativeLambda});
145 }
146
156 void evaluateInhomogeneousBoundaryCondition(Eigen::VectorXd& xIh, const double& lambda) {
157 inhomogeneousBoundaryVectorDummy_.setZero();
158 xIh.resizeLike(inhomogeneousBoundaryVectorDummy_);
159 xIh.setZero();
160 for (auto& f : dirichletFunctions_) {
161 interpolate(
162 basis_, inhomogeneousBoundaryVectorDummy_,
163 [&](const auto& globalCoord) { return f.value(globalCoord, lambda); }, dirichletFlagsBackend_);
164 xIh += inhomogeneousBoundaryVectorDummy_;
165 }
166 }
167
177 void evaluateInhomogeneousBoundaryConditionDerivative(Eigen::VectorXd& xIh, const double& lambda) {
178 inhomogeneousBoundaryVectorDummy_.setZero();
179 xIh.resizeLike(inhomogeneousBoundaryVectorDummy_);
180 xIh.setZero();
181 for (auto& f : dirichletFunctions_) {
182 interpolate(
183 basis_, inhomogeneousBoundaryVectorDummy_,
184 [&](const auto& globalCoord) { return f.derivative(globalCoord, lambda); }, dirichletFlagsBackend_);
185 xIh += inhomogeneousBoundaryVectorDummy_;
186 }
187 }
188
189private:
190 Eigen::VectorXd inhomogeneousBoundaryVectorDummy_;
191 Basis basis_;
192 FlagsType dirichletFlags_;
193 BackendType dirichletFlagsBackend_;
194 struct DirichletFunctions
195 {
196 using Signature = std::function<Eigen::Vector<double, worldDimension>(
197 const Dune::FieldVector<double, worldDimension>&, const double&)>;
198 Signature value;
199 Signature derivative;
200 };
201 std::vector<DirichletFunctions> dirichletFunctions_;
202};
203
204} // namespace Ikarus
Several concepts.
Definition: simpleassemblers.hh:22
Definition: utils/dirichletvalues.hh:28
Definition: utils/dirichletvalues.hh:30
Class for handling Dirichlet boundary conditions in Ikarus.
Definition: utils/dirichletvalues.hh:47
auto size() const
Definition: utils/dirichletvalues.hh:123
bool isConstrained(const MultiIndex &multiIndex) const
Definition: utils/dirichletvalues.hh:112
std::remove_cvref_t< B > Basis
Definition: utils/dirichletvalues.hh:49
void fixIthDOF(typename Basis::MultiIndex i)
Function to fix (set boolean values to true or false) of degrees of freedom.
Definition: utils/dirichletvalues.hh:104
decltype(Dune::Functions::istlVectorBackend(std::declval< FlagsType & >())) BackendType
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:70
void evaluateInhomogeneousBoundaryConditionDerivative(Eigen::VectorXd &xIh, const double &lambda)
Function to evaluate all stored inhomogeneous Dirichlet boundary derivative functions.
Definition: utils/dirichletvalues.hh:177
static constexpr int worldDimension
Definition: utils/dirichletvalues.hh:51
bool isConstrained(std::size_t i) const
Definition: utils/dirichletvalues.hh:117
void fixDOFs(F &&f)
Function to fix (set boolean values to true or false) degrees of freedom.
Definition: utils/dirichletvalues.hh:95
FC FlagsType
Definition: utils/dirichletvalues.hh:50
void storeInhomogeneousBoundaryCondition(F &&f)
Function to insert a function for inhomogeneous Dirichlet boundary conditions.
Definition: utils/dirichletvalues.hh:138
void evaluateInhomogeneousBoundaryCondition(Eigen::VectorXd &xIh, const double &lambda)
Function to evaluate all stored inhomogeneous Dirichlet boundary functions.
Definition: utils/dirichletvalues.hh:156
const auto & basis() const
Definition: utils/dirichletvalues.hh:107
auto fixedDOFsize() const
Definition: utils/dirichletvalues.hh:120
DirichletValues(const B &basis)
Definition: utils/dirichletvalues.hh:53
auto & container() const
Definition: utils/dirichletvalues.hh:126
Concept defining the requirements for functors with arguments.
Definition: concepts.hh:343