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#include <dune/functions/functionspacebases/flatmultiindex.hh>
22#include <dune/functions/functionspacebases/subspacebasis.hh>
23
24#include <Eigen/Core>
25
26#include <autodiff/forward/real/real.hpp>
27
29
30namespace Dune {
31template <class K, int N>
33}
34
35namespace Ikarus {
36
40template <class>
42
43template <Concepts::EigenVector T>
45{
46 using SizeType = Eigen::Index;
47};
48
49template <>
50struct DeriveSizeType<std::vector<bool>>
51{
52 using SizeType = std::vector<bool>::size_type;
53};
54
65template <typename B, typename FC = std::vector<bool>>
67{
68public:
69 using Basis = std::remove_cvref_t<B>;
70 using FlagsType = FC;
71 static constexpr int worldDimension = Basis::GridView::dimensionworld;
72 using BackendType = decltype(Dune::Functions::istlVectorBackend(std::declval<FlagsType&>()));
74 explicit DirichletValues(const B& basis)
75 : basis_{basis},
76 dirichletFlagsBackend_{dirichletFlags_} {
77 dirichletFlagsBackend_.resize(basis_);
78 std::fill(dirichletFlags_.begin(), dirichletFlags_.end(), false);
79 inhomogeneousBoundaryVectorDummy_.setZero(static_cast<Eigen::Index>(basis_.size()));
80 }
81
91 template <typename F, typename TreePath = Dune::TypeTree::HybridTreePath<>>
92 void fixBoundaryDOFs(F&& f, TreePath&& treePath = {}) {
93 using namespace Dune::Functions;
94 using SubSpaceLocalView =
95 typename std::remove_cvref_t<decltype(subspaceBasis(basis_, std::forward<TreePath>(treePath)))>::LocalView;
96
98 auto lambda = [&](auto&& indexGlobal) { f(dirichletFlagsBackend_, indexGlobal); };
99 Dune::Functions::forEachBoundaryDOF(subspaceBasis(basis_, std::forward<TreePath>(treePath)), lambda);
100 } else if constexpr (Concepts::IsFunctorWithArgs<F, BackendType, int, SubSpaceLocalView>) {
101 auto lambda = [&](auto&& localIndex, auto&& localView) { f(dirichletFlagsBackend_, localIndex, localView); };
102 Dune::Functions::forEachBoundaryDOF(subspaceBasis(basis_, std::forward<TreePath>(treePath)), lambda);
103 } else if constexpr (Concepts::IsFunctorWithArgs<F, BackendType, int, SubSpaceLocalView,
104 typename Basis::GridView::Intersection>) {
105 auto lambda = [&](auto&& localIndex, auto&& localView, auto&& intersection) {
106 f(dirichletFlagsBackend_, localIndex, localView, intersection);
107 };
108 Dune::Functions::forEachBoundaryDOF(subspaceBasis(basis_, std::forward<TreePath>(treePath)), lambda);
109 } else {
110 static_assert(Dune::AlwaysFalse<F>(), "fixBoundaryDOFs: A function with this signature is not supported");
111 }
112 }
113
122 template <typename F>
123 void fixDOFs(F&& f) {
124 f(basis_, dirichletFlagsBackend_);
125 }
126
133 template <typename MultiIndex>
134 requires(not std::integral<MultiIndex>)
135 void setSingleDOF(const MultiIndex i, bool flag) {
136 dirichletFlagsBackend_[i] = flag;
137 }
138
146 void setSingleDOF(std::size_t i, bool flag)
147 requires(std::same_as<typename Basis::MultiIndex, Dune::Functions::FlatMultiIndex<size_t>>)
148 {
149 dirichletFlags_[i] = flag;
150 }
151
155 void reset() {
156 std::fill(dirichletFlags_.begin(), dirichletFlags_.end(), false);
157 inhomogeneousBoundaryVectorDummy_.setZero(static_cast<Eigen::Index>(basis_.size()));
158 }
159
160 /* \brief Returns the local basis object */
161 const auto& basis() const { return basis_; }
162
163 /* \brief Returns a boolean values, if the give multiIndex is constrained */
164 template <typename MultiIndex>
165 requires(not std::integral<MultiIndex>)
166 [[nodiscard]] bool isConstrained(const MultiIndex& multiIndex) const {
167 return dirichletFlagsBackend_[multiIndex];
168 }
169
170 /* \brief Returns a boolean values, if the i-th degree of freedom is constrained */
171 [[nodiscard]] bool isConstrained(std::size_t i) const
172 requires(std::same_as<typename Basis::MultiIndex, Dune::Functions::FlatMultiIndex<size_t>>)
173 {
174 return dirichletFlags_[i];
175 }
176
177 /* \brief Returns how many degrees of freedoms are fixed */
178 auto fixedDOFsize() const { return std::ranges::count(dirichletFlags_, true); }
179
180 /* \brief Returns how many degrees of freedom there are */
181 auto size() const { return dirichletFlags_.size(); }
182
183 /* \brief Returns the underlying dof flag container */
184 auto& container() const { return dirichletFlags_; }
185
195 template <typename F>
197 auto derivativeLambda = [&](const auto& globalCoord, const double& lambda) {
198 autodiff::real lambdaDual = lambda;
199 lambdaDual[1] = 1; // Setting the derivative in lambda direction to 1
200 return derivative(f(globalCoord, lambdaDual));
201 };
202 dirichletFunctions_.push_back({f, derivativeLambda});
203 }
204
214 void evaluateInhomogeneousBoundaryCondition(Eigen::VectorXd& xIh, const double& lambda) {
215 inhomogeneousBoundaryVectorDummy_.setZero();
216 xIh.resizeLike(inhomogeneousBoundaryVectorDummy_);
217 xIh.setZero();
218 for (auto& f : dirichletFunctions_) {
219 interpolate(
220 basis_, inhomogeneousBoundaryVectorDummy_,
221 [&](const auto& globalCoord) { return f.value(globalCoord, lambda); }, dirichletFlagsBackend_);
222 xIh += inhomogeneousBoundaryVectorDummy_;
223 }
224 }
225
235 void evaluateInhomogeneousBoundaryConditionDerivative(Eigen::VectorXd& xIh, const double& lambda) {
236 inhomogeneousBoundaryVectorDummy_.setZero();
237 xIh.resizeLike(inhomogeneousBoundaryVectorDummy_);
238 xIh.setZero();
239 for (auto& f : dirichletFunctions_) {
240 interpolate(
241 basis_, inhomogeneousBoundaryVectorDummy_,
242 [&](const auto& globalCoord) { return f.derivative(globalCoord, lambda); }, dirichletFlagsBackend_);
243 xIh += inhomogeneousBoundaryVectorDummy_;
244 }
245 }
246
247private:
248 Eigen::VectorXd inhomogeneousBoundaryVectorDummy_;
249 Basis basis_;
250 FlagsType dirichletFlags_;
251 BackendType dirichletFlagsBackend_;
252 struct DirichletFunctions
253 {
254 using Signature = std::function<Eigen::Vector<double, worldDimension>(
255 const Dune::FieldVector<double, worldDimension>&, const double&)>;
256 Signature value;
257 Signature derivative;
258 };
259 std::vector<DirichletFunctions> dirichletFunctions_;
260};
261
262} // namespace Ikarus
Several concepts.
STL namespace.
Definition: assemblermanipulatorbuildingblocks.hh:22
Definition: utils/dirichletvalues.hh:30
Definition: utils/dirichletvalues.hh:32
A helper struct to derive the SizeType of the underlying container.
Definition: utils/dirichletvalues.hh:41
Eigen::Index SizeType
Definition: utils/dirichletvalues.hh:46
std::vector< bool >::size_type SizeType
Definition: utils/dirichletvalues.hh:52
Class for handling Dirichlet boundary conditions in Ikarus.
Definition: utils/dirichletvalues.hh:67
auto size() const
Definition: utils/dirichletvalues.hh:181
void setSingleDOF(const MultiIndex i, bool flag)
Fixes and unfixes (set boolean value to true or false) a specific degree of freedom.
Definition: utils/dirichletvalues.hh:135
bool isConstrained(const MultiIndex &multiIndex) const
Definition: utils/dirichletvalues.hh:166
bool isConstrained(std::size_t i) const
Definition: utils/dirichletvalues.hh:171
void setSingleDOF(std::size_t i, bool flag)
Fixes or unfixes (set boolean value to true or false) a specific degree of freedom.
Definition: utils/dirichletvalues.hh:146
std::remove_cvref_t< B > Basis
Definition: utils/dirichletvalues.hh:69
void fixBoundaryDOFs(F &&f, TreePath &&treePath={})
Function to fix (set boolean values to true or false) degrees of freedom on the boundary.
Definition: utils/dirichletvalues.hh:92
decltype(Dune::Functions::istlVectorBackend(std::declval< FlagsType & >())) BackendType
Definition: utils/dirichletvalues.hh:72
void evaluateInhomogeneousBoundaryConditionDerivative(Eigen::VectorXd &xIh, const double &lambda)
Function to evaluate all stored inhomogeneous Dirichlet boundary derivative functions.
Definition: utils/dirichletvalues.hh:235
static constexpr int worldDimension
Definition: utils/dirichletvalues.hh:71
void fixDOFs(F &&f)
Function to fix (set boolean values to true or false) degrees of freedom.
Definition: utils/dirichletvalues.hh:123
FC FlagsType
Definition: utils/dirichletvalues.hh:70
void reset()
Resets all degrees of freedom.
Definition: utils/dirichletvalues.hh:155
void storeInhomogeneousBoundaryCondition(F &&f)
Function to insert a function for inhomogeneous Dirichlet boundary conditions.
Definition: utils/dirichletvalues.hh:196
void evaluateInhomogeneousBoundaryCondition(Eigen::VectorXd &xIh, const double &lambda)
Function to evaluate all stored inhomogeneous Dirichlet boundary functions.
Definition: utils/dirichletvalues.hh:214
typename DeriveSizeType< FlagsType >::SizeType SizeType
Definition: utils/dirichletvalues.hh:73
const auto & basis() const
Definition: utils/dirichletvalues.hh:161
auto fixedDOFsize() const
Definition: utils/dirichletvalues.hh:178
DirichletValues(const B &basis)
Definition: utils/dirichletvalues.hh:74
auto & container() const
Definition: utils/dirichletvalues.hh:184
Concept defining the requirements for functors with arguments.
Definition: concepts.hh:347