version 0.4.7
functionhelper.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2026 The Ikarus Developers ikarus@ibb.uni-stuttgart.de
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
9#pragma once
10
11#include <ranges>
12
13#include <dune/common/float_cmp.hh>
14#include <dune/grid/utility/hierarchicsearch.hh>
15
19
20namespace Ikarus::utils {
30template <int size, typename LV>
31void obtainLagrangeGlobalNodePositions(const LV& localView,
32 std::vector<Dune::FieldVector<double, size>>& lagrangeNodeGlobalCoords) {
33 auto fT = [&]([[maybe_unused]] int nodeNumber, Dune::FieldVector<double, size>&& localCoordinate) {
34 lagrangeNodeGlobalCoords.emplace_back(localView.element().geometry().global(localCoordinate));
35 return false;
36 };
37 forEachLagrangeNodePosition(localView, fT);
38}
39
59template <int worldDim, typename Basis, Dune::FloatCmp::CmpStyle cmpStyle = Dune::FloatCmp::CmpStyle::absolute>
61 constexpr double tol = 1e-8;
62 using LocalView = std::remove_cvref_t<decltype(basis.localView())>;
63 using MultiIndex = typename LocalView::MultiIndex;
64 using Element = typename LocalView::Element;
65 using Tree = LocalView::Tree;
66 static constexpr bool isScalar = Tree::isLeaf;
67 static constexpr bool isPower = Tree::isPower;
68
69 if constexpr (Tree::isComposite) {
70 Dune::Hybrid::forEach(
71 Dune::Hybrid::integralRange(Dune::index_constant<std::tuple_size_v<typename Basis::PreBasis::SubPreBases>>()),
72 [&](const auto i) {
73 static_assert(
74 not Tree::template Child<i>::Type::isComposite,
75 "globalIndexFromGlobalPosition is not implemented to handle a composite basis within a composite basis.");
76 });
77 }
78
79 static constexpr std::size_t numChildren = Impl::PreBasisInfo<Tree>::size;
80 constexpr int myDim = Element::mydimension;
81 Dune::HierarchicSearch hSearch(basis.gridView().grid(), basis.gridView().indexSet());
82 std::conditional_t<isScalar, std::optional<MultiIndex>, std::optional<std::array<MultiIndex, numChildren>>>
84 const auto& ele = hSearch.findEntity(pos);
85 auto localView = basis.localView();
86 localView.bind(ele);
87 const auto geo = localView.element().geometry();
88 const auto& node = [&]() {
89 if constexpr (isScalar or isPower)
90 return localView.tree();
91 else
92 return localView.tree().template child<0>();
93 }();
94
95 Impl::checkLagrangeNode<isScalar>(node);
96
97 auto fT = [&](int nodeNumber, Dune::FieldVector<double, myDim>&& localCoordinate) {
98 if (Dune::FloatCmp::eq<Dune::FieldVector<double, worldDim>, cmpStyle>(geo.global(localCoordinate), pos, tol)) {
99 globalIndices.emplace();
100 if constexpr (isScalar)
101 globalIndices.value() = localView.index(node.localIndex(nodeNumber));
102 else {
103 for (int j = 0; j < numChildren; j++)
104 globalIndices.value()[j] = localView.index(node.child(j).localIndex(nodeNumber));
105 }
106 return true;
107 }
108 return false;
109 };
110 forEachLagrangeNodePosition(localView, fT);
111 if (not globalIndices.has_value())
112 DUNE_THROW(Dune::InvalidStateException, "No Lagrange node found at the given position in the grid.");
113 return globalIndices.value();
114}
115
124template <typename FE>
126 constexpr int dim = FE::Traits::mydim;
127 const auto& element = fe.gridElement();
128 const auto& referenceElement = Dune::referenceElement<double, dim>(element.type());
129 const int numberOfVertices = referenceElement.size(codim);
130
131 auto getPosition = [=](const int i) { return referenceElement.position(i, codim); };
132 return std::views::transform(std::views::iota(0, numberOfVertices), getPosition);
133}
134
142template <typename FE>
145}
146
154template <typename T>
155decltype(auto) maybeDeref(T& t) {
157 return *t;
158 else
159 return t;
160}
161
167template <typename A>
168requires(std::is_pointer_v<std::remove_cvref_t<A>> || traits::isSharedPtr<std::remove_cvref_t<A>>::value)
169auto obtainForcesDueToIDBC(const A& assembler) {
170 const auto& K = assembler->matrix(DBCOption::Raw);
171 auto& dv = assembler->dirichletValues();
172 auto newInc = Eigen::VectorXd::Zero(dv.size()).eval();
173 dv.evaluateInhomogeneousBoundaryConditionDerivative(newInc, 1.0);
174
175 Eigen::VectorXd F_dirichlet;
176 F_dirichlet = K * newInc;
177
178 if (assembler->dBCOption() == DBCOption::Full)
179 assembler->dirichletValues().setZeroAtConstrainedDofs(F_dirichlet);
180 else
181 F_dirichlet = assembler->createReducedVector(F_dirichlet);
182 return F_dirichlet;
183}
184
185} // namespace Ikarus::utils
Contains functions to traverse through a tree to its different nodes.
Implementation of creating a flat basis from a possibly blocked basis.
auto referenceElementSubEntityPositions(FE &fe, int codim)
A function to obtain the local coordinates of subentities of an FiniteElement.
Definition: functionhelper.hh:125
auto globalIndexFromGlobalPosition(const Basis &basis, const Dune::FieldVector< double, worldDim > &pos)
A helper function to obtain the global index from the global positions for a Lagrange node.
Definition: functionhelper.hh:60
auto referenceElementVertexPositions(FE &fe)
A function to obtain the local coordinates the vertices of an FiniteElement.
Definition: functionhelper.hh:143
void obtainLagrangeGlobalNodePositions(const LV &localView, std::vector< Dune::FieldVector< double, size > > &lagrangeNodeGlobalCoords)
A function to obtain the global positions of the nodes of an element with Lagrangian basis.
Definition: functionhelper.hh:31
void globalIndices(const FiniteElement &fe, std::vector< typename FiniteElement::LocalView::MultiIndex > &globalIndices)
Get the global indices for the provided finite element.
Definition: fehelper.hh:195
Definition: algorithms.hh:17
auto obtainForcesDueToIDBC(const A &assembler)
A helper function to compute the forces due to inhomogeneous Dirichlet BCs.
Definition: functionhelper.hh:169
void forEachLagrangeNodePosition(const LV &localView, F &&f)
A helper function that helps in traversing over the local coordinates of an element and call a user-d...
Definition: traversal.hh:77
decltype(auto) maybeDeref(T &t)
if T is a pointer type, return the dereferenced value, otherwise return the value itself.
Definition: functionhelper.hh:155
def basis(gv, tree)
Definition: basis.py:10
FE class is a base class for all finite elements.
Definition: febase.hh:79
const GridElement & gridElement() const
Get the grid element associated with the local view.
Definition: febase.hh:145
static constexpr int mydim
Dimension of the geometry.
Definition: fetraits.hh:63
Definition: utils/dirichletvalues.hh:38
Type trait to check if a type is a isSharedPtr.
Definition: traits.hh:136
Definition: utils/concepts.hh:641
Several concepts.