TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
mesh.hpp
1// Copyright (c) 2022-2023 Simons Foundation
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You may obtain a copy of the License at
14// https://www.gnu.org/licenses/gpl-3.0.txt
15//
16// Authors: Nils Wentzell
17
18#pragma once
19
20#include <cpp2py/cpp2py.hpp>
21
22#include "../mesh.hpp"
23
24namespace cpp2py {
25
26 // -----------------------------------
27 // all_t mapped to all
28 // -----------------------------------
29
30 template <> struct py_converter<triqs::mesh::all_t> {
31
32 static constexpr char *tp_name = "all";
33
34 static PyObject *c2py(triqs::mesh::all_t m) {
35 pyref all = pyref::get_class("builtins", "all", true);
36 if (all.is_null()) return NULL;
37 return all.new_ref();
38 }
39
40 static bool is_convertible(PyObject *ob, bool raise_exception) {
41 pyref all = pyref::get_class("builtins", "all", true);
42 return (all == ob);
43 }
44
45 static triqs::mesh::all_t py2c(PyObject *ob) { return {}; }
46 };
47
48 // -----------------------------------
49 // statistic_enum
50 // -----------------------------------
51
52 template <> struct py_converter<triqs::mesh::statistic_enum> {
53
54 static constexpr char *tp_name = "Statistic (\"Fermion\" | \"Boson\")";
55
56 static PyObject *c2py(triqs::mesh::statistic_enum x) {
57 if (x == triqs::mesh::Fermion) return PyUnicode_FromString("Fermion");
58 return PyUnicode_FromString("Boson"); // last case separate to avoid no return warning of compiler
59 }
60 static triqs::mesh::statistic_enum py2c(PyObject *ob) {
61 std::string s = PyUnicode_AsUTF8(ob);
62 if (s == "Fermion") return triqs::mesh::Fermion;
63 return triqs::mesh::Boson;
64 }
65 static bool is_convertible(PyObject *ob, bool raise_exception) {
66 if (!PyUnicode_Check(ob)) {
67 if (raise_exception) PyErr_SetString(PyExc_ValueError, "Convertion of C++ enum statistic_enum : the object is not a string");
68 return false;
69 }
70 std::string s = PyUnicode_AsUTF8(ob);
71 if (s == "Fermion") return true;
72 if (s == "Boson") return true;
73 if (raise_exception) {
74 auto err = "Convertion of C++ enum statistic_enum : \nThe string \"" + s + "\" is not in [Fermion,Boson]";
75 PyErr_SetString(PyExc_ValueError, err.c_str());
76 }
77 return false;
78 }
79 };
80
81 // -----------------------------------
82 // matsubara_freq
83 // -----------------------------------
84
85 template <> struct py_converter<triqs::mesh::matsubara_freq> {
86 using c_t = triqs::mesh::matsubara_freq;
87
88 static constexpr char *tp_name = "MatsubaraFreq";
89
90 static PyObject *c2py(c_t const &x) {
91 pyref cls = pyref::get_class("triqs.mesh", "MatsubaraFreq", true);
92 if (cls.is_null()) return NULL;
93
94 pyref kw = PyDict_New();
95
96 pyref n = convert_to_python(x.n);
97 if (n.is_null()) return NULL;
98 pyref beta = convert_to_python(x.beta);
99 if (beta.is_null()) return NULL;
100 pyref statistic = convert_to_python(x.statistic);
101 if (statistic.is_null()) return NULL;
102 PyDict_SetItemString(kw, "n", n);
103 PyDict_SetItemString(kw, "beta", beta);
104 PyDict_SetItemString(kw, "statistic", statistic);
105
106 pyref empty_tuple = PyTuple_New(0);
107 return PyObject_Call(cls, empty_tuple, kw);
108 }
109
110 static bool is_convertible(PyObject *ob, bool raise_exception) {
111 pyref cls = pyref::get_class("triqs.mesh", "MatsubaraFreq", true);
112 if (not pyref::check_is_instance(ob, cls, raise_exception)) return false;
113 return true;
114 }
115
116 // ----------------------------------------------
117
118 static c_t py2c(PyObject *ob) {
119 pyref x = borrowed(ob);
120 pyref n = x.attr("n");
121 pyref beta = x.attr("beta");
122 pyref statistic = x.attr("statistic");
123 return c_t{convert_from_python<long>(n), convert_from_python<double>(beta), convert_from_python<triqs::mesh::statistic_enum>(statistic)};
124 }
125 };
126
127 // -----------------------------------
128 // bravais_lattice::point_t
129 // -----------------------------------
130
131 template <> struct py_converter<triqs::lattice::bravais_lattice::point_t> {
132 using c_t = triqs::lattice::bravais_lattice::point_t;
133
134 static constexpr char *tp_name = "LatticePoint";
135
136 static PyObject *c2py(c_t const &x) {
137 pyref cls = pyref::get_class("triqs.lattice", "LatticePoint", true);
138 if (cls.is_null()) return NULL;
139
140 pyref kw = PyDict_New();
141
142 pyref index = convert_to_python(x.index());
143 if (index.is_null()) return NULL;
144 pyref lattice = convert_to_python(x.lattice());
145 if (lattice.is_null()) return NULL;
146 PyDict_SetItemString(kw, "index", index);
147 PyDict_SetItemString(kw, "lattice", lattice);
148
149 pyref empty_tuple = PyTuple_New(0);
150 return PyObject_Call(cls, empty_tuple, kw);
151 }
152
153 static bool is_convertible(PyObject *ob, bool raise_exception) {
154 pyref cls = pyref::get_class("triqs.lattice", "LatticePoint", true);
155 if (not pyref::check_is_instance(ob, cls, raise_exception)) return false;
156 return true;
157 }
158
159 // ----------------------------------------------
160
161 using lattice_py_type = struct {
162 PyObject_HEAD;
163 triqs::lattice::bravais_lattice *_c;
164 };
165
166 static c_t py2c(PyObject *ob) {
167
168 pyref x = borrowed(ob);
169 pyref index = x.attr("index");
170 pyref lattice = x.attr("lattice");
171 auto *lattice_c_ptr = reinterpret_cast<lattice_py_type *>(static_cast<PyObject *>(lattice))->_c;
172 if (lattice_c_ptr == NULL) {
173 std::cerr << "Severe internal error : lattice_ptr is null in py2c\n";
174 std::terminate();
175 }
176
177 return c_t{convert_from_python<std::array<long, 3>>(index), lattice_c_ptr};
178 }
179 };
180
181 // -----------------------------------
182 // Mesh Product
183 // -----------------------------------
184
185 template <triqs::mesh::Mesh... Ms> struct py_converter<triqs::mesh::prod<Ms...>> {
186 using c_t = triqs::mesh::prod<Ms...>;
187 using mtuple_conv = py_converter<typename c_t::m_tuple_t>; // the tuple of meshes
188
189#ifdef C2PY_INCLUDED
190 static std::string tp_name() {
191 std::ostringstream out;
192 std::string sep;
193 out << "MeshProduct[";
194 ((out << sep << ::c2py::python_typename<Ms>(), sep = ", "), ...);
195 out << "]";
196 return out.str();
197 }
198#endif
199
200 static PyObject *c2py(c_t m) {
201 pyref cls = pyref::get_class("triqs.mesh", "MeshProduct", true);
202 if (cls.is_null()) return NULL;
203 pyref m_tuple = mtuple_conv::c2py(m.components()); // take the C++ tuple of meshes and make the corresponding Python tuple
204 if (m_tuple.is_null()) return NULL;
205 return PyObject_Call(cls, m_tuple, NULL);
206 }
207
208 static bool is_convertible(PyObject *ob, bool raise_exception) {
209 pyref cls = pyref::get_class("triqs.mesh", "MeshProduct", true);
210
211 // first check it is a MeshProduct
212 if (not pyref::check_is_instance(ob, cls, raise_exception)) return false;
213 pyref x = borrowed(ob);
214
215 // check conversion of the mesh list
216 pyref ml = x.attr("_mlist");
217 return mtuple_conv::is_convertible(ml, raise_exception);
218 }
219
220 static c_t py2c(PyObject *ob) {
221 pyref x = borrowed(ob);
222 pyref ml = x.attr("_mlist");
223 return triqs::tuple::apply_construct<c_t>(mtuple_conv::py2c(ml));
224 }
225 };
226
227 // -----------------------------------
228 // mesh_point
229 // -----------------------------------
230
231 template <triqs::mesh::MeshPoint MP> struct py_converter<MP> {
232 using c_t = MP;
233
234 static constexpr char *tp_name = "MeshPoint";
235
236 static PyObject *c2py(c_t const &p) {
237
238 pyref cls = pyref::get_class("triqs.mesh", "MeshPoint", /* raise_exception */ true);
239 if (cls.is_null()) return NULL;
240
241 pyref index = convert_to_python(p.index());
242 if (index.is_null()) return NULL;
243
244 pyref data_index = convert_to_python(p.data_index());
245 if (data_index.is_null()) return NULL;
246
247 pyref mesh_hash = convert_to_python(p.mesh_hash());
248 if (mesh_hash.is_null()) return NULL;
249
250 if constexpr (requires { p.value(); }) {
251 pyref val = convert_to_python(p.value());
252 if (val.is_null()) return NULL;
253
254 if constexpr (requires { p.weight(); }) {
255 pyref weight = convert_to_python(p.weight());
256 if (weight.is_null()) return NULL;
257 return PyObject_Call(cls, pyref::make_tuple(index, data_index, mesh_hash, val, weight), NULL);
258 }
259 return PyObject_Call(cls, pyref::make_tuple(index, data_index, mesh_hash, val), NULL);
260 }
261
262 return PyObject_Call(cls, pyref::make_tuple(index, data_index, mesh_hash), NULL);
263 }
264 };
265
266} // namespace cpp2py
statistic_enum
Enum to specify particle statistics.
Definition utils.hpp:163
many_body_operator_generic< T > n(IndexTypes... indices)
Create a number operator .
decltype(auto) apply_construct(T &&t)
Brace-construct an object from the elements of a tuple.
Umbrella header for the TRIQS mesh types.
Additional converters for gf.