diff --git a/pytriqs/wrap_test/g.hpp b/pytriqs/wrap_test/g.hpp index 429ea49e..d0b8e12f 100644 --- a/pytriqs/wrap_test/g.hpp +++ b/pytriqs/wrap_test/g.hpp @@ -24,3 +24,23 @@ void pass_bgf(block_gf_view g) { h5_write(file, "g", g); } } + +// scalar gf + +gf_view make_sgf(double a) { + double beta = 1; + auto G1 = gf({beta, Fermion}); +{ + H5::H5File file("ess_test_g3a.h5", H5F_ACC_TRUNC); + h5_write(file, "g", G1); + } + return G1; +} + +void pass_sgf(gf_view g) { + + { + H5::H5File file("ess_test_g3b.h5", H5F_ACC_TRUNC); + h5_write(file, "g", g); + } +} diff --git a/pytriqs/wrap_test/test_g_desc.py b/pytriqs/wrap_test/test_g_desc.py index a192c3fd..599d66b6 100644 --- a/pytriqs/wrap_test/test_g_desc.py +++ b/pytriqs/wrap_test/test_g_desc.py @@ -8,6 +8,10 @@ module.add_include("") module.add_function (name = "make_bgf", signature = "block_gf_view (double a)", doc = "DOC of print_a") module.add_function (name = "pass_bgf", signature = "void (block_gf_view g) ", doc = "DOC of print_a") +module.add_function (name = "make_sgf", signature = "gf_view (double a)", doc = "DOC of print_a") +module.add_function (name = "pass_sgf", signature = "void (gf_view g)", doc = "DOC of print_a") + + if __name__ == '__main__' : module.generate_code(mako_template = sys.argv[1], wrap_file = sys.argv[2]) module.generate_py_converter_header(mako_template = sys.argv[3], wrap_file = sys.argv[4]) diff --git a/triqs/python_tools/wrapper_tools.hpp b/triqs/python_tools/wrapper_tools.hpp index a422189d..4934b358 100644 --- a/triqs/python_tools/wrapper_tools.hpp +++ b/triqs/python_tools/wrapper_tools.hpp @@ -1,5 +1,4 @@ - - #pragma once +#pragma once #include #include "structmember.h" #include @@ -27,7 +26,6 @@ namespace triqs { namespace py_tools { //--------------------- pyref ----------------------------- // a little class to hold an owned ref, make sure it is decref at destruction -// with some useful factories. class pyref { PyObject * ob = NULL; public: @@ -46,9 +44,6 @@ class pyref { pyref(pyref && p){ ob = p.ob; p.ob=NULL;} pyref& operator =(pyref const&) = delete; pyref& operator =(pyref &&p) {ob = p.ob; p.ob=NULL; return *this;} - // factories. No public constructor. - // The point is that PyObject is borrowed or new, depending on the function that produced it - // Need to check in the API doc for each case. static pyref module(std::string const &module_name) { return PyImport_ImportModule(module_name.c_str()); } static pyref string(std::string const &s) { return PyString_FromString(s.c_str());} }; @@ -58,18 +53,19 @@ class pyref { //--------------------- py_converters ----------------------------- // default version for a wrapped type. To be specialized later. +// py2c behaviour is undefined is is_convertible return false template struct py_converter; - //static PyObject * c2py(T const & x); - //static T & py2c(PyObject * ob); - //static bool is_convertible(PyObject * ob, bool raise_exception); - // + //{ + // static PyObject * c2py(T const & x); + // static T & py2c(PyObject * ob); + // static bool is_convertible(PyObject * ob, bool raise_exception); + //} // We only use these functions in the code, not converter // TODO : Does c2py return NULL in failure ? Or is it undefined... template static PyObject *convert_to_python(T &&x) { return py_converter::type>::c2py(std::forward(x)); } -// can convert_from_python raise a triqs exception ? NO template static auto convert_from_python(PyObject * ob) -> decltype(py_converter::py2c(ob)) { return py_converter::py2c(ob);} template static bool convertible_from_python(PyObject *ob, bool raise_exception) { return py_converter::is_convertible(ob, raise_exception); @@ -371,19 +367,6 @@ template <> struct py_converter { } }; -// --- gf ---- -/*template struct py_converter> { - using conv = py_converter>; - static PyObject *c2py(triqs::gfs::gf &g) { return conv::c2py(g); } - static PyObject *c2py(triqs::gfs::gf &&g) { return conv::c2py(g); } - static bool is_convertible(PyObject *ob, bool raise_exception) { - return conv::is_convertible(ob,raise_exception); - } - static triqs::gfs::gf py2c(PyObject *ob) { return conv::py2c(ob); } -}; -*/ - - // --- nothing <--> None ---- #ifdef TRIQS_GF_INCLUDED @@ -409,9 +392,7 @@ template struct py_converter; using c_type = triqs::gfs::gf_view; - static PyObject *c2py(c_type &&g) { return c2py(g);} - - static PyObject *c2py(c_type &g) { + static PyObject *c2py(c_type g) { // rm the view_proxy std::vector vg; vg.reserve(g.data().size()); @@ -448,6 +429,29 @@ template struct py_converter struct py_converter>{ + + using conv = py_converter>; + using c_t = triqs::gfs::gf_view; + + static PyObject *c2py(c_t g) { + return conv::c2py(reinterpret_scalar_valued_gf_as_matrix_valued(g)); + } + + static bool is_convertible(PyObject *ob, bool raise_exception) { + if (!conv::is_convertible(ob,raise_exception)) return false; + auto g = conv::py2c(ob); // matrix view + if (get_target_shape(g) == make_shape(1,1)) return true; + if (raise_exception) PyErr_SetString(PyExc_RuntimeError,"The green function is not of dimension 1x1 : can not be reinterpreted as a scalar_valued Green function"); + return false; + } + + static c_t py2c(PyObject *ob) { + return slice_target_to_scalar(conv::py2c(ob),0,0); + } +}; + #endif // ---- function ----