46 const Crystal& crystal_structure,
51 : crystal_structure_{crystal_structure}
52 , planewave_basis_{planewave_basis}
53 , kpoint_grid_{kpoint_grid}
54 , pseudopotential_quantum_system_{pseudopotential_quantum_system}
55 , execution_policy_{execution_policy} {}
64 cached_smooth_potential_ =
65 compute_smooth_grid_potential(real_space_potential, planewave_basis_);
67 cached_scaled_potential_.resize(local_smooth_grid_points);
69 for (
int grid_index = 0; grid_index < local_smooth_grid_points; grid_index++) {
70 cached_scaled_potential_[grid_index] =
71 cached_smooth_potential_[grid_index] * inverse_total_points;
79 cached_full_grid_potential_.resize(total_smooth_points);
81 local_smooth_grid_points,
82 cached_full_grid_potential_.data(),
86 smooth_potential_cache_valid_ =
true;
87 cached_block_d_matrix_.clear();
88 cached_block_d_offsets_.clear();
96 int number_of_plane_waves,
97 const std::vector<int>& g_vector_indices,
98 const std::vector<Real>& kinetic_energy_squared)
override {
99 current_kpoint_index_ = kpoint_index;
100 current_number_of_plane_waves_ = number_of_plane_waves;
101 current_g_vector_indices_ = &g_vector_indices;
102 current_kinetic_energy_squared_ = &kinetic_energy_squared;
106 precompute_g_to_fft_mapping(number_of_plane_waves, g_vector_indices, planewave_basis_);
113 Complex* output_hamiltonian_wavefunctions,
114 int number_of_vectors)
override {
127 if (band_group_size > 1 && number_of_vectors >= band_group_size) {
132 current_number_of_plane_waves_,
133 is_gamma_only_current_ ? 2 : 1);
134 if (partition.local_number_of_bands > 0) {
135 std::size_t offset =
static_cast<std::size_t
>(partition.local_first_band) *
136 current_number_of_plane_waves_;
137 apply_hamiltonian_batch(current_number_of_plane_waves_,
138 partition.local_number_of_bands,
139 *current_g_vector_indices_,
140 *current_kinetic_energy_squared_,
141 cached_scaled_potential_,
142 input_wavefunctions + offset,
143 output_hamiltonian_wavefunctions + offset);
146 partition.counts.data(),
147 partition.displacements.data());
150 apply_hamiltonian_batch(current_number_of_plane_waves_,
152 *current_g_vector_indices_,
153 *current_kinetic_energy_squared_,
154 cached_scaled_potential_,
156 output_hamiltonian_wavefunctions);
160 smooth_potential_cache_valid_ =
false;
161 cached_block_d_matrix_.clear();
162 cached_block_d_offsets_.clear();
171 return smooth_potential_cache_valid_;
178 return cached_scaled_potential_;
185 return g_to_fft_mapping_;
192 return minus_g_to_fft_mapping_;
199 return is_gamma_only_current_;
203 return gamma_origin_is_local_current_;
211 if (kpoint_index >=
static_cast<int>(cached_projector_map_.size())) {
212 cached_projector_map_.resize(kpoint_index + 1,
nullptr);
214 cached_projector_map_[kpoint_index] = projectors;
222 if (kpoint_index <
static_cast<int>(cached_projector_map_.size())) {
223 return cached_projector_map_[kpoint_index];
234 if (kpoint_index >=
static_cast<int>(cached_hubbard_projector_map_.size())) {
235 cached_hubbard_projector_map_.resize(kpoint_index + 1,
nullptr);
237 cached_hubbard_projector_map_[kpoint_index] = projectors;
246 cached_hubbard_d_matrix_ptr_ = dense_d_matrix_column_major;
262 [[nodiscard]]
static int band_thread_count(
const FFTGrid& fft_grid,
int number_of_iterations) {
264 if (transform_slots < 2) {
267 return std::min(transform_slots,
280 void apply_hamiltonian_batch(
int number_of_plane_waves,
281 int number_of_vectors,
282 const std::vector<int>& g_vector_indices,
283 const std::vector<Real>& kinetic_energy_squared,
284 const std::vector<Real>& real_space_potential,
285 const Complex* psi_wavefunctions,
286 Complex* hamiltonian_psi_wavefunctions)
const {
288 int leading_dimension = std::max(number_of_plane_waves, 1);
297 auto hpsi_timer_start = std::chrono::high_resolution_clock::now();
299 if (is_gamma_only_current_) {
305 const FFTGrid& fft_wave_gamma = planewave_basis_.
fft_wave();
311 int first_mirrored_index = gamma_origin_is_local_current_ ? 1 : 0;
312 [[maybe_unused]]
int gamma_band_threads =
313 band_thread_count(fft_wave_gamma, (number_of_vectors + 1) / 2);
321#pragma omp parallel for schedule(static) \
322 num_threads(gamma_band_threads) if (gamma_band_threads > 1)
323 for (
int pair_index = 0; pair_index < number_of_vectors; pair_index += 2) {
325 Complex* fft_input = fft_wave_gamma.slot_input_buffer(transform_slot);
326 int band_1 = pair_index;
327 int band_2 = pair_index + 1;
328 bool has_second_band = (band_2 < number_of_vectors);
330 const Complex* psi_1 = &psi_wavefunctions[band_1 * number_of_plane_waves];
331 Complex* hpsi_1 = &hamiltonian_psi_wavefunctions[band_1 * number_of_plane_waves];
333 has_second_band ? &psi_wavefunctions[band_2 * number_of_plane_waves] :
nullptr;
335 has_second_band ? &hamiltonian_psi_wavefunctions[band_2 * number_of_plane_waves]
339 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
340 hpsi_1[g_index] = kinetic_energy_squared[g_index] * psi_1[g_index];
342 if (has_second_band) {
343 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
344 hpsi_2[g_index] = kinetic_energy_squared[g_index] * psi_2[g_index];
349 std::memset(fft_input, 0, local_smooth_g_points *
sizeof(
Complex));
351 if (has_second_band) {
352 if (gamma_origin_is_local_current_) {
354 int fft_index_0 = g_to_fft_mapping_[0];
355 if (fft_index_0 >= 0) {
356 fft_input[fft_index_0] =
Complex(psi_1[0].real(), psi_2[0].real());
360 for (
int g_index = first_mirrored_index; g_index < number_of_plane_waves;
362 int fft_plus = g_to_fft_mapping_[g_index];
363 int fft_minus = minus_g_to_fft_mapping_[g_index];
368 fft_input[fft_plus] =
369 Complex(p1.real() - p2.imag(), p1.imag() + p2.real());
371 fft_input[fft_minus] =
372 Complex(p1.real() + p2.imag(), -p1.imag() + p2.real());
377 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
378 int fft_index = g_to_fft_mapping_[g_index];
379 if (fft_index >= 0) {
380 fft_input[fft_index] = psi_1[g_index];
383 for (
int g_index = first_mirrored_index; g_index < number_of_plane_waves;
385 int fft_minus = minus_g_to_fft_mapping_[g_index];
386 fft_input[fft_minus] = std::conj(psi_1[g_index]);
390 fft_wave_gamma.execute_inverse_raw_on_slot(transform_slot);
391 Complex* fft_output = fft_wave_gamma.slot_output_buffer(transform_slot);
393 for (
int grid_index = 0; grid_index < local_smooth_grid_points; ++grid_index) {
394 fft_output[grid_index] *= real_space_potential[grid_index];
397 fft_wave_gamma.prepare_forward_from_output_on_slot(transform_slot);
398 fft_wave_gamma.execute_forward_on_slot(transform_slot);
399 fft_output = fft_wave_gamma.slot_output_buffer(transform_slot);
402 if (has_second_band) {
403 if (gamma_origin_is_local_current_) {
405 int fft_index_0 = g_to_fft_mapping_[0];
406 if (fft_index_0 >= 0) {
407 Complex result_0 = fft_output[fft_index_0];
408 hpsi_1[0] +=
Complex(result_0.real(), 0.0);
409 hpsi_2[0] +=
Complex(result_0.imag(), 0.0);
413 for (
int g_index = first_mirrored_index; g_index < number_of_plane_waves;
415 int fft_plus = g_to_fft_mapping_[g_index];
416 int fft_minus = minus_g_to_fft_mapping_[g_index];
418 Complex result_plus = fft_output[fft_plus];
419 Complex result_minus_conj = std::conj(fft_output[fft_minus]);
420 hpsi_1[g_index] += (result_plus + result_minus_conj) * 0.5;
421 Complex diff = (result_plus - result_minus_conj) * 0.5;
422 hpsi_2[g_index] +=
Complex(diff.imag(), -diff.real());
427 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
428 int fft_index = g_to_fft_mapping_[g_index];
429 if (fft_index >= 0) {
430 hpsi_1[g_index] += fft_output[fft_index];
443 const FFTGrid& fft_wave = planewave_basis_.
fft_wave();
444 [[maybe_unused]]
int band_threads = band_thread_count(fft_wave, number_of_vectors);
457#pragma omp parallel for schedule(static) num_threads(band_threads) if (band_threads > 1)
458 for (
int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
460 Complex* fft_input = fft_wave.slot_input_buffer(transform_slot);
462 &psi_wavefunctions[vector_index * number_of_plane_waves];
463 Complex* hamiltonian_psi_vector =
464 &hamiltonian_psi_wavefunctions[vector_index * number_of_plane_waves];
467 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
468 hamiltonian_psi_vector[g_index] =
469 kinetic_energy_squared[g_index] * psi_vector[g_index];
473 std::memset(fft_input, 0, local_smooth_g_points *
sizeof(
Complex));
474 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
475 int fft_index = g_to_fft_mapping_[g_index];
476 if (fft_index >= 0) {
477 fft_input[fft_index] = psi_vector[g_index];
480 fft_wave.execute_inverse_raw_on_slot(transform_slot);
481 Complex* fft_output = fft_wave.slot_output_buffer(transform_slot);
482 for (
int grid_index = 0; grid_index < local_smooth_grid_points; ++grid_index) {
483 fft_output[grid_index] *= real_space_potential[grid_index];
485 fft_wave.prepare_forward_from_output_on_slot(transform_slot);
486 fft_wave.execute_forward_on_slot(transform_slot);
487 fft_output = fft_wave.slot_output_buffer(transform_slot);
488 for (
int g_index = 0; g_index < number_of_plane_waves; ++g_index) {
489 int fft_index = g_to_fft_mapping_[g_index];
490 if (fft_index >= 0) {
491 hamiltonian_psi_vector[g_index] += fft_output[fft_index];
496 auto hpsi_timer_after_fft = std::chrono::high_resolution_clock::now();
503 Matrix<Complex> computed_projectors;
504 const Matrix<Complex>* kleinman_bylander_potential_ptr =
nullptr;
505 if (current_kpoint_index_ <
static_cast<int>(cached_projector_map_.size()) &&
506 cached_projector_map_[current_kpoint_index_] !=
nullptr) {
507 kleinman_bylander_potential_ptr = cached_projector_map_[current_kpoint_index_];
509 Vector3D kpoint_coordinates = kpoint_grid_[current_kpoint_index_].coordinates;
517 number_of_plane_waves,
520 computed_projectors);
521 kleinman_bylander_potential_ptr = &computed_projectors;
523 const auto& kleinman_bylander_potential = *kleinman_bylander_potential_ptr;
525 if (kleinman_bylander_potential.empty()) {
529 int total_number_of_projectors =
static_cast<int>(kleinman_bylander_potential.rows());
531 auto* cast_wavefunctions =
reinterpret_cast<const std::complex<double>*
>(psi_wavefunctions);
532 auto* cast_hamiltonian_wavefunctions =
533 reinterpret_cast<std::complex<double>*
>(hamiltonian_psi_wavefunctions);
534 auto* cast_projector_matrix =
535 reinterpret_cast<const std::complex<double>*
>(kleinman_bylander_potential.data());
540 auto* cast_alpha_one =
reinterpret_cast<const std::complex<double>*
>(&alpha_one);
541 auto* cast_beta_zero =
reinterpret_cast<const std::complex<double>*
>(&beta_zero);
542 auto* cast_beta_one =
reinterpret_cast<const std::complex<double>*
>(&beta_one);
545 std::vector<Complex> all_overlap_coefficients(
546 total_number_of_projectors * number_of_vectors,
Complex(0.0, 0.0));
548 if (is_gamma_only_current_) {
550 int double_number_of_plane_waves = 2 * number_of_plane_waves;
551 int double_leading_dimension = 2 * leading_dimension;
552 double alpha_two = 2.0;
553 double d_beta_zero = 0.0;
555 auto* real_projectors =
556 reinterpret_cast<const double*
>(kleinman_bylander_potential.data());
557 auto* real_wavefunctions =
reinterpret_cast<const double*
>(psi_wavefunctions);
559 std::vector<double> overlap_real(
560 static_cast<size_t>(total_number_of_projectors) * number_of_vectors, 0.0);
563 &total_number_of_projectors,
565 &double_number_of_plane_waves,
567 const_cast<double*
>(real_projectors),
568 &double_leading_dimension,
569 const_cast<double*
>(real_wavefunctions),
570 &double_leading_dimension,
573 &total_number_of_projectors);
579 for (
int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
580 const Complex* psi_g0 = &psi_wavefunctions[vector_index * number_of_plane_waves];
581 for (
int projector_index = 0; projector_index < total_number_of_projectors;
583 int index = projector_index + vector_index * total_number_of_projectors;
584 if (gamma_origin_is_local_current_) {
585 Complex beta_g0 = kleinman_bylander_potential(projector_index, 0);
586 overlap_real[index] -= (std::conj(beta_g0) * psi_g0[0]).real();
588 all_overlap_coefficients[index] =
Complex(overlap_real[index], 0.0);
594 total_number_of_projectors * number_of_vectors);
597 auto* cast_all_overlap_coefficients =
598 reinterpret_cast<std::complex<double>*
>(all_overlap_coefficients.data());
602 &total_number_of_projectors,
604 &number_of_plane_waves,
606 cast_projector_matrix,
611 cast_all_overlap_coefficients,
612 &total_number_of_projectors);
616 total_number_of_projectors * number_of_vectors);
618 auto hpsi_timer_after_overlap = std::chrono::high_resolution_clock::now();
630 if (cached_block_d_matrix_.empty() || cached_block_d_offsets_.empty()) {
631 cached_block_d_offsets_.clear();
632 cached_block_d_sizes_.clear();
633 cached_block_d_projector_starts_.clear();
634 std::size_t packed_size = 0;
635 int starting_projector_index = 0;
636 for (
int atom_index = 0; atom_index < crystal_structure_.
number_of_atoms();
639 int number_of_projectors_for_atom =
642 cached_block_d_offsets_.push_back(packed_size);
643 cached_block_d_sizes_.push_back(number_of_projectors_for_atom);
644 cached_block_d_projector_starts_.push_back(starting_projector_index);
645 packed_size +=
static_cast<std::size_t
>(number_of_projectors_for_atom) *
646 static_cast<std::size_t
>(number_of_projectors_for_atom);
647 starting_projector_index += number_of_projectors_for_atom;
649 cached_block_d_matrix_.assign(packed_size,
Complex(0.0, 0.0));
651 for (std::size_t atom = 0; atom < cached_block_d_sizes_.size(); ++atom) {
652 int atom_index =
static_cast<int>(atom);
654 int block_size = cached_block_d_sizes_[atom];
655 Complex* block = cached_block_d_matrix_.data() + cached_block_d_offsets_[atom];
656 for (
int projector_index_a = 0; projector_index_a < block_size;
657 projector_index_a++) {
658 for (
int projector_index_b = 0; projector_index_b < block_size;
659 projector_index_b++) {
660 Real d_matrix_value =
666 if (std::abs(d_matrix_value) >
668 block[
static_cast<std::size_t
>(projector_index_a) +
669 static_cast<std::size_t
>(projector_index_b) * block_size] =
677 std::vector<Complex> all_scaled_overlap_coefficients(
678 static_cast<std::size_t
>(total_number_of_projectors) * number_of_vectors,
680 auto* cast_all_scaled_overlap_coefficients =
681 reinterpret_cast<std::complex<double>*
>(all_scaled_overlap_coefficients.data());
682 auto* cast_overlap_input =
683 reinterpret_cast<const std::complex<double>*
>(all_overlap_coefficients.data());
685 for (std::size_t atom = 0; atom < cached_block_d_sizes_.size(); ++atom) {
686 int block_size = cached_block_d_sizes_[atom];
687 if (block_size == 0) {
690 int projector_start = cached_block_d_projector_starts_[atom];
691 auto* cast_block =
reinterpret_cast<const std::complex<double>*
>(
692 cached_block_d_matrix_.data() + cached_block_d_offsets_[atom]);
700 const_cast<std::complex<double>*
>(cast_block),
702 const_cast<std::complex<double>*
>(cast_overlap_input + projector_start),
703 &total_number_of_projectors,
705 cast_all_scaled_overlap_coefficients + projector_start,
706 &total_number_of_projectors);
713 auto* cast_all_scaled_overlap_coefficients_const =
714 reinterpret_cast<const std::complex<double>*
>(all_scaled_overlap_coefficients.data());
718 &number_of_plane_waves,
720 &total_number_of_projectors,
722 cast_projector_matrix,
724 cast_all_scaled_overlap_coefficients_const,
725 &total_number_of_projectors,
727 cast_hamiltonian_wavefunctions,
737 current_kpoint_index_ < static_cast<int>(cached_hubbard_projector_map_.size()) &&
738 cached_hubbard_projector_map_[current_kpoint_index_] !=
nullptr &&
739 cached_hubbard_d_matrix_ptr_ !=
nullptr;
741 const auto& hubbard_projectors = *cached_hubbard_projector_map_[current_kpoint_index_];
742 int total_hubbard_orbitals =
static_cast<int>(hubbard_projectors.rows());
743 if (total_hubbard_orbitals > 0) {
744 auto* cast_hubbard_projector_matrix =
745 reinterpret_cast<const std::complex<double>*
>(hubbard_projectors.data());
748 std::vector<Complex> hubbard_overlaps(
static_cast<size_t>(total_hubbard_orbitals) *
751 auto* cast_hubbard_overlaps =
752 reinterpret_cast<std::complex<double>*
>(hubbard_overlaps.data());
755 &total_hubbard_orbitals,
757 &number_of_plane_waves,
759 cast_hubbard_projector_matrix,
764 cast_hubbard_overlaps,
765 &total_hubbard_orbitals);
788 if (is_gamma_only_current_) {
789 for (
int vector_index = 0; vector_index < number_of_vectors; ++vector_index) {
790 const Complex* wavefunction_g_zero =
791 &psi_wavefunctions[
static_cast<size_t>(vector_index) *
792 number_of_plane_waves];
793 for (
int orbital_index = 0; orbital_index < total_hubbard_orbitals;
795 Real g_zero_product =
796 gamma_origin_is_local_current_
797 ? (std::conj(hubbard_projectors(
798 static_cast<size_t>(orbital_index), 0)) *
799 wavefunction_g_zero[0])
803 static_cast<size_t>(vector_index) * total_hubbard_orbitals +
806 hubbard_overlaps[flat_index], g_zero_product);
811 total_hubbard_orbitals * number_of_vectors);
814 std::vector<Complex> hubbard_scaled_overlaps(
815 static_cast<size_t>(total_hubbard_orbitals) * number_of_vectors,
817 auto* cast_hubbard_d_matrix =
reinterpret_cast<const std::complex<double>*
>(
818 cached_hubbard_d_matrix_ptr_->data());
819 auto* cast_hubbard_overlaps_const =
820 reinterpret_cast<const std::complex<double>*
>(hubbard_overlaps.data());
821 auto* cast_hubbard_scaled_overlaps =
822 reinterpret_cast<std::complex<double>*
>(hubbard_scaled_overlaps.data());
825 &total_hubbard_orbitals,
827 &total_hubbard_orbitals,
829 cast_hubbard_d_matrix,
830 &total_hubbard_orbitals,
831 cast_hubbard_overlaps_const,
832 &total_hubbard_orbitals,
834 cast_hubbard_scaled_overlaps,
835 &total_hubbard_orbitals);
838 auto* cast_hubbard_scaled_overlaps_const =
839 reinterpret_cast<const std::complex<double>*
>(hubbard_scaled_overlaps.data());
842 &number_of_plane_waves,
844 &total_hubbard_orbitals,
846 cast_hubbard_projector_matrix,
848 cast_hubbard_scaled_overlaps_const,
849 &total_hubbard_orbitals,
851 cast_hamiltonian_wavefunctions,
857 auto hpsi_timer_end = std::chrono::high_resolution_clock::now();
860 std::chrono::duration<double, std::milli>(hpsi_timer_after_fft - hpsi_timer_start)
862 timing.hamiltonian_nonlocal_time_ms +=
863 std::chrono::duration<double, std::milli>(hpsi_timer_end - hpsi_timer_after_fft)
865 timing.hamiltonian_projector_overlap_time_ms +=
866 std::chrono::duration<double, std::milli>(hpsi_timer_after_overlap -
867 hpsi_timer_after_fft)
881 compute_smooth_grid_potential(
const std::vector<Real>& dense_real_space_potential,
882 const PlanewaveBasis& planewave_basis)
const {
884 int total_smooth_points = planewave_basis.fft_wave().total_grid_points();
887 auto full_smooth_potential_g =
892 total_smooth_points);
906 void precompute_g_to_fft_mapping(
int number_of_plane_waves,
907 const std::vector<int>& g_vector_indices,
908 const PlanewaveBasis& planewave_basis) {
911 number_of_plane_waves, g_vector_indices, planewave_basis, g_to_fft_mapping_);
914 if (planewave_basis.is_gamma_only()) {
915 minus_g_to_fft_mapping_.resize(number_of_plane_waves);
916 for (
int g_vector_index = 0; g_vector_index < number_of_plane_waves; g_vector_index++) {
917 const auto& g_vector =
918 planewave_basis.g_vectors()[g_vector_indices[g_vector_index]];
919 int miller_index_1 =
static_cast<int>(std::round(g_vector.miller.x));
920 int miller_index_2 =
static_cast<int>(std::round(g_vector.miller.y));
921 int miller_index_3 =
static_cast<int>(std::round(g_vector.miller.z));
922 minus_g_to_fft_mapping_[g_vector_index] =
923 planewave_basis.fft_wave().g_vector_to_fft_grid_index(
924 -miller_index_1, -miller_index_2, -miller_index_3);
927 minus_g_to_fft_mapping_.clear();
932 int fft_grid_dimension_1 = planewave_basis.fft_wave().grid_dimension_1();
933 int fft_grid_dimension_2 = planewave_basis.fft_wave().grid_dimension_2();
934 int fft_grid_dimension_3 = planewave_basis.fft_wave().grid_dimension_3();
935 g_to_fft_serial_mapping_.resize(number_of_plane_waves);
936 const auto& serial_fft = planewave_basis.fft_wave_serial();
937 for (
int g_vector_index = 0; g_vector_index < number_of_plane_waves; g_vector_index++) {
938 const auto& g_vector =
939 planewave_basis.g_vectors()[g_vector_indices[g_vector_index]];
940 int miller_index_1 =
static_cast<int>(std::round(g_vector.miller.x));
941 int miller_index_2 =
static_cast<int>(std::round(g_vector.miller.y));
942 int miller_index_3 =
static_cast<int>(std::round(g_vector.miller.z));
943 if (std::abs(miller_index_1) <= fft_grid_dimension_1 / 2 &&
944 std::abs(miller_index_2) <= fft_grid_dimension_2 / 2 &&
945 std::abs(miller_index_3) <= fft_grid_dimension_3 / 2) {
946 g_to_fft_serial_mapping_[g_vector_index] =
947 serial_fft.g_vector_to_fft_grid_index(
948 miller_index_1, miller_index_2, miller_index_3);
950 g_to_fft_serial_mapping_[g_vector_index] = -1;
958 const Crystal& crystal_structure_;
959 const PlanewaveBasis& planewave_basis_;
960 const KPointsGrid& kpoint_grid_;
961 const NormConservingPlanewaveKohnShamQuantumSystem& pseudopotential_quantum_system_;
962 const execution::ExecutionPolicy& execution_policy_;
966 int current_kpoint_index_ = 0;
967 int current_number_of_plane_waves_ = 0;
968 const std::vector<int>* current_g_vector_indices_ =
nullptr;
969 const std::vector<Real>* current_kinetic_energy_squared_ =
nullptr;
970 bool is_gamma_only_current_ =
false;
971 bool gamma_origin_is_local_current_ =
true;
975 std::vector<int> g_to_fft_mapping_;
976 std::vector<int> minus_g_to_fft_mapping_;
977 std::vector<int> g_to_fft_serial_mapping_;
982 std::vector<const q3::Matrix<Complex>*> cached_projector_map_;
987 std::vector<const q3::Matrix<Complex>*> cached_hubbard_projector_map_;
992 const std::vector<Complex>* cached_hubbard_d_matrix_ptr_ =
nullptr;
994 mutable std::vector<Real> cached_smooth_potential_;
995 mutable std::vector<Real> cached_scaled_potential_;
996 bool smooth_potential_cache_valid_ =
false;
1003 mutable std::vector<Complex> cached_block_d_matrix_;
1004 mutable std::vector<std::size_t> cached_block_d_offsets_;
1005 mutable std::vector<int> cached_block_d_sizes_;
1006 mutable std::vector<int> cached_block_d_projector_starts_;
1008 mutable std::vector<Real> cached_full_grid_potential_;