22 using namespace constants;
25 Real two_pi_over_lattice_parameter_squared =
32 for (
int atom_index = 0; atom_index < number_of_atoms; atom_index++) {
38 Real g_cutoff_magnitude =
43 Real upperbound = 2.0 * charge * charge * std::sqrt(2.0 * alpha / pi) *
44 std::erfc(std::sqrt(two_pi_over_lattice_parameter_squared *
45 g_cutoff_magnitude / (4.0 * alpha)));
53 Real ewald_g_space_sum = 0.0;
56 if (first_nonzero_g_index == 1) {
57 ewald_g_space_sum = -charge * charge / alpha / 4.0;
60 for (
int g_index = first_nonzero_g_index; g_index < number_of_g_vectors; g_index++) {
61 Complex charge_density_coefficient(0.0, 0.0);
62 for (
int atom_index = 0; atom_index < number_of_atoms; atom_index++) {
65 const auto& g_vector = planewave_basis.
g_vectors()[g_index];
66 Real phase_angle = two_pi * g_vector.g_cart.dot(atomic_position);
67 charge_density_coefficient +=
71 Real g_squared = planewave_basis.
g_vectors()[g_index].magnitude_squared *
72 two_pi_over_lattice_parameter_squared;
74 std::norm(charge_density_coefficient) * std::exp(-g_squared / alpha / 4.0) / g_squared;
82 ewald_g_space_sum += term;
84 ewald_g_space_sum = 2.0 * two_pi / cell_volume * ewald_g_space_sum;
87 if (first_nonzero_g_index == 1) {
88 for (
int atom_index = 0; atom_index < number_of_atoms; atom_index++) {
92 std::sqrt(8.0 / two_pi * alpha);
97 Real ewald_r_space_sum = 0.0;
98 Real rmax_bohr = 4.0 / std::sqrt(alpha);
99 Real rmax_alat = rmax_bohr / lattice_parameter;
101 std::abs(lattice_vectors[0].dot(lattice_vectors[1].cross(lattice_vectors[2])));
103 int limit_x = std::max(
105 static_cast<int>(std::ceil(rmax_alat * lattice_vectors[1].cross(lattice_vectors[2]).norm() /
107 int limit_y = std::max(
109 static_cast<int>(std::ceil(rmax_alat * lattice_vectors[2].cross(lattice_vectors[0]).norm() /
111 int limit_z = std::max(
113 static_cast<int>(std::ceil(rmax_alat * lattice_vectors[0].cross(lattice_vectors[1]).norm() /
116 for (
int atom_index_a = 0; atom_index_a < number_of_atoms; atom_index_a++) {
117 for (
int atom_index_b = 0; atom_index_b < number_of_atoms; atom_index_b++) {
125 for (
int lattice_index_x = -limit_x; lattice_index_x <= limit_x; lattice_index_x++) {
126 for (
int lattice_index_y = -limit_y; lattice_index_y <= limit_y;
128 for (
int lattice_index_z = -limit_z; lattice_index_z <= limit_z;
130 if (atom_index_a == atom_index_b && lattice_index_x == 0 &&
131 lattice_index_y == 0 && lattice_index_z == 0)
134 for (
int dimension_index = 0; dimension_index < 3; dimension_index++) {
135 real_space_vector[dimension_index] =
136 position_difference[dimension_index] +
137 lattice_index_x * lattice_vectors[0][dimension_index] +
138 lattice_index_y * lattice_vectors[1][dimension_index] +
139 lattice_index_z * lattice_vectors[2][dimension_index];
141 Real real_space_distance = real_space_vector.
norm() * lattice_parameter;
144 if (real_space_distance > rmax_bohr)
151 std::erfc(std::sqrt(alpha) * real_space_distance) / real_space_distance;
158 return 0.5 * electron_charge_squared_rydberg * (ewald_g_space_sum + ewald_r_space_sum);