25#if defined(FORCEFIELDS_UNIT_SYSTEM_HPP) && \
26 (FORCEFIELDS_UNIT_SYSTEM_HPP != \
27 FORCEFIELDS_UNIT_SYSTEM_ELECTRONVOLT_ANGSTROM_FEMTOSECOND_ECHARGE)
31double const re2_ = re_ * re_;
34double const ro_2_ = 84.54e-12 * unit_system::ERGS_PER_ANGSTROM2;
35double const ro1_ro2_ = -1.01e-12 * unit_system::ERGS_PER_ANGSTROM2;
36double const ro_theta_ = 2.288e-12 * unit_system::ERGS_PER_ANGSTROM2;
37double const theta_2_ = 7.607e-12 * unit_system::ERGS_PER_ANGSTROM2;
41double const ro_3_ = -10.168e-12 * unit_system::ERGS_PER_ANGSTROM2;
42double const ro_ro1_ro2_ = 0.201e-12 * unit_system::ERGS_PER_ANGSTROM2;
43double const ro_2_theta_ = 4.308e-12 * unit_system::ERGS_PER_ANGSTROM2;
44double const ro1_ro2_theta_ = -4.020e-12 * unit_system::ERGS_PER_ANGSTROM2;
45double const ro_theta_2_ = -1.175e-12 * unit_system::ERGS_PER_ANGSTROM2;
46double const thetat_3_ = -1.595e-12 * unit_system::ERGS_PER_ANGSTROM2;
50double const ro_4_ = -10.684e-12 * unit_system::ERGS_PER_ANGSTROM2;
51double const ro1_ro2_ro_2_ = -6.162e-12 * unit_system::ERGS_PER_ANGSTROM2;
52double const ro1_2_ro2_2_ = 2.717e-12 * unit_system::ERGS_PER_ANGSTROM2;
54double const ro_3_theta_ = 6.328e-12 * unit_system::ERGS_PER_ANGSTROM2;
55double const ro_ro1_ro2_theta_ = -4.020e-12 * unit_system::ERGS_PER_ANGSTROM2;
57double const ro_2_theta_2_ = -4.70e-12 * unit_system::ERGS_PER_ANGSTROM2;
58double const ro1_ro2_theta_2_ = 3.05e-12 * unit_system::ERGS_PER_ANGSTROM2;
61double const theta_4_ = -0.0318e-12 * unit_system::ERGS_PER_ANGSTROM2;
63double const re_ = 0.9572;
64double const thetae_ = 1.82421813418447321;
66double const re2_ = 0.91623184;
69double const ro_2_ = 52.7657211406036524;
70double const ro1_ro2_ = -0.630392457440379528;
71double const ro_theta_ = 1.42805736893424595;
72double const theta_2_ = 4.74791626113759158;
76double const ro_3_ = -6.3463668388651282;
77double const ro_ro1_ro2_ = 0.125454340540115145;
78double const ro_2_theta_ = 2.68884228381500501;
79double const ro1_ro2_theta_ = -2.509086810802303;
80double const ro_theta_2_ = -0.733377363853906838;
81double const thetat_3_ = -0.995520761997431114;
85double const ro_4_ = -6.668428728012886;
86double const ro1_ro2_ro_2_ = -3.84601814133427622;
87double const ro1_2_ro2_2_ = 1.69581812560941692;
88double const ro_3_theta_ = 3.94962719869576429;
89double const ro_ro1_ro2_theta_ = -2.509086810802303;
90double const ro_2_theta_2_ = -2.93350945541562735;
91double const ro1_ro2_theta_2_ = 1.90366039128035425;
92double const theta_4_ = -0.0198480001451525438;
126 double &U,
const double b[]) {
144 double &U,
const double b[],
const bool fixed[]) {
145 int const nMolecules = nAtoms / 3;
146 const double (*
const rh1)[6] =
reinterpret_cast<const double (*)[6]
>(R);
147 const double (*
const rh2)[6] =
reinterpret_cast<const double (*)[6]
>(&R[3]);
148 const double (*
const ro)[3] =
149 reinterpret_cast<const double (*)[3]
>(&R[nMolecules * 6]);
150 double (*
const fh1)[6] =
reinterpret_cast<double (*)[6]
>(F);
151 double (*
const fh2)[6] =
reinterpret_cast<double (*)[6]
>(&F[3]);
152 double (*
const fo)[3] =
reinterpret_cast<double (*)[3]
>(&F[nMolecules * 6]);
153 bool const(*
const xh1)[2] =
reinterpret_cast<bool const(*)[2]
>(fixed);
154 bool const(*
const xh2)[2] =
reinterpret_cast<bool const(*)[2]
>(&fixed[1]);
155 bool const(*
const xo)[1] =
156 reinterpret_cast<bool const(*)[1]
>(&fixed[nMolecules * 2]);
157 computeTemplate(nMolecules, rh1, rh2, ro, fh1, fh2, fo, U, b, xh1, xh2, xo);
198 double const d =
re_ / v.
_2 / v.
_1;
199 for (
int i = 0; i < 3; ++i)
200 ro.
n[i] = v.
v[i] * d;
205 double const thetaEquilibrium) {
207 double const theta = std::acos(cos_theta);
208 dth.
_1 = theta - thetaEquilibrium;
211 double const d_theta = -1.0 / std::sqrt(1.0 - cos_theta * cos_theta);
212 for (
int k = 0; k < 3; ++k) {
215 for (
int j = 0; j < 3; ++j) {
216 dth.
n1[k] -= v2.
v[j] / v2.
_1 / v1.
_1 * v1.
v[j] * v1.
v[k] / v1.
_2;
217 dth.
n2[k] -= v1.
v[j] / v1.
_1 / v2.
_1 * v2.
v[j] * v2.
v[k] / v2.
_2;
219 dth.
n1[k] += v2.
v[k] / v2.
_1 / v1.
_1;
220 dth.
n2[k] += v1.
v[k] / v1.
_1 / v2.
_1;
221 dth.
n1[k] *= d_theta;
222 dth.
n2[k] *= d_theta;
234 double const ro[],
double fh1[],
double fh2[],
235 double fo[],
double &energy) {
256 double &energy,
double fh1[],
double fh2[],
258 double d1 = 0, d2 = 0,
262 ro_2(ro1, ro2, energy, d1, d2);
263 ro1_ro2(ro1, ro2, energy, d1, d2);
264 ro_theta(ro1, ro2, dth, energy, d1, d2, d3);
269 ro_3(ro1, ro2, energy, d1, d2);
271 ro_2_theta(ro1, ro2, dth, energy, d1, d2, d3);
273 ro_theta_2(ro1, ro2, dth, energy, d1, d2, d3);
279 ro_4(ro1, ro2, energy, d1, d2);
283 ro_3_theta(ro1, ro2, dth, energy, d1, d2, d3);
292 for (
int i = 0; i < 3; ++i) {
293 fh1[i] -= d1 * ro1.
n[i] + d3 * dth.
n1[i];
294 fh2[i] -= d2 * ro2.
n[i] + d3 * dth.
n2[i];
295 fo[i] += d1 * ro1.
n[i] + d2 * ro2.
n[i] + d3 * dth.
n1[i] + d3 * dth.
n2[i];
317template <
int H,
int O>
319 const int nMolecules,
const double (*
const rh1)[H * 3],
320 const double (*
const rh2)[H * 3],
const double (*
const ro)[O * 3],
321 double (*
const fh1)[H * 3],
double (*
const fh2)[H * 3],
322 double (*
const fo)[O * 3],
double &energy,
double const b[],
323 bool const (*
const xh1)[H],
bool const (*
const xh2)[H],
324 bool const (*
const xo)[O]) {
325 for (
int i = 0; i < nMolecules; ++i) {
326 for (
int a = 0; a < 3; a++) {
335 for (
int i = nMolecules - 1; i >= 0; --i) {
336 bool const areFixed = xh1[i][0] and xh2[i][0] and xo[i][0];
338 intramolecular(rh1[i], rh2[i], ro[i], fh1[i], fh2[i], fo[i], energy);
341 assert(not std::isnan(energy) and not std::isinf(energy));
358 energy += ro_2_ * re2_ * (ro1.
_2 + ro2.
_2) / 2.0;
359 d1 += ro_2_ * re2_ * ro1.
_1;
360 d2 += ro_2_ * re2_ * ro2.
_1;
365 energy += ro1_ro2_ * re2_ * ro1.
_1 * ro2.
_1;
366 d1 += ro1_ro2_ * re2_ * ro2.
_1;
367 d2 += ro1_ro2_ * re2_ * ro1.
_1;
371 double &energy,
double &d1,
double &d2,
double &d3) {
372 energy += ro_theta_ * re2_ * (ro1.
_1 + ro2.
_1) * dth.
_1;
373 d1 += ro_theta_ * re2_ * dth.
_1;
374 d2 += ro_theta_ * re2_ * dth.
_1;
375 d3 += ro_theta_ * re2_ * (ro1.
_1 + ro2.
_1);
388 energy += theta_2_ * re2_ * dth.
_2 / 2.0;
389 d3 += theta_2_ * re2_ * dth.
_1;
397 energy += ro_3_ * re2_ * (ro1.
_3 + ro2.
_3);
398 d1 += 3.0 * ro_3_ * re2_ * ro1.
_2;
399 d2 += 3.0 * ro_3_ * re2_ * ro2.
_2;
404 energy += ro_ro1_ro2_ * re2_ * (ro1.
_1 + ro2.
_1) * ro1.
_1 * ro2.
_1;
405 d1 += ro_ro1_ro2_ * re2_ * (2.0 * ro1.
_1 * ro2.
_1 + ro2.
_2);
406 d2 += ro_ro1_ro2_ * re2_ * (2.0 * ro1.
_1 * ro2.
_1 + ro1.
_2);
410 double &energy,
double &d1,
double &d2,
double &d3) {
411 energy += ro_2_theta_ * re2_ * (ro1.
_2 + ro2.
_2) * dth.
_1;
412 d1 += ro_2_theta_ * re2_ * 2.0 * ro1.
_1 * dth.
_1;
413 d2 += ro_2_theta_ * re2_ * 2.0 * ro2.
_1 * dth.
_1;
414 d3 += ro_2_theta_ * re2_ * (ro1.
_2 + ro2.
_2);
418 double &energy,
double &d1,
double &d2,
double &d3) {
419 energy += ro1_ro2_theta_ * re2_ * ro1.
_1 * ro2.
_1 * dth.
_1;
420 d1 += ro1_ro2_theta_ * re2_ * ro2.
_1 * dth.
_1;
421 d2 += ro1_ro2_theta_ * re2_ * ro1.
_1 * dth.
_1;
422 d3 += ro1_ro2_theta_ * re2_ * ro1.
_1 * ro2.
_1;
426 double &energy,
double &d1,
double &d2,
double &d3) {
427 energy += ro_theta_2_ * re2_ * (ro1.
_1 + ro2.
_1) * dth.
_2;
428 d1 += ro_theta_2_ * re2_ * dth.
_2;
429 d2 += ro_theta_2_ * re2_ * dth.
_2;
430 d3 += ro_theta_2_ * re2_ * (ro1.
_1 + ro2.
_1) * 2.0 * dth.
_1;
434 energy += thetat_3_ * re2_ * dth.
_3;
435 d3 += thetat_3_ * re2_ * 3.0 * dth.
_2;
443 energy += ro_4_ * re2_ * (ro1.
_2 * ro1.
_2 + ro2.
_2 * ro2.
_2);
444 d1 += ro_4_ * re2_ * 4.0 * ro1.
_3;
445 d2 += ro_4_ * re2_ * 4.0 * ro2.
_3;
449 double &d1,
double &d2) {
450 energy += ro1_ro2_ro_2_ * re2_ * ro1.
_1 * ro2.
_1 * (ro1.
_2 + ro2.
_2);
451 d1 += ro1_ro2_ro_2_ * re2_ * (3.0 * ro2.
_1 * ro1.
_2 + ro2.
_3);
452 d2 += ro1_ro2_ro_2_ * re2_ * (3.0 * ro1.
_1 * ro2.
_2 + ro1.
_3);
456 double &d1,
double &d2) {
457 energy += ro1_2_ro2_2_ * re2_ * ro1.
_2 * ro2.
_2;
458 d1 += ro1_2_ro2_2_ * re2_ * 2.0 * ro1.
_1 * ro2.
_2;
459 d2 += ro1_2_ro2_2_ * re2_ * 2.0 * ro1.
_2 * ro2.
_1;
463 double &energy,
double &d1,
double &d2,
double &d3) {
464 energy += ro_3_theta_ * re2_ * (ro1.
_3 + ro2.
_3) * dth.
_1;
465 d1 += ro_3_theta_ * re2_ * 3.0 * ro1.
_2 * dth.
_1;
466 d2 += ro_3_theta_ * re2_ * 3.0 * ro2.
_2 * dth.
_1;
467 d3 += ro_3_theta_ * re2_ * (ro1.
_3 + ro2.
_3);
471 double &energy,
double &d1,
double &d2,
double &d3) {
473 ro_ro1_ro2_theta_ * re2_ * (ro1.
_1 + ro2.
_1) * ro1.
_1 * ro2.
_1 * dth.
_1;
474 d1 += ro_ro1_ro2_theta_ * re2_ * (2.0 * ro1.
_1 * ro2.
_1 + ro2.
_2) *
476 d2 += ro_ro1_ro2_theta_ * re2_ * (2.0 * ro1.
_1 * ro2.
_1 + ro1.
_2) *
478 d3 += ro_ro1_ro2_theta_ * re2_ * (ro1.
_1 + ro2.
_1) * ro1.
_1 *
483 double &energy,
double &d1,
double &d2,
double &d3) {
484 energy += ro_2_theta_2_ * re2_ * (ro1.
_2 + ro2.
_2) * dth.
_2;
485 d1 += ro_2_theta_2_ * re2_ * 2.0 * ro1.
_1 * dth.
_2;
486 d2 += ro_2_theta_2_ * re2_ * 2.0 * ro2.
_1 * dth.
_2;
487 d3 += ro_2_theta_2_ * re2_ * 2.0 * (ro1.
_2 + ro2.
_2) * dth.
_1;
491 double &energy,
double &d1,
double &d2,
double &d3) {
492 energy += ro1_ro2_theta_2_ * re2_ * ro1.
_1 * ro2.
_1 * dth.
_2;
493 d1 += ro1_ro2_theta_2_ * re2_ * ro2.
_1 * dth.
_2;
494 d2 += ro1_ro2_theta_2_ * re2_ * ro1.
_1 * dth.
_2;
495 d3 += ro1_ro2_theta_2_ * re2_ * ro1.
_1 * ro2.
_1 * 2.0 * dth.
_1;
500 energy += theta_4_ * re2_ * dth.
_2 * dth.
_2;
501 d3 += theta_4_ * re2_ * 4.0 * dth.
_3;
Potential CCL Table II for intramolecular interactions in water.
void ro_ro1_ro2_theta(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void ro_3(Rho const &s1, Rho const &s2, double &energy, double &d1, double &d2)
void initialiseRho(Vector3 const &v, Rho &r)
Initialise Rho.
void ro_3_theta(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void ro_2_theta_2(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void theta_4(Dtheta const &s3, double &energy, double &d3)
static double const thetae_
Distance OH at equilibrium.
void intramolecular(double const rh1[], double const rh2[], double const ro[], double fh1[], double fh2[], double fo[], double &energy)
Interactions inside one molecules.
void ro_theta(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void initialiseDtheta(Vector3 const &v1, Vector3 const &v2, Dtheta &dth, double const thetaEquilibrium)
Initialise Dtheta.
void ro1_ro2_theta(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void ro_ro1_ro2(Rho const &s1, Rho const &s2, double &energy, double &d1, double &d2)
char const * getName() const
Name of the potential.
void computeTemplate(const int nMolecules, const double(*const rh1)[H *3], const double(*const rh2)[H *3], const double(*const ro)[O *3], double(*const fh1)[H *3], double(*const fh2)[H *3], double(*const fo)[O *3], double &energy, double const b[], bool const (*const xh1)[H]=0, bool const (*const xh2)[H]=0, bool const (*const xo)[O]=0)
Compute forces and energy.
void ro_2(Rho const &ro1, Rho const &ro2, double &energy, double &d1, double &d2)
Energy and derivatives for Term 1.
void ro1_ro2_ro_2(Rho const &s1, Rho const &s2, double &energy, double &d1, double &d2)
static double const re_
Distance OH at equilibrium.
void ro_2_theta(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void ro1_ro2(Rho const &s1, Rho const &s2, double &energy, double &d1, double &d2)
void theta_2(Dtheta const &s3, double &energy, double &d3)
Energy and derivatives for Term 4.
void theta_3(Dtheta const &s3, double &energy, double &d3)
void ro_4(Rho const &s1, Rho const &s2, double &energy, double &d1, double &d2)
void ro1_ro2_theta_2(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void ro1_2_ro2_2(Rho const &s1, Rho const &s2, double &energy, double &d1, double &d2)
void computeHH_O_(const int nAtoms, const double R[], double F[], double &U, const double b[])
Compute the forces and the energy.
void ro_theta_2(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void setPeriodicity(const double periods[])
Set periodicity.
void distance(const double x[], const double y[], double z[], double &z1, double &z2)
Distance vector, norm and norm square.
PotentialBase()
Non bond interaction cutoff.
static double dotProduct(double const v[], double const w[])
Dot product.
double n2[3]
Same as n1 but for hydrogen 2.
double n1[3]
Convert derivative to force.
double n[3]
Convert derivative to force.
double _2
Vector's norm square.