36 const std::vector<int>& mesh_sizes,
37 const std::vector<Real>& g_vector_magnitudes,
39 int number_of_q_points) {
41 int number_of_species_types =
static_cast<int>(pseudopotential_set.
size());
42 int number_of_g_vectors =
static_cast<int>(g_vector_magnitudes.size());
45 std::vector<Real> q_point_values(number_of_q_points);
46 for (
int q_index = 0; q_index < number_of_q_points; q_index++) {
47 q_point_values[q_index] = q_index * q_spacing;
51 std::vector<std::vector<Real>> atomic_charge_density_table(number_of_species_types);
52 for (
int type_index = 0; type_index < number_of_species_types; type_index++) {
64 const auto* paw =
dynamic_cast<const PawPseudopotential*
>(&pseudopotential_set[type_index]);
65 if (paw !=
nullptr && paw->has_reciprocal_atomic_charge()) {
67 paw->reciprocal_charge_grid_spacing,
70 atomic_charge_density_table[type_index]);
73 if (pseudopotential_set[type_index].charge_atomic.radial_values.
empty()) {
74 throw std::runtime_error(
75 "Pseudopotential for " + pseudopotential_set[type_index].element +
76 " carries no atomic charge density in either representation, so no starting "
77 "density can be built from it.");
79 const auto& pseudopotential = pseudopotential_set[type_index];
80 int radial_mesh_size = mesh_sizes[type_index];
81 atomic_charge_density_table[type_index].resize(number_of_q_points);
82 for (
int q_index = 0; q_index < number_of_q_points; q_index++) {
83 Real q_value = q_point_values[q_index];
85 for (
int radial_index = 0; radial_index < radial_mesh_size; radial_index++) {
88 Real integrand = pseudopotential.charge_atomic.radial_values[radial_index] *
90 pseudopotential.radial_grid_derivative[radial_index];
92 if (radial_index == 0 || radial_index == radial_mesh_size - 1)
94 else if (radial_index % 2 == 1)
98 sum += weight * integrand;
100 atomic_charge_density_table[type_index][q_index] = sum / 3.0;
105 std::vector<std::vector<Real>> atomic_charge_density_g(number_of_species_types);
106 for (
int type_index = 0; type_index < number_of_species_types; type_index++) {
107 atomic_charge_density_g[type_index].resize(number_of_g_vectors);
108 for (
int g_vector_index = 0; g_vector_index < number_of_g_vectors; g_vector_index++) {
109 Real q = g_vector_magnitudes[g_vector_index];
111 atomic_charge_density_g[type_index][g_vector_index] =
112 atomic_charge_density_table[type_index][0];
115 atomic_charge_density_table[type_index], q, q_spacing, number_of_q_points);
117 if (std::isnan(atomic_charge_density_g[type_index][g_vector_index])) {
118 log::error(
"Atomic charge density G-space coefficient is NaN: "
119 "species_type={}, g_index={}, q_value={}",
127 return atomic_charge_density_g;
std::vector< std::vector< Real > > tabulate_atomic_charge_density_in_g_space(const PseudopotentialSet &pseudopotential_set, const std::vector< int > &mesh_sizes, const std::vector< Real > &g_vector_magnitudes, Real q_spacing, int number_of_q_points)