43 const Crystal& crystal_structure,
44 Real energy_cutoff_wavefunction,
45 std::vector<int>& g_vector_indices,
46 std::vector<Real>& kinetic_energy_squared,
47 const FFTGrid* fft_wave =
nullptr,
49 Real two_pi_over_lattice_parameter_squared =
54 for (
int dimension = 0; dimension < 3; dimension++) {
55 k_cartesian[dimension] = k_coordinates.
x * reciprocal_lattice[0][dimension] +
56 k_coordinates.
y * reciprocal_lattice[1][dimension] +
57 k_coordinates.
z * reciprocal_lattice[2][dimension];
60 Real wavefunction_cutoff_squared =
61 energy_cutoff_wavefunction / two_pi_over_lattice_parameter_squared;
63 g_vector_indices.clear();
64 kinetic_energy_squared.clear();
66 const auto& g_vectors = g_vectors_grid.
g_vectors();
67 int total_g =
static_cast<int>(g_vectors.size());
76 bool filter_by_ownership = (fft_wave !=
nullptr && band_size > 1);
78 for (
int g_index = 0; g_index < total_g; g_index++) {
79 if (filter_by_ownership &&
80 !fft_wave->owns_stick(
static_cast<int>(g_vectors[g_index].miller.x),
81 static_cast<int>(g_vectors[g_index].miller.y))) {
85 Vector3D k_plus_g = k_cartesian + g_vectors[g_index].g_cart;
87 if (k_plus_g_squared <=
89 g_vector_indices.push_back(g_index);
90 kinetic_energy_squared.push_back(k_plus_g_squared *
91 two_pi_over_lattice_parameter_squared);
95 std::vector<int> order(g_vector_indices.size());
96 std::iota(order.begin(), order.end(), 0);
97 std::sort(order.begin(), order.end(), [&kinetic_energy_squared](
int a,
int b) {
98 return kinetic_energy_squared[a] < kinetic_energy_squared[b];
101 std::vector<int> sorted_g_vector_indices(g_vector_indices.size());
102 std::vector<Real> sorted_kinetic_energies(kinetic_energy_squared.size());
103 for (
size_t index = 0; index < order.size(); index++) {
104 sorted_g_vector_indices[index] = g_vector_indices[order[index]];
105 sorted_kinetic_energies[index] = kinetic_energy_squared[order[index]];
107 g_vector_indices = std::move(sorted_g_vector_indices);
108 kinetic_energy_squared = std::move(sorted_kinetic_energies);