62 Real broadening_rydberg,
63 int energy_step_count = 1000,
64 Real energy_margin_rydberg = 0.05)
const {
65 if (mesh_x <= 0 || mesh_y <= 0 || mesh_z <= 0) {
66 throw std::invalid_argument(
67 "InterpolatedDensityOfStatesCalculator::compute: every mesh dimension must be "
70 if (broadening_rydberg <= 0.0) {
71 throw std::invalid_argument(
72 "InterpolatedDensityOfStatesCalculator::compute: broadening must be positive");
74 if (energy_step_count < 2) {
75 throw std::invalid_argument(
76 "InterpolatedDensityOfStatesCalculator::compute: need at least 2 energy points");
79 std::vector<std::vector<Real>> sampled_eigenvalues;
80 sampled_eigenvalues.reserve(
static_cast<std::size_t
>(mesh_x) * mesh_y * mesh_z);
81 for (
int index_x = 0; index_x < mesh_x; index_x++) {
82 for (
int index_y = 0; index_y < mesh_y; index_y++) {
83 for (
int index_z = 0; index_z < mesh_z; index_z++) {
85 static_cast<Real>(index_y) / mesh_y,
86 static_cast<Real>(index_z) / mesh_z);
87 sampled_eigenvalues.push_back(interpolator_.
eigenvalues_at(kpoint));
92 Real minimum_energy = sampled_eigenvalues.front().front();
93 Real maximum_energy = sampled_eigenvalues.front().front();
94 for (
const std::vector<Real>& row : sampled_eigenvalues) {
95 for (
Real value : row) {
96 minimum_energy = std::min(minimum_energy, value);
97 maximum_energy = std::max(maximum_energy, value);
100 const Real cutoff = 8.0 * broadening_rydberg;
101 const Real margin = std::max(energy_margin_rydberg, cutoff);
102 minimum_energy -= margin;
103 maximum_energy += margin;
108 const Real energy_step =
109 (maximum_energy - minimum_energy) /
static_cast<Real>(energy_step_count - 1);
110 for (
int step = 0; step < energy_step_count; step++) {
121 static_cast<Real>(sampled_eigenvalues.size()));
122 for (
const std::vector<Real>& row : sampled_eigenvalues) {
123 for (
Real eigenvalue : row) {
124 int first =
static_cast<int>(
125 std::ceil((eigenvalue - cutoff - minimum_energy) / energy_step));
126 int last =
static_cast<int>(
127 std::floor((eigenvalue + cutoff - minimum_energy) / energy_step));
128 first = std::max(first, 0);
129 last = std::min(last, energy_step_count - 1);
130 for (
int step = first; step <= last; step++) {
134 normalisation * std::exp(-0.5 * offset * offset);