mirror of
https://github.com/triqs/dft_tools
synced 2024-12-24 13:23:37 +01:00
lattice : python wrapper
This commit is contained in:
parent
5f6dadfede
commit
2b5dd322ce
@ -6,7 +6,7 @@ SET(PYTHON_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/descriptors.py
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/_gf_imfreq.py
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/_gf_imtime.py
|
||||
#${CMAKE_CURRENT_SOURCE_DIR}/_gf_legendre.py
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/_gf_legendre.py
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/_gf_refreq.py
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/_gf_retime.py
|
||||
#${CMAKE_CURRENT_SOURCE_DIR}/gf_two_real_times.py
|
||||
|
@ -5,12 +5,10 @@ SET(PYTHON_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tight_binding.py
|
||||
)
|
||||
|
||||
install (FILES ${CMAKE_SOURCE_DIR}/pytriqs/__init__.py.template DESTINATION "include/pytriqs/gf/local" RENAME __init__.py)
|
||||
|
||||
install (FILES ${PYTHON_SOURCES} DESTINATION ${TRIQS_PYTHON_LIB_DEST}/lattice)
|
||||
|
||||
# THE C++ code
|
||||
#SET(CPP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/C++)
|
||||
cython_module(LatticeTools lattice_tools lattice )
|
||||
|
||||
# ???
|
||||
#target_link_libraries(_pytriqs_LatticeTools triqs ${TRIQS_LINK_LIBS})
|
||||
# Build C extension module
|
||||
triqs_python_extension(lattice_tools lattice)
|
||||
|
||||
|
@ -1,116 +0,0 @@
|
||||
from dcomplex cimport *
|
||||
from shared_ptr cimport *
|
||||
from arrays cimport *
|
||||
from libcpp.pair cimport pair
|
||||
from libcpp.vector cimport vector
|
||||
from libcpp.string cimport string as std_string
|
||||
#from extractor cimport *
|
||||
#from h5 cimport *
|
||||
from cython.operator cimport dereference as deref, preincrement as inc #dereference and increment operator
|
||||
|
||||
import numpy
|
||||
|
||||
cdef extern from "triqs/lattice/brillouin_zone.hpp" :
|
||||
cdef cppclass bravais_lattice_c " triqs::lattice::bravais_lattice" :
|
||||
bravais_lattice_c(matrix[double] & units, vector[tqa_vector[double]] &, vector[std_string] &) except +
|
||||
int n_orbitals()
|
||||
matrix[double] units()
|
||||
int dim()
|
||||
tqa_vector[double] lattice_to_real_coordinates (tqa_vector_view[double] &)
|
||||
|
||||
cdef extern from "triqs/lattice/tight_binding.hpp" namespace "triqs::gf" :
|
||||
cdef cppclass tight_binding " triqs::lattice::tight_binding" :
|
||||
tight_binding(bravais_lattice_c & units, vector[vector[long]] &, vector[matrix[dcomplex]] &) except +
|
||||
|
||||
#Fix the name conflict pv wiht a pxd, cf doc....?
|
||||
array_view[complex,THREE] hopping_stack_c "hopping_stack" (tight_binding & TB, array_view[double,TWO] & k_stack)
|
||||
pair [array[double,ONE],array[double,TWO]] dos_c "dos" (tight_binding & TB, size_t nkpts, size_t neps)
|
||||
pair [array[double,ONE],array[double,ONE]] dos_patch_c "dos_patch" (tight_binding & TB, array_view[double,TWO] & triangles, size_t neps, size_t ndiv)
|
||||
array_view[double,TWO] energies_on_bz_path_c "energies_on_bz_path" (tight_binding & TB, tqa_vector[double] & K1, tqa_vector[double] & K2, size_t n_pts)
|
||||
array_view[complex,THREE] energy_matrix_on_bz_path_c "energy_matrix_on_bz_path" (tight_binding & TB, tqa_vector[double] & K1, tqa_vector[double] & K2, size_t n_pts)
|
||||
array_view[double,TWO] energies_on_bz_grid_c "energies_on_bz_grid" (tight_binding & TB, size_t n_pts)
|
||||
|
||||
cdef class BravaisLattice :
|
||||
"""
|
||||
"""
|
||||
cdef bravais_lattice_c * _c
|
||||
def __init__(self, units, orbital_positions = None ) :
|
||||
""" """
|
||||
cdef vector[std_string] names
|
||||
cdef vector[tqa_vector[double]] atom_pos
|
||||
orbital_positions = orbital_positions if orbital_positions else dict ("", (0,0,0) )
|
||||
for name, pos in orbital_positions.items():
|
||||
names.push_back(name)
|
||||
atom_pos.push_back(tqa_vector[double](pos))
|
||||
self._c = new bravais_lattice_c( matrix[double](units),atom_pos, names)
|
||||
|
||||
def __dealloc__(self):
|
||||
del self._c
|
||||
|
||||
def lattice_to_real_coordinates(self, R) :
|
||||
"""
|
||||
Transform into real coordinates.
|
||||
:param x_in: coordinates in the basis of the unit vectors
|
||||
:rtype: Output coordinates in R^3 (real coordinates) as an array
|
||||
"""
|
||||
return self._c.lattice_to_real_coordinates ( tqa_vector_view[double] (R)).to_python()
|
||||
|
||||
property dim :
|
||||
"""Dimension of the lattice"""
|
||||
def __get__(self) :
|
||||
"""Dimension of the lattice"""
|
||||
return self._c.dim()
|
||||
|
||||
def n_orbitals(self) :
|
||||
"""Number of orbitals"""
|
||||
return self._c.n_orbitals()
|
||||
|
||||
cdef class TightBinding:
|
||||
"""
|
||||
"""
|
||||
cdef tight_binding * _c
|
||||
def __init__(self, BravaisLattice bravais_lattice, hopping ) :
|
||||
""" """
|
||||
#self._c = new tight_binding(deref(bravais_lattice._c))
|
||||
#cdef vector[long] d
|
||||
cdef vector[matrix[dcomplex]] mats
|
||||
cdef vector[vector[long]] displs
|
||||
for displ, mat in hopping.items() :
|
||||
displs.push_back(displ)
|
||||
#d = displ
|
||||
mats.push_back(matrix[dcomplex] (numpy.array(mat, dtype =float)))
|
||||
#self._c.push_back( d, matrix[double] (numpy.array(mat, dtype =float)))
|
||||
self._c = new tight_binding(deref(bravais_lattice._c), displs, mats)
|
||||
|
||||
def __dealloc__(self):
|
||||
del self._c
|
||||
|
||||
# -------------------------------------------
|
||||
|
||||
def hopping_stack (TightBinding TB, k_stack) :
|
||||
""" """
|
||||
return hopping_stack_c(deref(TB._c), array_view[double,TWO](k_stack)).to_python()
|
||||
|
||||
def dos ( TightBinding TB, int nkpts, int neps):
|
||||
""" """
|
||||
a = dos_c(deref(TB._c), nkpts, neps)
|
||||
return (a.first.to_python(), a.second.to_python())
|
||||
|
||||
def dos_patch ( TightBinding TB, triangles, int neps, int ndiv):
|
||||
""" """
|
||||
a = dos_patch_c(deref(TB._c), array_view[double,TWO] (triangles), neps, ndiv)
|
||||
return (a.first.to_python(), a.second.to_python())
|
||||
|
||||
def energies_on_bz_path ( TightBinding TB, K1, K2, n_pts) :
|
||||
""" """
|
||||
return energies_on_bz_path_c (deref(TB._c), tqa_vector[double](K1), tqa_vector[double] (K2), n_pts).to_python()
|
||||
|
||||
def energy_matrix_on_bz_path ( TightBinding TB, K1, K2, n_pts) :
|
||||
""" """
|
||||
return energy_matrix_on_bz_path_c (deref(TB._c), tqa_vector[double](K1), tqa_vector[double] (K2), n_pts).to_python()
|
||||
|
||||
def energies_on_bz_grid ( TightBinding TB, n_pts) :
|
||||
""" """
|
||||
return energies_on_bz_grid_c (deref(TB._c), n_pts).to_python()
|
||||
|
||||
|
105
pytriqs/lattice/lattice_tools_desc.py
Normal file
105
pytriqs/lattice/lattice_tools_desc.py
Normal file
@ -0,0 +1,105 @@
|
||||
from wrap_generator import *
|
||||
|
||||
module = module_(full_name = "pytriqs.lattice_tools", doc = "Lattice tools (to be improved)")
|
||||
module.add_include("<triqs/lattice/brillouin_zone.hpp>")
|
||||
module.add_include("<triqs/lattice/tight_binding.hpp>")
|
||||
module.add_using("namespace triqs::lattice")
|
||||
module.add_using("namespace triqs::arrays")
|
||||
module.add_using("namespace triqs")
|
||||
module.add_using("r_t = arrays::vector<double>")
|
||||
module.add_using("k_t = arrays::vector<double>")
|
||||
|
||||
# --------- Bravais lattice ----------------------------------
|
||||
|
||||
bl = class_( py_type = "BravaisLattice",
|
||||
c_type = "bravais_lattice",
|
||||
c_type_absolute = "triqs::lattice::bravais_lattice",
|
||||
serializable= "tuple",
|
||||
)
|
||||
|
||||
bl.add_constructor(signature = "(matrix<double> units, std::vector<r_t> orbital_positions, std::vector<std::string> atom_orb_name)",
|
||||
doc = "")
|
||||
bl.add_constructor(signature = "(matrix<double> units, std::vector<r_t> orbital_positions)",
|
||||
doc = "")
|
||||
bl.add_constructor(signature = "(matrix<double> units)",
|
||||
doc = "")
|
||||
bl.add_constructor(signature = "()",
|
||||
doc = "")
|
||||
|
||||
bl.add_property(getter = cfunction(c_name="dim", signature = "int()"),
|
||||
doc = "Dimension of the lattice")
|
||||
|
||||
bl.add_property(getter = cfunction(c_name="n_orbitals", signature = "int()"),
|
||||
doc = "Number of orbitals")
|
||||
|
||||
bl.add_property(getter = cfunction(c_name="units", signature = "matrix_const_view<double>()"),
|
||||
doc = "Base vectors of the lattice")
|
||||
|
||||
bl.add_method(py_name = "lattice_to_real_coordinates",
|
||||
c_name = "lattice_to_real_coordinates",
|
||||
signature = "r_t(r_t x)",
|
||||
doc = "Transform into real coordinates.")
|
||||
|
||||
module.add_class(bl)
|
||||
|
||||
# --------- TightBinding ----------------------------------
|
||||
tb = class_( py_type = "TightBinding",
|
||||
c_type = "tight_binding",
|
||||
c_type_absolute = "triqs::lattice::tight_binding",
|
||||
#serializable= "tuple",
|
||||
)
|
||||
|
||||
tb.add_constructor(signature = "(bravais_lattice latt, PyObject* hopping)",
|
||||
calling_pattern =
|
||||
"""
|
||||
// We need to rewrite manually the call to the constructor :
|
||||
// hopping is a dict : displacement -> matrix
|
||||
// we flatten it into 2 vector of vector and matrix resp.
|
||||
// for the tight_binding constructor
|
||||
// First of all, if it is not a dict, error
|
||||
if (!PyDict_Check(hopping)) {PyErr_SetString(PyExc_TypeError, "hopping must be a mapping type (dict)"); return 0;}
|
||||
// The arguments for the C++ constructor
|
||||
std::vector<std::vector<long>> displs;
|
||||
std::vector<matrix<dcomplex>> mats;
|
||||
// we loop on the dict // Cf python doc for PyDict_Next
|
||||
PyObject *key, *value;
|
||||
Py_ssize_t pos = 0;
|
||||
while (PyDict_Next(hopping, &pos, &key, &value)) {
|
||||
displs.push_back(convert_from_python<std::vector<long>>(key));
|
||||
mats.push_back(convert_from_python<matrix<dcomplex>>(value));
|
||||
}
|
||||
auto result = tight_binding(*latt, displs, mats);
|
||||
""",
|
||||
doc = " ")
|
||||
|
||||
module.add_class(tb)
|
||||
|
||||
# --------- Module functions ----------------------------------
|
||||
|
||||
module.add_function(name = "hopping_stack",
|
||||
signature = "array<dcomplex, 3> (tight_binding TB, array_const_view<double, 2> k_stack)",
|
||||
doc = """ """)
|
||||
module.add_function(name = "dos",
|
||||
signature = "std::pair<array<double, 1>, array<double, 2>> (tight_binding TB, int nkpts, int neps)",
|
||||
doc = """ """)
|
||||
module.add_function(name = "dos_patch",
|
||||
signature = "std::pair<array<double, 1>, array<double, 1>> (tight_binding TB, array<double, 2> triangles, int neps, int ndiv)",
|
||||
doc = """ """)
|
||||
module.add_function(name = "energies_on_bz_path",
|
||||
signature = "array<double, 2> (tight_binding TB, k_t K1, k_t K2, int n_pts)",
|
||||
doc = """ """)
|
||||
module.add_function(name = "energy_matrix_on_bz_path",
|
||||
signature = "array<dcomplex, 3> (tight_binding TB, k_t K1, k_t K2, int n_pts)",
|
||||
doc = """ """)
|
||||
module.add_function(name = "energies_on_bz_grid",
|
||||
signature = "array<double, 2> (tight_binding TB, int n_pts)",
|
||||
doc = """ """)
|
||||
|
||||
########################
|
||||
## Code generation
|
||||
########################
|
||||
|
||||
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])
|
||||
|
8
pytriqs/wrap_generator/CMakeLists.txt
Normal file
8
pytriqs/wrap_generator/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
SET(PYTHON_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wrap_generator.py
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/py_converter_wrapper.mako.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wrapper.mako.cpp
|
||||
)
|
||||
|
||||
install (FILES ${PYTHON_SOURCES} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/triqs/wrap_generator)
|
||||
|
@ -57,10 +57,11 @@ class cfunction :
|
||||
def f(): # analyse the argument, be careful that , can also be in type, like A<B,C>, so we count the < >
|
||||
acc = ''
|
||||
for s in args.split(',') :
|
||||
acc += (',' if acc else '') + s
|
||||
acc += (',' if acc else '') + s.strip()
|
||||
if acc.count('<') == acc.count('>') :
|
||||
r, acc = acc,''
|
||||
yield r
|
||||
|
||||
args = [ re.sub('=',' ',x).split() for x in f() if x] # list of (type, name, default) or (type, name)
|
||||
else:
|
||||
self.rtype = kw.pop("rtype", None)
|
||||
@ -351,12 +352,17 @@ class class_ :
|
||||
All arguments passed by keywords to function_ construction
|
||||
"""
|
||||
assert 'c_name' not in kw, "No c_name here"
|
||||
assert 'calling_pattern' not in kw, "No calling_pattern here"
|
||||
f = cfunction(c_name = "__init__", is_constructor = True, **kw)
|
||||
#assert 'calling_pattern' not in kw, "No calling_pattern here"
|
||||
if 'calling_pattern' not in kw : kw['c_name'] = "__init__"
|
||||
f = cfunction(is_constructor = True, **kw)
|
||||
build_type = regular_type_if_view_else_type(self.c_type) if self.c_type_is_view and build_from_regular_type else self.c_type
|
||||
all_args = ",".join([ ('*' if t in module_.wrapped_types else '') + n for t,n,d in f.args])
|
||||
#all_args = ",".join([ ('*' if t in module_.wrapped_types else '') + n + (' = ' + d if d else '') for t,n,d in f.args])
|
||||
f._calling_pattern = "((%s *)self)->_c ->"%self.py_type + ('operator =' if not self.c_type_is_view else 'rebind') + " (%s (%s));"%(build_type,all_args)
|
||||
if 'calling_pattern' not in kw :
|
||||
f._calling_pattern = "((%s *)self)->_c ->"%self.py_type + ('operator =' if not self.c_type_is_view else 'rebind') + " (%s (%s));"%(build_type,all_args)
|
||||
else :
|
||||
f._calling_pattern = kw['calling_pattern'] + "\n ((%s *)self)->_c ->"%self.py_type + ('operator =' if not self.c_type_is_view else 'rebind') + " (std::move(result));"
|
||||
|
||||
if not self.constructor :
|
||||
self.constructor = pyfunction(py_name = "__init__", **kw)
|
||||
self.constructor.is_constructor = True
|
||||
|
@ -150,11 +150,18 @@ static PyObject* ${c.py_type}_new(PyTypeObject *type, PyObject *args, PyObject *
|
||||
${c.py_type} *self;
|
||||
self = (${c.py_type} *)type->tp_alloc(type, 0);
|
||||
if (self != NULL) {
|
||||
try {
|
||||
%if not c.c_type_is_view :
|
||||
self->_c = new ${c.c_type}{};
|
||||
%else :
|
||||
self->_c = new ${c.c_type}{typename ${c.c_type}::regular_type{}}; // no default constructor for views
|
||||
%endif
|
||||
}
|
||||
catch (std::exception const & e) {
|
||||
std::cout << e.what()<<std::endl;
|
||||
PyErr_SetString(PyExc_RuntimeError, "Default constructor of class ${c.py_type} is throwing an exception !");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
from pytriqs.lattice.tight_binding import *
|
||||
|
||||
# Define the Bravais Lattice : a square lattice in 2d
|
||||
BL = BravaisLattice(units = [(1,0,0) , (0,1,0) ], orbital_positions= {"" : (0,0,0)} )
|
||||
BL = BravaisLattice(units = [(1,0,0) , (0,1,0) ])
|
||||
|
||||
# Prepare a nearest neighbour hopping on BL
|
||||
t = -1.00 # First neighbour Hopping
|
||||
|
@ -44,7 +44,7 @@ namespace lattice {
|
||||
bravais_lattice(matrix<double> const& units, std::vector<r_t> atom_orb_pos)
|
||||
: bravais_lattice(units, atom_orb_pos, std::vector<std::string>(atom_orb_pos.size(), "")) {}
|
||||
bravais_lattice(matrix<double> const& units) : bravais_lattice(units, std::vector<r_t>{{0, 0, 0}}) {}
|
||||
bravais_lattice() : bravais_lattice(arrays::make_unit_matrix<double>(3)) {}
|
||||
bravais_lattice() : bravais_lattice(arrays::make_unit_matrix<double>(2)) {}
|
||||
|
||||
int n_orbitals() const { return atom_orb_name.size(); }
|
||||
arrays::matrix_const_view<double> units() const { return units_; }
|
||||
|
@ -38,6 +38,8 @@ namespace lattice {
|
||||
public:
|
||||
///
|
||||
tight_binding(bravais_lattice const& bl, std::vector<std::vector<long>> all_disp, std::vector<matrix<dcomplex>> all_matrices);
|
||||
|
||||
tight_binding() = default;
|
||||
|
||||
/// Underlying lattice
|
||||
bravais_lattice const& lattice() const { return bl_; }
|
||||
|
@ -301,6 +301,38 @@ template <typename T> struct py_converter<std::vector<T>> {
|
||||
}
|
||||
};
|
||||
|
||||
// --- pair ---
|
||||
|
||||
template <typename T1, typename T2> struct py_converter<std::pair<T1,T2>> {
|
||||
static PyObject * c2py(std::pair<T1,T2> const &p) {
|
||||
PyObject * list = PyList_New(0);
|
||||
if (PyList_Append(list, py_converter<T1>::c2py(std::get<0>(p))) == -1) { Py_DECREF(list); return NULL;} // error
|
||||
if (PyList_Append(list, py_converter<T2>::c2py(std::get<1>(p))) == -1) { Py_DECREF(list); return NULL;} // error
|
||||
return list;
|
||||
}
|
||||
|
||||
static bool is_convertible(PyObject *ob, bool raise_exception) {
|
||||
if (!PySequence_Check(ob)) goto _false;
|
||||
{
|
||||
pyref seq = PySequence_Fast(ob, "expected a sequence");
|
||||
if (!py_converter<T1>::is_convertible(PySequence_Fast_GET_ITEM((PyObject*)seq, 0),raise_exception)) goto _false; //borrowed ref
|
||||
if (!py_converter<T2>::is_convertible(PySequence_Fast_GET_ITEM((PyObject*)seq, 1),raise_exception)) goto _false; //borrowed ref
|
||||
return true;
|
||||
}
|
||||
_false:
|
||||
if (raise_exception) { PyErr_SetString(PyExc_TypeError, "Can not convert to std::pair");}
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::pair<T1,T2> py2c(PyObject * ob) {
|
||||
pyref seq = PySequence_Fast(ob, "expected a sequence");
|
||||
return std::make_pair(
|
||||
py_converter<T1>::py2c(PySequence_Fast_GET_ITEM((PyObject*)seq, 0)),
|
||||
py_converter<T2>::py2c(PySequence_Fast_GET_ITEM((PyObject*)seq, 1))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// --- mini_vector<T,N>---
|
||||
// via std::vector
|
||||
template <typename T, int N> struct py_converter<triqs::utility::mini_vector<T,N>> {
|
||||
@ -339,6 +371,10 @@ template <typename T, int R> struct py_converter<triqs::arrays::array_view<T, R>
|
||||
template <typename T> struct py_converter<triqs::arrays::matrix_view<T>> : py_converter_array<triqs::arrays::matrix_view<T>> {};
|
||||
template <typename T> struct py_converter<triqs::arrays::vector_view<T>> : py_converter_array<triqs::arrays::vector_view<T>> {};
|
||||
|
||||
template <typename T, int R> struct py_converter<triqs::arrays::array_const_view<T, R>> : py_converter_array<triqs::arrays::array_const_view<T, R>> {};
|
||||
template <typename T> struct py_converter<triqs::arrays::matrix_const_view<T>> : py_converter_array<triqs::arrays::matrix_const_view<T>> {};
|
||||
template <typename T> struct py_converter<triqs::arrays::vector_const_view<T>> : py_converter_array<triqs::arrays::vector_const_view<T>> {};
|
||||
|
||||
template <typename T, int R> struct py_converter<triqs::arrays::array<T, R>> : py_converter_array<triqs::arrays::array<T, R>> {};
|
||||
template <typename T> struct py_converter<triqs::arrays::matrix<T>> : py_converter_array<triqs::arrays::matrix<T>> {};
|
||||
template <typename T> struct py_converter<triqs::arrays::vector<T>> : py_converter_array<triqs::arrays::vector<T>> {};
|
||||
|
Loading…
Reference in New Issue
Block a user