1#include "./superlattice.hpp"
4#include <itertools/itertools.hpp>
16namespace triqs::experimental::lattice {
18 constexpr auto all_ = nda::range::all;
20 superlattice::superlattice(nda::array<long, 2> sl_units, nda::array<long, 2> cluster_pts) : units(sl_units), cluster_points(cluster_pts) {
22 if (
n_cluster_sites() == 0)
throw std::runtime_error{
"Superlattice must have at least one cluster point."};
23 TRIQS_ASSERT((units.shape() == std::array{dim(), dim()}));
25 transfo_SL_L = nda::matrix<double>{
transpose(units)};
27 if (abs(nda::linalg::det(transfo_SL_L)) !=
static_cast<double>(
n_cluster_sites()))
28 throw std::runtime_error{
"Mismatch between det(superlattice vectors) and number of cluster points!"};
29 transfo_SL_L = nda::linalg::inv(transfo_SL_L);
36 auto R1 = nda::vector<double>(r_l);
37 auto R = transfo_SL_L * r_l;
38 nda::vector<long> R_rounded = nda::map([](
double x) {
return std::round(x); })(R);
39 if (max_element(abs(R - R_rounded)) < epsilon) {
48 template <
int D,
typename V> std::array<long, D> make_std_array_from_vector(V
const &vec) {
49 if (vec.size() != D)
throw std::runtime_error(
"make_std_array_from_vector. Vector size does not match the array size.");
50 std::array<long, D> arr{};
51 for (
int i = 0; i < D; ++i) arr[i] = vec[i];
59 using itertools::enumerate;
60 if (sl.
dim() != kdim)
throw std::runtime_error(
"Superlattice dimension does not match the Fourier polynomial dimension.");
64 auto orb_range = [&](
long a) {
return nda::range(a * n_orb_L, (a + 1) * n_orb_L); };
67 std::vector<std::array<long, kdim>> SL_R_list;
68 std::map<std::array<long, kdim>,
long> SL_R_idx;
69 std::vector<nda::array<dcomplex, 2>> SL_coeff_list;
74 auto ai = cpts(i, all_);
75 auto aj = cpts(j, all_);
76 for (
auto &&[r_idx, r] : enumerate(fp.
get_R_list())) {
77 auto r1 = nda::vector<long>(kdim);
78 for (
int u = 0; u < kdim; ++u) r1[u] = r[u] + ai[u] - aj[u];
79 auto R_rounded = sl.
L_to_SL(r1);
81 auto R_rounded_2 = detail::make_std_array_from_vector<kdim>(R_rounded.value());
82 auto [it, is_new] = SL_R_idx.emplace(R_rounded_2, SL_R_list.size());
84 SL_R_list.push_back(R_rounded_2);
85 SL_coeff_list.emplace_back(nda::zeros<dcomplex>(n_orb_SL, n_orb_SL));
87 SL_coeff_list[it->second](orb_range(i), orb_range(j)) += fp[r_idx];
91 return {std::move(SL_R_list), std::move(SL_coeff_list)};
96 template fourier_polynomial<2, 3>
fold(superlattice
const &sl, fourier_polynomial<2, 3>
const &fp);
97 template fourier_polynomial<2, 2>
fold(superlattice
const &sl, fourier_polynomial<2, 2>
const &fp);
98 template fourier_polynomial<2, 1>
fold(superlattice
const &sl, fourier_polynomial<2, 1>
const &fp);
Owning container for a Fourier-series representation of a lattice function.
auto const & get_R_list() const
Get the list of real-space lattice vectors.
auto get_coeff_arr()
Get the packed coefficient array.
Representation of a superlattice built on top of an underlying Bravais lattice.
auto const & get_cluster_pts() const
Get the cluster points of the superlattice.
std::optional< nda::vector< long > > L_to_SL(nda::vector< long > const &r_l, double epsilon=1.e-12) const
Transform a point from lattice coordinates to superlattice coordinates.
long dim() const
Get the dimension of the superlattice.
long n_cluster_sites() const
Get the number of cluster sites in one superlattice unit cell.
superlattice(nda::array< long, 2 > sl_units, nda::array< long, 2 > cluster_pts)
Construct a superlattice from its unit vectors and cluster points.
TRIQS exception hierarchy and related macros.
fourier_polynomial< 2, kdim > fold(superlattice const &sl, fourier_polynomial< 2, kdim > const &fp)
Fold a Fourier polynomial defined on a lattice onto a superlattice.
gf< M, matrix_valued > transpose(gf_view< M, matrix_valued > g)
Transpose the target matrix of a matrix-valued Green's function, returning a new Green's function.
#define TRIQS_ASSERT(X)
Throw a triqs::runtime_error if the boolean expression X evaluates to false.