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 {
29template <typename LV>
31 const LV& localView,
32 std::vector<Dune::FieldVector<double, LV::Element::Geometry::coorddimension>>& lagrangeNodeGlobalCoords) {
33 auto fT = [&]([[maybe_unused]] int nodeNumber,
35 lagrangeNodeGlobalCoords.emplace_back(localView.element().geometry().global(localCoordinate));
36 return false;
37 };
38 forEachLagrangeNodePosition(localView, fT);
39}
40
60template <int worldDim, typename Basis, Dune::FloatCmp::CmpStyle cmpStyle = Dune::FloatCmp::CmpStyle::absolute>
62 constexpr double tol = 1e-8;
63 using LocalView = std::remove_cvref_t<decltype(basis.localView())>;
64 using MultiIndex = typename LocalView::MultiIndex;
65 using Element = typename LocalView::Element;
66 using Tree = LocalView::Tree;
67 static constexpr bool isScalar = Tree::isLeaf;
68 static constexpr bool isPower = Tree::isPower;
69
70 if constexpr (Tree::isComposite) {
71 Dune::Hybrid::forEach(
72 Dune::Hybrid::integralRange(Dune::index_constant<std::tuple_size_v<typename Basis::PreBasis::SubPreBases>>()),
73 [&](const auto i) {
74 static_assert(
75 not Tree::template Child<i>::Type::isComposite,
76 "globalIndexFromGlobalPosition is not implemented to handle a composite basis within a composite basis.");
77 });
78 }
79
80 static constexpr std::size_t numChildren = Impl::PreBasisInfo<Tree>::size;
81 constexpr int myDim = Element::mydimension;
82 Dune::HierarchicSearch hSearch(basis.gridView().grid(), basis.gridView().indexSet());
83 std::conditional_t<isScalar, std::optional<MultiIndex>, std::optional<std::array<MultiIndex, numChildren>>>
85 const auto& ele = hSearch.findEntity(pos);
86 auto localView = basis.localView();
87 localView.bind(ele);
88 const auto geo = localView.element().geometry();
89 const auto& node = [&]() {
90 if constexpr (isScalar or isPower)
91 return localView.tree();
92 else
93 return localView.tree().template child<0>();
94 }();
95
96 Impl::checkLagrangeNode<isScalar>(node);
97
98 auto fT = [&](int nodeNumber, Dune::FieldVector<double, myDim>&& localCoordinate) {
99 if (Dune::FloatCmp::eq<Dune::FieldVector<double, worldDim>, cmpStyle>(geo.global(localCoordinate), pos, tol)) {
100 globalIndices.emplace();
101 if constexpr (isScalar)
102 globalIndices.value() = localView.index(node.localIndex(nodeNumber));
103 else {
104 for (int j = 0; j < numChildren; j++)
105 globalIndices.value()[j] = localView.index(node.child(j).localIndex(nodeNumber));
106 }
107 return true;
108 }
109 return false;
110 };
111 forEachLagrangeNodePosition(localView, fT);
112 if (not globalIndices.has_value())
113 DUNE_THROW(Dune::InvalidStateException, "No Lagrange node found at the given position in the grid.");
114 return globalIndices.value();
115}
116
125template <typename FE>
127 constexpr int dim = FE::Traits::mydim;
128 const auto& element = fe.gridElement();
129 const auto& referenceElement = Dune::referenceElement<double, dim>(element.type());
130 const int numberOfVertices = referenceElement.size(codim);
131
132 auto getPosition = [=](const int i) { return referenceElement.position(i, codim); };
133 return std::views::transform(std::views::iota(0, numberOfVertices), getPosition);
134}
135
143template <typename FE>
146}
147
155template <typename T>
156decltype(auto) maybeDeref(T& t) {
158 return *t;
159 else
160 return t;
161}
162
168template <typename A>
169requires(std::is_pointer_v<std::remove_cvref_t<A>> || traits::isSharedPtr<std::remove_cvref_t<A>>::value)
170auto obtainForcesDueToIDBC(const A& assembler) {
171 const auto& K = assembler->matrix(DBCOption::Raw);
172 auto& dv = assembler->dirichletValues();
173 auto newInc = Eigen::VectorXd::Zero(dv.size()).eval();
174 dv.evaluateInhomogeneousBoundaryConditionDerivative(newInc, 1.0);
175
176 Eigen::VectorXd F_dirichlet;
177 F_dirichlet = K * newInc;
178
179 if (assembler->dBCOption() == DBCOption::Full)
180 assembler->dirichletValues().setZeroAtConstrainedDofs(F_dirichlet);
181 else
182 F_dirichlet = assembler->createReducedVector(F_dirichlet);
183 return F_dirichlet;
184}
185
186} // namespace Ikarus::utils
Implementation of creating a flat basis from a possibly blocked basis.
Contains functions to traverse through a tree to its different nodes.
auto referenceElementSubEntityPositions(FE &fe, int codim)
A function to obtain the local coordinates of subentities of an FiniteElement.
Definition: functionhelper.hh:126
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:61
auto referenceElementVertexPositions(FE &fe)
A function to obtain the local coordinates the vertices of an FiniteElement.
Definition: functionhelper.hh:144
void obtainLagrangeGlobalNodePositions(const LV &localView, std::vector< Dune::FieldVector< double, LV::Element::Geometry::coorddimension > > &lagrangeNodeGlobalCoords)
A function to obtain the global positions of the nodes of an element with Lagrangian basis.
Definition: functionhelper.hh:30
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:170
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:156
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.