26#if defined(FORCEFIELDS_UNIT_SYSTEM_HPP) && \
27 (FORCEFIELDS_UNIT_SYSTEM_HPP != \
28 FORCEFIELDS_UNIT_SYSTEM_ELECTRONVOLT_ANGSTROM_FEMTOSECOND_ECHARGE)
32double const thetae_ = 104.52 *
DEGREE;
34double const re2_ = re_ * re_;
38double const ro_2_ = 84.54e-12 * ERGS_PER_ANGSTROM2;
39double const ro1_ro2_ = -1.01e-12 * ERGS_PER_ANGSTROM2;
40double const ro_theta_ = 2.288e-12 * ERGS_PER_ANGSTROM2;
41double const theta_2_ = 7.607e-12 * ERGS_PER_ANGSTROM2;
45double const ro_3_ = -10.168e-12 * ERGS_PER_ANGSTROM2;
46double const ro_ro1_ro2_ = 0.201e-12 * ERGS_PER_ANGSTROM2;
47double const ro_2_theta_ = 4.308e-12 * ERGS_PER_ANGSTROM2;
48double const ro1_ro2_theta_ = -4.020e-12 * ERGS_PER_ANGSTROM2;
49double const ro_theta_2_ = -1.175e-12 * ERGS_PER_ANGSTROM2;
50double const thetat_3_ = -1.595e-12 * ERGS_PER_ANGSTROM2;
54double const ro_4_ = -10.684e-12 * ERGS_PER_ANGSTROM2;
55double const ro1_ro2_ro_2_ = -6.162e-12 * ERGS_PER_ANGSTROM2;
56double const ro1_2_ro2_2_ = 2.717e-12 * ERGS_PER_ANGSTROM2;
58double const ro_3_theta_ = 6.328e-12 * ERGS_PER_ANGSTROM2;
59double const ro_ro1_ro2_theta_ = -4.020e-12 * ERGS_PER_ANGSTROM2;
61double const ro_2_theta_2_ = -4.70e-12 * ERGS_PER_ANGSTROM2;
62double const ro1_ro2_theta_2_ = 3.05e-12 * ERGS_PER_ANGSTROM2;
65double const theta_4_ = -0.0318e-12 * ERGS_PER_ANGSTROM2;
67double const re_ = 0.9572;
68double const thetae_ = 1.82421813418447321;
70double const re2_ = 0.91623184;
74double const ro_2_ = 52.7657211406036524;
75double const ro1_ro2_ = -0.630392457440379528;
76double const ro_theta_ = 1.42805736893424595;
77double const theta_2_ = 4.74791626113759158;
81double const ro_3_ = -6.3463668388651282;
82double const ro_ro1_ro2_ = 0.125454340540115145;
83double const ro_2_theta_ = 2.68884228381500501;
84double const ro1_ro2_theta_ = -2.509086810802303;
85double const ro_theta_2_ = -0.733377363853906838;
86double const thetat_3_ = -0.995520761997431114;
90double const ro_4_ = -6.668428728012886;
91double const ro1_ro2_ro_2_ = -3.84601814133427622;
92double const ro1_2_ro2_2_ = 1.69581812560941692;
93double const ro_3_theta_ = 3.94962719869576429;
94double const ro_ro1_ro2_theta_ = -2.509086810802303;
95double const ro_2_theta_2_ = -2.93350945541562735;
96double const ro1_ro2_theta_2_ = 1.90366039128035425;
97double const theta_4_ = -0.0198480001451525438;
131 double &U,
const double b[]) {
149 double &U,
const double b[],
const bool fixed[]) {
150 int const nMolecules = nAtoms / 3;
151 const double (*
const rh1)[6] =
reinterpret_cast<const double (*)[6]
>(R);
152 const double (*
const rh2)[6] =
reinterpret_cast<const double (*)[6]
>(&R[3]);
153 const double (*
const ro)[3] =
154 reinterpret_cast<const double (*)[3]
>(&R[nMolecules * 6]);
155 double (*
const fh1)[6] =
reinterpret_cast<double (*)[6]
>(F);
156 double (*
const fh2)[6] =
reinterpret_cast<double (*)[6]
>(&F[3]);
157 double (*
const fo)[3] =
reinterpret_cast<double (*)[3]
>(&F[nMolecules * 6]);
158 bool const(*
const xh1)[2] =
reinterpret_cast<bool const(*)[2]
>(fixed);
159 bool const(*
const xh2)[2] =
reinterpret_cast<bool const(*)[2]
>(&fixed[1]);
160 bool const(*
const xo)[1] =
161 reinterpret_cast<bool const(*)[1]
>(&fixed[nMolecules * 2]);
162 computeTemplate(nMolecules, rh1, rh2, ro, fh1, fh2, fo, U, b, xh1, xh2, xo);
203 double const d =
re_ / v.
_2 / v.
_1;
204 for (
int i = 0; i < 3; ++i)
205 ro.
n[i] = v.
v[i] * d;
210 double const thetaEquilibrium) {
212 double const theta = std::acos(cos_theta);
213 dth.
_1 = theta - thetaEquilibrium;
216 double const d_theta = -1.0 / std::sqrt(1.0 - cos_theta * cos_theta);
217 for (
int k = 0; k < 3; ++k) {
220 for (
int j = 0; j < 3; ++j) {
221 dth.
n1[k] -= v2.
v[j] / v2.
_1 / v1.
_1 * v1.
v[j] * v1.
v[k] / v1.
_2;
222 dth.
n2[k] -= v1.
v[j] / v1.
_1 / v2.
_1 * v2.
v[j] * v2.
v[k] / v2.
_2;
224 dth.
n1[k] += v2.
v[k] / v2.
_1 / v1.
_1;
225 dth.
n2[k] += v1.
v[k] / v1.
_1 / v2.
_1;
226 dth.
n1[k] *= d_theta;
227 dth.
n2[k] *= d_theta;
239 double const ro[],
double fh1[],
double fh2[],
240 double fo[],
double &energy) {
261 double &energy,
double fh1[],
double fh2[],
263 double d1 = 0, d2 = 0,
267 ro_2(ro1, ro2, energy, d1, d2);
268 ro1_ro2(ro1, ro2, energy, d1, d2);
269 ro_theta(ro1, ro2, dth, energy, d1, d2, d3);
274 ro_3(ro1, ro2, energy, d1, d2);
276 ro_2_theta(ro1, ro2, dth, energy, d1, d2, d3);
278 ro_theta_2(ro1, ro2, dth, energy, d1, d2, d3);
284 ro_4(ro1, ro2, energy, d1, d2);
288 ro_3_theta(ro1, ro2, dth, energy, d1, d2, d3);
297 for (
int i = 0; i < 3; ++i) {
298 fh1[i] -= d1 * ro1.
n[i] + d3 * dth.
n1[i];
299 fh2[i] -= d2 * ro2.
n[i] + d3 * dth.
n2[i];
300 fo[i] += d1 * ro1.
n[i] + d2 * ro2.
n[i] + d3 * dth.
n1[i] + d3 * dth.
n2[i];
322template <
int H,
int O>
324 const int nMolecules,
const double (*
const rh1)[H * 3],
325 const double (*
const rh2)[H * 3],
const double (*
const ro)[O * 3],
326 double (*
const fh1)[H * 3],
double (*
const fh2)[H * 3],
327 double (*
const fo)[O * 3],
double &energy,
double const b[],
328 bool const (*
const xh1)[H],
bool const (*
const xh2)[H],
329 bool const (*
const xo)[O]) {
330 for (
int i = 0; i < nMolecules; ++i) {
331 for (
int a = 0; a < 3; a++) {
340 for (
int i = nMolecules - 1; i >= 0; --i) {
341 bool const areFixed = xh1[i][0] and xh2[i][0] and xo[i][0];
343 intramolecular(rh1[i], rh2[i], ro[i], fh1[i], fh2[i], fo[i], energy);
346 assert(not std::isnan(energy) and not std::isinf(energy));
363 energy += ro_2_ * re2_ * (ro1.
_2 + ro2.
_2) / 2.0;
364 d1 += ro_2_ * re2_ * ro1.
_1;
365 d2 += ro_2_ * re2_ * ro2.
_1;
370 energy += ro1_ro2_ * re2_ * ro1.
_1 * ro2.
_1;
371 d1 += ro1_ro2_ * re2_ * ro2.
_1;
372 d2 += ro1_ro2_ * re2_ * ro1.
_1;
376 double &energy,
double &d1,
double &d2,
double &d3) {
377 energy += ro_theta_ * re2_ * (ro1.
_1 + ro2.
_1) * dth.
_1;
378 d1 += ro_theta_ * re2_ * dth.
_1;
379 d2 += ro_theta_ * re2_ * dth.
_1;
380 d3 += ro_theta_ * re2_ * (ro1.
_1 + ro2.
_1);
393 energy += theta_2_ * re2_ * dth.
_2 / 2.0;
394 d3 += theta_2_ * re2_ * dth.
_1;
402 energy += ro_3_ * re2_ * (ro1.
_3 + ro2.
_3);
403 d1 += 3.0 * ro_3_ * re2_ * ro1.
_2;
404 d2 += 3.0 * ro_3_ * re2_ * ro2.
_2;
409 energy += ro_ro1_ro2_ * re2_ * (ro1.
_1 + ro2.
_1) * ro1.
_1 * ro2.
_1;
410 d1 += ro_ro1_ro2_ * re2_ * (2.0 * ro1.
_1 * ro2.
_1 + ro2.
_2);
411 d2 += ro_ro1_ro2_ * re2_ * (2.0 * ro1.
_1 * ro2.
_1 + ro1.
_2);
415 double &energy,
double &d1,
double &d2,
double &d3) {
416 energy += ro_2_theta_ * re2_ * (ro1.
_2 + ro2.
_2) * dth.
_1;
417 d1 += ro_2_theta_ * re2_ * 2.0 * ro1.
_1 * dth.
_1;
418 d2 += ro_2_theta_ * re2_ * 2.0 * ro2.
_1 * dth.
_1;
419 d3 += ro_2_theta_ * re2_ * (ro1.
_2 + ro2.
_2);
423 double &energy,
double &d1,
double &d2,
double &d3) {
424 energy += ro1_ro2_theta_ * re2_ * ro1.
_1 * ro2.
_1 * dth.
_1;
425 d1 += ro1_ro2_theta_ * re2_ * ro2.
_1 * dth.
_1;
426 d2 += ro1_ro2_theta_ * re2_ * ro1.
_1 * dth.
_1;
427 d3 += ro1_ro2_theta_ * re2_ * ro1.
_1 * ro2.
_1;
431 double &energy,
double &d1,
double &d2,
double &d3) {
432 energy += ro_theta_2_ * re2_ * (ro1.
_1 + ro2.
_1) * dth.
_2;
433 d1 += ro_theta_2_ * re2_ * dth.
_2;
434 d2 += ro_theta_2_ * re2_ * dth.
_2;
435 d3 += ro_theta_2_ * re2_ * (ro1.
_1 + ro2.
_1) * 2.0 * dth.
_1;
439 energy += thetat_3_ * re2_ * dth.
_3;
440 d3 += thetat_3_ * re2_ * 3.0 * dth.
_2;
448 energy += ro_4_ * re2_ * (ro1.
_2 * ro1.
_2 + ro2.
_2 * ro2.
_2);
449 d1 += ro_4_ * re2_ * 4.0 * ro1.
_3;
450 d2 += ro_4_ * re2_ * 4.0 * ro2.
_3;
454 double &d1,
double &d2) {
455 energy += ro1_ro2_ro_2_ * re2_ * ro1.
_1 * ro2.
_1 * (ro1.
_2 + ro2.
_2);
456 d1 += ro1_ro2_ro_2_ * re2_ * (3.0 * ro2.
_1 * ro1.
_2 + ro2.
_3);
457 d2 += ro1_ro2_ro_2_ * re2_ * (3.0 * ro1.
_1 * ro2.
_2 + ro1.
_3);
461 double &d1,
double &d2) {
462 energy += ro1_2_ro2_2_ * re2_ * ro1.
_2 * ro2.
_2;
463 d1 += ro1_2_ro2_2_ * re2_ * 2.0 * ro1.
_1 * ro2.
_2;
464 d2 += ro1_2_ro2_2_ * re2_ * 2.0 * ro1.
_2 * ro2.
_1;
468 double &energy,
double &d1,
double &d2,
double &d3) {
469 energy += ro_3_theta_ * re2_ * (ro1.
_3 + ro2.
_3) * dth.
_1;
470 d1 += ro_3_theta_ * re2_ * 3.0 * ro1.
_2 * dth.
_1;
471 d2 += ro_3_theta_ * re2_ * 3.0 * ro2.
_2 * dth.
_1;
472 d3 += ro_3_theta_ * re2_ * (ro1.
_3 + ro2.
_3);
476 double &energy,
double &d1,
double &d2,
double &d3) {
478 ro_ro1_ro2_theta_ * re2_ * (ro1.
_1 + ro2.
_1) * ro1.
_1 * ro2.
_1 * dth.
_1;
479 d1 += ro_ro1_ro2_theta_ * re2_ * (2.0 * ro1.
_1 * ro2.
_1 + ro2.
_2) *
481 d2 += ro_ro1_ro2_theta_ * re2_ * (2.0 * ro1.
_1 * ro2.
_1 + ro1.
_2) *
483 d3 += ro_ro1_ro2_theta_ * re2_ * (ro1.
_1 + ro2.
_1) * ro1.
_1 *
488 double &energy,
double &d1,
double &d2,
double &d3) {
489 energy += ro_2_theta_2_ * re2_ * (ro1.
_2 + ro2.
_2) * dth.
_2;
490 d1 += ro_2_theta_2_ * re2_ * 2.0 * ro1.
_1 * dth.
_2;
491 d2 += ro_2_theta_2_ * re2_ * 2.0 * ro2.
_1 * dth.
_2;
492 d3 += ro_2_theta_2_ * re2_ * 2.0 * (ro1.
_2 + ro2.
_2) * dth.
_1;
496 double &energy,
double &d1,
double &d2,
double &d3) {
497 energy += ro1_ro2_theta_2_ * re2_ * ro1.
_1 * ro2.
_1 * dth.
_2;
498 d1 += ro1_ro2_theta_2_ * re2_ * ro2.
_1 * dth.
_2;
499 d2 += ro1_ro2_theta_2_ * re2_ * ro1.
_1 * dth.
_2;
500 d3 += ro1_ro2_theta_2_ * re2_ * ro1.
_1 * ro2.
_1 * 2.0 * dth.
_1;
505 energy += theta_4_ * re2_ * dth.
_2 * dth.
_2;
506 d3 += theta_4_ * re2_ * 4.0 * dth.
_3;
Potential CCL Table II for intramolecular interactions in water.
static double const re_
Distance OH at equilibrium.
static double const thetae_
Distance OH at equilibrium.
void theta_4(Dtheta const &s3, double &energy, double &d3)
void ro_3(Rho const &s1, Rho const &s2, double &energy, double &d1, double &d2)
void theta_3(Dtheta const &s3, double &energy, double &d3)
void ro_ro1_ro2_theta(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void ro_theta(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void ro_3_theta(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void theta_2(Dtheta const &s3, double &energy, double &d3)
Energy and derivatives for Term 4.
void ro1_ro2_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)
char const * getName() const
Name of the potential.
void initialiseRho(Vector3 const &v, Rho &r)
Initialise Rho.
void initialiseDtheta(Vector3 const &v1, Vector3 const &v2, Dtheta &dth, double const thetaEquilibrium)
Initialise Dtheta.
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_2(Rho const &ro1, Rho const &ro2, double &energy, double &d1, double &d2)
Energy and derivatives for Term 1.
void ro_4(Rho const &s1, Rho const &s2, double &energy, double &d1, double &d2)
void ro_2_theta_2(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void ro_2_theta(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void computeHH_O_(const int nAtoms, const double R[], double F[], double &U, const double b[])
Compute the forces and the energy.
void ro1_ro2_ro_2(Rho const &s1, Rho const &s2, double &energy, double &d1, double &d2)
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_theta_2(Rho const &s1, Rho const &s2, Dtheta const &s3, double &energy, double &d1, double &d2, double &d3)
void ro1_ro2_theta_2(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)
void ro1_2_ro2_2(Rho const &s1, Rho const &s2, double &energy, double &d1, double &d2)
PotentialBase()
Non bond interaction cutoff.
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.
static double dotProduct(double const v[], double const w[])
Dot product.
Physical constants and unit conversion.
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.