Add more complete SolverUtils bindings to NekPy
Issue/feature addressed
This MR adds a more complete set of bindings for the SolverUtils
library, allowing users to write Python-side solvers via subclasses to EquationSystem
and UnsteadySystem
. There are some other improvements:
- Fix a memory leak in
Array<OneD, ...>
- Add support for automatic conversion for more complex types based on the 1D array class, particularly
Array<OneD, Array<OneD, NekDouble>>
andArray<OneD, std::shared_ptr<T>>
-
SessionReader
now includes some additional bindings for useful functions likeGetVariables
Implementation
The implementation is reasonably involved. The main additions are as follows.
NekFactory
There is more generic support for NekFactory
, which should make binding future factory-pattern based classes easier/with less boilerplate. This will be backported to some of the other classes (e.g. modules within NekMesh/FieldConvert) in a future MR. The pattern used is
#include <SolverUtils/Python/EquationSystem.h>
void export_EquationSystem()
{
static NekFactory_Register<EquationSystemFactory> fac(
GetEquationSystemFactory());
py::class_<EqSysWrap, std::shared_ptr<EqSysWrap>, boost::noncopyable>(
// in this case we assume equationsystem classes will have constructors
// rather than specify a specific creator function
"EquationSystem", py::init<LibUtilities::SessionReaderSharedPtr,
SpatialDomains::MeshGraphSharedPtr>())
// usual stuff here for wrapping member functions...
// Factory functions.
.def("Create", &EquationSystem_Create)
.staticmethod("Create")
.def("Register", [](std::string const &filterName,
py::object &obj) { fac(filterName, obj); })
.staticmethod("Create");
}
SharedArray
To facilitate more complex types, constructors have been templated based on std::enable_if_t
and SFINAE patterns. For example:
template <typename T> struct OneDArrayToPython
{
static PyObject *convert(Array<OneD, T> const &arr)
{
return convert_impl(arr);
}
template <typename U = T,
std::enable_if_t<std::is_arithmetic<U>::value> * = nullptr>
static PyObject *convert_impl(Array<OneD, U> const &arr)
{
// converter for normal floating-point and integral types
}
template <typename U = T,
std::enable_if_t<is_shared_ptr<U>::value ||
is_nekarray_oned<U>::value> * = nullptr>
{
// converter for array and std::shared_ptr types
}
Tests
Unit tests have been added for EquationSystem
and two demos supplied to show the use of bindings for UnsteadySystem
and EquationSystem
.
Suggested reviewers
Please suggest any people who would be appropriate to review your code.
Notes
Please add any other information that could be useful for reviewers.
Checklist
-
Functions and classes, or changes to them, are documented. [ ] User guide/documentation is updated.-
Changelog is updated. -
Suitable tests added for new functionality. -
Contributed code is correctly formatted. (See the contributing guidelines). -
License added to any new files. -
No extraneous files have been added (e.g. compiler output or test data files).