33double const thetae_ = 104.52 *
DEGREE;
34double const charge_ = 0.520 *
ECHARGE;
35double const charge2_ = charge_ * charge_;
38double const epsilon_ =
44 std::cos(::thetae_ / 2.0);
46double const wh_ = ron_ / rok_ * 0.5;
47double const wo_ = (1.0 - wh_ * 2.0);
71 :
Ccl(cutoff, switchingWidth) {}
86 double &U,
const double b[]) {
104 double &U,
const double b[],
const bool fixed[]) {
105 int const nMolecules = nAtoms / 3;
106 const double (*
const rh1)[6] =
reinterpret_cast<const double (*)[6]
>(R);
107 const double (*
const rh2)[6] =
reinterpret_cast<const double (*)[6]
>(&R[3]);
108 const double (*
const ro)[3] =
109 reinterpret_cast<const double (*)[3]
>(&R[nMolecules * 6]);
110 double (*
const fh1)[6] =
reinterpret_cast<double (*)[6]
>(F);
111 double (*
const fh2)[6] =
reinterpret_cast<double (*)[6]
>(&F[3]);
112 double (*
const fo)[3] =
reinterpret_cast<double (*)[3]
>(&F[nMolecules * 6]);
113 bool const(*
const xh1)[2] =
reinterpret_cast<bool const(*)[2]
>(fixed);
114 bool const(*
const xh2)[2] =
reinterpret_cast<bool const(*)[2]
>(&fixed[1]);
115 bool const(*
const xo)[1] =
116 reinterpret_cast<bool const(*)[1]
>(&fixed[nMolecules * 2]);
117 computeTemplate(nMolecules, rh1, rh2, ro, fh1, fh2, fo, U, b, xh1, xh2, xo);
156template <
int H,
int O>
158 const int nMolecules,
const double (*
const rh1)[H * 3],
159 const double (*
const rh2)[H * 3],
const double (*
const ro)[O * 3],
160 double (*
const fh1)[H * 3],
double (*
const fh2)[H * 3],
161 double (*
const fo)[O * 3],
double &energy,
double const b[],
162 bool const (*
const xh1)[H],
bool const (*
const xh2)[H],
163 bool const (*
const xo)[O]) {
164 for (
int i = 0; i < nMolecules; ++i) {
165 for (
int a = 0; a < 3; a++) {
173 for (
int i = nMolecules - 1; i >= 0; --i) {
174 double rc1[3], rn1[3], fn1[3] = {0};
178 Water w1 = {rh1[i], rh2[i], ro[i], rn1, rc1, fh1[i], fh2[i], fo[i], fn1};
179 intramolecular(rh1[i], rh2[i], ro[i], fh1[i], fh2[i], fo[i], energy);
180 for (
int j = i - 1; j >= 0; --j) {
181 bool areFixed =
false;
182 if (xh1 and xh2 and xo) {
183 areFixed = xh1[i][0] and xh2[i][0] and xo[i][0];
185 areFixed &= xh1[j][0] and xh2[j][0] and xo[j][0];
189 double rc2[3], rn2[3], fn2[3] = {0};
192 Water w2 = {rh1[j], rh2[j], ro[j], rn2, rc2,
193 fh1[j], fh2[j], fo[j], fn2};
201 assert(not std::isnan(energy) and not std::isinf(energy));
212 distance(w1.rc_, w2.rc_, z, z1, z2);
216 double f1[3][3] = {{0}}, f2[3][3] = {{0}};
219 Water v1 = {w1.rh1_, w1.rh2_, w1.ro_, w1.rn_, w1.rc_,
220 f1[0], f1[1], 0, f1[2]};
221 Water v2 = {w2.rh1_, w2.rh2_, w2.ro_, w2.rn_, w2.rc_,
222 f2[0], f2[1], 0, f2[2]};
231 for (
int i = 0; i < 3; ++i) {
232 w1.fh1_[i] += v1.fh1_[i];
233 w1.fh2_[i] += v1.fh2_[i];
234 w1.fn_[i] += v1.fn_[i];
235 w2.fh1_[i] += v2.fh1_[i];
236 w2.fh2_[i] += v2.fh2_[i];
237 w2.fn_[i] += v2.fn_[i];
254 coulomb(w1.rh1_, w2.rh1_, w1.fh1_, w2.fh1_, U, charge2_);
255 coulomb(w1.rh1_, w2.rh2_, w1.fh1_, w2.fh2_, U, charge2_);
256 coulomb(w1.rh2_, w2.rh1_, w1.fh2_, w2.fh1_, U, charge2_);
257 coulomb(w1.rh2_, w2.rh2_, w1.fh2_, w2.fh2_, U, charge2_);
259 coulomb(w1.rn_, w2.rh1_, w1.fn_, w2.fh1_, U, -2.0 * charge2_);
260 coulomb(w1.rn_, w2.rh2_, w1.fn_, w2.fh2_, U, -2.0 * charge2_);
261 coulomb(w1.rh1_, w2.rn_, w1.fh1_, w2.fn_, U, -2.0 * charge2_);
262 coulomb(w1.rh2_, w2.rn_, w1.fh2_, w2.fn_, U, -2.0 * charge2_);
264 coulomb(w1.rn_, w2.rn_, w1.fn_, w2.fn_, U, 4.0 * charge2_);
278 lennardJones(w1.ro_, w2.ro_, w1.fo_, w2.fo_, U, epsilon_, sigma_);
280 double f1[3] = {0}, f2[3] = {0};
282 lennardJones(w1.ro_, w2.ro_, f1, f2, energy, epsilon_, sigma_);
283 switching(w1.ro_, w2.ro_, f1, f2, energy);
285 for (
int i = 0; i < 3; i++) {
void intramolecular(double const rh1[], double const rh2[], double const ro[], double fh1[], double fh2[], double fo[], double &energy)
Interactions inside one molecules.
void spreadWeightedForce(double const w1, double const w2, double const w3, double f1[], double f2[], double f3[], double const fc[])
Spread force on barycentre to atoms.
void switching(ChargeGroup< N, R, F > &g1, ChargeGroup< N, R, F > &g2, double &energy, double cutoff, double switchingWidth)
void coulomb(const double r1[], const double r2[], double f1[], double f2[], double &u, double const qq)
Compute Coulomb interaction between two charges.
void lennardJones(double const distance, double &force, double &energy, double const epsilon, double const sigma)
Lennard-Jones 12-6 between two atoms.
void calculateCentre(double const r1[], double const r2[], double rc[])
Calculate centre of two points.
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.
void calculateWeightedCentre(double const w1, double const w2, double const w3, double const r1[], double const r2[], double const r3[], double rc[])
Calculate barycentre.
static char const * getName()
Name of the potential.
void coulombWithCutoff(Water &w1, Water &w2, double &U)
Interactions between two molecules.
void computeHH_O_(const int nAtoms, const double R[], double F[], double &U, const double b[])
Compute the forces and the energy.
void lennardJonesWithCutoff(Water &w1, Water &w2, double &U)
Interactions between two molecules.
void coulombFull(Water &w1, Water &w2, double &U)
Interactions between two molecules.
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.
Physical constants and unit conversion.
Pointers for one molecule of water.
TIP4P potential for water.
Physical constants, unit conversion.