| 66 |
|
namespace OpenMD { |
| 67 |
|
|
| 68 |
|
Electrostatic::Electrostatic(): name_("Electrostatic"), initialized_(false), |
| 69 |
– |
forceField_(NULL), info_(NULL), |
| 69 |
|
haveCutoffRadius_(false), |
| 70 |
|
haveDampingAlpha_(false), |
| 71 |
|
haveDielectric_(false), |
| 72 |
< |
haveElectroSplines_(false) |
| 72 |
> |
haveElectroSplines_(false), |
| 73 |
> |
info_(NULL), forceField_(NULL) |
| 74 |
> |
|
| 75 |
|
{ |
| 76 |
|
flucQ_ = new FluctuatingChargeForces(info_); |
| 77 |
|
} |
| 769 |
|
Tb.zero(); // Torque on site b |
| 770 |
|
Ea.zero(); // Electric field at site a |
| 771 |
|
Eb.zero(); // Electric field at site b |
| 772 |
+ |
Pa = 0.0; // Site potential at site a |
| 773 |
+ |
Pb = 0.0; // Site potential at site b |
| 774 |
|
dUdCa = 0.0; // fluctuating charge force at site a |
| 775 |
|
dUdCb = 0.0; // fluctuating charge force at site a |
| 776 |
|
|
| 845 |
|
if (idat.excluded) { |
| 846 |
|
*(idat.skippedCharge2) += C_a; |
| 847 |
|
} else { |
| 848 |
< |
// only do the field if we're not excluded: |
| 848 |
> |
// only do the field and site potentials if we're not excluded: |
| 849 |
|
Eb -= C_a * pre11_ * dv01 * rhat; |
| 850 |
+ |
Pb += C_a * pre11_ * v01; |
| 851 |
|
} |
| 852 |
|
} |
| 853 |
|
|
| 855 |
|
D_a = *(idat.dipole1); |
| 856 |
|
rdDa = dot(rhat, D_a); |
| 857 |
|
rxDa = cross(rhat, D_a); |
| 858 |
< |
if (!idat.excluded) |
| 858 |
> |
if (!idat.excluded) { |
| 859 |
|
Eb -= pre12_ * ((dv11-v11or) * rdDa * rhat + v11or * D_a); |
| 860 |
+ |
Pb += pre12_ * v11 * rdDa; |
| 861 |
+ |
} |
| 862 |
+ |
|
| 863 |
|
} |
| 864 |
|
|
| 865 |
|
if (a_is_Quadrupole) { |
| 869 |
|
rQa = rhat * Q_a; |
| 870 |
|
rdQar = dot(rhat, Qar); |
| 871 |
|
rxQar = cross(rhat, Qar); |
| 872 |
< |
if (!idat.excluded) |
| 872 |
> |
if (!idat.excluded) { |
| 873 |
|
Eb -= pre14_ * (trQa * rhat * dv21 + 2.0 * Qar * v22or |
| 874 |
|
+ rdQar * rhat * (dv22 - 2.0*v22or)); |
| 875 |
+ |
Pb += pre14_ * (v21 * trQa + v22 * rdQar); |
| 876 |
+ |
} |
| 877 |
|
} |
| 878 |
|
|
| 879 |
|
if (b_is_Charge) { |
| 887 |
|
} else { |
| 888 |
|
// only do the field if we're not excluded: |
| 889 |
|
Ea += C_b * pre11_ * dv01 * rhat; |
| 890 |
+ |
Pa += C_b * pre11_ * v01; |
| 891 |
+ |
|
| 892 |
|
} |
| 893 |
|
} |
| 894 |
|
|
| 896 |
|
D_b = *(idat.dipole2); |
| 897 |
|
rdDb = dot(rhat, D_b); |
| 898 |
|
rxDb = cross(rhat, D_b); |
| 899 |
< |
if (!idat.excluded) |
| 899 |
> |
if (!idat.excluded) { |
| 900 |
|
Ea += pre12_ * ((dv11-v11or) * rdDb * rhat + v11or * D_b); |
| 901 |
+ |
Pa += pre12_ * v11 * rdDb; |
| 902 |
+ |
} |
| 903 |
|
} |
| 904 |
|
|
| 905 |
|
if (b_is_Quadrupole) { |
| 909 |
|
rQb = rhat * Q_b; |
| 910 |
|
rdQbr = dot(rhat, Qbr); |
| 911 |
|
rxQbr = cross(rhat, Qbr); |
| 912 |
< |
if (!idat.excluded) |
| 912 |
> |
if (!idat.excluded) { |
| 913 |
|
Ea += pre14_ * (trQb * rhat * dv21 + 2.0 * Qbr * v22or |
| 914 |
|
+ rdQbr * rhat * (dv22 - 2.0*v22or)); |
| 915 |
+ |
Pa += pre14_ * (v21 * trQb + v22 * rdQbr); |
| 916 |
+ |
} |
| 917 |
|
} |
| 918 |
|
|
| 919 |
|
|
| 1114 |
|
*(idat.eField2) += Eb * *(idat.electroMult); |
| 1115 |
|
} |
| 1116 |
|
|
| 1117 |
+ |
if (idat.doSitePotential) { |
| 1118 |
+ |
*(idat.sPot1) += Pa * *(idat.electroMult); |
| 1119 |
+ |
*(idat.sPot2) += Pb * *(idat.electroMult); |
| 1120 |
+ |
} |
| 1121 |
+ |
|
| 1122 |
|
if (a_is_Fluctuating) *(idat.dVdFQ1) += dUdCa * *(idat.sw); |
| 1123 |
|
if (b_is_Fluctuating) *(idat.dVdFQ2) += dUdCb * *(idat.sw); |
| 1124 |
|
|
| 1556 |
|
mMin = 1; |
| 1557 |
|
} |
| 1558 |
|
pot += kPot; |
| 1559 |
+ |
} |
| 1560 |
+ |
|
| 1561 |
+ |
void Electrostatic::getSitePotentials(Atom* a1, Atom* a2, bool excluded, |
| 1562 |
+ |
RealType &spot1, RealType &spot2) { |
| 1563 |
+ |
|
| 1564 |
+ |
if (!initialized_) { |
| 1565 |
+ |
cerr << "initializing\n"; |
| 1566 |
+ |
initialize(); |
| 1567 |
+ |
cerr << "done\n"; |
| 1568 |
+ |
} |
| 1569 |
+ |
|
| 1570 |
+ |
const RealType mPoleConverter = 0.20819434; |
| 1571 |
+ |
|
| 1572 |
+ |
AtomType* atype1 = a1->getAtomType(); |
| 1573 |
+ |
AtomType* atype2 = a2->getAtomType(); |
| 1574 |
+ |
int atid1 = atype1->getIdent(); |
| 1575 |
+ |
int atid2 = atype2->getIdent(); |
| 1576 |
+ |
data1 = ElectrostaticMap[Etids[atid1]]; |
| 1577 |
+ |
data2 = ElectrostaticMap[Etids[atid2]]; |
| 1578 |
+ |
|
| 1579 |
+ |
Pa = 0.0; // Site potential at site a |
| 1580 |
+ |
Pb = 0.0; // Site potential at site b |
| 1581 |
+ |
|
| 1582 |
+ |
Vector3d d = a2->getPos() - a1->getPos(); |
| 1583 |
+ |
info_->getSnapshotManager()->getCurrentSnapshot()->wrapVector(d); |
| 1584 |
+ |
RealType rij = d.length(); |
| 1585 |
+ |
// some variables we'll need independent of electrostatic type: |
| 1586 |
+ |
|
| 1587 |
+ |
RealType ri = 1.0 / rij; |
| 1588 |
+ |
rhat = d * ri; |
| 1589 |
+ |
|
| 1590 |
+ |
|
| 1591 |
+ |
if ((rij >= cutoffRadius_) || excluded) { |
| 1592 |
+ |
spot1 = 0.0; |
| 1593 |
+ |
spot2 = 0.0; |
| 1594 |
+ |
return; |
| 1595 |
+ |
} |
| 1596 |
+ |
|
| 1597 |
+ |
// logicals |
| 1598 |
+ |
|
| 1599 |
+ |
a_is_Charge = data1.is_Charge; |
| 1600 |
+ |
a_is_Dipole = data1.is_Dipole; |
| 1601 |
+ |
a_is_Quadrupole = data1.is_Quadrupole; |
| 1602 |
+ |
a_is_Fluctuating = data1.is_Fluctuating; |
| 1603 |
+ |
|
| 1604 |
+ |
b_is_Charge = data2.is_Charge; |
| 1605 |
+ |
b_is_Dipole = data2.is_Dipole; |
| 1606 |
+ |
b_is_Quadrupole = data2.is_Quadrupole; |
| 1607 |
+ |
b_is_Fluctuating = data2.is_Fluctuating; |
| 1608 |
+ |
|
| 1609 |
+ |
// Obtain all of the required radial function values from the |
| 1610 |
+ |
// spline structures: |
| 1611 |
+ |
|
| 1612 |
+ |
|
| 1613 |
+ |
if (a_is_Charge || b_is_Charge) { |
| 1614 |
+ |
v01 = v01s->getValueAt(rij); |
| 1615 |
+ |
} |
| 1616 |
+ |
if (a_is_Dipole || b_is_Dipole) { |
| 1617 |
+ |
v11 = v11s->getValueAt(rij); |
| 1618 |
+ |
v11or = ri * v11; |
| 1619 |
+ |
} |
| 1620 |
+ |
if (a_is_Quadrupole || b_is_Quadrupole) { |
| 1621 |
+ |
v21 = v21s->getValueAt(rij); |
| 1622 |
+ |
v22 = v22s->getValueAt(rij); |
| 1623 |
+ |
v22or = ri * v22; |
| 1624 |
+ |
} |
| 1625 |
+ |
|
| 1626 |
+ |
if (a_is_Charge) { |
| 1627 |
+ |
C_a = data1.fixedCharge; |
| 1628 |
+ |
|
| 1629 |
+ |
if (a_is_Fluctuating) { |
| 1630 |
+ |
C_a += a1->getFlucQPos(); |
| 1631 |
+ |
} |
| 1632 |
+ |
|
| 1633 |
+ |
Pb += C_a * pre11_ * v01; |
| 1634 |
+ |
} |
| 1635 |
+ |
|
| 1636 |
+ |
if (a_is_Dipole) { |
| 1637 |
+ |
D_a = a1->getDipole() * mPoleConverter; |
| 1638 |
+ |
rdDa = dot(rhat, D_a); |
| 1639 |
+ |
Pb += pre12_ * v11 * rdDa; |
| 1640 |
+ |
} |
| 1641 |
+ |
|
| 1642 |
+ |
if (a_is_Quadrupole) { |
| 1643 |
+ |
Q_a = a1->getQuadrupole() * mPoleConverter; |
| 1644 |
+ |
trQa = Q_a.trace(); |
| 1645 |
+ |
Qar = Q_a * rhat; |
| 1646 |
+ |
rdQar = dot(rhat, Qar); |
| 1647 |
+ |
Pb += pre14_ * (v21 * trQa + v22 * rdQar); |
| 1648 |
+ |
} |
| 1649 |
+ |
|
| 1650 |
+ |
if (b_is_Charge) { |
| 1651 |
+ |
C_b = data2.fixedCharge; |
| 1652 |
+ |
|
| 1653 |
+ |
if (b_is_Fluctuating) |
| 1654 |
+ |
C_b += a2->getFlucQPos(); |
| 1655 |
+ |
|
| 1656 |
+ |
Pa += C_b * pre11_ * v01; |
| 1657 |
+ |
} |
| 1658 |
+ |
|
| 1659 |
+ |
if (b_is_Dipole) { |
| 1660 |
+ |
D_b = a2->getDipole() * mPoleConverter; |
| 1661 |
+ |
rdDb = dot(rhat, D_b); |
| 1662 |
+ |
Pa += pre12_ * v11 * rdDb; |
| 1663 |
+ |
} |
| 1664 |
+ |
|
| 1665 |
+ |
if (b_is_Quadrupole) { |
| 1666 |
+ |
Q_a = a2->getQuadrupole() * mPoleConverter; |
| 1667 |
+ |
trQb = Q_b.trace(); |
| 1668 |
+ |
Qbr = Q_b * rhat; |
| 1669 |
+ |
rdQbr = dot(rhat, Qbr); |
| 1670 |
+ |
Pa += pre14_ * (v21 * trQb + v22 * rdQbr); |
| 1671 |
+ |
} |
| 1672 |
+ |
|
| 1673 |
+ |
spot1 = Pa; |
| 1674 |
+ |
spot2 = Pb; |
| 1675 |
|
} |
| 1676 |
|
} |