7#ifndef DUNE_FUFEM_PYTHON_CONVERSION_HH
8#define DUNE_FUFEM_PYTHON_CONVERSION_HH
12#if HAVE_PYTHON || DOXYGEN
36#include <dune/grid/common/gridfactory.hh>
47template<
int dim,
int dimworld = dim,
class ctype =
double>
48class BoundarySegmentFromCallable
79struct Conversion<double>
81 enum {useDefaultConstructorConversion=
true};
82 static void toC(PyObject* x,
double& y) { y = PyFloat_AsDouble(x); }
83 static PyObject*
toPy(
const double& x) {
return PyFloat_FromDouble(x); }
90 enum {useDefaultConstructorConversion=
true};
92#if PY_MAJOR_VERSION >= 3
93 static void toC(PyObject* x,
int& y) { y = PyLong_AsLong(x); }
94 static PyObject*
toPy(
const int& x) {
return PyLong_FromLong(x); }
96 static void toC(PyObject* x,
int& y) { y = PyInt_AsLong(x); }
97 static PyObject*
toPy(
const int& x) {
return PyInt_FromLong(x); }
103struct Conversion<long>
105 enum {useDefaultConstructorConversion=
true};
107 static void toC(PyObject* x,
long& y) { y = PyLong_AsLong(x); }
108 static PyObject*
toPy(
const long& x) {
return PyLong_FromLong(x); }
113struct Conversion<bool>
115 enum {useDefaultConstructorConversion=
true};
116 static void toC(PyObject* x,
bool& y) {
117 int i = PyObject_IsTrue(x);
119 handlePythonError(
"Conversion<bool>::toC()",
"cannot interpret python object as bool");
122 static PyObject*
toPy(
const bool& x) {
return PyBool_FromLong(x); }
127struct Conversion<unsigned int>
129 enum {useDefaultConstructorConversion=
true};
130#if PY_MAJOR_VERSION >= 3
131 static void toC(PyObject* x,
unsigned int& y) { y = PyLong_AsUnsignedLongMask(x); }
132 static PyObject*
toPy(
const unsigned int& x) {
return PyLong_FromLong(x); }
134 static void toC(PyObject* x,
unsigned int& y) { y = PyInt_AsUnsignedLongMask(x); }
135 static PyObject*
toPy(
const unsigned int& x) {
return PyInt_FromLong(x); }
141struct Conversion<unsigned long>
143 enum {useDefaultConstructorConversion=
true};
144#if PY_MAJOR_VERSION >= 3
145 static void toC(PyObject* x,
unsigned long& y) { y = PyLong_AsUnsignedLongMask(x); }
146 static PyObject*
toPy(
const unsigned long& x) {
return PyLong_FromLong(x); }
148 static void toC(PyObject* x,
unsigned long& y) { y = PyInt_AsUnsignedLongMask(x); }
149 static PyObject*
toPy(
const unsigned long& x) {
return PyInt_FromLong(x); }
155struct Conversion<
std::string>
157 enum {useDefaultConstructorConversion=
true};
159#if PY_MAJOR_VERSION >= 3
160 static void toC(PyObject* x,
std::string& y) { y = PyUnicode_AsUTF8(x); }
161 static PyObject*
toPy(
const std::string& x) {
return Imp::inc(PyUnicode_FromString(x.
c_str())); }
163 static void toC(PyObject* x,
std::string& y) { y = PyString_AsString(x); }
170struct Conversion<char[i]>
172 static void toC(PyObject* x,
char y[i])
177#if PY_MAJOR_VERSION >= 3
178 static PyObject*
toPy(
const char x[i]) {
return Imp::inc(PyUnicode_FromString(x)); }
180 static PyObject*
toPy(
const char x[i]) {
return PyString_FromString(x); }
186struct Conversion<
std::shared_ptr<P> >
188 enum {useDefaultConstructorConversion=
true};
204struct Conversion<
std::vector<T> >
206 enum {useDefaultConstructorConversion=
true};
209 if (not PySequence_Check(list))
211 int size = PySequence_Size(list);
213 for(
int i=0; i<
size; ++i)
214 Reference(PySequence_GetItem(list, i)).toC(v[i]);
223 PyObject* list = PyList_New(v.
size());
224 for(
size_t i=0; i<v.
size(); ++i)
225 PyList_SetItem(list, i, Imp::inc(
makeObject(v[i])));
232template<
class K,
class V,
class C,
class A>
233struct Conversion<
std::map<K, V, C, A> >
235 enum {useDefaultConstructorConversion=
true};
238 if (not PyDict_Check(
dict))
243 while (PyDict_Next(
dict, &pos, &key, &value))
247 Reference(Imp::inc(key)).toC(cKey);
248 Reference(Imp::inc(value)).toC(cValue);
261template<
class T, std::
size_t n>
262struct Conversion<
std::array<T,n>>
264 enum {useDefaultConstructorConversion=
true};
267 if (not PySequence_Check(list))
272 Reference(Imp::inc(list)).toC(v[0]);
276 if (PySequence_Size(list)!=n)
277 DUNE_THROW(
Dune::Exception,
"cannot convert a sequence of size " << PySequence_Size(list) <<
" to a std::array of size " << n);
279 for(
size_t i=0; i<n; ++i)
280 Reference(PySequence_GetItem(list, i)).toC(v[i]);
291 PyObject*
tuple = PyTuple_New(n);
292 for(
int i=0; i<n; ++i)
293 PyTuple_SetItem(tuple, i, Imp::inc(
makeObject(v[i])));
300template<
class T,
int n>
301struct Conversion<
Dune::FieldVector<T,n> >
303 enum {useDefaultConstructorConversion=
true};
306 if (not PySequence_Check(list))
311 Reference(Imp::inc(list)).toC(v[0]);
315 if (PySequence_Size(list)!=n)
316 DUNE_THROW(
Dune::Exception,
"cannot convert a sequence of size " << PySequence_Size(list) <<
" to a Dune::FieldVector of size " << n);
318 for(
size_t i=0; i<n; ++i)
319 Reference(PySequence_GetItem(list, i)).toC(v[i]);
330 PyObject*
tuple = PyTuple_New(n);
331 for(
int i=0; i<n; ++i)
332 PyTuple_SetItem(tuple, i, Imp::inc(
makeObject(v[i])));
339template<
class T,
int n,
int m>
340struct Conversion<
Dune::FieldMatrix<T,n,m> >
342 enum {useDefaultConstructorConversion=
true};
345 if (not PySequence_Check(list))
350 Reference(Imp::inc(list)).toC(v[0]);
354 if (PySequence_Size(list)!=n)
357 for(
size_t i=0; i<n; ++i)
358 Reference(PySequence_GetItem(list, i)).toC(v[i]);
369 PyObject*
tuple = PyTuple_New(n);
370 for(
int i=0; i<n; ++i)
371 PyTuple_SetItem(tuple, i, Imp::inc(
makeObject(v[i])));
379struct Conversion<
Dune::BlockVector<T> >
381 enum {useDefaultConstructorConversion=
true};
384 if (not PySequence_Check(list))
386 int size = PySequence_Size(list);
388 for(
int i=0; i<
size; ++i)
389 Reference(PySequence_GetItem(list, i)).toC(v[i]);
398 PyObject* list = PyList_New(v.size());
399 for(
size_t i=0; i<v.size(); ++i)
400 PyList_SetItem(list, i, Imp::inc(
makeObject(v[i])));
409struct Conversion<
Dune::TupleVector<T...> >
411 enum {useDefaultConstructorConversion=
true};
415 if (not PySequence_Check(list))
420 DUNE_THROW(
Dune::Exception,
"cannot convert a sequence of size " << PySequence_Size(list) <<
" to a Dune::TupleVector of size " << v.
size());
423 Reference(PySequence_GetItem(list, i)).toC(v[i]);
436 PyObject*
tuple = PyTuple_New(n);
438 PyTuple_SetItem(tuple, i, Imp::inc(
makeObject(v[i])));
448struct Conversion<
Dune::ParameterTree>
450 enum {useDefaultConstructorConversion=
true};
453 if (not PyDict_Check(
dict))
458 while (PyDict_Next(
dict, &pos, &key, &value))
462 if (PyDict_Check(value))
463 Reference(Imp::inc(value)).toC(param.
sub(cKey));
465 param[cKey] = Reference(Imp::inc(value)).str();
476template<
class Domain,
class Range>
477struct Conversion<
std::function<Range(Domain)>>
479 enum {useDefaultConstructorConversion=
true};
482 f = Python::makeFunction<Range(Domain)>(Imp::inc(pyF));
486template<
int dim,
int dimworld,
class ctype>
487struct Conversion<
Dune::BoundarySegment<dim, dimworld, ctype>*>
489 enum {useDefaultConstructorConversion=
true};
494 using Segment = Impl::BoundarySegmentFromCallable<dim, dimworld, ctype>;
496 segmentPointer =
new Segment(make_function<Range>(Imp::inc(pyF)));
517template<
class Gr
idType>
518struct Conversion<
Dune::GridFactory<GridType> >
520 enum {useDefaultConstructorConversion=
true};
524 const int dim = GridType::dimension;
525 const int dimworld = GridType::dimensionworld;
533 Reference
grid(Imp::inc(pyGridRaw));
535 Reference vertexIt =
iter(
grid.get(
"vertices"));
539 Reference elementIt =
iter(
grid.get(
"elements"));
540 for(Reference element =
next(elementIt); element; element =
next(elementIt))
542 auto type = Dune::geometryTypeFromVertexCount(
dim,
size(element));
546 if (
grid.hasAttr(
"segments"))
548 Reference segmentIt =
iter(
grid.get(
"segments"));
549 for(Reference segment =
next(segmentIt); segment; segment =
next(segmentIt))
566 #warning dunepython.hh was included but python was not found or enabled!
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
constexpr void forEach(Range &&range, F &&f)
virtual void operator()()=0
#define DUNE_THROW(E,...)
Definition callable.hh:34
Reference iter(const Reference &seq)
Get iterator of iterable object.
Definition common.hh:406
bool isCallable(const Reference &ref)
Check if python object is callable.
Definition common.hh:532
void handlePythonError(const std::string &origin, const std::string &message)
If a python error occurred throw an exception and clear python error indicator.
Definition common.hh:589
Reference tuple(const Ts &... ts)
Definition common.hh:370
Reference makeObject(const T &t)
Create python object from C++ object.
Definition common.hh:351
Reference next(const Reference &iter)
Get next item from iterator.
Definition common.hh:421
Reference dict()
Create an empty Python tuple.
Definition common.hh:380
const Grid & grid() const
void resize(size_type size)
ParameterTree & sub(const std::string &sub)
static constexpr std::size_t size()
virtual void insertElement(const GeometryType &type, const std::vector< unsigned int > &vertices)
virtual void insertVertex(const FieldVector< ctype, dimworld > &pos)
virtual void insertBoundarySegment(const std::vector< unsigned int > &vertices)
Class representing a face.
Definition facehierarchy.hh:120
static PyObject * toPy(const T &x)
Definition common.hh:72
static void toC(PyObject *x, T &y)
Definition common.hh:67