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 "../mesh/concepts.hpp"
22#include "../mesh/prod.hpp"
23#include "../mesh/utils.hpp"
25
26#include <c2py/converters/basic_types.hpp>
27#include <c2py/converters/stl/array.hpp>
28#include <c2py/converters/wrapped.hpp>
29#include <c2py/py_converter.hpp>
30#include <c2py/pyref.hpp>
31#include <Python.h>
32
33#include <array>
34#include <exception>
35#include <iostream>
36#include <sstream>
37#include <string>
38
39namespace c2py {
40
41 // -----------------------------------
42 // all_t mapped to all
43 // -----------------------------------
44
45 template <> struct py_converter<triqs::mesh::all_t> {
46
47 static constexpr const char *tp_name = "all";
48
49 static PyObject *c2py(triqs::mesh::all_t m) {
50 pyref all = pyref::get_class("builtins", "all", true);
51 if (all.is_null()) return NULL;
52 return all.new_ref();
53 }
54
55 static bool is_convertible(PyObject *ob, bool raise_exception) {
56 pyref all = pyref::get_class("builtins", "all", true);
57 return (all == ob);
58 }
59
60 static triqs::mesh::all_t py2c(PyObject *ob) { return {}; }
61 };
62
63 // -----------------------------------
64 // statistic_enum
65 // -----------------------------------
66
67 template <> struct py_converter<triqs::mesh::statistic_enum> {
68
69 static constexpr const char *tp_name = R"(Statistic ("Fermion" | "Boson"))";
70
71 static PyObject *c2py(triqs::mesh::statistic_enum x) {
72 if (x == triqs::mesh::Fermion) return PyUnicode_FromString("Fermion");
73 return PyUnicode_FromString("Boson"); // last case separate to avoid no return warning of compiler
74 }
75 static triqs::mesh::statistic_enum py2c(PyObject *ob) {
76 std::string s = PyUnicode_AsUTF8(ob);
77 if (s == "Fermion") return triqs::mesh::Fermion;
78 return triqs::mesh::Boson;
79 }
80 static bool is_convertible(PyObject *ob, bool raise_exception) {
81 if (!PyUnicode_Check(ob)) {
82 if (raise_exception) PyErr_SetString(PyExc_ValueError, "Convertion of C++ enum statistic_enum : the object is not a string");
83 return false;
84 }
85 std::string s = PyUnicode_AsUTF8(ob);
86 if (s == "Fermion") return true;
87 if (s == "Boson") return true;
88 if (raise_exception) {
89 auto err = "Convertion of C++ enum statistic_enum : \nThe string \"" + s + "\" is not in [Fermion,Boson]";
90 PyErr_SetString(PyExc_ValueError, err.c_str());
91 }
92 return false;
93 }
94 };
95
96 // -----------------------------------
97 // matsubara_freq
98 // -----------------------------------
99
100 template <> struct py_converter<triqs::mesh::matsubara_freq> {
101 using c_t = triqs::mesh::matsubara_freq;
102
103 static constexpr const char *tp_name = "MatsubaraFreq";
104
105 static PyObject *c2py(c_t const &x) {
106 pyref cls = pyref::get_class("triqs.mesh", "MatsubaraFreq", true);
107 if (cls.is_null()) return NULL;
108
109 pyref kw = PyDict_New();
110
111 pyref n = cxx2py(x.n);
112 if (n.is_null()) return NULL;
113 pyref beta = cxx2py(x.beta);
114 if (beta.is_null()) return NULL;
115 pyref statistic = cxx2py(x.statistic);
116 if (statistic.is_null()) return NULL;
117 PyDict_SetItemString(kw, "n", n);
118 PyDict_SetItemString(kw, "beta", beta);
119 PyDict_SetItemString(kw, "statistic", statistic);
120
121 pyref empty_tuple = PyTuple_New(0);
122 return PyObject_Call(cls, empty_tuple, kw);
123 }
124
125 static bool is_convertible(PyObject *ob, bool raise_exception) {
126 pyref cls = pyref::get_class("triqs.mesh", "MatsubaraFreq", true);
127 if (not pyref::check_is_instance(ob, cls, raise_exception)) return false;
128 return true;
129 }
130
131 // ----------------------------------------------
132
133 static c_t py2c(PyObject *ob) {
134 pyref x = pyref::borrowed(ob);
135 pyref n = x.attr("n");
136 pyref beta = x.attr("beta");
137 pyref statistic = x.attr("statistic");
138 return c_t{py2cxx<long>(n), py2cxx<double>(beta), py2cxx<triqs::mesh::statistic_enum>(statistic)};
139 }
140 };
141
142 // -----------------------------------
143 // Mesh Product
144 // -----------------------------------
145
146 template <triqs::mesh::Mesh... Ms> struct py_converter<triqs::mesh::prod<Ms...>> {
147 using c_t = triqs::mesh::prod<Ms...>;
148 using mtuple_conv = py_converter<typename c_t::m_tuple_t>; // the tuple of meshes
149
150 static std::string tp_name() {
151 std::ostringstream out;
152 std::string sep;
153 out << "MeshProduct[";
154 ((out << sep << ::c2py::python_typename<Ms>(), sep = ", "), ...);
155 out << "]";
156 return out.str();
157 }
158
159 static PyObject *c2py(c_t m) {
160 pyref cls = pyref::get_class("triqs.mesh", "MeshProduct", true);
161 if (cls.is_null()) return NULL;
162 pyref m_tuple = mtuple_conv::c2py(m.components()); // take the C++ tuple of meshes and make the corresponding Python tuple
163 if (m_tuple.is_null()) return NULL;
164 return PyObject_Call(cls, m_tuple, NULL);
165 }
166
167 static bool is_convertible(PyObject *ob, bool raise_exception) {
168 pyref cls = pyref::get_class("triqs.mesh", "MeshProduct", true);
169
170 // first check it is a MeshProduct
171 if (not pyref::check_is_instance(ob, cls, raise_exception)) return false;
172 pyref x = pyref::borrowed(ob);
173
174 // check conversion of the mesh list
175 pyref ml = x.attr("_mlist");
176 return mtuple_conv::is_convertible(ml, raise_exception);
177 }
178
179 static c_t py2c(PyObject *ob) {
180 pyref x = pyref::borrowed(ob);
181 pyref ml = x.attr("_mlist");
182 return triqs::tuple::apply_construct<c_t>(mtuple_conv::py2c(ml));
183 }
184 };
185
186 // -----------------------------------
187 // mesh_point
188 // -----------------------------------
189
190 template <triqs::mesh::MeshPoint MP> struct py_converter<MP> {
191 using c_t = MP;
192
193 static constexpr const char *tp_name = "MeshPoint";
194
195 static PyObject *c2py(c_t const &p) {
196
197 pyref cls = pyref::get_class("triqs.mesh", "MeshPoint", /* raise_exception */ true);
198 if (cls.is_null()) return NULL;
199
200 pyref index = cxx2py(p.index());
201 if (index.is_null()) return NULL;
202
203 pyref data_index = cxx2py(p.data_index());
204 if (data_index.is_null()) return NULL;
205
206 pyref mesh_hash = cxx2py(p.mesh_hash());
207 if (mesh_hash.is_null()) return NULL;
208
209 if constexpr (requires { p.value(); }) {
210 pyref val = cxx2py(p.value());
211 if (val.is_null()) return NULL;
212
213 if constexpr (requires { p.weight(); }) {
214 pyref weight = cxx2py(p.weight());
215 if (weight.is_null()) return NULL;
216 return PyObject_Call(cls, pyref::make_tuple(index, data_index, mesh_hash, val, weight), NULL);
217 }
218 return PyObject_Call(cls, pyref::make_tuple(index, data_index, mesh_hash, val), NULL);
219 }
220
221 return PyObject_Call(cls, pyref::make_tuple(index, data_index, mesh_hash), NULL);
222 }
223 };
224
225} // namespace c2py
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.
Provides a struct to represent Matsubara frequencies.
Provides concepts for mesh points and meshes.
Provides various utilities used with Meshes.
Additional converters for gf.
Provides a product mesh type.
Generic tuple manipulation tools.