///
/// Functions and classes for manipulating k-points
///
/// @author: Junyi Wang (jywang)
///

#ifndef TBPLAS_BASE_KPOINTS_H
#define TBPLAS_BASE_KPOINTS_H

#include <tuple>
#include <vector>

#include <eigen3/Eigen/Dense>

namespace tbplas::base {
/// @brief Generate path in the reciprocal space connecting highly symmetric k-points.
/// @param[in] hs_kpoints fractional coordinates of highly symmetric k-points in COLUMN_WISE order
/// @param[in] num_interp numbers of intermediate k-points between two highly symmetric k-points
/// @return {kpath, hs_index}\n
/// kpath: fractional coordinates of k-points along the path in COLUMN_WISE order\n
/// hs_index: indices of highly symmetric k-points in kpath
std::tuple<Eigen::Matrix3Xd, Eigen::VectorXi> gen_kpath(const Eigen::Matrix3Xd& hs_kpoints, const std::vector<int>& num_interp);

/// @brief Convert k_path generated by gen_path into distances in reciprocal space.
/// @param[in] lattice_vectors Cartesian coordinates of lattice vectors in ROW_WISE order
/// @param[in] kpoints fractional coordinates of kpoints in COLUMN_WISE order
/// @return distance in reciprocal space in same unit as reciprocal lattice vectors
Eigen::VectorXd gen_kdist(const Eigen::Matrix3d& lat_vec, const Eigen::Matrix3Xd& kpoints);

/// @brief Generate uniform mesh grid in the first Brillouin zone.
/// @param[in] grid_size dimension of mesh grid along three directions
/// @return fractional coordinates of kpoints in the grid
Eigen::Matrix3Xd gen_kmesh(const std::tuple<int, int, int>& grid_size);

} // namespace tbplas::base

#endif