49 : crystal_structure_(crystal_structure)
50 , planewave_basis_(planewave_basis)
51 , kpoint_grid_(kpoint_grid)
52 , scf_state_(scf_state) {}
54 [[nodiscard]] std::vector<Vector3D>
compute()
const {
56 std::vector<Vector3D> hubbard_force(number_of_atoms, {0.0, 0.0, 0.0});
59 if (manifolds.empty()) {
69 return compute_with_orthogonal_projectors();
78 return compute_with_overlap_operator();
81 const auto& pseudopotential_set =
84 constexpr Real q_spacing = 0.01;
85 constexpr int number_of_q_points = 900;
87 pseudopotential_set, crystal_structure_.
cell_volume(), q_spacing, number_of_q_points);
89 size_t number_of_manifolds = manifolds.size();
90 std::vector<int> manifold_row_offsets(number_of_manifolds);
91 int total_hubbard_orbitals = 0;
92 for (
size_t manifold_index = 0; manifold_index < number_of_manifolds; manifold_index++) {
93 manifold_row_offsets[manifold_index] = total_hubbard_orbitals;
94 total_hubbard_orbitals +=
95 static_cast<int>(manifolds[manifold_index].orbital_indices.size());
101 const Matrix3x3& reciprocal_lattice_vectors =
104 for (
int kpoint_index_state = 0; kpoint_index_state < number_of_kpoint_states;
105 kpoint_index_state++) {
106 int spin_index = kpoint_index_state / number_of_kpoints;
107 int kpoint_index = kpoint_index_state % number_of_kpoints;
110 Real kpoint_weight = kpoint_grid_[kpoint_index].weight;
114 number_of_plane_waves)
117 Vector3D kpoint_vector = kpoint_grid_[kpoint_index].coordinates;
119 for (
int direction = 0; direction < 3; direction++) {
120 kpoint_cartesian[direction] =
121 kpoint_vector.
x * reciprocal_lattice_vectors[0][direction] +
122 kpoint_vector.
y * reciprocal_lattice_vectors[1][direction] +
123 kpoint_vector.
z * reciprocal_lattice_vectors[2][direction];
126 std::vector<std::vector<Complex>> all_atomic_orbitals;
128 number_of_plane_waves,
134 atomic_wavefunction_table,
137 all_atomic_orbitals);
143 std::vector<std::vector<Complex>> minus_i_k_plus_g(
144 3, std::vector<Complex>(number_of_plane_waves));
145 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
146 const auto& g_vector = planewave_basis_.
g_vectors()[plane_wave_indices[g_index]];
147 for (
int direction = 0; direction < 3; direction++) {
148 Real k_plus_g_direction =
149 (g_vector.g_cart[direction] + kpoint_cartesian[direction]) *
151 minus_i_k_plus_g[direction][g_index] =
Complex(0.0, -k_plus_g_direction);
155 std::vector<Real> band_occupations(number_of_bands);
156 for (
int band_index = 0; band_index < number_of_bands; band_index++) {
157 band_occupations[band_index] =
158 scf_state_.
occupation(kpoint_index_state, band_index);
177 std::vector<int> occupied_band_indices;
178 for (
int band_index = 0; band_index < number_of_bands; band_index++) {
180 occupied_band_indices.push_back(band_index);
183 int number_of_occupied_bands =
static_cast<int>(occupied_band_indices.size());
189 std::vector<Complex> packed_orbitals(
static_cast<size_t>(number_of_plane_waves) *
190 total_hubbard_orbitals);
191 for (
size_t manifold_index = 0; manifold_index < number_of_manifolds;
193 const auto& manifold = manifolds[manifold_index];
194 int row_offset = manifold_row_offsets[manifold_index];
195 for (
size_t m = 0; m < manifold.orbital_indices.size(); m++) {
196 const auto& orbital =
197 all_atomic_orbitals[
static_cast<size_t>(manifold.orbital_indices[m])];
198 std::copy(orbital.begin(),
199 orbital.begin() + number_of_plane_waves,
200 packed_orbitals.begin() +
201 (
static_cast<size_t>(row_offset) + m) * number_of_plane_waves);
210 std::vector<std::vector<Complex>> batched_overlaps(4);
212 std::vector<Complex> modified_wavefunction(
213 static_cast<size_t>(number_of_plane_waves) * number_of_occupied_bands);
214 for (
int component = 0; component < 4; component++) {
215 for (
int occupied_band_index = 0;
216 occupied_band_index < number_of_occupied_bands;
217 occupied_band_index++) {
218 int band_index = occupied_band_indices[occupied_band_index];
220 static_cast<size_t>(occupied_band_index) * number_of_plane_waves;
221 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
223 kpoint_index_state, band_index, g_index);
224 modified_wavefunction[offset + g_index] =
225 (component == 0) ? psi
226 : psi * minus_i_k_plus_g[component - 1][g_index];
230 number_of_plane_waves,
231 total_hubbard_orbitals,
232 number_of_occupied_bands,
233 packed_orbitals.data(),
234 modified_wavefunction.data(),
235 batched_overlaps[
static_cast<size_t>(component)]);
250 number_of_plane_waves,
251 total_hubbard_orbitals,
252 number_of_occupied_bands,
253 packed_orbitals.data(),
254 modified_wavefunction.data(),
257 batched_overlaps[
static_cast<size_t>(component)]);
262 for (
size_t manifold_index = 0; manifold_index < number_of_manifolds;
264 const auto& manifold = manifolds[manifold_index];
265 int manifold_size =
static_cast<int>(manifold.orbital_indices.size());
266 int row_offset = manifold_row_offsets[manifold_index];
269 static_cast<size_t>(manifold_size));
270 std::vector<Matrix<Complex>> direction_derivative_overlaps(
273 static_cast<size_t>(manifold_size)));
280 for (
int occupied_band_index = 0; occupied_band_index < number_of_occupied_bands;
281 occupied_band_index++) {
283 static_cast<size_t>(occupied_band_indices[occupied_band_index]);
284 size_t column_offset =
285 static_cast<size_t>(occupied_band_index) * total_hubbard_orbitals;
286 for (
int m = 0; m < manifold_size; m++) {
287 size_t packed_index = column_offset +
static_cast<size_t>(row_offset) +
288 static_cast<size_t>(m);
289 overlaps(band_index,
static_cast<size_t>(m)) =
290 batched_overlaps[0][packed_index];
291 for (
int direction = 0; direction < 3; direction++) {
292 direction_derivative_overlaps[direction](band_index,
293 static_cast<size_t>(m)) =
294 batched_overlaps[
static_cast<size_t>(direction) + 1][packed_index];
310 overlaps.
data(), number_of_bands * manifold_size);
311 for (
int direction = 0; direction < 3; direction++) {
313 direction_derivative_overlaps[direction].data(),
314 number_of_bands * manifold_size);
325 std::vector<Complex> manifold_d_matrix(
static_cast<size_t>(manifold_size) *
327 for (
int m = 0; m < manifold_size; m++) {
328 for (
int m_prime = 0; m_prime < manifold_size; m_prime++) {
329 int global_row = row_offset + m;
330 int global_column = row_offset + m_prime;
331 manifold_d_matrix[
static_cast<size_t>(m * manifold_size + m_prime)] =
332 combined_d_matrix[
static_cast<size_t>(global_row) +
333 static_cast<size_t>(global_column) *
334 total_hubbard_orbitals];
338 for (
int direction = 0; direction < 3; direction++) {
339 Real force_contribution =
343 direction_derivative_overlaps[direction],
347 hubbard_force[manifold.atom_index][direction] += force_contribution;
352 return hubbard_force;
417 [[nodiscard]] std::vector<Vector3D> compute_with_orthogonal_projectors()
const {
419 std::vector<Vector3D> hubbard_force(number_of_atoms, {0.0, 0.0, 0.0});
426 constexpr Real q_spacing = 0.01;
427 constexpr int number_of_q_points = 900;
429 pseudopotential_set, crystal_structure_.
cell_volume(), q_spacing, number_of_q_points);
440 int number_of_atomic_orbitals =
static_cast<int>(orbital_labels.size());
441 std::vector<int> atom_orbital_first(number_of_atoms, number_of_atomic_orbitals);
442 std::vector<int> atom_orbital_last(number_of_atoms, 0);
443 for (
int orbital = 0; orbital < number_of_atomic_orbitals; orbital++) {
444 int atom_index = orbital_labels[
static_cast<size_t>(orbital)].atom_index;
445 atom_orbital_first[atom_index] = std::min(atom_orbital_first[atom_index], orbital);
446 atom_orbital_last[atom_index] = std::max(atom_orbital_last[atom_index], orbital + 1);
449 int total_projectors = pseudopotential_basis.total_number_of_projectors();
450 std::vector<int> projector_offset_by_atom(number_of_atoms, 0);
451 std::vector<int> projector_channels_by_atom(number_of_atoms, 0);
453 int projector_offset = 0;
454 for (
int atom_index = 0; atom_index < number_of_atoms; atom_index++) {
456 int number_of_projector_channels =
457 pseudopotential_basis.number_of_projector_channels(species_index);
458 projector_offset_by_atom[atom_index] = projector_offset;
459 projector_channels_by_atom[atom_index] = number_of_projector_channels;
460 projector_offset += number_of_projector_channels;
463 auto augmentation_overlap = [&](
int atom_index,
int channel_i,
int channel_j) ->
Real {
465 static_cast<const UltrasoftPlanewaveKohnShamQuantumSystem&
>(
468 pseudopotential_basis,
474 size_t number_of_manifolds = manifolds.size();
475 std::vector<int> manifold_row_offsets(number_of_manifolds);
476 int total_hubbard_orbitals = 0;
477 for (
size_t manifold_index = 0; manifold_index < number_of_manifolds; manifold_index++) {
478 manifold_row_offsets[manifold_index] = total_hubbard_orbitals;
479 total_hubbard_orbitals +=
480 static_cast<int>(manifolds[manifold_index].orbital_indices.size());
486 const Matrix3x3& reciprocal_lattice_vectors =
489 for (
int kpoint_index_state = 0; kpoint_index_state < number_of_kpoint_states;
490 kpoint_index_state++) {
491 int spin_index = kpoint_index_state / number_of_kpoints;
492 int kpoint_index = kpoint_index_state % number_of_kpoints;
495 Real kpoint_weight = kpoint_grid_[kpoint_index].weight;
499 number_of_plane_waves)
502 Vector3D kpoint_cartesian;
504 Vector3D kpoint_vector = kpoint_grid_[kpoint_index].coordinates;
505 for (
int direction = 0; direction < 3; direction++)
506 kpoint_cartesian[direction] =
507 kpoint_vector.x * reciprocal_lattice_vectors[0][direction] +
508 kpoint_vector.y * reciprocal_lattice_vectors[1][direction] +
509 kpoint_vector.z * reciprocal_lattice_vectors[2][direction];
512 std::vector<std::vector<Complex>> all_atomic_orbitals;
514 number_of_plane_waves,
520 atomic_wavefunction_table,
523 all_atomic_orbitals);
525 std::vector<std::vector<Complex>> minus_i_k_plus_g(
526 3, std::vector<Complex>(number_of_plane_waves));
527 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
528 const auto& g_vector = planewave_basis_.
g_vectors()[plane_wave_indices[g_index]];
529 for (
int direction = 0; direction < 3; direction++)
530 minus_i_k_plus_g[direction][g_index] =
532 -(g_vector.g_cart[direction] + kpoint_cartesian[direction]) *
536 std::vector<Real> band_occupations(number_of_bands);
537 std::vector<int> occupied_band_indices;
538 for (
int band_index = 0; band_index < number_of_bands; band_index++) {
539 band_occupations[band_index] =
540 scf_state_.
occupation(kpoint_index_state, band_index);
542 occupied_band_indices.push_back(band_index);
544 int number_of_occupied_bands =
static_cast<int>(occupied_band_indices.size());
553 std::vector<Complex> packed_orbitals(
static_cast<size_t>(number_of_plane_waves) *
554 number_of_atomic_orbitals);
555 for (
int orbital = 0; orbital < number_of_atomic_orbitals; orbital++)
556 std::copy(all_atomic_orbitals[
static_cast<size_t>(orbital)].begin(),
557 all_atomic_orbitals[
static_cast<size_t>(orbital)].begin() +
558 number_of_plane_waves,
559 packed_orbitals.begin() +
560 static_cast<size_t>(orbital) * number_of_plane_waves);
561 std::vector<Complex> packed_bands(
static_cast<size_t>(number_of_plane_waves) *
562 number_of_occupied_bands);
563 for (
int occupied_band_index = 0; occupied_band_index < number_of_occupied_bands;
564 occupied_band_index++)
565 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++)
566 packed_bands[
static_cast<size_t>(occupied_band_index) * number_of_plane_waves +
570 occupied_band_indices[
static_cast<size_t>(occupied_band_index)],
573 auto weight_by_direction = [&](
const std::vector<Complex>& source,
int direction) {
574 std::vector<Complex> weighted(source.size());
575 size_t columns = source.size() /
static_cast<size_t>(number_of_plane_waves);
576 for (
size_t column = 0; column < columns; column++)
577 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
578 size_t offset = column * number_of_plane_waves + g_index;
579 weighted[offset] = source[offset] * minus_i_k_plus_g[direction][g_index];
591 auto contract = [&](
const Complex* left,
595 bool right_carries_g_component =
false) {
596 std::vector<Complex> result;
598 number_of_plane_waves, number_of_left, number_of_right, left, right, result);
606 right_carries_g_component,
610 result.data(),
static_cast<int>(result.size()));
614 if (has_augmented_overlap) {
616 throw std::runtime_error(
617 "Ortho-atomic ultrasoft Hubbard forces require an execution policy");
620 Matrix<Complex> kleinman_bylander_projectors;
625 pseudopotential_basis.beta_function_table(),
627 number_of_plane_waves,
629 kleinman_bylander_projectors);
632 kleinman_bylander_projectors,
635 std::vector<Complex> overlap_applied_orbitals(packed_orbitals.size());
636 overlap_operator->apply_batch(number_of_plane_waves,
637 number_of_atomic_orbitals,
638 packed_orbitals.data(),
639 overlap_applied_orbitals.data());
640 std::vector<Complex> overlap_applied_bands(packed_bands.size());
641 overlap_operator->apply_batch(number_of_plane_waves,
642 number_of_occupied_bands,
644 overlap_applied_bands.data());
646 auto overlap_matrix = contract(packed_orbitals.data(),
647 number_of_atomic_orbitals,
648 overlap_applied_orbitals.data(),
649 number_of_atomic_orbitals);
652 auto atomic_band_overlaps = contract(packed_orbitals.data(),
653 number_of_atomic_orbitals,
654 overlap_applied_bands.data(),
655 number_of_occupied_bands);
656 auto element = [number_of_atomic_orbitals](
int row,
int column) {
657 return static_cast<size_t>(row + column * number_of_atomic_orbitals);
661 std::vector<Complex> projection(
static_cast<size_t>(number_of_atomic_orbitals) *
662 number_of_occupied_bands,
664 for (
int occupied_band_index = 0; occupied_band_index < number_of_occupied_bands;
665 occupied_band_index++) {
666 for (
int orbital = 0; orbital < number_of_atomic_orbitals; orbital++) {
667 for (
int inner_orbital = 0; inner_orbital < number_of_atomic_orbitals;
669 projection[element(orbital, occupied_band_index)] +=
670 transform.inverse_square_root[element(orbital, inner_orbital)] *
671 atomic_band_overlaps[element(inner_orbital, occupied_band_index)];
681 auto apply_overlap_derivative = [&](
const Complex* input_vectors,
682 int number_of_vectors,
685 std::vector<Complex> derivative_projectors(
686 static_cast<size_t>(number_of_plane_waves) * total_projectors,
688 int displaced_projector_offset = projector_offset_by_atom[displaced_atom];
689 int displaced_projector_channels = projector_channels_by_atom[displaced_atom];
690 for (
int channel = 0; channel < displaced_projector_channels; channel++) {
691 int projector_index = displaced_projector_offset + channel;
692 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
693 derivative_projectors[
static_cast<size_t>(projector_index) *
694 number_of_plane_waves +
696 kleinman_bylander_projectors[projector_index][g_index] *
697 minus_i_k_plus_g[direction][g_index];
701 auto projector_overlaps = contract(kleinman_bylander_projectors.data(),
705 auto derivative_projector_overlaps = contract(derivative_projectors.data(),
709 std::vector<Complex> result(
static_cast<size_t>(number_of_plane_waves) *
712 for (
int channel_row = 0; channel_row < displaced_projector_channels;
714 int projector_row = displaced_projector_offset + channel_row;
715 for (
int channel_column = 0; channel_column < displaced_projector_channels;
718 augmentation_overlap(displaced_atom, channel_row, channel_column);
719 if (std::abs(overlap_value) <
723 int projector_column = displaced_projector_offset + channel_column;
724 for (
int vector_index = 0; vector_index < number_of_vectors;
726 size_t overlap_index =
727 static_cast<size_t>(projector_column) +
728 static_cast<size_t>(vector_index) * total_projectors;
729 Complex derivative_projector_coefficient =
730 overlap_value * projector_overlaps[overlap_index];
731 Complex projector_coefficient =
732 overlap_value * derivative_projector_overlaps[overlap_index];
733 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
734 size_t result_index =
735 static_cast<size_t>(vector_index) * number_of_plane_waves +
737 result[result_index] +=
738 derivative_projectors[
static_cast<size_t>(projector_row) *
739 number_of_plane_waves +
741 derivative_projector_coefficient +
742 kleinman_bylander_projectors[projector_row][g_index] *
743 projector_coefficient;
751 for (
int displaced_atom = 0; displaced_atom < number_of_atoms; displaced_atom++) {
752 int displaced_first = atom_orbital_first[displaced_atom];
753 int displaced_last = atom_orbital_last[displaced_atom];
755 for (
int direction = 0; direction < 3; direction++) {
756 std::vector<Complex> orbital_derivatives(packed_orbitals.size(),
758 for (
int orbital = displaced_first; orbital < displaced_last; orbital++) {
759 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
760 size_t orbital_index =
761 static_cast<size_t>(orbital) * number_of_plane_waves + g_index;
762 orbital_derivatives[orbital_index] =
763 packed_orbitals[orbital_index] *
764 minus_i_k_plus_g[direction][g_index];
768 std::vector<Complex> overlap_applied_orbital_derivatives(
769 orbital_derivatives.size());
770 overlap_operator->apply_batch(number_of_plane_waves,
771 number_of_atomic_orbitals,
772 orbital_derivatives.data(),
773 overlap_applied_orbital_derivatives.data());
774 auto overlap_derivative_on_orbitals =
775 apply_overlap_derivative(packed_orbitals.data(),
776 number_of_atomic_orbitals,
779 auto overlap_derivative_on_bands =
780 apply_overlap_derivative(packed_bands.data(),
781 number_of_occupied_bands,
785 auto left_orbital_metric_derivative =
786 contract(orbital_derivatives.data(),
787 number_of_atomic_orbitals,
788 overlap_applied_orbitals.data(),
789 number_of_atomic_orbitals);
790 auto overlap_metric_derivative =
791 contract(packed_orbitals.data(),
792 number_of_atomic_orbitals,
793 overlap_derivative_on_orbitals.data(),
794 number_of_atomic_orbitals);
795 auto right_orbital_metric_derivative =
796 contract(packed_orbitals.data(),
797 number_of_atomic_orbitals,
798 overlap_applied_orbital_derivatives.data(),
799 number_of_atomic_orbitals);
800 std::vector<Complex> metric_derivative(overlap_matrix.size());
801 for (
size_t matrix_index = 0; matrix_index < metric_derivative.size();
803 metric_derivative[matrix_index] =
804 left_orbital_metric_derivative[matrix_index] +
805 overlap_metric_derivative[matrix_index] +
806 right_orbital_metric_derivative[matrix_index];
808 for (
int column = 0; column < number_of_atomic_orbitals; column++) {
809 for (
int row = 0; row <= column; row++) {
811 0.5 * (metric_derivative[element(row, column)] +
812 std::conj(metric_derivative[element(column, row)]));
813 metric_derivative[element(row, column)] = hermitian_value;
814 metric_derivative[element(column, row)] =
815 std::conj(hermitian_value);
818 auto inverse_square_root_derivative =
821 auto left_orbital_projection_derivative =
822 contract(orbital_derivatives.data(),
823 number_of_atomic_orbitals,
824 overlap_applied_bands.data(),
825 number_of_occupied_bands);
826 auto overlap_projection_derivative =
827 contract(packed_orbitals.data(),
828 number_of_atomic_orbitals,
829 overlap_derivative_on_bands.data(),
830 number_of_occupied_bands);
831 std::vector<Complex> raw_projection_derivative(atomic_band_overlaps.size());
832 for (
size_t overlap_index = 0;
833 overlap_index < raw_projection_derivative.size();
835 raw_projection_derivative[overlap_index] =
836 left_orbital_projection_derivative[overlap_index] +
837 overlap_projection_derivative[overlap_index];
840 std::vector<Complex> negative_projection_derivative(projection.size(),
842 for (
int occupied_band_index = 0;
843 occupied_band_index < number_of_occupied_bands;
844 occupied_band_index++) {
845 for (
int orbital = 0; orbital < number_of_atomic_orbitals; orbital++) {
846 for (
int inner_orbital = 0;
847 inner_orbital < number_of_atomic_orbitals;
849 negative_projection_derivative[element(orbital,
850 occupied_band_index)] -=
851 inverse_square_root_derivative[element(orbital,
853 atomic_band_overlaps[element(inner_orbital,
854 occupied_band_index)] +
855 transform.inverse_square_root[element(orbital,
857 raw_projection_derivative[element(inner_orbital,
858 occupied_band_index)];
863 for (
size_t manifold_index = 0; manifold_index < number_of_manifolds;
865 const auto& manifold = manifolds[manifold_index];
866 int manifold_size =
static_cast<int>(manifold.orbital_indices.size());
867 int row_offset = manifold_row_offsets[manifold_index];
868 Matrix<Complex> manifold_overlaps(
static_cast<size_t>(number_of_bands),
869 static_cast<size_t>(manifold_size));
870 Matrix<Complex> derivative_overlaps(
871 static_cast<size_t>(number_of_bands),
872 static_cast<size_t>(manifold_size));
873 for (
int manifold_orbital = 0; manifold_orbital < manifold_size;
874 manifold_orbital++) {
876 manifold.orbital_indices[
static_cast<size_t>(manifold_orbital)];
877 for (
int occupied_band_index = 0;
878 occupied_band_index < number_of_occupied_bands;
879 occupied_band_index++) {
880 size_t band_index =
static_cast<size_t>(
881 occupied_band_indices[
static_cast<size_t>(
882 occupied_band_index)]);
883 manifold_overlaps(band_index,
884 static_cast<size_t>(manifold_orbital)) =
885 projection[element(orbital, occupied_band_index)];
886 derivative_overlaps(band_index,
887 static_cast<size_t>(manifold_orbital)) =
888 negative_projection_derivative[element(
889 orbital, occupied_band_index)];
893 const auto& combined_d_matrix =
895 std::vector<Complex> manifold_d_matrix(
896 static_cast<size_t>(manifold_size) * manifold_size);
897 for (
int row = 0; row < manifold_size; row++) {
898 for (
int column = 0; column < manifold_size; column++) {
899 manifold_d_matrix[
static_cast<size_t>(row * manifold_size +
901 combined_d_matrix[
static_cast<size_t>(row_offset + row) +
902 static_cast<size_t>(row_offset + column) *
903 total_hubbard_orbitals];
907 hubbard_force[displaced_atom][direction] +=
921 auto overlap_matrix = contract(packed_orbitals.data(),
922 number_of_atomic_orbitals,
923 packed_orbitals.data(),
924 number_of_atomic_orbitals);
926 auto atomic_band_overlaps = contract(packed_orbitals.data(),
927 number_of_atomic_orbitals,
929 number_of_occupied_bands);
930 std::vector<std::vector<Complex>> orbital_derivative_overlaps(3);
931 std::vector<std::vector<Complex>> band_derivative_overlaps(3);
932 for (
int direction = 0; direction < 3; direction++) {
933 auto weighted_orbitals = weight_by_direction(packed_orbitals, direction);
934 auto weighted_bands = weight_by_direction(packed_bands, direction);
935 orbital_derivative_overlaps[
static_cast<size_t>(direction)] =
936 contract(packed_orbitals.data(),
937 number_of_atomic_orbitals,
938 weighted_orbitals.data(),
939 number_of_atomic_orbitals,
941 band_derivative_overlaps[
static_cast<size_t>(direction)] =
942 contract(packed_orbitals.data(),
943 number_of_atomic_orbitals,
944 weighted_bands.data(),
945 number_of_occupied_bands,
949 auto element = [number_of_atomic_orbitals](
int row,
int column) {
950 return static_cast<size_t>(row + column * number_of_atomic_orbitals);
954 std::vector<Complex> projection(
static_cast<size_t>(number_of_atomic_orbitals) *
955 number_of_occupied_bands,
957 for (
int occupied_band_index = 0; occupied_band_index < number_of_occupied_bands;
958 occupied_band_index++)
959 for (
int orbital = 0; orbital < number_of_atomic_orbitals; orbital++) {
961 for (
int inner = 0; inner < number_of_atomic_orbitals; inner++)
962 accumulated += transform.inverse_square_root[element(orbital, inner)] *
963 atomic_band_overlaps[element(inner, occupied_band_index)];
964 projection[element(orbital, occupied_band_index)] = accumulated;
967 for (
int displaced_atom = 0; displaced_atom < number_of_atoms; displaced_atom++) {
968 int displaced_first = atom_orbital_first[displaced_atom];
969 int displaced_last = atom_orbital_last[displaced_atom];
970 auto belongs_to_displaced_atom = [&](
int orbital) {
971 return orbital >= displaced_first && orbital < displaced_last;
974 for (
int direction = 0; direction < 3; direction++) {
975 const auto& orbital_derivative =
976 orbital_derivative_overlaps[
static_cast<size_t>(direction)];
977 const auto& band_derivative =
978 band_derivative_overlaps[
static_cast<size_t>(direction)];
980 std::vector<Complex> overlap_derivative(
981 static_cast<size_t>(number_of_atomic_orbitals) * number_of_atomic_orbitals,
983 for (
int column = 0; column < number_of_atomic_orbitals; column++)
984 for (
int row = 0; row < number_of_atomic_orbitals; row++) {
985 bool row_moves = belongs_to_displaced_atom(row);
986 bool column_moves = belongs_to_displaced_atom(column);
987 if (row_moves == column_moves)
989 Complex value = orbital_derivative[element(row, column)];
990 overlap_derivative[element(row, column)] =
991 column_moves ? value : -value;
993 auto inverse_square_root_derivative =
996 for (
size_t manifold_index = 0; manifold_index < number_of_manifolds;
998 const auto& manifold = manifolds[manifold_index];
999 int manifold_size =
static_cast<int>(manifold.orbital_indices.size());
1000 int row_offset = manifold_row_offsets[manifold_index];
1002 Matrix<Complex> manifold_overlaps(
static_cast<size_t>(number_of_bands),
1003 static_cast<size_t>(manifold_size));
1004 Matrix<Complex> derivative_overlaps(
static_cast<size_t>(number_of_bands),
1005 static_cast<size_t>(manifold_size));
1006 for (
int m = 0; m < manifold_size; m++) {
1007 int orbital = manifold.orbital_indices[
static_cast<size_t>(m)];
1008 for (
int occupied_band_index = 0;
1009 occupied_band_index < number_of_occupied_bands;
1010 occupied_band_index++) {
1011 Complex transform_term(0.0, 0.0);
1012 for (
int inner = 0; inner < number_of_atomic_orbitals; inner++)
1014 inverse_square_root_derivative[element(orbital, inner)] *
1015 atomic_band_overlaps[element(inner, occupied_band_index)];
1016 Complex own_orbital_term(0.0, 0.0);
1017 for (
int inner = displaced_first; inner < displaced_last; inner++)
1019 transform.inverse_square_root[element(orbital, inner)] *
1020 band_derivative[element(inner, occupied_band_index)];
1022 static_cast<size_t>(occupied_band_indices[
static_cast<size_t>(
1023 occupied_band_index)]);
1024 manifold_overlaps(band_row,
static_cast<size_t>(m)) =
1025 projection[element(orbital, occupied_band_index)];
1026 derivative_overlaps(band_row,
static_cast<size_t>(m)) =
1027 own_orbital_term - transform_term;
1031 const auto& combined_d_matrix =
1033 std::vector<Complex> manifold_d_matrix(
static_cast<size_t>(manifold_size) *
1035 for (
int m = 0; m < manifold_size; m++)
1036 for (
int m_prime = 0; m_prime < manifold_size; m_prime++)
1037 manifold_d_matrix[
static_cast<size_t>(m * manifold_size +
1039 combined_d_matrix[
static_cast<size_t>(row_offset + m) +
1040 static_cast<size_t>(row_offset + m_prime) *
1041 total_hubbard_orbitals];
1043 hubbard_force[displaced_atom][direction] +=
1047 derivative_overlaps,
1056 return hubbard_force;
1105 [[nodiscard]] std::vector<Vector3D> compute_with_overlap_operator()
const {
1107 std::vector<Vector3D> hubbard_force(number_of_atoms, {0.0, 0.0, 0.0});
1112 const auto& ultrasoft_basis =
1113 static_cast<const UltrasoftPlanewaveKohnShamQuantumSystem&
>(scf_state_.
quantum_system())
1116 int total_projectors = basis.total_number_of_projectors();
1117 if (total_projectors == 0)
1118 return hubbard_force;
1120 constexpr Real q_spacing = 0.01;
1121 constexpr int number_of_q_points = 900;
1123 pseudopotential_set, crystal_structure_.
cell_volume(), q_spacing, number_of_q_points);
1125 size_t number_of_manifolds = manifolds.size();
1126 std::vector<int> manifold_row_offsets(number_of_manifolds);
1127 int total_hubbard_orbitals = 0;
1128 for (
size_t manifold_index = 0; manifold_index < number_of_manifolds; manifold_index++) {
1129 manifold_row_offsets[manifold_index] = total_hubbard_orbitals;
1130 total_hubbard_orbitals +=
1131 static_cast<int>(manifolds[manifold_index].orbital_indices.size());
1141 std::vector<int> projector_atom(total_projectors, 0);
1142 std::vector<int> projector_offset_by_atom(number_of_atoms, 0);
1143 std::vector<int> channels_by_atom(number_of_atoms, 0);
1146 for (
int atom_index = 0; atom_index < number_of_atoms; atom_index++) {
1148 int number_of_channels = basis.number_of_projector_channels(species_index);
1149 projector_offset_by_atom[atom_index] = offset;
1150 channels_by_atom[atom_index] = number_of_channels;
1151 for (
int channel = 0; channel < number_of_channels; channel++)
1152 projector_atom[offset + channel] = atom_index;
1153 offset += number_of_channels;
1157 auto augmentation_charge = [&](
int atom_index,
int channel_i,
int channel_j) ->
Real {
1168 const Matrix3x3& reciprocal_lattice_vectors =
1171 for (
int kpoint_index_state = 0; kpoint_index_state < number_of_kpoint_states;
1172 kpoint_index_state++) {
1173 int spin_index = kpoint_index_state / number_of_kpoints;
1174 int kpoint_index = kpoint_index_state % number_of_kpoints;
1177 Real kpoint_weight = kpoint_grid_[kpoint_index].weight;
1181 number_of_plane_waves)
1184 Vector3D kpoint_cartesian;
1186 Vector3D kpoint_vector = kpoint_grid_[kpoint_index].coordinates;
1187 for (
int direction = 0; direction < 3; direction++)
1188 kpoint_cartesian[direction] =
1189 kpoint_vector.x * reciprocal_lattice_vectors[0][direction] +
1190 kpoint_vector.y * reciprocal_lattice_vectors[1][direction] +
1191 kpoint_vector.z * reciprocal_lattice_vectors[2][direction];
1194 std::vector<std::vector<Complex>> all_atomic_orbitals;
1196 number_of_plane_waves,
1201 pseudopotential_set,
1202 atomic_wavefunction_table,
1205 all_atomic_orbitals);
1207 Matrix<Complex> beta_projectors;
1211 pseudopotential_set,
1212 basis.beta_function_table(),
1214 number_of_plane_waves,
1218 std::vector<std::vector<Complex>> minus_i_k_plus_g(
1219 3, std::vector<Complex>(number_of_plane_waves));
1220 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
1221 const auto& g_vector = planewave_basis_.
g_vectors()[plane_wave_indices[g_index]];
1222 for (
int direction = 0; direction < 3; direction++)
1223 minus_i_k_plus_g[direction][g_index] =
1225 -(g_vector.g_cart[direction] + kpoint_cartesian[direction]) *
1229 std::vector<Real> band_occupations(number_of_bands);
1230 for (
int band_index = 0; band_index < number_of_bands; band_index++)
1231 band_occupations[band_index] =
1232 scf_state_.
occupation(kpoint_index_state, band_index);
1251 auto contract = [&](
const Complex* left_rows,
1255 int number_of_right,
1256 size_t right_stride,
1258 std::vector<Complex> result(
static_cast<size_t>(number_of_left) * number_of_right,
1260 for (
int left = 0; left < number_of_left; left++) {
1261 const Complex* left_row = left_rows +
static_cast<size_t>(left) * left_stride;
1262 for (
int right = 0; right < number_of_right; right++) {
1264 right_columns +
static_cast<size_t>(right) * right_stride;
1265 Complex accumulated(0.0, 0.0);
1266 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
1267 Complex value = std::conj(left_row[g_index]) * right_column[g_index];
1268 accumulated += modifier ? value * modifier[g_index] : value;
1270 if (is_gamma_only) {
1271 Real g_zero_product = (modifier ==
nullptr && g_zero_index >= 0)
1272 ? (std::conj(left_row[g_zero_index]) *
1273 right_column[g_zero_index])
1279 result[
static_cast<size_t>(left) * number_of_right + right] = accumulated;
1284 result.data(),
static_cast<int>(result.size()));
1289 std::vector<Complex> orbitals(
static_cast<size_t>(total_hubbard_orbitals) *
1290 number_of_plane_waves);
1291 for (
size_t manifold_index = 0; manifold_index < number_of_manifolds;
1293 const auto& manifold = manifolds[manifold_index];
1294 int row_offset = manifold_row_offsets[manifold_index];
1295 for (
size_t m = 0; m < manifold.orbital_indices.size(); m++) {
1296 const auto& orbital =
1297 all_atomic_orbitals[
static_cast<size_t>(manifold.orbital_indices[m])];
1298 std::copy(orbital.begin(),
1299 orbital.begin() + number_of_plane_waves,
1301 (
static_cast<size_t>(row_offset) + m) * number_of_plane_waves);
1304 std::vector<Complex> wavefunctions(
static_cast<size_t>(number_of_bands) *
1305 number_of_plane_waves);
1306 for (
int band_index = 0; band_index < number_of_bands; band_index++)
1307 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++)
1308 wavefunctions[
static_cast<size_t>(band_index) * number_of_plane_waves +
1313 auto phi_psi = contract(orbitals.data(),
1314 total_hubbard_orbitals,
1315 number_of_plane_waves,
1316 wavefunctions.data(),
1318 number_of_plane_waves,
1320 auto phi_beta = contract(orbitals.data(),
1321 total_hubbard_orbitals,
1322 number_of_plane_waves,
1323 beta_projectors.data(),
1325 number_of_plane_waves,
1327 auto beta_psi = contract(beta_projectors.data(),
1329 number_of_plane_waves,
1330 wavefunctions.data(),
1332 number_of_plane_waves,
1334 std::vector<std::vector<Complex>> phi_derivative_psi(3), phi_derivative_beta(3),
1335 beta_derivative_psi(3);
1336 for (
int direction = 0; direction < 3; direction++) {
1337 phi_derivative_psi[direction] = contract(orbitals.data(),
1338 total_hubbard_orbitals,
1339 number_of_plane_waves,
1340 wavefunctions.data(),
1342 number_of_plane_waves,
1343 minus_i_k_plus_g[direction].data());
1344 phi_derivative_beta[direction] = contract(orbitals.data(),
1345 total_hubbard_orbitals,
1346 number_of_plane_waves,
1347 beta_projectors.data(),
1349 number_of_plane_waves,
1350 minus_i_k_plus_g[direction].data());
1351 beta_derivative_psi[direction] = contract(beta_projectors.data(),
1353 number_of_plane_waves,
1354 wavefunctions.data(),
1356 number_of_plane_waves,
1357 minus_i_k_plus_g[direction].data());
1360 auto orbital_band = [&](
int orbital,
int band) {
1361 return static_cast<size_t>(orbital) * number_of_bands + band;
1363 auto orbital_projector = [&](
int orbital,
int projector) {
1364 return static_cast<size_t>(orbital) * total_projectors + projector;
1366 auto projector_band = [&](
int projector,
int band) {
1367 return static_cast<size_t>(projector) * number_of_bands + band;
1375 std::vector<Complex> projection = phi_psi;
1376 std::vector<std::vector<Complex>> own_atom_term(3, phi_derivative_psi[0]);
1377 for (
int direction = 0; direction < 3; direction++)
1378 own_atom_term[direction] = phi_derivative_psi[direction];
1380 for (
int atom_index = 0; atom_index < number_of_atoms; atom_index++) {
1381 int offset = projector_offset_by_atom[atom_index];
1382 for (
int channel_i = 0; channel_i < channels_by_atom[atom_index]; channel_i++) {
1383 for (
int channel_j = 0; channel_j < channels_by_atom[atom_index]; channel_j++) {
1384 Real q_value = augmentation_charge(atom_index, channel_i, channel_j);
1387 int projector_i = offset + channel_i;
1388 int projector_j = offset + channel_j;
1389 for (
int orbital = 0; orbital < total_hubbard_orbitals; orbital++) {
1390 Complex phi_beta_i = phi_beta[orbital_projector(orbital, projector_i)];
1391 for (
int band = 0; band < number_of_bands; band++) {
1392 Complex beta_j_psi = beta_psi[projector_band(projector_j, band)];
1393 projection[orbital_band(orbital, band)] +=
1394 q_value * phi_beta_i * beta_j_psi;
1395 for (
int direction = 0; direction < 3; direction++)
1396 own_atom_term[direction][orbital_band(orbital, band)] +=
1398 phi_derivative_beta[direction][orbital_projector(
1399 orbital, projector_i)] *
1407 Matrix<Complex> overlaps(
static_cast<size_t>(number_of_bands),
1408 static_cast<size_t>(total_hubbard_orbitals));
1409 for (
int orbital = 0; orbital < total_hubbard_orbitals; orbital++)
1410 for (
int band = 0; band < number_of_bands; band++)
1411 overlaps(
static_cast<size_t>(band),
static_cast<size_t>(orbital)) =
1412 projection[orbital_band(orbital, band)];
1419 for (
int displaced_atom = 0; displaced_atom < number_of_atoms; displaced_atom++) {
1420 int offset = projector_offset_by_atom[displaced_atom];
1421 int number_of_channels = channels_by_atom[displaced_atom];
1423 for (
int direction = 0; direction < 3; direction++) {
1424 std::vector<Complex> derivative(
static_cast<size_t>(total_hubbard_orbitals) *
1428 for (
int channel_i = 0; channel_i < number_of_channels; channel_i++) {
1429 for (
int channel_j = 0; channel_j < number_of_channels; channel_j++) {
1431 augmentation_charge(displaced_atom, channel_i, channel_j);
1434 int projector_i = offset + channel_i;
1435 int projector_j = offset + channel_j;
1436 for (
int orbital = 0; orbital < total_hubbard_orbitals; orbital++) {
1438 phi_beta[orbital_projector(orbital, projector_i)];
1439 Complex phi_derivative_beta_i =
1440 phi_derivative_beta[direction]
1441 [orbital_projector(orbital, projector_i)];
1442 for (
int band = 0; band < number_of_bands; band++) {
1444 beta_psi[projector_band(projector_j, band)];
1445 Complex beta_j_derivative_psi =
1446 beta_derivative_psi[direction]
1447 [projector_band(projector_j, band)];
1448 derivative[orbital_band(orbital, band)] -=
1449 q_value * (phi_derivative_beta_i * beta_j_psi -
1450 phi_beta_i * beta_j_derivative_psi);
1456 for (
size_t manifold_index = 0; manifold_index < number_of_manifolds;
1458 const auto& manifold = manifolds[manifold_index];
1459 int manifold_size =
static_cast<int>(manifold.orbital_indices.size());
1460 int row_offset = manifold_row_offsets[manifold_index];
1461 bool displaced_owns_manifold = manifold.atom_index == displaced_atom;
1463 Matrix<Complex> derivative_overlaps(
static_cast<size_t>(number_of_bands),
1464 static_cast<size_t>(manifold_size));
1465 for (
int m = 0; m < manifold_size; m++) {
1466 int orbital = row_offset + m;
1467 for (
int band = 0; band < number_of_bands; band++) {
1468 Complex value = derivative[orbital_band(orbital, band)];
1469 if (displaced_owns_manifold)
1470 value += own_atom_term[direction][orbital_band(orbital, band)];
1471 derivative_overlaps(
static_cast<size_t>(band),
1472 static_cast<size_t>(m)) = value;
1476 const auto& combined_d_matrix =
1478 std::vector<Complex> manifold_d_matrix(
static_cast<size_t>(manifold_size) *
1480 for (
int m = 0; m < manifold_size; m++)
1481 for (
int m_prime = 0; m_prime < manifold_size; m_prime++)
1482 manifold_d_matrix[
static_cast<size_t>(m * manifold_size +
1484 combined_d_matrix[
static_cast<size_t>(row_offset + m) +
1485 static_cast<size_t>(row_offset + m_prime) *
1486 total_hubbard_orbitals];
1488 Matrix<Complex> manifold_overlaps(
static_cast<size_t>(number_of_bands),
1489 static_cast<size_t>(manifold_size));
1490 for (
int m = 0; m < manifold_size; m++)
1491 for (
int band = 0; band < number_of_bands; band++)
1492 manifold_overlaps(
static_cast<size_t>(band),
1493 static_cast<size_t>(m)) =
1494 overlaps(
static_cast<size_t>(band),
1495 static_cast<size_t>(row_offset + m));
1497 hubbard_force[displaced_atom][direction] +=
1501 derivative_overlaps,
1510 return hubbard_force;
1513 const Crystal& crystal_structure_;
1514 const PlanewaveBasis& planewave_basis_;
1515 const KPointsGrid& kpoint_grid_;
1516 const NormConservingPlanewaveKohnShamSCFState& scf_state_;