126 {
127 std::vector<double> drho_dr(3 * N);
128 for (long k = 0; k < 3 * N; k++) {
129 F[k] = 0.0;
130 }
131 *U = 0;
132
133
134 const double halfBox0 = box[0] * 0.5;
135 const double halfBox1 = box[1] * 0.5;
136 const double halfBox2 = box[2] * 0.5;
137
138 for (long i = 0; i < N; i++) {
139 std::fill(drho_dr.begin(), drho_dr.end(), 0.0);
141 const double cutoff2 = epar.r_cut * epar.r_cut;
142
143 double dens = 0.0;
144 const double xi = R[3 * i];
145 const double yi = R[3 * i + 1];
146 const double zi = R[3 * i + 2];
147
148 for (long j = 0; j < N; j++) {
149 if (i == j)
150 continue;
151
152 double dx = xi - R[3 * j];
153 double dy = yi - R[3 * j + 1];
154 double dz = zi - R[3 * j + 2];
155
156
157 if (dx > halfBox0)
158 dx -= box[0];
159 else if (dx < -halfBox0)
160 dx += box[0];
161 if (dy > halfBox1)
162 dy -= box[1];
163 else if (dy < -halfBox1)
164 dy += box[1];
165 if (dz > halfBox2)
166 dz -= box[2];
167 else if (dz < -halfBox2)
168 dz += box[2];
169
170 double r2 = dx * dx + dy * dy + dz * dz;
171
172 if (r2 > cutoff2)
173 continue;
174
175 double r = std::sqrt(r2);
176
177
178 double r6 = r2 * r2 * r2;
179 double exp_b1 = std::exp(-epar.beta1 * r);
180 double exp_b2 = std::exp(-2.0 * epar.beta2 * r);
181 double rho_pair = exp_b1 + 512.0 * exp_b2;
182
183 dens += r6 * rho_pair;
184
185
186 double r5 = r2 * r2 * r;
187 double mag_force_den =
188 6.0 * r5 * rho_pair +
189 r6 * (-epar.beta1 * exp_b1 - 1024.0 * epar.beta2 * exp_b2);
190
191 double invR = 1.0 / r;
192 double fscale = -mag_force_den * invR;
193 drho_dr[3 * i] += fscale * dx;
194 drho_dr[3 * i + 1] += fscale * dy;
195 drho_dr[3 * i + 2] += fscale * dz;
196 drho_dr[3 * j] -= fscale * dx;
197 drho_dr[3 * j + 1] -= fscale * dy;
198 drho_dr[3 * j + 2] -= fscale * dz;
199
200 if (j > i) {
201
202 double expArg = std::exp(-epar.alphaM * (r - epar.Rm));
203 double d = 1.0 - expArg;
204 double phi_r = epar.Dm * d * d - epar.Dm;
205
206
207 double mag_force = 2.0 * epar.alphaM * epar.Dm * d * (d - 1.0);
208
209 double fcomp_scale = mag_force * invR;
210 F[3 * i] -= fcomp_scale * dx;
211 F[3 * i + 1] -= fcomp_scale * dy;
212 F[3 * i + 2] -= fcomp_scale * dz;
213 F[3 * j] += fcomp_scale * dx;
214 F[3 * j + 1] += fcomp_scale * dy;
215 F[3 * j + 2] += fcomp_scale * dz;
216 *U += phi_r;
217 }
218 }
219
222 for (long k = 0; k < 3 * N; k++) {
223 F[k] -= dF_drho * drho_dr[k];
224 }
225 }
226}
element_parameters get_element_parameters(int atomic_number)
static double embedding_force(const double *func_coeff, double rho)
static double embedding_function(const double *func_coeff, double rho)