103 const std::vector<Complex>& total_potential_g) {
109 int number_of_species =
static_cast<int>(pseudopotential_set.size());
120 struct SpeciesAuxData {
121 int number_of_projectors;
123 std::vector<Complex> v_conj_times_q;
125 std::vector<std::pair<int, int>> upper_triangle_pairs;
127 std::vector<SpeciesAuxData> species_aux(number_of_species);
129 for (
int species_index = 0; species_index < number_of_species; ++species_index) {
130 int number_of_projectors = projector_mapping.number_of_channels(species_index);
131 species_aux[species_index].number_of_projectors = number_of_projectors;
139 if (!pseudopotential_set[species_index].has_augmentation_charges()) {
143 auto& aux = species_aux[species_index];
145 for (
int projector_index_i = 0; projector_index_i < number_of_projectors;
146 ++projector_index_i) {
147 for (
int projector_index_j = projector_index_i;
148 projector_index_j < number_of_projectors;
149 ++projector_index_j) {
150 aux.upper_triangle_pairs.emplace_back(projector_index_i, projector_index_j);
154 int number_of_pairs =
static_cast<int>(aux.upper_triangle_pairs.size());
155 aux.v_conj_times_q.resize(
static_cast<size_t>(number_of_pairs) * number_of_g_vectors);
157 for (
int pair_index = 0; pair_index < number_of_pairs; ++pair_index) {
158 auto [proj_i, proj_j] = aux.upper_triangle_pairs[pair_index];
159 int channel_pair_index = proj_i * number_of_projectors + proj_j;
161 species_index, channel_pair_index, number_of_g_vectors);
163 Complex* dest = aux.v_conj_times_q.data() +
164 static_cast<size_t>(pair_index) * number_of_g_vectors;
165 for (
int g_index = 0; g_index < number_of_g_vectors; ++g_index) {
170 dest[g_index] = std::conj(total_potential_g[g_index]) * q_g_data[g_index];
185 for (
int atom_index = 0; atom_index < number_of_atoms; ++atom_index) {
187 const auto& aux = species_aux[species_type_index];
188 int number_of_projectors = aux.number_of_projectors;
192 for (
int projector_index_i = 0; projector_index_i < number_of_projectors;
193 ++projector_index_i) {
194 for (
int projector_index_j = 0; projector_index_j < number_of_projectors;
195 ++projector_index_j) {
197 projector_mapping.combined_lm_index(species_type_index, projector_index_i);
199 projector_mapping.combined_lm_index(species_type_index, projector_index_j);
200 if (combined_lm_i == combined_lm_j) {
201 int projector_beta_index_i =
202 projector_mapping.to_beta_index(species_type_index, projector_index_i);
203 int projector_beta_index_j =
204 projector_mapping.to_beta_index(species_type_index, projector_index_j);
207 pseudopotential_set[species_type_index]
208 .d_ion_matrix[projector_beta_index_i][projector_beta_index_j];
215 if (cached_structure_factors_.empty()) {
220 for (
int species_index = 0; species_index < number_of_species; ++species_index) {
221 if (!pseudopotential_set[species_index].has_augmentation_charges()) {
225 const auto& aux = species_aux[species_index];
226 int number_of_pairs =
static_cast<int>(aux.upper_triangle_pairs.size());
227 int number_of_projectors = aux.number_of_projectors;
230 std::vector<int> species_atom_indices;
231 for (
int atom_index = 0; atom_index < number_of_atoms; ++atom_index) {
233 species_atom_indices.push_back(atom_index);
236 int number_of_atoms_of_species =
static_cast<int>(species_atom_indices.size());
239 std::vector<Complex> structure_factor_matrix(
static_cast<size_t>(number_of_g_vectors) *
240 number_of_atoms_of_species);
241 for (
int local_atom = 0; local_atom < number_of_atoms_of_species; ++local_atom) {
242 int atom_index = species_atom_indices[local_atom];
243 const auto& structure_factor = cached_structure_factors_[atom_index];
244 std::copy(structure_factor.begin(),
245 structure_factor.end(),
246 structure_factor_matrix.begin() +
247 static_cast<size_t>(local_atom) * number_of_g_vectors);
255 std::vector<Complex> all_integrals(
static_cast<size_t>(number_of_pairs) *
256 number_of_atoms_of_species);
262 &number_of_atoms_of_species,
263 &number_of_g_vectors,
265 aux.v_conj_times_q.data(),
266 &number_of_g_vectors,
267 structure_factor_matrix.data(),
268 &number_of_g_vectors,
270 all_integrals.data(),
279 Real gamma_scale = is_gamma_only ? 2.0 : 1.0;
288 std::vector<Real> g0_correction;
290 g0_correction.resize(number_of_pairs, 0.0);
291 for (
int pair_index = 0; pair_index < number_of_pairs; ++pair_index) {
294 aux.v_conj_times_q[
static_cast<size_t>(pair_index) * number_of_g_vectors];
295 g0_correction[pair_index] = std::real(g0_val) * cell_volume;
299 for (
int local_atom = 0; local_atom < number_of_atoms_of_species; ++local_atom) {
300 int atom_index = species_atom_indices[local_atom];
302 all_integrals.data() +
static_cast<size_t>(local_atom) * number_of_pairs;
303 for (
int pair_index = 0; pair_index < number_of_pairs; ++pair_index) {
304 auto [proj_i, proj_j] = aux.upper_triangle_pairs[pair_index];
306 std::real(integrals[pair_index]) * cell_volume * gamma_scale;
308 if (is_gamma_only && !g0_correction.empty()) {
309 contribution -= g0_correction[pair_index];
313 if (proj_i != proj_j) {