19#include <dune/common/float_cmp.hh>
20#include <dune/common/hybridutilities.hh>
21#include <dune/common/indices.hh>
22#include <dune/functions/backends/istlvectorbackend.hh>
23#include <dune/functions/functionspacebases/boundarydofs.hh>
24#include <dune/functions/functionspacebases/compositebasis.hh>
25#include <dune/functions/functionspacebases/flatmultiindex.hh>
26#include <dune/functions/functionspacebases/interpolate.hh>
27#include <dune/functions/functionspacebases/subspacebasis.hh>
31#include <autodiff/forward/real/real.hpp>
36template <
class K,
int N>
48template <Concepts::EigenVector T>
61 template <
typename Tree>
66 template <
typename Tree>
67 requires(Tree::isLeaf)
68 struct PreBasisInfo<Tree>
70 static constexpr std::size_t size = 0;
71 using NodalSolutionType = double;
74 template <
typename Tree>
75 requires(Tree::isPower)
76 struct PreBasisInfo<Tree>
78 static constexpr std::size_t size = Tree::degree();
79 using NodalSolutionType = Eigen::Vector<double, size>;
82 template <
typename Tree>
83 requires(Tree::isComposite)
84 struct PreBasisInfo<Tree>
86 using ChildTreeType = Tree::template Child<0>::Type;
87 static_assert(not ChildTreeType::isComposite,
88 "DirichletValues is not implemented to handle a composite basis within a composite basis.");
90 static constexpr std::size_t size = PreBasisInfo<ChildTreeType>::size;
91 using NodalSolutionType = PreBasisInfo<ChildTreeType>::NodalSolutionType;
107template <
typename B,
typename FC = std::vector<
bool>>
111 using Basis = std::remove_cvref_t<B>;
113 using BackendType =
decltype(Dune::Functions::istlVectorBackend(std::declval<FlagsType&>()));
122 dirichletFlagsBackend_{dirichletFlags_} {
123 dirichletFlagsBackend_.resize(basis_);
124 std::fill(dirichletFlags_.begin(), dirichletFlags_.end(),
false);
125 if constexpr (Tree::isComposite) {
126 Dune::Hybrid::forEach(
127 Dune::Hybrid::integralRange(Dune::index_constant<std::tuple_size_v<typename Basis::PreBasis::SubPreBases>>()),
129 static_assert(not Tree::template Child<i>::Type::isComposite,
130 "DirichletValues is not implemented to handle a composite basis within a composite basis.");
144 template <
typename F,
typename TreePath = Dune::TypeTree::Hybr
idTreePath<>>
146 using namespace Dune::Functions;
147 using SubSpaceLocalView =
148 typename std::remove_cvref_t<decltype(subspaceBasis(basis_, std::forward<TreePath>(treePath)))>
::LocalView;
151 auto lambda = [&](
auto&& indexGlobal) { f(dirichletFlagsBackend_, indexGlobal); };
152 Dune::Functions::forEachBoundaryDOF(subspaceBasis(basis_, std::forward<TreePath>(treePath)), lambda);
153 }
else if constexpr (Concepts::IsFunctorWithArgs<F, BackendType, int, SubSpaceLocalView>) {
154 auto lambda = [&](
auto&& localIndex,
auto&& localView) { f(dirichletFlagsBackend_, localIndex, localView); };
155 Dune::Functions::forEachBoundaryDOF(subspaceBasis(basis_, std::forward<TreePath>(treePath)), lambda);
156 }
else if constexpr (Concepts::IsFunctorWithArgs<F,
BackendType, int, SubSpaceLocalView,
157 typename Basis::GridView::Intersection>) {
158 auto lambda = [&](
auto&& localIndex,
auto&& localView,
auto&& intersection) {
159 f(dirichletFlagsBackend_, localIndex, localView, intersection);
161 Dune::Functions::forEachBoundaryDOF(subspaceBasis(basis_, std::forward<TreePath>(treePath)), lambda);
163 static_assert(Dune::AlwaysFalse<F>(),
"fixBoundaryDOFs: A function with this signature is not supported");
175 template <
typename F>
177 f(basis_, dirichletFlagsBackend_);
186 template <
typename MultiIndex>
187 requires(not std::integral<MultiIndex>)
189 dirichletFlagsBackend_[i] = flag;
200 requires(std::same_as<typename Basis::MultiIndex, Dune::Functions::FlatMultiIndex<size_t>>)
202 dirichletFlags_[i] = flag;
208 void reset() { std::fill(dirichletFlags_.begin(), dirichletFlags_.end(),
false); }
211 const auto&
basis()
const {
return basis_; }
214 template <
typename MultiIndex>
215 requires(not std::integral<MultiIndex>)
217 return dirichletFlagsBackend_[multiIndex];
222 requires(std::same_as<typename Basis::MultiIndex, Dune::Functions::FlatMultiIndex<size_t>>)
224 return dirichletFlags_[i];
228 auto fixedDOFsize()
const {
return std::ranges::count(dirichletFlags_,
true); }
231 auto size()
const {
return dirichletFlags_.size(); }
247 template <
typename F>
249 auto derivativeLambda = [&](
const auto& globalCoord,
const double& lambda) {
250 autodiff::real lambdaDual = lambda;
252 return derivative(f(globalCoord, lambdaDual));
254 dirichletFunctions_.push_back({f, derivativeLambda});
255 setInhomogeneousBoundaryConditionFlag(lambda);
264 for (Eigen::Index i = 0; i < xIh.size(); ++i)
279 Eigen::VectorXd inhomogeneousBoundaryVectorDummy;
280 inhomogeneousBoundaryVectorDummy.setZero(this->
size());
281 xIh.resizeLike(inhomogeneousBoundaryVectorDummy);
283 auto runInterpolateImpl = [&](
const auto&
basis) {
284 for (
auto& f : dirichletFunctions_) {
285 interpolate(
basis, inhomogeneousBoundaryVectorDummy,
286 [&](
const auto& globalCoord) {
return f.value(globalCoord, lambda); });
287 xIh += inhomogeneousBoundaryVectorDummy;
290 runInterpolate(runInterpolateImpl);
303 Eigen::VectorXd inhomogeneousBoundaryVectorDummy;
304 inhomogeneousBoundaryVectorDummy.setZero(this->
size());
305 xIh.resizeLike(inhomogeneousBoundaryVectorDummy);
307 auto runInterpolateImpl = [&](
const auto&
basis) {
308 for (
auto& f : dirichletFunctions_) {
309 interpolate(
basis, inhomogeneousBoundaryVectorDummy,
310 [&](
const auto& globalCoord) {
return f.derivative(globalCoord, lambda); });
311 xIh += inhomogeneousBoundaryVectorDummy;
314 runInterpolate(runInterpolateImpl);
321 struct DirichletFunctions
325 Signature derivative;
327 std::vector<DirichletFunctions> dirichletFunctions_;
329 void setInhomogeneousBoundaryConditionFlag(
double lambda) {
330 Eigen::VectorXd inhomogeneousBoundaryVectorDummy;
331 inhomogeneousBoundaryVectorDummy.setZero(this->
size());
333 for (
const std::size_t i : Dune::range(this->
size()))
334 if (Dune::FloatCmp::ne(inhomogeneousBoundaryVectorDummy[i], 0.0))
338 template <
typename F>
339 void runInterpolate(F&& f)
const {
340 if constexpr (Tree::isComposite)
341 f(subspaceBasis(basis_, Dune::Indices::_0));
Definition: assemblermanipulatorbuildingblocks.hh:22
Definition: utils/dirichletvalues.hh:35
Definition: utils/dirichletvalues.hh:37
A helper struct to derive the SizeType of the underlying container.
Definition: utils/dirichletvalues.hh:46
Eigen::Index SizeType
Definition: utils/dirichletvalues.hh:51
std::vector< bool >::size_type SizeType
Definition: utils/dirichletvalues.hh:57
Class for handling Dirichlet boundary conditions in Ikarus.
Definition: utils/dirichletvalues.hh:109
auto size() const
Definition: utils/dirichletvalues.hh:231
void setZeroAtConstrainedDofs(Eigen::VectorXd &xIh) const
Function to write zeros at constrained Dirichlet entries.
Definition: utils/dirichletvalues.hh:263
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:188
bool isConstrained(const MultiIndex &multiIndex) const
Definition: utils/dirichletvalues.hh:216
bool isConstrained(std::size_t i) const
Definition: utils/dirichletvalues.hh:221
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:199
std::remove_cvref_t< B > Basis
Definition: utils/dirichletvalues.hh:111
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:145
decltype(Dune::Functions::istlVectorBackend(std::declval< FlagsType & >())) BackendType
Definition: utils/dirichletvalues.hh:113
void evaluateInhomogeneousBoundaryConditionDerivative(Eigen::VectorXd &xIh, const double &lambda) const
Function to evaluate all stored inhomogeneous Dirichlet boundary derivative functions.
Definition: utils/dirichletvalues.hh:302
void storeInhomogeneousBoundaryCondition(F &&f, double lambda=1.0)
Function to insert a function for inhomogeneous Dirichlet boundary conditions.
Definition: utils/dirichletvalues.hh:248
LocalView::Tree Tree
Definition: utils/dirichletvalues.hh:117
static constexpr int worldDimension
Definition: utils/dirichletvalues.hh:115
void fixDOFs(F &&f)
Function to fix (set boolean values to true or false) degrees of freedom.
Definition: utils/dirichletvalues.hh:176
FC FlagsType
Definition: utils/dirichletvalues.hh:112
void evaluateInhomogeneousBoundaryCondition(Eigen::VectorXd &xIh, const double &lambda) const
Function to evaluate all stored inhomogeneous Dirichlet boundary functions.
Definition: utils/dirichletvalues.hh:278
Basis::LocalView LocalView
Definition: utils/dirichletvalues.hh:116
void reset()
Resets all degrees of freedom.
Definition: utils/dirichletvalues.hh:208
typename DeriveSizeType< FlagsType >::SizeType SizeType
Definition: utils/dirichletvalues.hh:114
const auto & basis() const
Definition: utils/dirichletvalues.hh:211
auto fixedDOFsize() const
Definition: utils/dirichletvalues.hh:228
DirichletValues(const B &basis)
Definition: utils/dirichletvalues.hh:120
static constexpr std::size_t numberOfChildrenAtNode
Definition: utils/dirichletvalues.hh:119
auto & container() const
Definition: utils/dirichletvalues.hh:234
typename Impl::PreBasisInfo< Tree >::NodalSolutionType NodalSolutionType
Definition: utils/dirichletvalues.hh:118
Concept defining the requirements for functors with arguments.
Definition: utils/concepts.hh:357