version 0.4.4
functionhelper.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2025 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
18
19namespace Ikarus::utils {
29template <int size, typename LV>
30void obtainLagrangeGlobalNodePositions(const LV& localView,
31 std::vector<Dune::FieldVector<double, size>>& lagrangeNodeGlobalCoords) {
32 auto fT = [&]([[maybe_unused]] int nodeNumber, Dune::FieldVector<double, size>&& localCoordinate) {
33 lagrangeNodeGlobalCoords.emplace_back(localView.element().geometry().global(localCoordinate));
34 return false;
35 };
36 forEachLagrangeNodePosition(localView, fT);
37}
38
49template <int worldDim, typename Basis>
51 static_assert(Concepts::LagrangeNode<std::remove_cvref_t<decltype(basis.localView().tree().child(0))>>,
52 "globalIndexFromGlobalPosition is only supported for Lagrange basis");
53 constexpr double tol = 1e-8;
54 using LocalView = std::remove_cvref_t<decltype(basis.localView())>;
55 using MultiIndex = typename LocalView::MultiIndex;
56 using Element = typename LocalView::Element;
57 constexpr int myDim = Element::mydimension;
58 Dune::HierarchicSearch hSearch(basis.gridView().grid(), basis.gridView().indexSet());
59 const auto& ele = hSearch.findEntity(pos);
60 auto localView = basis.localView();
61 localView.bind(ele);
62 const auto geo = localView.element().geometry();
63 const auto& node = localView.tree();
64 std::optional<std::array<MultiIndex, worldDim>> globalIndices;
65
66 auto fT = [&](int nodeNumber, Dune::FieldVector<double, myDim>&& localCoordinate) {
67 if (Dune::FloatCmp::eq(geo.global(localCoordinate), pos, tol)) {
68 globalIndices.emplace();
69 for (int j = 0; j < worldDim; j++)
70 globalIndices.value()[j] = localView.index(node.child(j).localIndex(nodeNumber));
71 return true;
72 }
73 return false;
74 };
75 forEachLagrangeNodePosition(localView, fT);
76 if (not globalIndices.has_value())
77 DUNE_THROW(Dune::InvalidStateException, "No Lagrange node found at the given position in the grid.");
78 return globalIndices.value();
79}
80
89template <typename FE>
91 constexpr int dim = FE::Traits::mydim;
92 const auto& element = fe.gridElement();
93 const auto& referenceElement = Dune::referenceElement<double, dim>(element.type());
94 const int numberOfVertices = referenceElement.size(codim);
95
96 auto getPosition = [=](const int i) { return referenceElement.position(i, codim); };
97 return std::views::transform(std::views::iota(0, numberOfVertices), getPosition);
98}
99
107template <typename FE>
110}
111
119template <typename T>
120decltype(auto) maybeDeref(T& t) {
122 return *t;
123 else
124 return t;
125}
126
132template <typename A>
133requires(std::is_pointer_v<std::remove_cvref_t<A>> || traits::isSharedPtr<std::remove_cvref_t<A>>::value)
134auto obtainForcesDueToIDBC(const A& assembler) {
135 const auto& K = assembler->matrix(DBCOption::Raw);
136 auto& dv = assembler->dirichletValues();
137 auto newInc = Eigen::VectorXd::Zero(dv.size()).eval();
138 dv.evaluateInhomogeneousBoundaryConditionDerivative(newInc, 1.0);
139
140 Eigen::VectorXd F_dirichlet;
141 F_dirichlet = K * newInc;
142
143 if (assembler->dBCOption() == DBCOption::Full)
144 assembler->dirichletValues().setZeroAtConstrainedDofs(F_dirichlet);
145 else
146 F_dirichlet = assembler->createReducedVector(F_dirichlet);
147 return F_dirichlet;
148}
149
150} // namespace Ikarus::utils
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:90
auto referenceElementVertexPositions(FE &fe)
A function to obtain the local coordinates the vertices of an FiniteElement.
Definition: functionhelper.hh:108
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:50
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: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:127
Definition: algorithms.hh:17
auto obtainForcesDueToIDBC(const A &assembler)
A helper function to compute the forces due to inhomogeneous Dirichlet BCs.
Definition: functionhelper.hh:134
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:65
decltype(auto) maybeDeref(T &t)
if T is a pointer type, return the dereferenced value, otherwise return the value itself.
Definition: functionhelper.hh:120
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:128
static constexpr int mydim
Dimension of the geometry.
Definition: fetraits.hh:63
Definition: utils/dirichletvalues.hh:34
Type trait to check if a type is a isSharedPtr.
Definition: traits.hh:136
Concept to check if a node in a basis tree is a Lagrangian node.
Definition: utils/concepts.hh:92
Definition: utils/concepts.hh:641
Several concepts.