40 Real total_charge = 0.0;
41 for (
int atom_index = 0; atom_index < crystal_structure_.
number_of_atoms(); atom_index++) {
46 Real alpha_ewald = 2.9;
47 while (alpha_ewald > 0.1) {
53 gcutm / (4.0 * alpha_ewald)));
59 Real reciprocal_space_multiplicity = planewave_basis_.
is_gamma_only() ? 2.0 : 1.0;
61 Real stress_diagonal_contribution = 0.0;
62 if (g_vector_start == 1) {
63 stress_diagonal_contribution =
65 (4.0 * alpha_ewald) * (total_charge / crystal_structure_.
cell_volume()) *
69 Real stress_xx = 0, stress_yx = 0, stress_yy = 0, stress_zx = 0, stress_zy = 0,
71 for (
int g_vector_index = g_vector_start;
74 const auto& g_vector = planewave_basis_.
g_vectors()[g_vector_index];
75 Real g_vector_squared = g_vector.magnitude_squared *
79 Real g_squared_over_four_alpha = g_vector_squared / (4.0 * alpha_ewald);
81 Complex structure_factor(0.0, 0.0);
82 for (
int atom_index = 0; atom_index < crystal_structure_.
number_of_atoms();
95 std::exp(-g_squared_over_four_alpha) / g_vector_squared *
96 std::norm(structure_factor);
97 stress_diagonal_contribution -= ewald_stress_term;
99 Real factor = ewald_stress_term *
101 (g_squared_over_four_alpha + 1.0) / g_vector_squared;
102 stress_xx += factor * g_vector.g_cart.x * g_vector.g_cart.x;
103 stress_yx += factor * g_vector.g_cart.y * g_vector.g_cart.x;
104 stress_yy += factor * g_vector.g_cart.y * g_vector.g_cart.y;
105 stress_zx += factor * g_vector.g_cart.z * g_vector.g_cart.x;
106 stress_zy += factor * g_vector.g_cart.z * g_vector.g_cart.y;
107 stress_zz += factor * g_vector.g_cart.z * g_vector.g_cart.z;
110 result_.
ewald[0][0] = stress_diagonal_contribution + stress_xx;
111 result_.
ewald[0][1] = stress_yx;
112 result_.
ewald[1][1] = stress_diagonal_contribution + stress_yy;
113 result_.
ewald[0][2] = stress_zx;
114 result_.
ewald[1][2] = stress_zy;
115 result_.
ewald[2][2] = stress_diagonal_contribution + stress_zz;
118 Real rmax_bohr = 4.0 / std::sqrt(alpha_ewald);
119 Real rmax_alat = rmax_bohr / lattice_parameter;
121 std::abs(lattice_vectors[0].dot(lattice_vectors[1].cross(lattice_vectors[2])));
123 int limit_x = std::max(
125 static_cast<int>(std::ceil(
126 rmax_alat * lattice_vectors[1].cross(lattice_vectors[2]).norm() / volume_alat)));
127 int limit_y = std::max(
129 static_cast<int>(std::ceil(
130 rmax_alat * lattice_vectors[2].cross(lattice_vectors[0]).norm() / volume_alat)));
131 int limit_z = std::max(
133 static_cast<int>(std::ceil(
134 rmax_alat * lattice_vectors[0].cross(lattice_vectors[1]).norm() / volume_alat)));
136 for (
int atom_index_a = 0; atom_index_a < crystal_structure_.
number_of_atoms();
138 for (
int atom_index_b = 0; atom_index_b < crystal_structure_.
number_of_atoms();
144 Vector3D atom_displacement_cartesian =
147 for (
int lattice_index_x = -limit_x; lattice_index_x <= limit_x;
149 for (
int lattice_index_y = -limit_y; lattice_index_y <= limit_y;
151 for (
int lattice_index_z = -limit_z; lattice_index_z <= limit_z;
153 if (atom_index_a == atom_index_b && lattice_index_x == 0 &&
154 lattice_index_y == 0 && lattice_index_z == 0)
157 for (
int direction = 0; direction < 3; direction++) {
158 displacement_vector[direction] =
159 atom_displacement_cartesian[direction] +
160 (lattice_index_x * lattice_vectors[0][direction] +
161 lattice_index_y * lattice_vectors[1][direction] +
162 lattice_index_z * lattice_vectors[2][direction]);
164 Real displacement_magnitude =
165 displacement_vector.
norm() * lattice_parameter;
166 if (displacement_magnitude <
169 if (displacement_magnitude > rmax_bohr)
178 (2.0 * crystal_structure_.
cell_volume()) * lattice_parameter *
179 lattice_parameter * valence_charge_a * valence_charge_b /
180 (displacement_magnitude * displacement_magnitude *
181 displacement_magnitude) *
182 (std::erfc(std::sqrt(alpha_ewald) * displacement_magnitude) +
183 displacement_magnitude *
185 std::exp(-alpha_ewald * displacement_magnitude *
186 displacement_magnitude));
188 for (
int direction_a = 0; direction_a < 3; direction_a++) {
189 for (
int direction_b = direction_a; direction_b < 3;
191 result_.
ewald[direction_a][direction_b] +=
192 ewald_factor * displacement_vector[direction_a] *
193 displacement_vector[direction_b];
202 for (
int direction_a = 0; direction_a < 3; direction_a++) {
203 for (
int direction_b = direction_a + 1; direction_b < 3; direction_b++) {
204 result_.
ewald[direction_b][direction_a] = result_.
ewald[direction_a][direction_b];
208 for (
int direction_a = 0; direction_a < 3; direction_a++) {
209 for (
int direction_b = 0; direction_b < 3; direction_b++) {
210 result_.
ewald[direction_a][direction_b] = -result_.
ewald[direction_a][direction_b];