package name.mjw.jamber;
import javax.vecmath.Vector3d;
/**
* Van der Waals interaction between two atoms. Here, the Lennard Jones 12-6
* potential is used.
*
* @author mjw
*
*/
public class LJTwelveSix extends ForceFieldTerm {
/**
* Atom i in in a bond
*/
private Atom i;
/**
* Atom j in in a bond
*/
private Atom j;
/**
* Characteristic distance of atom i, in Angstrom
*/
private double ri;
/**
* Well depth of atom i, in kcal/mol
*/
private double ei;
/**
* Characteristic distance of atom j, in Angstrom
*/
private double rj;
/**
* Well depth of atom j, in kcal/mol
*/
private double ej;
/**
* Scaling factor to apply to the interaction.
* For 1-4 interactions, this is termed scnb and is 1/2.0
*/
private double scalingFactor;
/**
* Lennard Jones (12-6)
*
* @param i Atom i in the bond
* @param ri Characteristic distance of atom i, in Angstrom
* @param ei Well depth of atom i, in kcal/mol
* @param j Atom j in the bond
* @param rj Characteristic distance of atom j, in Angstrom
* @param ej Well depth of atom j, in kcal/mol
* @param scalingFactor scaling factor to apply to interaction
*/
public LJTwelveSix(Atom i, double ri, double ei, Atom j, double rj,
double ej, double scalingFactor) {
this.setAtomI(i);
this.setAtomJ(j);
this.setRi(ri);
this.setEi(ei);
this.setRj(rj);
this.setEj(ej);
this.setScalingFactor(scalingFactor);
}
/**
* Returns the current distance between the two atoms, in Angstroms
*/
double getCurrentDistance() {
Vector3d dist = new Vector3d();
dist.sub(i.getPosition(), j.getPosition());
return dist.length();
}
/**
*
*/
public double getLennardJonesA() {
double r0 = this.ri + this.rj;
double eij = Math.pow((this.ei * this.ej), 0.5);
return eij * Math.pow(r0, 12);
}
/**
*
*/
public double getLennardJonesB() {
double r0 = this.ri + this.rj;
double eij = Math.pow((this.ei * this.ej), 0.5);
return 2.0 * eij * Math.pow(r0, 6);
}
/**
* Returns the potential energy of the bond in Kcal
*/
public double getPotentialEnergy() {
double energy;
energy = (this.getLennardJonesA() / Math.pow(getCurrentDistance(), 12))
- (this.getLennardJonesB() / Math.pow(getCurrentDistance(), 6));
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 ( (-(12 * this.getLennardJonesA()) / Math.pow(getCurrentDistance(), 13))
+ ( (6*this.getLennardJonesB()) / Math.pow(getCurrentDistance(), 7)) ) / 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 * scalingFactor);
i.addForce(temp3d);
j.subForce(temp3d);
}
/**
* Sets atom i of the bond
*/
private void setAtomI(Atom i) {
this.i = i;
}
/**
* Gets atom i of the bond
*/
public Atom getI() {
return i;
}
/**
* Sets atom j of the bond
*/
private void setAtomJ(Atom j) {
this.j = j;
}
/**
* Gets atom j of the bond
*/
public Atom getJ() {
return j;
}
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(" ri:\t\t\t\t\t\t").append(this.getRi()).append(NEW_LINE);
result.append(" ei:\t\t\t\t\t\t").append(this.getEi()).append(NEW_LINE);
result.append(" rj:\t\t\t\t\t\t").append(this.getRj()).append(NEW_LINE);
result.append(" ej:\t\t\t\t\t\t").append(this.getEj()).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("}");
return result.toString();
}
double getRi() {
return ri;
}
private void setRi(double ri) {
this.ri = ri;
}
private void setEi(double ei) {
this.ei = ei;
}
double getEi() {
return ei;
}
double getRj() {
return rj;
}
private void setRj(double rj) {
this.rj = rj;
}
double getEj() {
return ej;
}
private void setEj(double ej) {
this.ej = ej;
}
double getScalingFactor() {
return scalingFactor;
}
private void setScalingFactor(double scalingFactor) {
this.scalingFactor = scalingFactor;
}
}