34#include <fmt/ranges.h>
52namespace triqs::mesh {
58 using lattice::brillouin_zone;
138 : index_(n), m_ptr_(m_ptr), data_index_(d), mesh_hash_(m_ptr->
mesh_hash()) {}
142 : index_(mp.index_), m_ptr_(mp.m_ptr_), data_index_(mp.data_index_), mesh_hash_(mp.mesh_hash_), value_(mp.value_) {}
148 [[nodiscard]]
long data_index()
const {
return data_index_; }
155 auto guard = std::lock_guard{value_mutex_};
156 return *(value_ = m_ptr_->to_value(index_));
161 [[nodiscard]] uint64_t
mesh_hash() const noexcept {
return mesh_hash_; }
172 [[deprecated(
"() is deprecated for a brzone::mesh_point_t. Use [] instead")]]
double operator()(
int d)
const {
return value()[d]; }
193 std::array<long, 3> index_ = {0, 0, 0};
194 brzone const *m_ptr_ =
nullptr;
195 long data_index_ = 0;
196 uint64_t mesh_hash_ = 0;
197 mutable std::optional<value_t> value_ = {};
198 mutable std::mutex value_mutex_ = {};
214 size_(nda::stdutil::product(
dims)),
216 s1_(dims_[1] * dims_[2]),
217 units_(nda::linalg::inv(1.0 * nda::diag(
dims)) *
bz.
units()),
218 units_inv_(nda::linalg::inv(units_)),
220 EXPECTS(dims_[0] > 0 and dims_[1] > 0 and dims_[2] > 0);
233 EXPECTS((M.shape() == std::array{3l, 3l}));
234 EXPECTS(nda::is_matrix_diagonal(M));
253 for (
auto i : nda::range(3))
254 if (n[i] < 0 or n[i] >= dims_[i])
return false;
266 return n[0] * s1_ + n[1] * s2_ + n[2];
318 EXPECTS(0 <= d and d <
size());
319 long const r0 = d % s1_;
320 return {d / s1_, r0 / s2_, r0 % s2_};
370 return nda::transpose(units_)(nda::range::all, nda::range(bz_.ndim())) * nda::basic_array_view{n}(nda::range(bz_.ndim()));
374 [[nodiscard]] C2PY_PROPERTY_GET(
dims)
auto const &
dims()
const {
return dims_; }
377 [[nodiscard]] C2PY_PROPERTY_GET(
units)
auto units()
const {
return nda::matrix_const_view<double>{units_}; }
380 [[nodiscard]] C2PY_PROPERTY_GET(
units_inv)
auto units_inv()
const {
return nda::matrix_const_view<double>{units_inv_}; }
383 [[nodiscard]] C2PY_PROPERTY_GET(
bz)
auto const &
bz() const noexcept {
return bz_; }
389 [[nodiscard]]
long size()
const {
return size_; }
410 template <
typename V>
411 requires(
is_k_expr<V> or std::ranges::contiguous_range<V> or nda::ArrayOfRank<V, 1>)
417 auto ks = nda::stack_vector<double, 3>{k[0], k[1], k[2]};
418 auto k_units = nda::transpose(units_inv_) * ks;
419 auto n = nda::stack_vector<long, 3>(nda::floor(k_units));
422 auto w = k_units - n;
425 auto dst = std::numeric_limits<double>::infinity();
428 long r1 = std::min(dims_[0], 2l);
429 long r2 = std::min(dims_[1], 2l);
430 long r3 = std::min(dims_[2], 2l);
433 nda::stack_vector<long, 3> res;
434 for (
auto const &[i1, i2, i3] : itertools::product_range(r1, r2, r3)) {
435 auto iv = nda::stack_vector<long, 3>{i1, i2, i3};
436 auto dstp = nda::linalg::norm(nda::transpose(units_) * (w - iv));
460 [[nodiscard]]
auto cend()
const {
return end(); }
476 return sout <<
"Brillouin zone mesh with " << m.
dims() <<
" k-points and an underlying " << m.
bz();
483 void serialize(
auto &ar)
const { ar & bz_ & dims_ & size_ & s2_ & s1_ & units_ & units_inv_ & mesh_hash_; }
489 void deserialize(
auto &ar) { ar & bz_ & dims_ & size_ & s2_ & s1_ & units_ & units_inv_ & mesh_hash_; }
492 [[nodiscard]]
static std::string
hdf5_format() {
return "MeshBrillouinZone"; }
502 h5::group gr = g.create_group(name);
503 h5::write_hdf5_format(gr, m);
504 h5::write(gr,
"dims", m.dims_);
505 h5::write(gr,
"brillouin_zone", m.bz_);
516 h5::group gr = g.open_group(name);
517 h5::assert_hdf5_format(gr, m,
true);
519 std::array<long, 3>
dims{};
520 if (gr.has_key(
"dims")) {
521 h5::read(gr,
"dims",
dims);
524 auto M = h5::read<matrix<long>>(gr,
"periodization_matrix");
525 dims = {M(0, 0), M(1, 1), M(2, 2)};
529 if (gr.has_key(
"brillouin_zone")) {
530 h5::read(gr,
"brillouin_zone",
bz);
531 }
else if (gr.has_key(
"bz")) {
533 h5::read(gr,
"bz",
bz);
535 std::cout <<
"WARNING: Reading old MeshBrillouinZone without BrillouinZone\n";
543 std::array<long, 3> dims_ = {0, 0, 0};
547 nda::matrix<double> units_ = nda::eye<double>(3);
548 nda::matrix<double> units_inv_ = nda::eye<double>(3);
549 uint64_t mesh_hash_ = 0;
562 auto evaluate(detail::brzone1d
const &m,
auto const &f,
double vi) {
563 long i =
static_cast<long>(std::floor(vi));
564 double w = vi - double(i);
598 template <
typename V>
599 requires(std::ranges::contiguous_range<V> or nda::ArrayOfRank<V, 1> or is_k_expr<V>)
600 auto evaluate(
brzone const &m,
auto const &f, V
const &k) {
602 return evaluate(m, f, k.value());
604 auto v_index = nda::make_regular(nda::transpose(m.
units_inv()) * nda::basic_array_view{k});
605 auto g = [&f](
long x,
long y,
long z) {
return f(
typename brzone::index_t{x, y, z}); };
606 auto [d0, d1, d2] = m.
dims();
607 return evaluate(std::tuple{detail::brzone1d{d0}, detail::brzone1d{d1}, detail::brzone1d{d2}}, g, v_index[0], v_index[1], v_index[2]);
627 template <
typename T>
648 template <BzMeshPo
int L, BzMeshPo
int R>
k_expr<
'+', L, R>
operator+(L &&l, R &&r) {
return {std::forward<L>(l), std::forward<R>(r)}; }
659 template <BzMeshPo
int L, BzMeshPo
int R>
k_expr<
'-', L, R>
operator-(L &&l, R &&r) {
return {std::forward<L>(l), std::forward<R>(r)}; }
670 template <std::
integral Int, BzMeshPo
int R>
k_expr<
'*', long, R>
operator*(Int l, R &&r) {
return {
static_cast<long>(l), std::forward<R>(r)}; }
iterator end()
Get an iterator past the last block.
iterator begin()
Get an iterator to the first block.
int size() const
Get the total number of blocks.
Provides a Brillouin zone class.
mesh_point_t()=default
Default constructor leaves the mesh point uninitialized.
brzone()=default
Default constructor constructs an empty mesh.
k_t value_t
Value type of a Brillouin Zone.
Mesh point of a triqs::mesh::brzone mesh.
mesh_point_t(mesh_point_t const &mp)
Copy constructor to handle the presence of the std::mutex object correctly.
friend std::ostream & operator<<(std::ostream &sout, mesh_point_t const &mp)
Write triqs::mesh::brzone::mesh_point_t to a std::ostream.
mesh_point_t()=default
Default constructor leaves the mesh point uninitialized.
double operator()(int d) const
Get the coordinate of the corresponding reciprocal vector .
double operator[](int i) const
Get the coordinate of the corresponding reciprocal vector .
uint64_t mesh_hash() const noexcept
Get the hash value of the parent mesh.
value_t const & value() const
Get the reciprocal vector corresponding to the mesh point.
brzone mesh_t
Parent mesh type.
mesh_t::index_t index() const
Get the index of the mesh point.
long data_index() const
Get the data index of the mesh point.
mesh_point_t(std::array< long, 3 > const &n, brzone const *m_ptr, long d)
Construct a mesh point with a given index , pointer to the Brillouin zone mesh the mesh point belongs...
Brillouin zone mesh type.
mesh_point_t operator()(index_t const &n) const
Function call operator to access a mesh point by its index .
friend void h5_write(h5::group g, std::string const &name, brzone const &m)
Write a triqs::mesh::brzone mesh to HDF5.
auto cend() const
Get a const iterator to the end of the mesh.
value_t to_value(index_t const &n) const
Map an index to its corresponding -point .
bool is_index_valid(index_t const &n) const noexcept
Check if an index is valid, i.e. corresponds to a in the first BZ.
long size() const
Get the size of the mesh, i.e. the total number of mesh points in the first BZ.
brzone(brillouin_zone const &bz, nda::matrix< long > const &M)
Construct a Brillouin zone mesh with the given periodization matrix.
auto const & dims() const
Get the number of mesh points in each of the three dimensions.
auto units() const
Get the matrix containing the scaled reciprocal basis vectors in its rows.
auto end() const
Get an iterator to the end of the mesh.
index_t to_index(closest_mesh_point_t< V > const &cmp) const
Map a given -vector or expression to the closest in the first BZ and return its index .
auto units_inv() const
Get the matrix .
static std::string hdf5_format()
Get the HDF5 format tag.
index_t closest_index(V const &k) const
Map a given -vector or expression to the closest in the first BZ and return its index .
auto const & bz() const noexcept
Get the underlying Brillouin zone.
bool operator==(brzone const &m) const
Equal-to comparison operator compares the underlying Brillouin zone and the number of k-points in eac...
index_t to_index(data_index_t d) const
Map a data index to the corresponding index .
data_index_t to_data_index(index_t const &n) const
Map an index to its corresponding data index .
std::array< long, 3 > index_t
Index type.
long data_index_t
Data index type.
mesh_point_t operator[](long d) const
Subscript operator to access a mesh point by its data index .
brillouin_zone::value_t value_t
Value type.
data_index_t to_data_index(k_expr_unary< OP, L > const &ex) const
Map an unary -expression to a data index .
index_t index_modulo(index_t const &n_tilde) const
Map an arbitrary index to the unique index in the first BZ.
friend void h5_read(h5::group g, std::string const &name, brzone &m)
Read a triqs::mesh::brzone mesh from HDF5.
mesh_point_t operator[](closest_mesh_point_t< value_t > const &cmp) const
Subscript operator to access a mesh point by a -point contained in a triqs::mesh::closest_mesh_point...
brzone(brillouin_zone const &bz, long n_k)
Construct a Brillouin zone mesh with the same number of mesh points in each direction.
uint64_t mesh_hash() const
Get the hash value of the mesh.
friend std::ostream & operator<<(std::ostream &sout, brzone const &m)
Write a triqs::mesh::brzone mesh to a std::ostream.
void serialize(auto &ar) const
Serialize the mesh to a generic archive.
void deserialize(auto &ar)
Deserialize the mesh from a generic archive.
brzone()=default
Default constructor constructs an empty mesh.
auto cbegin() const
Get a const iterator to the beginning of the mesh.
data_index_t to_data_index(k_expr< OP, L, R > const &ex) const
Map a binary -expression to a data index .
auto begin() const
Get an iterator to the beginning of the mesh.
data_index_t to_data_index(closest_mesh_point_t< V > const &cmp) const
Map a -vector to its data index .
brzone(brillouin_zone const &bz, std::array< long, 3 > const &dims)
Construct a Brillouin zone mesh with the given number of mesh points.
Concept for a Brillouin zone mesh point.
k_expr<'+', L, R > operator+(L &&l, R &&r)
Lazy addition of two triqs::mesh::BzMeshPoint objects.
k_expr_unary<'-', L > operator-(L &&l)
Lazy unary minus for triqs::mesh::BzMeshPoint objects.
k_expr<' *', long, R > operator*(Int l, R &&r)
Lazy multiplication of a triqs::mesh::BzMeshPoint object with a scalar.
constexpr bool is_k_expr
Type trait to check if a type is a triqs::mesh::k_expr or triqs::mesh::k_expr_unary.
uint64_t hash(Ts &&...ts)
Generic hash function for multiple arguments.
long positive_modulo(long x, long y)
Calculate the positive modulo of two integer numbers.
Provides expression templates for -vectors.
Common macros used in TRIQS.
Provides various utilities used with Meshes.
Provides a generic random access iterator for 1D meshes.
constexpr nda::clef::placeholder< 3 > w
Placeholder for the frequency .
Lazy struct used in various function overloads as a placeholder for the closest mesh point to a given...
T value
Use the mesh point closest to this value.
Unary minus -vector expression.
auto index() const
Get the index of the reciprocal vector (see triqs::mesh::brzone::mesh_point_t::index()).
uint64_t mesh_hash() const
Get the hash value of the mesh to which the operand belongs.
Binary -vector expression.
uint64_t mesh_hash() const
Get the hash value of the mesh to which the right hand side operand belongs.
auto index() const
Get the index of the -vector corresponding to the evaluated expression.
A generic random access iterator for 1D meshes.