version 0.3.7
registerelement.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
9#pragma once
10
11#include <dune/fufem/boundarypatch.hh>
12#include <dune/functions/functionspacebases/lagrangebasis.hh>
13#include <dune/functions/functionspacebases/powerbasis.hh>
14#include <dune/grid/yaspgrid.hh>
15#include <dune/python/common/typeregistry.hh>
16#include <dune/python/functions/globalbasis.hh>
17#include <dune/python/pybind11/eigen.h>
18#include <dune/python/pybind11/functional.h>
19#include <dune/python/pybind11/pybind11.h>
20#include <dune/python/pybind11/stl.h>
21
24#include <ikarus/utils/basis.hh>
25
26namespace Ikarus::Python {
27
44 template <bool defaultInitializers = true, class FE, class... options>
45 void registerElement(pybind11::handle scope, pybind11::class_<FE, options...> cls) {
46 using pybind11::operator""_a;
47
48 using GlobalBasis = typename FE::Basis;
49 using FlatBasis = typename FE::FlatBasis;
50 using GridView = typename GlobalBasis::GridView;
51 using Element = typename FE::Element;
52 using Traits = typename FE::Traits;
53 using FERequirements = typename FE::FERequirementType;
54 using ResultRequirementsType = typename FE::ResultRequirementsType;
55
56 if constexpr (defaultInitializers)
57 cls.def(pybind11::init([](const GlobalBasis& basis, const Element& element, double emod, double nu) {
58 return new FE(basis, element, emod, nu);
59 }),
60 pybind11::keep_alive<1, 2>(), pybind11::keep_alive<1, 3>());
61
62 using LoadFunction = std::function<Eigen::Vector<double, Traits::worlddim>(
64 if constexpr (defaultInitializers)
65 cls.def(
66 pybind11::init([](const GlobalBasis& basis, const Element& element, double emod, double nu,
67 const LoadFunction volumeLoad) { return new FE(basis, element, emod, nu, volumeLoad); }),
68 pybind11::keep_alive<1, 2>(), pybind11::keep_alive<1, 3>());
69 if constexpr (defaultInitializers)
70 cls.def(pybind11::init([](const GlobalBasis& basis, const Element& element, double emod, double nu,
71 const LoadFunction volumeLoad, const BoundaryPatch<GridView>& bp,
72 const LoadFunction neumannBoundaryLoad) {
73 return new FE(basis, element, emod, nu, volumeLoad, &bp, neumannBoundaryLoad);
74 }),
75 pybind11::keep_alive<1, 2>(), pybind11::keep_alive<1, 3>(), pybind11::keep_alive<1, 7>());
76
77 pybind11::module scopedf = pybind11::module::import("dune.functions");
78
79 typedef Dune::Python::LocalViewWrapper<FlatBasis> LocalViewWrapper;
80 auto includes = Dune::Python::IncludeFiles{"dune/python/functions/globalbasis.hh"};
81 auto lv = Dune::Python::insertClass<LocalViewWrapper>(
82 scopedf, "LocalViewWrapper",
83 Dune::Python::GenerateTypeName("Dune::Python::LocalViewWrapperWrapper", Dune::MetaType<FlatBasis>()),
84 includes)
85 .first;
86 lv.def("bind", &LocalViewWrapper::bind);
87 lv.def("unbind", &LocalViewWrapper::unbind);
88 lv.def("index", [](const LocalViewWrapper& localView, int index) { return localView.index(index); });
89 lv.def("__len__", [](LocalViewWrapper& self) -> int { return self.size(); });
90
91 Dune::Python::Functions::registerTree<typename LocalViewWrapper::Tree>(lv);
92 lv.def("tree", [](const LocalViewWrapper& view) { return view.tree(); });
93
94 auto basisName = Dune::className<FlatBasis>();
95 auto entry = Dune::Python::insertClass<FlatBasis>(
96 scopedf, "DefaultGlobalBasis", pybind11::buffer_protocol(), Dune::Python::GenerateTypeName(basisName),
97 Dune::Python::IncludeFiles{"dune/python/functions/globalbasis.hh"});
98 if (entry.second) Dune::Python::registerGlobalBasis(scopedf, entry.first);
99
100 cls.def(
101 "localView",
102 [](FE& self) -> LocalViewWrapper {
103 auto lvWrapped = LocalViewWrapper(self.localView().globalBasis());
104 // this can be simplified when https://gitlab.dune-project.org/staging/dune-functions/-/merge_requests/418
105 // becomes available
106 pybind11::object obj = pybind11::cast(self.localView().element());
107 lvWrapped.bind(obj);
108 return lvWrapped;
109 },
110 pybind11::keep_alive<0, 1>());
111 cls.def("calculateScalar", [](FE& self, const FERequirements& req) { return self.calculateScalar(req); });
112 cls.def("calculateVector", [](FE& self, const FERequirements& req, Eigen::Ref<Eigen::VectorXd> vec) {
113 return self.calculateVector(req, vec);
114 });
115 cls.def(
116 "calculateMatrix",
117 [](FE& self, const FERequirements& req, Eigen::Ref<Eigen::MatrixXd> mat) {
118 return self.calculateMatrix(req, mat);
119 },
120 pybind11::arg("FERequirements"), pybind11::arg("elementMatrix").noconvert());
121
122 if constexpr (requires { std::declval<FE>().materialTangent(); })
123 cls.def("materialTangent", [](FE& self) { return self.materialTangent(); });
124
125 cls.def(
126 "resultAt",
127 [](FE& self, const ResultRequirementsType& req, const Dune::FieldVector<double, Traits::mydim>& local,
128 ResultType resType = ResultType::noType) {
129 ResultTypeMap<double> resultTypeMap;
130 self.calculateAt(req, local, resultTypeMap);
131 if (resType == ResultType::noType)
132 return resultTypeMap.getSingleResult().second;
133 else
134 return resultTypeMap.getResult(resType);
135 },
136 pybind11::arg("resultRequirements"), pybind11::arg("local"), pybind11::arg("resultType") = ResultType::noType);
137 }
138
139} // namespace Ikarus::Python
Definition of the LinearElastic class for finite element mechanics computations.
ResultType
A strongly typed enum class representing the type of the result request.
Definition: ferequirements.hh:103
void registerElement(pybind11::handle scope, pybind11::class_< FE, options... > cls)
Register Python bindings for a generic finite element class.
Definition: registerelement.hh:45
void init(int argc, char **argv, bool enableFileLogger=true)
Initializes the Ikarus framework.
Definition: init.hh:81
Definition: flatassembler.hh:20
def basis(gv, tree)
Definition: basis.py:10
Class representing the requirements for finite element calculations.
Definition: ferequirements.hh:170
Class representing a map of result types to result arrays.
Definition: ferequirements.hh:342
auto & getSingleResult()
Get the result array for a single result type.
Definition: ferequirements.hh:379
ResultArray & getResult(const ResultType &resultType)
Get the result array for a specific result type.
Definition: ferequirements.hh:368
Definition: resultevaluators.hh:20
Definition of the LinearElastic class for finite element mechanics computations.
Wrapper around Dune-functions global basis.