6#include "molecules/Comp2Param.h"
7#include "molecules/Molecule.h"
18inline void PotForceLJ(
const double dr[3],
const double& dr2,
19 const double& eps24,
const double& sig2,
20 double f[3],
double& u6)
22 double invdr2 = 1. / dr2;
23 double lj6 = sig2 * invdr2; lj6 = lj6 * lj6 * lj6;
24 double lj12 = lj6 * lj6;
25 double lj12m6 = lj12 - lj6;
27 double fac = eps24 * (lj12 + lj12m6) * invdr2;
28 for (
unsigned short d = 0; d < 3; ++d)
36inline void PotForce2Dipole(
const double dr[3],
const double& dr2,
const double* eii,
const double* ejj,
37 const double& my2,
const double& rffac,
38 double f[3],
double m1[3],
double m2[3],
double& u,
double& MyRF)
40 double invdr2 = 1. / dr2;
41 double invdr1 = sqrt(invdr2);
42 double myfac = my2 * invdr2 * invdr1;
46 for (
unsigned short d = 0; d < 3; ++d) {
47 const double& drd = dr[d];
48 const double& eiid = eii[d];
49 const double& ejjd = ejj[d];
52 cosgij += eiid * ejjd;
56 u = myfac * (cosgij - 3. * costi * costj);
57 MyRF -= rffac * cosgij;
58 const double partialRijInvdr1 = -3. * u * invdr2;
59 const double partialTiInvdr1 = -myfac * 3. * costj * invdr1;
60 const double partialTjInvdr1 = -myfac * 3. * costi * invdr1;
61 const double& partialGij = myfac;
62 const double fac = -partialRijInvdr1 + (costi*partialTiInvdr1 + costj*partialTjInvdr1) * invdr1;
63 for (
unsigned short d = 0; d < 3; ++d)
64 f[d] = fac * dr[d] - partialTiInvdr1*eii[d] - partialTjInvdr1*ejj[d];
66 double eiXej[3], eXrij[3];
67 eiXej[0] = eii[1] * ejj[2] - eii[2] * ejj[1];
68 eiXej[1] = eii[2] * ejj[0] - eii[0] * ejj[2];
69 eiXej[2] = eii[0] * ejj[1] - eii[1] * ejj[0];
70 eXrij[0] = eii[1] * dr[2] - eii[2] * dr[1];
71 eXrij[1] = eii[2] * dr[0] - eii[0] * dr[2];
72 eXrij[2] = eii[0] * dr[1] - eii[1] * dr[0];
73 for (
unsigned short d = 0; d < 3; ++d)
74 m1[d] = -partialTiInvdr1 * eXrij[d] + (-partialGij + rffac) * eiXej[d];
75 eXrij[0] = ejj[1] * dr[2] - ejj[2] * dr[1];
76 eXrij[1] = ejj[2] * dr[0] - ejj[0] * dr[2];
77 eXrij[2] = ejj[0] * dr[1] - ejj[1] * dr[0];
78 for (
unsigned short d = 0; d < 3; ++d)
79 m2[d] = -partialTjInvdr1 * eXrij[d] + (partialGij - rffac) * eiXej[d];
86inline void PotForce2Quadrupole(
const double dr[3],
const double& dr2,
const double* eii,
const double* ejj,
88 double f[3],
double m1[3],
double m2[3],
double& u)
90 double invdr2 = 1. / dr2;
91 double invdr1 = sqrt(invdr2);
92 double qfac = q2075 * invdr2 * invdr2 * invdr1;
96 for (
unsigned short d = 0; d < 3; ++d) {
97 const double& drd = dr[d];
98 const double& eiid = eii[d];
99 const double& ejjd = ejj[d];
102 cosgij += eiid * ejjd;
106 double cos2ti = costi * costi;
107 double cos2tj = costj * costj;
108 double term = (cosgij - 5. * costi * costj);
109 u = qfac * (1. - 5. * (cos2ti + cos2tj) - 15. * cos2ti * cos2tj + 2. * term * term);
110 const double partialRijInvdr1 = -5. * u * invdr2;
111 const double partialTiInvdr1 = -qfac * 10. * (costi + 3. * costi * cos2tj + 2. * costj * term) * invdr1;
112 const double partialTjInvdr1 = -qfac * 10. * (costj + 3. * cos2ti * costj + 2. * costi * term) * invdr1;
113 const double partialGij = qfac * 4. * term;
114 const double fac = -partialRijInvdr1 + (costi*partialTiInvdr1 + costj*partialTjInvdr1) * invdr1;
115 for (
unsigned short d = 0; d < 3; ++d)
116 f[d] = fac * dr[d] - partialTiInvdr1*eii[d] - partialTjInvdr1*ejj[d];
118 double eiXej[3], eXrij[3];
119 eiXej[0] = eii[1] * ejj[2] - eii[2] * ejj[1];
120 eiXej[1] = eii[2] * ejj[0] - eii[0] * ejj[2];
121 eiXej[2] = eii[0] * ejj[1] - eii[1] * ejj[0];
122 eXrij[0] = eii[1] * dr[2] - eii[2] * dr[1];
123 eXrij[1] = eii[2] * dr[0] - eii[0] * dr[2];
124 eXrij[2] = eii[0] * dr[1] - eii[1] * dr[0];
125 for (
unsigned short d = 0; d < 3; ++d)
126 m1[d] = -partialTiInvdr1 * eXrij[d] - partialGij * eiXej[d];
128 eXrij[0] = ejj[1] * dr[2] - ejj[2] * dr[1];
129 eXrij[1] = ejj[2] * dr[0] - ejj[0] * dr[2];
130 eXrij[2] = ejj[0] * dr[1] - ejj[1] * dr[0];
131 for (
unsigned short d = 0; d < 3; ++d)
132 m2[d] = -partialTjInvdr1 * eXrij[d] + partialGij * eiXej[d];
139inline void PotForceDiQuadrupole(
const double dr[3],
const double& dr2,
const double* eii,
const double* ejj,
141 double f[3],
double m1[3],
double m2[3],
double& u)
143 double invdr2 = 1. / dr2;
144 double invdr1 = sqrt(invdr2);
145 double myqfac = myq15 * invdr2 * invdr2;
149 for (
unsigned short d = 0; d < 3; ++d) {
150 const double& drd = dr[d];
151 const double& eiid = eii[d];
152 const double& ejjd = ejj[d];
155 cosgij += eiid * ejjd;
159 double cos2tj = costj * costj;
160 u = myqfac * (-costi * (5. * cos2tj - 1.) + 2. * cosgij * costj);
161 const double partialRijInvdr1 = -4. * u * invdr2;
162 const double partialTiInvdr1 = myqfac * (-5. * cos2tj + 1.) * invdr1;
163 const double partialTjInvdr1 = myqfac * 2. * (-5. * costi * costj + cosgij) * invdr1;
164 const double partialGij = myqfac * 2. * costj;
165 const double fac = -partialRijInvdr1 + (costi*partialTiInvdr1 + costj*partialTjInvdr1) * invdr1;
166 for (
unsigned short d = 0; d < 3; ++d)
167 f[d] = fac * dr[d] - partialTiInvdr1*eii[d] - partialTjInvdr1*ejj[d];
169 double eiXej[3], eXrij[3];
170 eiXej[0] = eii[1] * ejj[2] - eii[2] * ejj[1];
171 eiXej[1] = eii[2] * ejj[0] - eii[0] * ejj[2];
172 eiXej[2] = eii[0] * ejj[1] - eii[1] * ejj[0];
173 eXrij[0] = eii[1] * dr[2] - eii[2] * dr[1];
174 eXrij[1] = eii[2] * dr[0] - eii[0] * dr[2];
175 eXrij[2] = eii[0] * dr[1] - eii[1] * dr[0];
176 for (
unsigned short d = 0; d < 3; ++d)
177 m1[d] = -partialTiInvdr1 * eXrij[d] - partialGij * eiXej[d];
179 eXrij[0] = ejj[1] * dr[2] - ejj[2] * dr[1];
180 eXrij[1] = ejj[2] * dr[0] - ejj[0] * dr[2];
181 eXrij[2] = ejj[0] * dr[1] - ejj[1] * dr[0];
182 for (
unsigned short d = 0; d < 3; ++d)
183 m2[d] = -partialTjInvdr1 * eXrij[d] + partialGij * eiXej[d];
190inline void PotForce2Charge(
const double dr[3],
const double& dr2,
191 const double& q1q2per4pie0,
double f[3],
double& u)
193 double invdr2 = 1.0 / dr2;
194 double invdr = sqrt(invdr2);
195 u = q1q2per4pie0 * invdr;
196 const double fac = u * invdr2;
197 for (
unsigned short d = 0; d < 3; d++)
205inline void PotForceChargeQuadrupole(
const double dr[3],
const double& dr2,
206 const double* ejj,
const double& qQ05per4pie0,
207 double f[3],
double m2[3],
double& u)
209 double invdr2 = 1.0 / dr2;
210 double invdr = sqrt(invdr2);
212 for (
unsigned short d = 0; d < 3; d++) {
213 costj += ejj[d] * dr[d];
216 double qQinv4dr3 = qQ05per4pie0 * invdr * invdr2;
217 u = qQinv4dr3 * (3.0 * costj * costj - 1);
219 const double partialRijInvdr1 = -3.0 * u * invdr2;
220 const double partialTjInvdr1 = 6.0 * costj * qQinv4dr3 * invdr;
221 const double fac = costj * partialTjInvdr1 * invdr - partialRijInvdr1;
222 for (
unsigned short d = 0; d < 3; ++d)
223 f[d] = fac*dr[d] - partialTjInvdr1 * ejj[d];
225 double minuseXrij[3];
226 minuseXrij[0] = ejj[2]*dr[1] - ejj[1]*dr[2];
227 minuseXrij[1] = ejj[0]*dr[2] - ejj[2]*dr[0];
228 minuseXrij[2] = ejj[1]*dr[0] - ejj[0]*dr[1];
229 for (
unsigned short d = 0; d < 3; ++d)
230 m2[d] = partialTjInvdr1 * minuseXrij[d];
237inline void PotForceChargeDipole(
const double dr[3],
const double& dr2,
238 const double* ejj,
const double& minusqmyper4pie0,
239 double f[3],
double m2[3],
double& u)
241 double invdr2 = 1.0 / dr2;
242 double invdr = sqrt(invdr2);
244 for (
unsigned short d = 0; d < 3; d++) {
245 costj += ejj[d] * dr[d];
248 double uInvcostj = minusqmyper4pie0 * invdr2;
249 u = uInvcostj * costj;
252 const double partialTjInvdr1 = uInvcostj*invdr;
253 const double fac = 3.0 * u * invdr2;
254 for (
unsigned short d = 0; d < 3; ++d)
255 f[d] = fac*dr[d] - partialTjInvdr1 * ejj[d];
257 double minuseXrij[3];
258 minuseXrij[0] = ejj[2]*dr[1] - ejj[1]*dr[2];
259 minuseXrij[1] = ejj[0]*dr[2] - ejj[2]*dr[0];
260 minuseXrij[2] = ejj[1]*dr[0] - ejj[0]*dr[1];
261 for (
unsigned short d = 0; d < 3; ++d)
262 m2[d] = partialTjInvdr1 * minuseXrij[d];
282inline void PotForce(
Molecule& mi,
Molecule& mj,
ParaStrm& params,
double drm[3],
double& Upot6LJ,
double& UpotXpoles,
double& MyRF,
double Virial[3],
bool calculateLJ)
295 const unsigned int nc1 = mi.numLJcenters();
296 const unsigned int nc2 = mj.numLJcenters();
297 for (
unsigned int si = 0; si < nc1; ++si) {
298 const std::array<double,3> dii = mi.ljcenter_d_abs(si);
299 for (
unsigned int sj = 0; sj < nc2; ++sj) {
300 const std::array<double,3> djj = mj.ljcenter_d_abs(sj);
301 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
309 PotForceLJ(drs, dr2, eps24, sig2, f, u);
312 mi.Fljcenteradd(si, f);
313 mj.Fljcentersub(sj, f);
315 for (
unsigned short d = 0; d < 3; ++d)
316 Virial[d] += 0.5*drm[d] * f[d];
324 const unsigned ne1 = mi.numCharges();
325 const unsigned ne2 = mj.numCharges();
326 const unsigned int nq1 = mi.numQuadrupoles();
327 const unsigned int nq2 = mj.numQuadrupoles();
328 const unsigned int nd1 = mi.numDipoles();
329 const unsigned int nd2 = mj.numDipoles();
330 for (
unsigned si = 0; si < ne1; si++) {
331 const std::array<double,3> dii = mi.charge_d_abs(si);
333 for (
unsigned sj = 0; sj < ne2; sj++) {
334 const std::array<double,3> djj = mj.charge_d_abs(sj);
336 params >> q1q2per4pie0;
337 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
338 PotForce2Charge(drs, dr2, q1q2per4pie0, f, u);
340 mi.Fchargeadd(si, f);
341 mj.Fchargesub(sj, f);
344 for (
unsigned short d = 0; d < 3; d++)
345 Virial[d] += 0.5*drm[d] * f[d];
348 for (
unsigned sj = 0; sj < nq2; sj++) {
349 const std::array<double,3> djj = mj.quadrupole_d_abs(sj);
351 params >> qQ05per4pie0;
352 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
353 const std::array<double,3> ejj = mj.quadrupole_e(sj);
354 PotForceChargeQuadrupole(drs, dr2, ejj.data(), qQ05per4pie0, f, m2, u);
356 mi.Fchargeadd(si, f);
357 mj.Fquadrupolesub(sj, f);
361 for (
unsigned short d = 0; d < 3; d++)
362 Virial[d] += 0.5*drm[d] * f[d];
365 for (
unsigned sj = 0; sj < nd2; sj++) {
366 const std::array<double,3> djj = mj.dipole_d_abs(sj);
367 double minusqmyper4pie0;
368 params >> minusqmyper4pie0;
369 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
370 const std::array<double,3> ejj = mj.dipole_e(sj);
371 PotForceChargeDipole(drs, dr2, ejj.data(), minusqmyper4pie0, f, m2, u);
373 mi.Fchargeadd(si, f);
374 mj.Fdipolesub(sj, f);
378 for (
unsigned short d = 0; d < 3; d++)
379 Virial[d] += 0.5*drm[d] * f[d];
382 for (
unsigned int si = 0; si < nq1; ++si) {
383 const std::array<double,3> dii = mi.quadrupole_d_abs(si);
384 const std::array<double,3> eii = mi.quadrupole_e(si);
387 for (
unsigned sj = 0; sj < ne2; sj++) {
388 const std::array<double,3> djj = mj.charge_d_abs(sj);
390 params >> qQ05per4pie0;
391 minusSiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
392 PotForceChargeQuadrupole(drs, dr2, eii.data(), qQ05per4pie0, f, m1, u);
394 mi.Fquadrupolesub(si, f);
395 mj.Fchargeadd(sj, f);
399 for (
unsigned short d = 0; d < 3; d++)
400 Virial[d] -= 0.5*drm[d] * f[d];
403 for (
unsigned int sj = 0; sj < nq2; ++sj) {
405 const std::array<double,3> djj = mj.quadrupole_d_abs(sj);
408 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
409 const std::array<double,3> ejj = mj.quadrupole_e(sj);
410 PotForce2Quadrupole(drs, dr2, eii.data(), ejj.data(), q2075, f, m1, m2, u);
412 mi.Fquadrupoleadd(si, f);
413 mj.Fquadrupolesub(sj, f);
418 for (
unsigned short d = 0; d < 3; ++d)
419 Virial[d] += 0.5*drm[d] * f[d];
422 for (
unsigned int sj = 0; sj < nd2; ++sj) {
424 const std::array<double,3> djj = mj.dipole_d_abs(sj);
427 minusSiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
428 const std::array<double,3> ejj = mj.dipole_e(sj);
429 PotForceDiQuadrupole(drs, dr2, ejj.data(), eii.data(), qmy15, f, m2, m1, u);
431 mi.Fquadrupolesub(si, f);
432 mj.Fdipoleadd(sj, f);
436 for (
unsigned short d = 0; d < 3; d++)
437 Virial[d] -= 0.5*drm[d] * f[d];
440 for (
unsigned int si = 0; si < nd1; ++si) {
441 const std::array<double,3> dii = mi.dipole_d_abs(si);
442 const std::array<double,3> eii = mi.dipole_e(si);
444 for (
unsigned sj = 0; sj < ne2; sj++) {
445 const std::array<double,3> djj = mj.charge_d_abs(sj);
446 double minusqmyper4pie0;
447 params >> minusqmyper4pie0;
448 minusSiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
449 PotForceChargeDipole(drs, dr2, eii.data(), minusqmyper4pie0, f, m1, u);
451 mi.Fdipolesub(si, f);
452 mj.Fchargeadd(sj, f);
456 for (
unsigned short d = 0; d < 3; d++)
457 Virial[d] -= 0.5*drm[d] * f[d];
460 for (
unsigned int sj = 0; sj < nq2; ++sj) {
462 const std::array<double,3> djj = mj.quadrupole_d_abs(sj);
465 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
466 const std::array<double,3> ejj = mj.quadrupole_e(sj);
467 PotForceDiQuadrupole(drs, dr2, eii.data(), ejj.data(), myq15, f, m1, m2, u);
469 mi.Fdipoleadd(si, f);
470 mj.Fquadrupolesub(sj, f);
474 for (
unsigned short d = 0; d < 3; ++d)
475 Virial[d] += 0.5*drm[d] * f[d];
478 for (
unsigned int sj = 0; sj < nd2; ++sj) {
479 const std::array<double,3> djj = mj.dipole_d_abs(sj);
484 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
485 const std::array<double,3> ejj = mj.dipole_e(sj);
486 PotForce2Dipole(drs, dr2, eii.data(), ejj.data(), my2, rffac, f, m1, m2, u, MyRF);
488 mi.Fdipoleadd(si, f);
489 mj.Fdipolesub(sj, f);
493 for (
unsigned short d = 0; d < 3; ++d)
494 Virial[d] += 0.5*drm[d] * f[d];
502 mardyn_assert(params.
eos());
506inline void FluidPot(
Molecule& mi,
Molecule& mj,
ParaStrm& params,
double [3],
double& Upot6LJ,
double& UpotXpoles,
double& MyRF,
bool calculateLJ)
513 const unsigned int nc1 = mi.numLJcenters();
514 const unsigned int nc2 = mj.numLJcenters();
515 for (
unsigned int si = 0; si < nc1; ++si) {
516 const std::array<double,3> dii = mi.ljcenter_d_abs(si);
517 for (
unsigned int sj = 0; sj < nc2; ++sj) {
518 const std::array<double,3> djj = mj.ljcenter_d_abs(sj);
519 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
528 PotForceLJ(drs, dr2, eps24, sig2, f, u);
538 const unsigned ne1 = mi.numCharges();
539 const unsigned ne2 = mj.numCharges();
540 const unsigned int nq1 = mi.numQuadrupoles();
541 const unsigned int nq2 = mj.numQuadrupoles();
542 const unsigned int nd1 = mi.numDipoles();
543 const unsigned int nd2 = mj.numDipoles();
544 for (
unsigned si = 0; si < ne1; si++) {
545 const std::array<double,3> dii = mi.charge_d_abs(si);
547 for (
unsigned sj = 0; sj < ne2; sj++) {
548 const std::array<double,3> djj = mj.charge_d_abs(sj);
550 params >> q1q2per4pie0;
551 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
552 PotForce2Charge(drs, dr2, q1q2per4pie0, f, u);
556 for (
unsigned sj = 0; sj < nq2; sj++) {
557 const std::array<double,3> djj = mj.quadrupole_d_abs(sj);
559 params >> qQ05per4pie0;
560 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
561 const std::array<double,3> ejj = mj.quadrupole_e(sj);
562 PotForceChargeQuadrupole(drs, dr2, ejj.data(), qQ05per4pie0, f, m2, u);
566 for (
unsigned sj = 0; sj < nd2; sj++) {
567 const std::array<double,3> djj = mj.dipole_d_abs(sj);
568 double minusqmyper4pie0;
569 params >> minusqmyper4pie0;
570 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
571 const std::array<double,3> ejj = mj.dipole_e(sj);
572 PotForceChargeDipole(drs, dr2, ejj.data(), minusqmyper4pie0, f, m2, u);
576 for (
unsigned int si = 0; si < nq1; ++si) {
577 const std::array<double,3> dii = mi.quadrupole_d_abs(si);
578 const std::array<double,3> eii = mi.quadrupole_e(si);
581 for (
unsigned sj = 0; sj < ne2; sj++) {
582 const std::array<double,3> djj = mj.charge_d_abs(sj);
584 params >> qQ05per4pie0;
585 minusSiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
586 PotForceChargeQuadrupole(drs, dr2, eii.data(), qQ05per4pie0, f, m1, u);
590 for (
unsigned int sj = 0; sj < nq2; ++sj) {
591 const std::array<double,3> djj = mj.quadrupole_d_abs(sj);
594 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
595 const std::array<double,3> ejj = mj.quadrupole_e(sj);
596 PotForce2Quadrupole(drs, dr2, eii.data(), ejj.data(), q2075, f, m1, m2, u);
600 for (
unsigned int sj = 0; sj < nd2; ++sj) {
601 const std::array<double,3> djj = mj.dipole_d_abs(sj);
604 minusSiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
605 const std::array<double,3> ejj = mj.dipole_e(sj);
607 PotForceDiQuadrupole(drs, dr2, ejj.data(), eii.data(), qmy15, f, m2, m1, u);
611 for (
unsigned int si = 0; si < nd1; ++si) {
612 const std::array<double,3> dii = mi.dipole_d_abs(si);
613 const std::array<double,3> eii = mi.dipole_e(si);
615 for (
unsigned sj = 0; sj < ne2; sj++) {
616 const std::array<double,3> djj = mj.charge_d_abs(sj);
617 double minusqmyper4pie0;
618 params >> minusqmyper4pie0;
619 minusSiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
620 PotForceChargeDipole(drs, dr2, eii.data(), minusqmyper4pie0, f, m1, u);
624 for (
unsigned int sj = 0; sj < nq2; ++sj) {
626 const std::array<double,3> djj = mj.quadrupole_d_abs(sj);
629 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
630 const std::array<double,3> ejj = mj.quadrupole_e(sj);
631 PotForceDiQuadrupole(drs, dr2, eii.data(), ejj.data(), myq15, f, m1, m2, u);
635 for (
unsigned int sj = 0; sj < nd2; ++sj) {
637 const std::array<double,3> djj = mj.dipole_d_abs(sj);
642 SiteSiteDistanceAbs(dii.data(), djj.data(), drs, dr2);
643 const std::array<double,3> ejj = mj.dipole_e(sj);
644 PotForce2Dipole(drs, dr2, eii.data(), ejj.data(), my2, rffac, f, m1, m2, u, MyRF);
650 mardyn_assert(params.
eos());
FullMolecule modeled as LJ sphere with point polarities.
Definition: FullMolecule.h:18
Definition: ParaStrm.h:21
bool eos() const
end of stream reached?
Definition: ParaStrm.h:43