106 |
|
angstromToM_ = 1.0e-10; |
107 |
|
debyeToCm_ = 3.33564095198e-30; |
108 |
|
|
109 |
< |
// number of points for electrostatic splines |
110 |
< |
np_ = 100; |
109 |
> |
// Default number of points for electrostatic splines |
110 |
> |
np_ = 140; |
111 |
|
|
112 |
|
// variables to handle different summation methods for long-range |
113 |
|
// electrostatics: |
246 |
|
b3c = (5.0 * b2c + pow(2.0*a2, 3) * expTerm * invArootPi) / r2; |
247 |
|
b4c = (7.0 * b3c + pow(2.0*a2, 4) * expTerm * invArootPi) / r2; |
248 |
|
b5c = (9.0 * b4c + pow(2.0*a2, 5) * expTerm * invArootPi) / r2; |
249 |
< |
selfMult_ = b0c + 2.0 * a2 * invArootPi; |
249 |
> |
selfMult_ = b0c + a2 * invArootPi; |
250 |
|
} else { |
251 |
|
a2 = 0.0; |
252 |
|
b0c = 1.0 / r; |
279 |
|
// working variables for Taylor expansion: |
280 |
|
RealType rmRc, rmRc2, rmRc3, rmRc4; |
281 |
|
|
282 |
+ |
// Approximate using splines using a maximum of 0.1 Angstroms |
283 |
+ |
// between points. |
284 |
+ |
int nptest = int((cutoffRadius_ + 2.0) / 0.1); |
285 |
+ |
np_ = (np_ > nptest) ? np_ : nptest; |
286 |
+ |
|
287 |
|
// Add a 2 angstrom safety window to deal with cutoffGroups that |
288 |
|
// have charged atoms longer than the cutoffRadius away from each |
289 |
|
// other. Splining is almost certainly the best choice here. |
504 |
|
v33v.push_back(v33); |
505 |
|
v34v.push_back(v34); |
506 |
|
v35v.push_back(v35); |
507 |
< |
|
507 |
> |
|
508 |
|
v41v.push_back(v41); |
509 |
|
v42v.push_back(v42); |
510 |
|
v43v.push_back(v43); |
690 |
|
Vector3d D_a, D_b; // Dipoles (space-fixed) |
691 |
|
Mat3x3d Q_a, Q_b; // Quadrupoles (space-fixed) |
692 |
|
|
693 |
< |
RealType ri, ri2, ri3, ri4; // Distance utility scalars |
693 |
> |
RealType ri; // Distance utility scalar |
694 |
|
RealType rdDa, rdDb; // Dipole utility scalars |
695 |
|
Vector3d rxDa, rxDb; // Dipole utility vectors |
696 |
|
RealType rdQar, rdQbr, trQa, trQb; // Quadrupole utility scalars |
698 |
|
RealType pref; |
699 |
|
|
700 |
|
RealType DadDb, trQaQb, DadQbr, DbdQar; // Cross-interaction scalars |
701 |
+ |
RealType rQaQbr; |
702 |
|
Vector3d DaxDb, DadQb, DbdQa, DaxQbr, DbxQar; // Cross-interaction vectors |
703 |
< |
Vector3d rQaQb, QaQbr, QaxQb; |
703 |
> |
Vector3d rQaQb, QaQbr, QaxQb, rQaxQbr; |
704 |
|
Mat3x3d QaQb; // Cross-interaction matrices |
705 |
|
|
706 |
|
RealType U(0.0); // Potential |
735 |
|
|
736 |
|
ri = 1.0 / *(idat.rij); |
737 |
|
Vector3d rhat = *(idat.d) * ri; |
732 |
– |
ri2 = ri * ri; |
738 |
|
|
739 |
|
// logicals |
740 |
|
|
797 |
|
v46 = v46s->getValueAt( *(idat.rij) ); |
798 |
|
} |
799 |
|
|
795 |
– |
|
800 |
|
// calculate the single-site contributions (fields, etc). |
801 |
|
|
802 |
|
if (a_is_Charge) { |
808 |
|
|
809 |
|
if (idat.excluded) { |
810 |
|
*(idat.skippedCharge2) += C_a; |
811 |
+ |
} else { |
812 |
+ |
// only do the field if we're not excluded: |
813 |
+ |
Eb -= C_a * pre11_ * v02 * rhat; |
814 |
|
} |
808 |
– |
Eb -= C_a * pre11_ * v02 * rhat; |
815 |
|
} |
816 |
|
|
817 |
|
if (a_is_Dipole) { |
818 |
|
D_a = *(idat.dipole1); |
819 |
|
rdDa = dot(rhat, D_a); |
820 |
|
rxDa = cross(rhat, D_a); |
821 |
< |
Eb -= pre12_ * (v13 * rdDa * rhat + v12 * D_a); |
821 |
> |
if (!idat.excluded) |
822 |
> |
Eb -= pre12_ * (v13 * rdDa * rhat + v12 * D_a); |
823 |
|
} |
824 |
|
|
825 |
|
if (a_is_Quadrupole) { |
829 |
|
rQa = rhat * Q_a; |
830 |
|
rdQar = dot(rhat, Qar); |
831 |
|
rxQar = cross(rhat, Qar); |
832 |
< |
Eb -= pre14_ * ((trQa * rhat + 2.0 * Qar) * v23 + rdQar * rhat * v24); |
832 |
> |
if (!idat.excluded) |
833 |
> |
Eb -= pre14_ * ((trQa * rhat + 2.0 * Qar) * v23 + rdQar * rhat * v24); |
834 |
|
} |
835 |
|
|
836 |
|
if (b_is_Charge) { |
841 |
|
|
842 |
|
if (idat.excluded) { |
843 |
|
*(idat.skippedCharge1) += C_b; |
844 |
+ |
} else { |
845 |
+ |
// only do the field if we're not excluded: |
846 |
+ |
Ea += C_b * pre11_ * v02 * rhat; |
847 |
|
} |
837 |
– |
Ea += C_b * pre11_ * v02 * rhat; |
848 |
|
} |
849 |
|
|
850 |
|
if (b_is_Dipole) { |
851 |
|
D_b = *(idat.dipole2); |
852 |
|
rdDb = dot(rhat, D_b); |
853 |
|
rxDb = cross(rhat, D_b); |
854 |
< |
Ea += pre12_ * (v13 * rdDb * rhat + v12 * D_b); |
854 |
> |
if (!idat.excluded) |
855 |
> |
Ea += pre12_ * (v13 * rdDb * rhat + v12 * D_b); |
856 |
|
} |
857 |
|
|
858 |
|
if (b_is_Quadrupole) { |
862 |
|
rQb = rhat * Q_b; |
863 |
|
rdQbr = dot(rhat, Qbr); |
864 |
|
rxQbr = cross(rhat, Qbr); |
865 |
< |
Ea += pre14_ * ((trQb * rhat + 2.0 * Qbr) * v23 + rdQbr * rhat * v24); |
865 |
> |
if (!idat.excluded) |
866 |
> |
Ea += pre14_ * ((trQb * rhat + 2.0 * Qbr) * v23 + rdQbr * rhat * v24); |
867 |
|
} |
868 |
|
|
869 |
|
if ((a_is_Fluctuating || b_is_Fluctuating) && idat.excluded) { |
965 |
|
F -= pref * (DadDb * rhat + rdDb * D_a + rdDa * D_b)*v23; |
966 |
|
F -= pref * (rdDa * rdDb) * v24 * rhat; |
967 |
|
Ta += pref * ( v21 * DaxDb - v22 * rdDb * rxDa); |
968 |
< |
Tb += pref * (-v21 * DaxDb + v22 * rdDa * rxDb); |
968 |
> |
Tb += pref * (-v21 * DaxDb - v22 * rdDa * rxDb); |
969 |
|
|
970 |
|
// Even if we excluded this pair from direct interactions, we |
971 |
|
// still have the reaction-field-mediated dipole-dipole |
1019 |
|
F += pref * (rdDb * rdQar * rhat * v35); |
1020 |
|
Ta += pref * ((-2.0*cross(DbdQa, rhat) + 2.0*DbxQar)*v31 |
1021 |
|
+ 2.0*rdDb*rxQar*v32); |
1022 |
< |
Tb += pref * ((trQa*rxDb + 2.0 * DbxQar)*v31 + rxDb*rdQar*v32); |
1022 |
> |
Tb += pref * ((trQa*rxDb - 2.0 * DbxQar)*v31 + rxDb*rdQar*v32); |
1023 |
|
} |
1024 |
|
if (b_is_Quadrupole) { |
1025 |
< |
pref = pre44_ * *(idat.electroMult); |
1025 |
> |
pref = pre44_ * *(idat.electroMult); // yes |
1026 |
|
QaQb = Q_a * Q_b; |
1027 |
|
trQaQb = QaQb.trace(); |
1028 |
|
rQaQb = rhat * QaQb; |
1029 |
< |
QaQbr = QaQb * rhat; |
1029 |
> |
QaQbr = QaQb * rhat; |
1030 |
|
QaxQb = cross(Q_a, Q_b); |
1031 |
< |
|
1032 |
< |
U += pref * (trQa * trQb + 2.0*trQaQb) * v41; |
1033 |
< |
U += pref * (trQa*rdQbr + trQb*rdQar + 4.0*dot(rQa, Qbr)) * v42; |
1031 |
> |
rQaQbr = dot(rQa, Qbr); |
1032 |
> |
rQaxQbr = cross(rQa, Qbr); |
1033 |
> |
|
1034 |
> |
U += pref * (trQa * trQb + 2.0 * trQaQb) * v41; |
1035 |
> |
U += pref * (trQa * rdQbr + trQb * rdQar + 4.0 * rQaQbr) * v42; |
1036 |
|
U += pref * (rdQar * rdQbr) * v43; |
1037 |
|
|
1038 |
< |
F += pref * (trQa*trQb*rhat + 2.0*trQaQb*rhat)*v44; |
1039 |
< |
F += pref * (2.0*trQb*rQa + 2.0*trQa*rQb)*v44; |
1040 |
< |
F += pref * (4.0* QaQb * rhat + 4.0 * rhat * QaQb)*v44; |
1027 |
< |
F += pref * (trQa*rdQbr*rhat + trQb*rdQar*rhat |
1028 |
< |
+ 4.0*dot(rQa, Qbr)*rhat)*v45; |
1029 |
< |
F += pref * (2.0*rQa*rdQbr + 2.0*rdQar*rQb)*v45; |
1030 |
< |
F += pref * (rdQar*rdQbr*rhat) * v46; |
1038 |
> |
F += pref * rhat * (trQa * trQb + 2.0 * trQaQb)*v44; |
1039 |
> |
F += pref * rhat * (trQa * rdQbr + trQb * rdQar + 4.0 * rQaQbr)*v45; |
1040 |
> |
F += pref * rhat * (rdQar * rdQbr)*v46; |
1041 |
|
|
1042 |
< |
Ta += pref * (-4.0 * QaxQb * v41); |
1043 |
< |
Ta += pref * (-2.0*trQb*cross(rQa, rhat) |
1044 |
< |
+ 4.0*cross(rhat, QaQbr) |
1045 |
< |
- 4.0*cross(rQa, Qbr)) * v42; |
1042 |
> |
F += pref * 2.0 * (trQb*rQa + trQa*rQb)*v44; |
1043 |
> |
F += pref * 4.0 * (rQaQb + QaQbr)*v44; |
1044 |
> |
F += pref * 2.0 * (rQa*rdQbr + rdQar*rQb)*v45; |
1045 |
> |
|
1046 |
> |
Ta += pref * (- 4.0 * QaxQb * v41); |
1047 |
> |
Ta += pref * (- 2.0 * trQb * cross(rQa, rhat) |
1048 |
> |
+ 4.0 * cross(rhat, QaQbr) |
1049 |
> |
- 4.0 * rQaxQbr) * v42; |
1050 |
|
Ta += pref * 2.0 * cross(rhat,Qar) * rdQbr * v43; |
1051 |
|
|
1038 |
– |
Tb += pref * (4.0 * QaxQb * v41); |
1039 |
– |
Tb += pref * (-2.0*trQa*cross(rQb, rhat) |
1040 |
– |
- 4.0*cross(rQaQb, rhat) |
1041 |
– |
+ 4.0*cross(rQa, Qbr))*v42; |
1042 |
– |
Tb += pref * 2.0 * cross(rhat,Qbr) * rdQar * v43; |
1052 |
|
|
1053 |
+ |
Tb += pref * (+ 4.0 * QaxQb * v41); |
1054 |
+ |
Tb += pref * (- 2.0 * trQa * cross(rQb, rhat) |
1055 |
+ |
- 4.0 * cross(rQaQb, rhat) |
1056 |
+ |
+ 4.0 * rQaxQbr) * v42; |
1057 |
+ |
// Possible replacement for line 2 above: |
1058 |
+ |
// + 4.0 * cross(rhat, QbQar) |
1059 |
+ |
|
1060 |
+ |
Tb += pref * 2.0 * cross(rhat,Qbr) * rdQar * v43; |
1061 |
+ |
|
1062 |
+ |
// cerr << " tsum = " << Ta + Tb - cross( *(idat.d) , F ) << "\n"; |
1063 |
|
} |
1064 |
|
} |
1065 |
|
|
1100 |
|
*(idat.t2) += *(idat.sw) * indirect_Tb; |
1101 |
|
} |
1102 |
|
return; |
1103 |
< |
} |
1103 |
> |
} |
1104 |
|
|
1105 |
|
void Electrostatic::calcSelfCorrection(SelfData &sdat) { |
1106 |
|
|
1143 |
|
|
1144 |
|
case esm_SHIFTED_FORCE: |
1145 |
|
case esm_SHIFTED_POTENTIAL: |
1146 |
< |
if (i_is_Charge) { |
1147 |
< |
self = -0.5 * selfMult_ * C_a * (C_a + *(sdat.skippedCharge)) * pre11_; |
1146 |
> |
if (i_is_Charge) { |
1147 |
> |
self = - selfMult_ * C_a * (C_a + *(sdat.skippedCharge)) * pre11_; |
1148 |
|
(*(sdat.pot))[ELECTROSTATIC_FAMILY] += self; |
1149 |
|
} |
1150 |
|
break; |