93 pseudopotential_set, cell_volume, q_spacing_, number_of_q_points_);
95 log::info(
" Atomic wavefunctions interpolation table initialized ({} q-points, dq={})",
111 int number_of_plane_waves,
113 const std::vector<int>& g_vector_indices,
114 const Crystal& crystal_structure,
118 std::vector<std::vector<Complex>>& atomic_wavefunctions) {
124 std::vector<std::vector<Complex>> pure_atomic_orbitals;
126 number_of_plane_waves,
132 atomic_wavefunction_table_,
135 pure_atomic_orbitals);
137 int number_of_atomic_wavefunctions =
static_cast<int>(pure_atomic_orbitals.size());
138 int total_wavefunction_count = std::max(number_of_atomic_wavefunctions, number_of_bands);
139 atomic_wavefunctions.assign(total_wavefunction_count,
140 std::vector<Complex>(number_of_plane_waves,
Complex(0.0, 0.0)));
141 for (
int wavefunction_index = 0; wavefunction_index < number_of_atomic_wavefunctions;
142 wavefunction_index++) {
143 atomic_wavefunctions[wavefunction_index] =
144 std::move(pure_atomic_orbitals[wavefunction_index]);
158 static constexpr int default_random_seed = 42;
159 std::mt19937 random_number_generator(default_random_seed +
161 std::uniform_real_distribution<Real> distribution(0.0, 1.0);
163 if (number_of_atomic_wavefunctions >= number_of_bands) {
164 for (
int wavefunction_loop_index = 0;
165 wavefunction_loop_index < total_wavefunction_count;
166 wavefunction_loop_index++) {
167 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
168 Real random_amplitude = distribution(random_number_generator);
169 Real random_phase = distribution(random_number_generator);
171 atomic_wavefunctions[wavefunction_loop_index][g_index] *=
172 (1.0 + 0.0 *
Complex(random_amplitude * std::cos(perturbation_arg),
173 random_amplitude * std::sin(perturbation_arg)));
187 const Vector3D& kpoint_coordinates = kpoint_grid[kpoint_index].coordinates;
188 for (
int wavefunction_loop_index = number_of_atomic_wavefunctions;
189 wavefunction_loop_index < total_wavefunction_count;
190 wavefunction_loop_index++) {
191 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
193 planewave_basis.
g_vectors()[g_vector_indices[g_index]].miller;
194 Real random_amplitude = hashed_unit_interval(
195 kpoint_coordinates, wavefunction_loop_index, miller, 0);
196 Real random_phase = hashed_unit_interval(
197 kpoint_coordinates, wavefunction_loop_index, miller, 1);
199 atomic_wavefunctions[wavefunction_loop_index][g_index] =
200 Complex(random_amplitude * std::cos(phase_argument),
201 random_amplitude * std::sin(phase_argument));
227 int kpoint_index_state,
228 int number_of_plane_waves,
230 const std::vector<int>& g_vector_indices,
231 const std::vector<Real>& kinetic_energy_squared,
232 const std::vector<Real>& smooth_potential,
233 const Crystal& crystal_structure,
238 const std::vector<std::vector<Complex>>& atomic_wavefunctions,
241 int number_of_starting_wavefunctions =
static_cast<int>(atomic_wavefunctions.size());
242 int leading_dimension = std::max(number_of_plane_waves, 1);
248 std::vector<Complex> contiguous_wavefunctions(
static_cast<size_t>(number_of_plane_waves) *
249 number_of_starting_wavefunctions,
251 for (
int wavefunction_index = 0; wavefunction_index < number_of_starting_wavefunctions;
252 wavefunction_index++) {
253 std::memcpy(&contiguous_wavefunctions[wavefunction_index * number_of_plane_waves],
254 atomic_wavefunctions[wavefunction_index].data(),
255 number_of_plane_waves *
sizeof(
Complex));
259 std::vector<Complex> contiguous_hamiltonian_wavefunctions(
260 static_cast<size_t>(number_of_plane_waves) * number_of_starting_wavefunctions,
262 apply_hamiltonian_batch_contiguous(number_of_plane_waves,
263 number_of_starting_wavefunctions,
265 kinetic_energy_squared,
272 pseudopotential_quantum_system,
273 precomputed_kleinman_bylander_potential,
274 contiguous_wavefunctions.
data(),
275 contiguous_hamiltonian_wavefunctions.data());
286 std::vector<Complex> contiguous_overlap_storage;
287 Complex* contiguous_overlap_wavefunctions = contiguous_wavefunctions.data();
290 contiguous_overlap_storage.assign(contiguous_wavefunctions.begin(),
291 contiguous_wavefunctions.end());
292 contiguous_overlap_wavefunctions = contiguous_overlap_storage.data();
293 apply_overlap_contiguous(number_of_plane_waves,
294 number_of_starting_wavefunctions,
297 pseudopotential_quantum_system,
298 precomputed_kleinman_bylander_potential,
299 contiguous_wavefunctions.
data(),
300 contiguous_overlap_wavefunctions);
304 std::vector<Complex> hamiltonian_matrix(
305 static_cast<size_t>(number_of_starting_wavefunctions) *
306 number_of_starting_wavefunctions,
308 std::vector<Complex> overlap_matrix(
static_cast<size_t>(number_of_starting_wavefunctions) *
309 number_of_starting_wavefunctions,
312 std::complex<double> alpha_one(1.0, 0.0);
313 std::complex<double> beta_zero(0.0, 0.0);
315 auto* cast_wavefunctions =
316 reinterpret_cast<std::complex<double>*
>(contiguous_wavefunctions.data());
317 auto* cast_hamiltonian_wavefunctions =
318 reinterpret_cast<std::complex<double>*
>(contiguous_hamiltonian_wavefunctions.data());
319 auto* cast_overlap_wavefunctions =
320 reinterpret_cast<std::complex<double>*
>(contiguous_overlap_wavefunctions);
329 int leading_dimension = std::max(number_of_plane_waves, 1);
330 int double_number_of_plane_waves = 2 * number_of_plane_waves;
331 int double_leading_dimension = 2 * leading_dimension;
332 double alpha_two = 2.0;
333 double d_beta_zero = 0.0;
335 auto* real_wavefunctions =
reinterpret_cast<double*
>(contiguous_wavefunctions.data());
336 auto* real_hamiltonian_wavefunctions =
337 reinterpret_cast<double*
>(contiguous_hamiltonian_wavefunctions.data());
338 auto* real_overlap_wavefunctions =
339 reinterpret_cast<double*
>(contiguous_overlap_wavefunctions);
342 std::vector<double> hamiltonian_matrix_real(
343 static_cast<size_t>(number_of_starting_wavefunctions) *
344 number_of_starting_wavefunctions,
348 &number_of_starting_wavefunctions,
349 &number_of_starting_wavefunctions,
350 &double_number_of_plane_waves,
353 &double_leading_dimension,
354 real_hamiltonian_wavefunctions,
355 &double_leading_dimension,
357 hamiltonian_matrix_real.data(),
358 &number_of_starting_wavefunctions);
361 std::vector<double> overlap_matrix_real(
362 static_cast<size_t>(number_of_starting_wavefunctions) *
363 number_of_starting_wavefunctions,
367 &number_of_starting_wavefunctions,
368 &number_of_starting_wavefunctions,
369 &double_number_of_plane_waves,
372 &double_leading_dimension,
373 real_overlap_wavefunctions,
374 &double_leading_dimension,
376 overlap_matrix_real.data(),
377 &number_of_starting_wavefunctions);
381 for (
int column = 0; column < number_of_starting_wavefunctions; ++column) {
383 contiguous_hamiltonian_wavefunctions[column * number_of_plane_waves];
385 contiguous_overlap_wavefunctions[column * number_of_plane_waves];
386 for (
int row = 0; row < number_of_starting_wavefunctions; ++row) {
387 Complex left_g0 = contiguous_wavefunctions[row * number_of_plane_waves];
388 int index = column * number_of_starting_wavefunctions + row;
389 hamiltonian_matrix_real[index] -= (std::conj(left_g0) * h_right_g0).real();
390 overlap_matrix_real[index] -= (std::conj(left_g0) * s_right_g0).real();
397 index < number_of_starting_wavefunctions * number_of_starting_wavefunctions;
399 hamiltonian_matrix[index] =
Complex(hamiltonian_matrix_real[index], 0.0);
400 overlap_matrix[index] =
Complex(overlap_matrix_real[index], 0.0);
403 int leading_dimension = std::max(number_of_plane_waves, 1);
410 &number_of_starting_wavefunctions,
411 &number_of_starting_wavefunctions,
412 &number_of_plane_waves,
416 cast_hamiltonian_wavefunctions,
419 reinterpret_cast<std::complex<double>*
>(hamiltonian_matrix.data()),
420 &number_of_starting_wavefunctions);
425 &number_of_starting_wavefunctions,
426 &number_of_starting_wavefunctions,
427 &number_of_plane_waves,
431 cast_overlap_wavefunctions,
434 reinterpret_cast<std::complex<double>*
>(overlap_matrix.data()),
435 &number_of_starting_wavefunctions);
445 reinterpret_cast<std::vector<Real>&
>(hamiltonian_matrix));
447 reinterpret_cast<std::vector<Real>&
>(overlap_matrix));
454 std::vector<Real> subspace_eigenvalues(number_of_starting_wavefunctions, 0.0);
456 int eigenproblem_type = 1;
460 int matrix_size = number_of_starting_wavefunctions * number_of_starting_wavefunctions;
461 std::vector<Real> hamiltonian_real(matrix_size);
462 std::vector<Real> overlap_real(matrix_size);
463 for (
int matrix_element_index = 0; matrix_element_index < matrix_size;
464 ++matrix_element_index) {
465 hamiltonian_real[matrix_element_index] =
466 hamiltonian_matrix[matrix_element_index].real();
467 overlap_real[matrix_element_index] = overlap_matrix[matrix_element_index].real();
470 int work_size = std::max(1, 3 * number_of_starting_wavefunctions - 1);
471 std::vector<Real> work(work_size);
472 Real optimal_work_size;
474 dsygv_(&eigenproblem_type,
477 &number_of_starting_wavefunctions,
478 hamiltonian_real.data(),
479 &number_of_starting_wavefunctions,
481 &number_of_starting_wavefunctions,
482 subspace_eigenvalues.data(),
486 work_size =
static_cast<int>(optimal_work_size);
487 work.resize(work_size);
489 dsygv_(&eigenproblem_type,
492 &number_of_starting_wavefunctions,
493 hamiltonian_real.data(),
494 &number_of_starting_wavefunctions,
496 &number_of_starting_wavefunctions,
497 subspace_eigenvalues.data(),
503 for (
int matrix_element_index = 0; matrix_element_index < matrix_size;
504 ++matrix_element_index) {
505 hamiltonian_matrix[matrix_element_index] =
506 Complex(hamiltonian_real[matrix_element_index], 0.0);
509 int work_size = 2 * number_of_starting_wavefunctions +
510 number_of_starting_wavefunctions * number_of_starting_wavefunctions;
511 std::vector<Complex> complex_work_space(work_size);
512 std::vector<Real> real_work_space(
513 std::max(1, 3 * number_of_starting_wavefunctions - 2));
515 zhegv_(&eigenproblem_type,
518 &number_of_starting_wavefunctions,
519 reinterpret_cast<std::complex<double>*
>(hamiltonian_matrix.data()),
520 &number_of_starting_wavefunctions,
521 reinterpret_cast<std::complex<double>*
>(overlap_matrix.data()),
522 &number_of_starting_wavefunctions,
523 subspace_eigenvalues.data(),
524 reinterpret_cast<std::complex<double>*
>(complex_work_space.data()),
526 real_work_space.data(),
531 log::error(
"LAPACK eigensolver failed in rotate_wavefunctions with info = {}", info);
535 for (
int band_index = 0; band_index < number_of_bands; band_index++) {
537 kpoint_index_state, band_index, subspace_eigenvalues[band_index]);
545 std::vector<Complex> rotated_wavefunctions(
546 static_cast<size_t>(number_of_plane_waves) * number_of_bands,
Complex(0.0, 0.0));
550 &number_of_plane_waves,
552 &number_of_starting_wavefunctions,
556 reinterpret_cast<std::complex<double>*
>(hamiltonian_matrix.data()),
557 &number_of_starting_wavefunctions,
559 reinterpret_cast<std::complex<double>*
>(rotated_wavefunctions.data()),
576 for (
int band_index = 0; band_index < number_of_bands; ++band_index) {
578 rotated_wavefunctions[band_index * number_of_plane_waves];
579 g_zero_coefficient =
Complex(g_zero_coefficient.real(), 0.0);
584 for (
int band_index = 0; band_index < number_of_bands; band_index++) {
587 std::memcpy(band_data,
588 &rotated_wavefunctions[band_index * number_of_plane_waves],
589 number_of_plane_waves *
sizeof(
Complex));
601 [[nodiscard]]
static Real hashed_unit_interval(
const Vector3D& kpoint_coordinates,
605 auto mix = [](std::uint64_t value) {
606 value += 0x9E3779B97F4A7C15ULL;
607 value = (value ^ (value >> 30)) * 0xBF58476D1CE4E5B9ULL;
608 value = (value ^ (value >> 27)) * 0x94D049BB133111EBULL;
609 return value ^ (value >> 31);
615 constexpr Real kpoint_resolution = 1.0e9;
616 std::uint64_t state = mix(0x51A3C0FFEEULL);
617 for (
Real component : {kpoint_coordinates.
x, kpoint_coordinates.
y, kpoint_coordinates.
z}) {
619 static_cast<std::uint64_t
>(std::llround(component * kpoint_resolution)));
621 state = mix(state ^
static_cast<std::uint64_t
>(vector_index));
622 for (
int component : {miller.
x, miller.
y, miller.
z}) {
623 state = mix(state ^
static_cast<std::uint64_t
>(
static_cast<std::int64_t
>(component)));
625 state = mix(state ^
static_cast<std::uint64_t
>(stream));
626 return static_cast<Real>(state >> 11) * 0x1.0p-53;
630 std::vector<std::vector<std::vector<Real>>> atomic_wavefunction_table_;
633 int number_of_q_points_ = 0;
643 static void apply_hamiltonian_batch_contiguous(
644 int number_of_plane_waves,
645 int number_of_vectors,
646 const std::vector<int>& g_vector_indices,
647 const std::vector<Real>& kinetic_energy_squared,
648 const std::vector<Real>& smooth_potential,
649 const Crystal& crystal_structure,
656 const Complex* psi_wavefunctions,
657 Complex* hamiltonian_psi_wavefunctions) {
665 int transform_buffer_points =
669 std::vector<int> g_to_fft_mapping(number_of_plane_waves);
670 for (
int g_vector_index = 0; g_vector_index < number_of_plane_waves; g_vector_index++) {
671 const auto& g_vector = planewave_basis.
g_vectors()[g_vector_indices[g_vector_index]];
672 g_to_fft_mapping[g_vector_index] =
674 g_vector.miller.x, g_vector.miller.y, g_vector.miller.z);
678 std::vector<int> minus_g_to_fft_mapping;
687 minus_g_to_fft_mapping.resize(number_of_plane_waves);
688 for (
int g_vector_index = 0; g_vector_index < number_of_plane_waves; g_vector_index++) {
689 const auto& g_vector =
690 planewave_basis.
g_vectors()[g_vector_indices[g_vector_index]];
691 minus_g_to_fft_mapping[g_vector_index] =
693 -g_vector.miller.x, -g_vector.miller.y, -g_vector.miller.z);
698 std::vector<Complex> psi_real_space(transform_buffer_points,
Complex(0.0, 0.0));
702 for (
int pair_index = 0; pair_index < number_of_vectors; pair_index += 2) {
703 int band_1 = pair_index;
704 int band_2 = pair_index + 1;
705 bool has_second_band = (band_2 < number_of_vectors);
707 const Complex* psi_1 = &psi_wavefunctions[band_1 * number_of_plane_waves];
708 Complex* hpsi_1 = &hamiltonian_psi_wavefunctions[band_1 * number_of_plane_waves];
710 has_second_band ? &psi_wavefunctions[band_2 * number_of_plane_waves] :
nullptr;
712 has_second_band ? &hamiltonian_psi_wavefunctions[band_2 * number_of_plane_waves]
716 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
717 hpsi_1[g_index] = kinetic_energy_squared[g_index] * psi_1[g_index];
719 if (has_second_band) {
720 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
721 hpsi_2[g_index] = kinetic_energy_squared[g_index] * psi_2[g_index];
731 std::memset(psi_real_space.data(), 0, transform_buffer_points *
sizeof(
Complex));
733 if (has_second_band) {
736 int fft_index_0 = g_to_fft_mapping[0];
737 if (fft_index_0 >= 0) {
738 psi_real_space[fft_index_0] =
Complex(psi_1[0].real(), psi_2[0].real());
742 for (
int g_index = first_mirrored_index; g_index < number_of_plane_waves;
744 int fft_plus = g_to_fft_mapping[g_index];
745 int fft_minus = minus_g_to_fft_mapping[g_index];
750 psi_real_space[fft_plus] =
751 Complex(p1.real() - p2.imag(), p1.imag() + p2.real());
753 psi_real_space[fft_minus] =
754 Complex(p1.real() + p2.imag(), -p1.imag() + p2.real());
759 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
760 int fft_index = g_to_fft_mapping[g_index];
761 if (fft_index >= 0) {
762 psi_real_space[fft_index] = psi_1[g_index];
765 for (
int g_index = first_mirrored_index; g_index < number_of_plane_waves;
767 int fft_minus = minus_g_to_fft_mapping[g_index];
768 psi_real_space[fft_minus] = std::conj(psi_1[g_index]);
780 for (
int index_grid = 0; index_grid < local_smooth_grid_points; ++index_grid) {
781 psi_real_space[index_grid] *= smooth_potential[index_grid];
792 if (has_second_band) {
795 int fft_index_0 = g_to_fft_mapping[0];
796 if (fft_index_0 >= 0) {
797 Complex result_0 = psi_real_space[fft_index_0];
798 hpsi_1[0] +=
Complex(result_0.real(), 0.0);
799 hpsi_2[0] +=
Complex(result_0.imag(), 0.0);
803 for (
int g_index = first_mirrored_index; g_index < number_of_plane_waves;
805 int fft_plus = g_to_fft_mapping[g_index];
806 int fft_minus = minus_g_to_fft_mapping[g_index];
808 Complex result_plus = psi_real_space[fft_plus];
809 Complex result_minus_conj = std::conj(psi_real_space[fft_minus]);
811 hpsi_1[g_index] += (result_plus + result_minus_conj) * 0.5;
816 Complex diff = (result_plus - result_minus_conj) * 0.5;
817 hpsi_2[g_index] +=
Complex(diff.imag(), -diff.real());
822 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
823 int fft_index = g_to_fft_mapping[g_index];
824 if (fft_index >= 0) {
825 hpsi_1[g_index] += psi_real_space[fft_index];
832 for (
int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
834 &psi_wavefunctions[vector_index * number_of_plane_waves];
835 Complex* hamiltonian_psi_vector =
836 &hamiltonian_psi_wavefunctions[vector_index * number_of_plane_waves];
839 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
840 hamiltonian_psi_vector[g_index] =
841 kinetic_energy_squared[g_index] * psi_vector[g_index];
845 std::memset(psi_real_space.data(), 0, transform_buffer_points *
sizeof(
Complex));
846 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
847 int fft_index = g_to_fft_mapping[g_index];
848 if (fft_index >= 0) {
849 psi_real_space[fft_index] = psi_vector[g_index];
853 for (
int index_grid = 0; index_grid < local_smooth_grid_points; ++index_grid) {
854 psi_real_space[index_grid] *= smooth_potential[index_grid];
857 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
858 int fft_index = g_to_fft_mapping[g_index];
859 if (fft_index >= 0) {
860 hamiltonian_psi_vector[g_index] += psi_real_space[fft_index];
867 if (kleinman_bylander_potential.
empty()) {
871 int total_number_of_projectors =
static_cast<int>(kleinman_bylander_potential.
rows());
874 std::vector<Complex> all_overlap_coefficients(
875 static_cast<size_t>(total_number_of_projectors) * number_of_vectors,
Complex(0.0, 0.0));
877 std::complex<double> alpha_one(1.0, 0.0);
878 std::complex<double> beta_zero(0.0, 0.0);
879 std::complex<double> beta_one(1.0, 0.0);
883 int double_number_of_plane_waves = 2 * number_of_plane_waves;
884 int double_leading_dimension = std::max(double_number_of_plane_waves, 1);
885 double alpha_two = 2.0;
886 double d_beta_zero = 0.0;
888 auto* real_projectors =
reinterpret_cast<const double*
>(kleinman_bylander_potential[0]);
889 auto* real_wavefunctions =
reinterpret_cast<const double*
>(psi_wavefunctions);
891 std::vector<double> overlap_real(
892 static_cast<size_t>(total_number_of_projectors) * number_of_vectors, 0.0);
895 &total_number_of_projectors,
897 &double_number_of_plane_waves,
899 const_cast<double*
>(real_projectors),
900 &double_leading_dimension,
901 const_cast<double*
>(real_wavefunctions),
902 &double_leading_dimension,
905 &total_number_of_projectors);
908 for (
int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
909 const Complex* psi_g0 = &psi_wavefunctions[vector_index * number_of_plane_waves];
910 for (
int projector_index = 0; projector_index < total_number_of_projectors;
912 int index = projector_index + vector_index * total_number_of_projectors;
914 Complex beta_g0 = kleinman_bylander_potential(projector_index, 0);
915 overlap_real[index] -= (std::conj(beta_g0) * psi_g0[0]).real();
917 all_overlap_coefficients[index] =
Complex(overlap_real[index], 0.0);
921 int leading_dimension = std::max(number_of_plane_waves, 1);
925 &total_number_of_projectors,
927 &number_of_plane_waves,
929 reinterpret_cast<const std::complex<double>*
>(kleinman_bylander_potential[0]),
931 reinterpret_cast<const std::complex<double>*
>(psi_wavefunctions),
934 reinterpret_cast<std::complex<double>*
>(all_overlap_coefficients.data()),
935 &total_number_of_projectors);
945 reinterpret_cast<std::vector<Real>&
>(all_overlap_coefficients));
948 std::vector<Complex> scaled_overlap_coefficients(
949 static_cast<size_t>(total_number_of_projectors) * number_of_vectors,
Complex(0.0, 0.0));
951 int starting_projector_index = 0;
952 for (
int atom_index = 0; atom_index < crystal_structure.
number_of_atoms(); atom_index++) {
954 int number_of_projectors =
957 std::vector<int> angular_momentum_values;
958 for (
int index_projector = 0; index_projector < number_of_projectors;
960 int angular_momentum =
962 species_index, index_projector);
964 (void)magnetic_projection;
965 angular_momentum_values.push_back(angular_momentum);
968 int number_of_projectors_atom =
static_cast<int>(angular_momentum_values.size());
970 if (number_of_projectors_atom > 0) {
971 for (
int vector_index = 0; vector_index < number_of_vectors; vector_index++) {
973 vector_index * total_number_of_projectors + starting_projector_index;
975 vector_index * total_number_of_projectors + starting_projector_index;
976 for (
int projector_index_a = 0; projector_index_a < number_of_projectors_atom;
977 projector_index_a++) {
978 for (
int projector_index_b = 0;
979 projector_index_b < number_of_projectors_atom;
980 projector_index_b++) {
982 atom_index, species_index, projector_index_a, projector_index_b);
983 if (std::abs(d_matrix_element) >
985 scaled_overlap_coefficients[offset_out + projector_index_a] +=
987 all_overlap_coefficients[offset_in + projector_index_b];
992 starting_projector_index += number_of_projectors_atom;
996 int leading_dimension_apply = std::max(number_of_plane_waves, 1);
1000 &number_of_plane_waves,
1002 &total_number_of_projectors,
1004 reinterpret_cast<const std::complex<double>*
>(kleinman_bylander_potential[0]),
1005 &leading_dimension_apply,
1006 reinterpret_cast<const std::complex<double>*
>(scaled_overlap_coefficients.data()),
1007 &total_number_of_projectors,
1009 reinterpret_cast<std::complex<double>*
>(hamiltonian_psi_wavefunctions),
1010 &leading_dimension_apply);
1022 static void apply_overlap_contiguous(
1023 int number_of_plane_waves,
1024 int number_of_vectors,
1025 const Crystal& crystal_structure,
1029 const Complex* psi_wavefunctions,
1030 Complex* overlap_psi_wavefunctions) {
1035 int total_number_of_projectors =
static_cast<int>(kleinman_bylander_potential.
rows());
1038 std::vector<Complex> all_overlap_coefficients(
1039 static_cast<size_t>(total_number_of_projectors) * number_of_vectors,
Complex(0.0, 0.0));
1041 std::complex<double> alpha_one(1.0, 0.0);
1042 std::complex<double> beta_zero(0.0, 0.0);
1043 std::complex<double> beta_one(1.0, 0.0);
1047 if (is_gamma_only) {
1048 int double_number_of_plane_waves = 2 * number_of_plane_waves;
1049 int double_leading_dimension = std::max(double_number_of_plane_waves, 1);
1050 double alpha_two = 2.0;
1051 double double_beta_zero = 0.0;
1053 auto* real_projectors =
reinterpret_cast<const double*
>(kleinman_bylander_potential[0]);
1054 auto* real_wavefunctions =
reinterpret_cast<const double*
>(psi_wavefunctions);
1056 std::vector<double> overlap_real(
1057 static_cast<size_t>(total_number_of_projectors) * number_of_vectors, 0.0);
1060 &total_number_of_projectors,
1062 &double_number_of_plane_waves,
1064 const_cast<double*
>(real_projectors),
1065 &double_leading_dimension,
1066 const_cast<double*
>(real_wavefunctions),
1067 &double_leading_dimension,
1069 overlap_real.data(),
1070 &total_number_of_projectors);
1074 if (has_zero_g_vector) {
1075 for (
int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
1077 &psi_wavefunctions[vector_index * number_of_plane_waves];
1078 for (
int projector_index = 0; projector_index < total_number_of_projectors;
1079 ++projector_index) {
1080 Complex beta_g0 = kleinman_bylander_potential(projector_index, 0);
1081 int index = projector_index + vector_index * total_number_of_projectors;
1082 overlap_real[index] -= (std::conj(beta_g0) * psi_g0[0]).real();
1083 all_overlap_coefficients[index] =
Complex(overlap_real[index], 0.0);
1087 for (
size_t index = 0; index < overlap_real.size(); ++index) {
1088 all_overlap_coefficients[index] =
Complex(overlap_real[index], 0.0);
1092 int leading_dimension = std::max(number_of_plane_waves, 1);
1095 &total_number_of_projectors,
1097 &number_of_plane_waves,
1099 reinterpret_cast<const std::complex<double>*
>(kleinman_bylander_potential[0]),
1101 reinterpret_cast<const std::complex<double>*
>(psi_wavefunctions),
1104 reinterpret_cast<std::complex<double>*
>(all_overlap_coefficients.data()),
1105 &total_number_of_projectors);
1110 reinterpret_cast<std::vector<Real>&
>(all_overlap_coefficients));
1113 std::vector<Complex> scaled_overlap_coefficients(
1114 static_cast<size_t>(total_number_of_projectors) * number_of_vectors,
Complex(0.0, 0.0));
1116 int starting_projector_index = 0;
1117 for (
int atom_index = 0; atom_index < crystal_structure.
number_of_atoms(); atom_index++) {
1119 int number_of_beta_functions =
1122 std::vector<int> angular_momentums, magnetic_projections, beta_indices;
1123 for (
int beta_index = 0; beta_index < number_of_beta_functions; beta_index++) {
1124 int angular_momentum =
1126 element_type, beta_index);
1128 angular_momentums.push_back(angular_momentum);
1129 magnetic_projections.push_back(magnetic_projection);
1130 beta_indices.push_back(beta_index);
1133 int number_of_projectors_on_atom =
static_cast<int>(angular_momentums.size());
1134 if (number_of_projectors_on_atom > 0) {
1135 for (
int vector_index = 0; vector_index < number_of_vectors; vector_index++) {
1137 vector_index * total_number_of_projectors + starting_projector_index;
1138 for (
int projector_a_index = 0;
1139 projector_a_index < number_of_projectors_on_atom;
1140 projector_a_index++) {
1141 for (
int projector_b_index = 0;
1142 projector_b_index < number_of_projectors_on_atom;
1143 projector_b_index++) {
1144 int beta_a = beta_indices[projector_a_index];
1145 int beta_b = beta_indices[projector_b_index];
1147 if (angular_momentums[projector_a_index] ==
1148 angular_momentums[projector_b_index] &&
1149 magnetic_projections[projector_a_index] ==
1150 magnetic_projections[projector_b_index]) {
1153 pseudopotential_quantum_system)
1155 .augmentation_overlap_integral(
1156 element_type, beta_a, beta_b);
1159 scaled_overlap_coefficients[offset + projector_a_index] +=
1160 q_value * all_overlap_coefficients[offset + projector_b_index];
1165 starting_projector_index += number_of_projectors_on_atom;
1169 int leading_dimension_step3 = std::max(number_of_plane_waves, 1);
1173 &number_of_plane_waves,
1175 &total_number_of_projectors,
1177 reinterpret_cast<const std::complex<double>*
>(kleinman_bylander_potential[0]),
1178 &leading_dimension_step3,
1179 reinterpret_cast<const std::complex<double>*
>(scaled_overlap_coefficients.data()),
1180 &total_number_of_projectors,
1182 reinterpret_cast<std::complex<double>*
>(overlap_psi_wavefunctions),
1183 &leading_dimension_step3);