package name.mjw.jamber;
import javax.vecmath.Vector3d;
/**
* Coulombic interaction between two atoms.
*
* @author mjw
*
*/
public class ElectroStatic extends ForceFieldTerm {
/**
* Atom i in in a bond
*/
private Atom i;
/**
* Atom j in in a bond
*/
private Atom j;
private double scalingFactor;
// http://ambermd.org/Questions/units.html
final private double AMBER_COULOMB_PREFACTOR = 332.0522173;
//final private double EXACT_COULOMB_PREFACTOR = 332.063777774;
/**
* Electrostatic term between two atoms
*
* @param i
* Atom i
* @param j
* Atom j
*
* @param scalingFactor scaling factor to apply to interaction
*/
public ElectroStatic(Atom i, Atom j, double scalingFactor) {
this.setAtomI(i);
this.setAtomJ(j);
this.setScalingFactor(scalingFactor);
}
/**
* Returns the current distances between the two atoms in Angstroms
*/
private double getCurrentDistance() {
Vector3d dist = new Vector3d();
dist.sub(i.getPosition(), j.getPosition());
return dist.length();
}
/**
* Returns the potential energy of the interaction in kcal/mol
*/
public double getPotentialEnergy() {
double energy;
// http://ambermd.org/Questions/units.html
energy = AMBER_COULOMB_PREFACTOR * ((i.getCharge()) * (j.getCharge()))
/ getCurrentDistance();
return energy/scalingFactor;
}
/**
* Returns the current (scalar) gradient of the potential energy term. This
* is the analytical derivative of the potential energy at this point
*/
@Override
public double getAnalyticalGradient() {
return (-1 * getPotentialEnergy() / getCurrentDistance())/scalingFactor;
}
/**
* Calculates and imparts the force of the bond to its member atoms
*/
public void evaluateForce() {
Vector3d temp3d = new Vector3d();
temp3d.sub(i.getPosition(), j.getPosition());
double forceVectorSum = getAnalyticalGradient();
double unitForce = forceVectorSum / temp3d.length();
temp3d.scale(unitForce);
i.addForce(temp3d);
j.subForce(temp3d);
}
/**
* Sets atom i of the bond
*/
public void setAtomI(Atom i) {
this.i = i;
}
/**
* Gets atom i of the bond
*/
public Atom getI() {
return i;
}
/**
* Sets atom j of the bond
*/
public void setAtomJ(Atom j) {
this.j = j;
}
/**
* Gets atom j of the bond
*/
public Atom getJ() {
return j;
}
public double getScalingFactor() {
return scalingFactor;
}
public void setScalingFactor(double scalingFactor) {
this.scalingFactor = scalingFactor;
}
public String toString() {
StringBuilder result = new StringBuilder();
String NEW_LINE = System.getProperty("line.separator");
result.append(this.getClass().getName()).append(" Object {")
.append(NEW_LINE);
result.append(
String.format(" Atoms:\t\t\t\t\t\t%-2s-%-2s", i.getName(),
j.getName())).append(NEW_LINE);
result.append(
String.format(" AtomTypes:\t\t\t\t\t%-2s-%-2s",
i.getAMBERAtomType(), j.getAMBERAtomType())).append(
NEW_LINE);
result.append(" charge on i:\t\t\t\t\t").append(this.i.getCharge())
.append(NEW_LINE);
result.append(" charge on j:\t\t\t\t\t").append(this.j.getCharge())
.append(NEW_LINE);
result.append(" current length:\t\t\t\t")
.append(this.getCurrentDistance()).append(NEW_LINE);
result.append(" current potential contribution:\t\t")
.append(this.getPotentialEnergy()).append(NEW_LINE);
result.append(i.toString());
result.append(j.toString());
result.append("}");
return result.toString();
}
}