55#warning zhu_philpott debug: DEBUG_LEVEL defined
56#define DEBUG_LEVEL_RETURN(x) \
57 if (x == DEBUG_LEVEL) \
60#define DEBUG_LEVEL_RETURN(x)
75 :
SpceCcl(cutoff, switchingWidth) {
112 const double r[],
double f[],
113 double &energy,
double const b[],
114 bool const fixed[]) {
115 const double (*
const rh1)[6] =
reinterpret_cast<const double (*)[6]
>(r);
116 const double (*
const rh2)[6] =
reinterpret_cast<const double (*)[6]
>(&r[3]);
117 const double (*
const ro)[3] =
118 reinterpret_cast<const double (*)[3]
>(&r[nWater * 6]);
119 const double (*
const rPt)[3] =
120 reinterpret_cast<const double (*)[3]
>(&r[nWater * 9]);
122 double (*
const fh1)[6] =
reinterpret_cast<double (*)[6]
>(f);
123 double (*
const fh2)[6] =
reinterpret_cast<double (*)[6]
>(&f[3]);
124 double (*
const fo)[3] =
reinterpret_cast<double (*)[3]
>(&f[nWater * 6]);
125 double (*
const fPt)[3] =
reinterpret_cast<double (*)[3]
>(&f[nWater * 9]);
128 bool const(*
const xh1)[2] =
reinterpret_cast<bool const(*)[2]
>(fixed);
129 bool const(*
const xh2)[2] =
reinterpret_cast<bool const(*)[2]
>(&fixed[1]);
130 bool const(*
const xo)[1] =
131 reinterpret_cast<bool const(*)[1]
>(&fixed[nWater * 2]);
132 bool const *
const xPt = &fixed[nWater * 3];
133 computeTemplate(nWater, rh1, rh2, ro, fh1, fh2, fo, nPt, rPt, fPt, energy,
134 b, xh1, xh2, xo, xPt);
136 bool const(*
const xh1)[2] = 0;
137 bool const(*
const xh2)[2] = 0;
138 bool const(*
const xo)[1] = 0;
139 computeTemplate(nWater, rh1, rh2, ro, fh1, fh2, fo, nPt, rPt, fPt, energy,
162 double f[],
double &energy,
double const b[],
163 bool const fixed[]) {
164 const double (*
const rh1)[6] =
reinterpret_cast<const double (*)[6]
>(r);
165 const double (*
const rh2)[6] =
reinterpret_cast<const double (*)[6]
>(&r[3]);
166 const double (*
const ro)[3] =
167 reinterpret_cast<const double (*)[3]
>(&r[nWater * 6]);
168 const double (*
const rPt)[3] =
169 reinterpret_cast<const double (*)[3]
>(
positions_.data());
171 double (*
const fh1)[6] =
reinterpret_cast<double (*)[6]
>(f);
172 double (*
const fh2)[6] =
reinterpret_cast<double (*)[6]
>(&f[3]);
173 double (*
const fo)[3] =
reinterpret_cast<double (*)[3]
>(&f[nWater * 6]);
174 double (*
const fPt)[3] =
reinterpret_cast<double (*)[3]
>(
forces_.data());
177 bool const(*
const xh1)[2] =
reinterpret_cast<bool const(*)[2]
>(fixed);
178 bool const(*
const xh2)[2] =
reinterpret_cast<bool const(*)[2]
>(&fixed[1]);
179 bool const(*
const xo)[1] =
180 reinterpret_cast<bool const(*)[1]
>(&fixed[nWater * 2]);
181 computeTemplate(nWater, rh1, rh2, ro, fh1, fh2, fo,
nPlatinum_, rPt, fPt,
182 energy, b, xh1, xh2, xo, 0);
184 bool const(*
const xh1)[2] = 0;
185 bool const(*
const xh2)[2] = 0;
186 bool const(*
const xo)[1] = 0;
187 computeTemplate(nWater, rh1, rh2, ro, fh1, fh2, fo,
nPlatinum_, rPt, fPt,
188 energy, b, xh1, xh2, xo, 0);
210 return "ZhuPhilpott";
214template <
int H,
int O,
int H3,
int O3>
216 const int nWater,
const double (*
const rh1)[H3],
217 const double (*
const rh2)[H3],
const double (*
const ro)[O3],
218 double (*
const fh1)[H3],
double (*
const fh2)[H3],
double (*
const fo)[O3],
219 const int nPt,
const double rPt[][3],
double fPt[][3],
double &energy,
220 double const b[],
bool const (*
const xh1)[H],
bool const (*
const xh2)[H],
221 bool const (*
const xo)[O],
bool const xPt[]) {
222 for (
int i = 0; i < nWater; ++i) {
223 for (
int a = 0; a < 3; ++a) {
229 for (
int i = 0; i < nPt; ++i) {
230 for (
int a = 0; a < 3; ++a)
235 for (
int i = nWater - 1; i >= 0; --i) {
236 double centre1[3] = {0};
238 Water w1(rh1[i], rh2[i], ro[i], centre1, fh1[i], fh2[i], fo[i]);
240 assert(not std::isnan(energy));
245 assert(not std::isnan(energy));
249 assert(not std::isnan(energy));
250 for (
int j = i - 1; j >= 0; --j) {
251 bool areFixed =
false;
252 if (xh1 and xh2 and xo) {
253 areFixed = xh1[i][0] and xh2[i][0] and xo[i][0];
255 areFixed &= xh1[j][0] and xh2[j][0] and xo[j][0];
259 double centre2[3] = {0};
261 Water w2(rh1[j], rh2[j], ro[j], centre2, fh1[j], fh2[j], fo[j]);
274 for (
int a = 0; a < 3; a++) {
275 assert(not std::isnan(fh1[i][a]));
276 assert(not std::isnan(fh2[i][a]));
277 assert(not std::isnan(fo[i][a]));
281 assert(not std::isnan(energy) and not std::isinf(energy));
293 double const rPt[][3],
double fPt[][3],
295 for (
int i = 0; i < nPt; ++i) {
303 double fo[3] = {0}, fPtTmp[3] = {0};
307 for (
int j = 0; j < 3; j++) {
308 water.
fo_[j] += fo[j];
309 fPt[i][j] += fPtTmp[j];
318 double fh[3] = {0}, fPtTmp[3] = {0};
322 for (
int j = 0; j < 3; j++) {
323 water.
fh1_[j] += fh[j];
324 fPt[i][j] += fPtTmp[j];
333 double fh[3] = {0}, fPtTmp[3] = {0};
337 for (
int j = 0; j < 3; j++) {
338 water.
fh2_[j] += fh[j];
339 fPt[i][j] += fPtTmp[j];
347 double F1[],
double F2[],
double &energy) {
348 double R12[3], F12[3] = {0}, r1, f1 = 0;
350 anisotropic(R12, F12, energy, P::epsilonOPt_, P::sigmaOPt_, P::alpha_);
351 isotropic10(r1, f1, energy, P::epsilonOPt_, P::sigmaOPt_, P::C10_O_);
352 for (
int j = 0; j < 3; j++) {
353 F1[j] += F12[j] + f1 * R12[j] / r1;
354 F2[j] -= F12[j] + f1 * R12[j] / r1;
360 double F1[],
double F2[],
double &energy) {
361 double R12[3], F12[3] = {0}, r1, f1 = 0;
363 anisotropic(R12, F12, energy, P::epsilonHPt_, P::sigmaHPt_, P::alpha_);
364 isotropic10(r1, f1, energy, P::epsilonHPt_, P::sigmaHPt_, P::C10_H_);
365 for (
int j = 0; j < 3; j++) {
366 F1[j] += F12[j] + f1 * R12[j] / r1;
367 F2[j] -= F12[j] + f1 * R12[j] / r1;
389 double &energy,
double const epsilon,
390 double const sigma,
double const alpha) {
391 double z2, z, a, b, A, B, dE_da, dE_db, rho, rho2, alpha2;
393 alpha2 = alpha * alpha;
396 rho = std::sqrt(rho2);
400 a = sigma2 / (rho2 * alpha2 + z2);
401 b = sigma2 / (rho2 / alpha2 + z2);
402 double a2 = a * a, a3 = a2 * a;
406 energy += 4.0 *
epsilon * (A - B);
407 dE_da = 24.0 *
epsilon * a2 * a3;
409 double invSigma2 = 1.0 / sigma2;
410 f = 2.0 * (dE_da * a2 * alpha2 + dE_db * b2 / alpha2) * invSigma2;
413 f = 2.0 * (dE_da * a2 + dE_db * b2) * invSigma2;
431 double &energy,
double const epsilon,
432 double const sigma,
double const C10) {
434 double s10 = s * s * s * s * s;
436 energy += -4.0 *
epsilon * C10 * s10;
453 double r[4][3], f[3][3] = {{0}};
454 for (
int k = 0; k < 2; k++) {
455 r[0][k] = w2.
rh1_[k];
456 r[1][k] = w2.
rh2_[k];
461 r[0][2] = -w2.
rh1_[2];
462 r[1][2] = -w2.
rh2_[2];
463 r[2][2] = -w2.
ro_[2];
464 r[3][2] = -w2.
rc_[2];
465 Water w2m(r[0], r[1], r[2], r[3], f[0], f[1], f[2]);
472 for (
int k = 0; k < 2; k++) {
473 w2.
fh1_[k] += f[0][k];
474 w2.
fh2_[k] += f[1][k];
475 w2.
fo_[k] += f[2][k];
478 w2.
fh1_[2] -= f[0][2];
479 w2.
fh2_[2] -= f[1][2];
480 w2.
fo_[2] -= f[2][2];
497 double const relativePermittivity) {
503 double f1[3][3] = {{0}}, f2[3][3] = {{0}};
504 Water v1(w1, f1[0], f1[1], f1[2]);
505 Water v2(w2, f2[0], f2[1], f2[2]);
526 double const relativePermittivity) {
528 const double qq2overEr =
charge2_ / relativePermittivity;
static double sigma(double const A, double const B)
Conversion for Lennard-Jones.
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 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.
static double epsilon(double const A, double const B)
Conversion for Lennard-Jones.
void intramolecular(Water &water, double &U)
Interactions within a molecules.
void lennardJonesWithCutoff(Water &w1, Water &w2, double &U)
Interactions between two molecules.
static const double charge2_
Square of # charge_.
std::vector< double > positions_
void computeHH_O_(const int nWater, const double r[], double f[], double &energy, double const b[], bool const fixed[])
Compute water-platinum interactions, call with water's positions only.
void operator=(ZhuPhilpott const &)
void coulombFull(Water &w1, Water &w2, double &U, double const relativePermittivity)
Coulomb interaction between two molecules with cutoff.
int nPlatinum() const
Number of platinum atoms.
void interactWithCorePt(Water &water, int const nPt, double const rPt[][3], double fPt[][3], double &energy)
Interaction of one molecule of water with the whole platinum.
void anisotropic(const double distance[], double force[], double &energy, double const epsilon, double const sigma, double const alpha)
Anisotropic interaction between water and platinum.
void computeTemplate(const int nWater, const double(*const rh1)[H3], const double(*const rh2)[H3], const double(*const ro)[O3], double(*const fh1)[H3], double(*const fh2)[H3], double(*const fo)[O3], const int nPt, const double rPt[][3], double fPt[][3], double &energy, double const b[], bool const (*const xh1)[H]=0, bool const (*const xh2)[H]=0, bool const (*const xo)[O]=0, bool const *xPt=0)
void interactWithImage(Water &w1, Water &w2, double &U)
Interactions of a molecule with an image.
void setPlatinum(int nPlatinum, double const positions[])
Initialises the positions of the atoms of platinum.
void coulombWithCutoff(Water &w1, Water &w2, double &u, double const relativePermittivity)
Coulomb interaction between two molecules within the swithcing zone.
void isotropic10(double const distance, double &force, double &energy, double const epsilon, double const sigma, double const C10)
Isotropic interaction between water and platinum.
void interactionPtH(double const R1[], double const R2[], double F1[], double F2[], double &energy)
static char const * getName()
Name of the potential.
void interactionPtO(double const R1[], double const R2[], double F1[], double F2[], double &energy)
void computeHH_O_Pt_(const int nWater, const int nPt, const double r[], double f[], double &energy, double const b[], bool const fixed[])
Compute water-platinum forcefield.
std::vector< double > forces_
Pointers to molecule of water.
void addForces(Water const &w)
#define DEBUG_LEVEL_RETURN(x)
Potential for water and Platinum.