34 [[nodiscard]] std::vector<Vector3D>
compute()
const {
35 using namespace constants;
39 Real total_charge = 0.0;
40 for (
int atom_index = 0; atom_index < crystal_structure_.
number_of_atoms(); atom_index++) {
48 static constexpr Real initial_ewald_convergence_parameter = 2.9;
49 static constexpr Real ewald_convergence_parameter_step = 0.1;
50 Real alpha = initial_ewald_convergence_parameter;
51 while (alpha > ewald_convergence_parameter_step) {
52 alpha -= ewald_convergence_parameter_step;
54 2.0 * total_charge * total_charge * std::sqrt(2.0 * alpha / pi) *
56 cutoff_g_space / (4.0 * alpha)));
61 if (alpha < ewald_convergence_parameter_step) {
62 alpha = ewald_convergence_parameter_step;
65 std::vector<Vector3D> forces(crystal_structure_.
number_of_atoms(), {0.0, 0.0, 0.0});
69 for (
int g_vector_index = first_nonzero_g_index;
72 Real g_vector_squared = planewave_basis_.
g_vectors()[g_vector_index].magnitude_squared *
92 Real factor = std::exp(-g_vector_squared / alpha / 4.0) / g_vector_squared * 2.0 *
95 Complex valence_charge_density_g(0.0, 0.0);
96 for (
int atom_index = 0; atom_index < crystal_structure_.
number_of_atoms();
100 Real phase = two_pi * planewave_basis_.
g_vectors()[g_vector_index].g_cart.dot(
107 for (
int atom_index = 0; atom_index < crystal_structure_.
number_of_atoms();
111 Real phase = two_pi * planewave_basis_.
g_vectors()[g_vector_index].g_cart.dot(
117 for (
int direction = 0; direction < 3; direction++) {
118 Real g_cartesian_component =
119 planewave_basis_.
g_vectors()[g_vector_index].g_cart[direction] *
121 Real force_prefactor = valence_charge_i * factor * g_cartesian_component;
123 valence_charge_density_g * std::conj(structure_factor_i);
130 forces[atom_index][direction] += electron_charge_squared_rydberg * two_pi /
132 force_prefactor * complex_product.imag();
138 Real rmax_bohr = 4.0 / std::sqrt(alpha);
139 Real rmax_alat = rmax_bohr / lattice_parameter;
141 std::abs(lattice_vectors[0].dot(lattice_vectors[1].cross(lattice_vectors[2])));
143 int limit_x = std::max(
145 static_cast<int>(std::ceil(
146 rmax_alat * lattice_vectors[1].cross(lattice_vectors[2]).norm() / volume_alat)));
147 int limit_y = std::max(
149 static_cast<int>(std::ceil(
150 rmax_alat * lattice_vectors[2].cross(lattice_vectors[0]).norm() / volume_alat)));
151 int limit_z = std::max(
153 static_cast<int>(std::ceil(
154 rmax_alat * lattice_vectors[0].cross(lattice_vectors[1]).norm() / volume_alat)));
156 for (
int atom_index_a = 0; atom_index_a < crystal_structure_.
number_of_atoms();
158 for (
int atom_index_b = 0; atom_index_b < crystal_structure_.
number_of_atoms();
167 for (
int lattice_vector_multiplier_1 = -limit_x;
168 lattice_vector_multiplier_1 <= limit_x;
169 lattice_vector_multiplier_1++) {
170 for (
int lattice_vector_multiplier_2 = -limit_y;
171 lattice_vector_multiplier_2 <= limit_y;
172 lattice_vector_multiplier_2++) {
173 for (
int lattice_vector_multiplier_3 = -limit_z;
174 lattice_vector_multiplier_3 <= limit_z;
175 lattice_vector_multiplier_3++) {
176 if (atom_index_a == atom_index_b && lattice_vector_multiplier_1 == 0 &&
177 lattice_vector_multiplier_2 == 0 &&
178 lattice_vector_multiplier_3 == 0) {
182 for (
int direction = 0; direction < 3; direction++) {
183 displacement_vector[direction] =
184 position_difference[direction] +
185 lattice_vector_multiplier_1 * lattice_vectors[0][direction] +
186 lattice_vector_multiplier_2 * lattice_vectors[1][direction] +
187 lattice_vector_multiplier_3 * lattice_vectors[2][direction];
189 Real distance_magnitude =
190 displacement_vector.
norm() * lattice_parameter;
191 if (distance_magnitude <
195 if (distance_magnitude > rmax_bohr) {
199 Real argument = std::sqrt(alpha) * distance_magnitude;
205 (2.0 * argument / std::sqrt(pi) * std::exp(-argument * argument) +
206 std::erfc(argument)) /
207 (distance_magnitude * distance_magnitude);
209 for (
int direction = 0; direction < 3; direction++) {
210 forces[atom_index_a][direction] -=
211 electron_charge_squared_rydberg * factor *
212 displacement_vector[direction] * lattice_parameter /