use of ffx.potential.bonded.Atom in project ffx by mjschnie.
the class ForceFieldEnergyOpenMM method getOpenMMPositions.
/**
* getOpenMMPositions takes in a PointerByReference containing the position
* information of the context. This method creates a Vec3Array that contains
* the three dimensional information of the positions of the atoms. The
* method then adds these values to a new double array x and returns it to
* the method call
*
* @param positions
* @param numberOfVariables
* @param x
* @return x
*/
public double[] getOpenMMPositions(PointerByReference positions, int numberOfVariables, double[] x) {
assert numberOfVariables == getNumberOfVariables();
if (x == null || x.length < numberOfVariables) {
x = new double[numberOfVariables];
}
Atom[] atoms = molecularAssembly.getAtomArray();
int nAtoms = atoms.length;
for (int i = 0; i < nAtoms; i++) {
int offset = i * 3;
OpenMM_Vec3 pos = OpenMM_Vec3Array_get(positions, i);
x[offset] = pos.x * OpenMM_AngstromsPerNm;
x[offset + 1] = pos.y * OpenMM_AngstromsPerNm;
x[offset + 2] = pos.z * OpenMM_AngstromsPerNm;
Atom atom = atoms[i];
atom.moveTo(x[offset], x[offset + 1], x[offset + 2]);
}
return x;
}
use of ffx.potential.bonded.Atom in project ffx by mjschnie.
the class ForceFieldEnergyOpenMM method addAtoms.
/**
* Adds atoms from the molecular assembly to the OpenMM System and reports
* to the user the number of particles added.
*/
private void addAtoms() throws Exception {
Atom[] atoms = molecularAssembly.getAtomArray();
int nAtoms = atoms.length;
numParticles = 0;
for (int i = 0; i < nAtoms; i++) {
Atom atom = atoms[i];
OpenMM_System_addParticle(system, atom.getMass());
if (atom.getMass() <= 0.0) {
throw new Exception(" Atom without mass greater than 0.");
}
numParticles++;
}
logger.log(Level.INFO, " Added particles ({0})", nAtoms);
}
use of ffx.potential.bonded.Atom in project ffx by mjschnie.
the class ForceFieldEnergyOpenMM method updateFixedChargeNonBondedForce.
/**
* Updates the fixed-charge non-bonded force for change in Use flags.
*
* @param atoms Array of all Atoms in the system
* @param vdwLambdaTerm If true, set charges and eps values to zero for
* Lambda atoms
*/
private void updateFixedChargeNonBondedForce(Atom[] atoms, boolean vdwLambdaTerm) {
VanDerWaals vdW = super.getVdwNode();
/**
* Only 6-12 LJ with arithmetic mean to define sigma and geometric mean
* for epsilon is supported.
*/
VanDerWaalsForm vdwForm = vdW.getVDWForm();
if (vdwForm.vdwType != LENNARD_JONES || vdwForm.radiusRule != ARITHMETIC || vdwForm.epsilonRule != GEOMETRIC) {
logger.log(Level.SEVERE, String.format(" Unsuppporterd van der Waals functional form."));
return;
}
/**
* OpenMM vdW force requires a diameter (i.e. not radius).
*/
double radScale = 1.0;
if (vdwForm.radiusSize == RADIUS) {
radScale = 2.0;
}
/**
* OpenMM vdw force requires atomic sigma values (i.e. not r-min).
*/
if (vdwForm.radiusType == R_MIN) {
radScale /= 1.122462048309372981;
}
/**
* Update parameters.
*/
int nAtoms = atoms.length;
for (int i = 0; i < nAtoms; i++) {
Atom atom = atoms[i];
boolean applyLambda = atom.applyLambda();
double charge = Double.MIN_VALUE;
MultipoleType multipoleType = atom.getMultipoleType();
if (multipoleType != null && atoms[i].getElectrostatics()) {
charge = multipoleType.charge;
if (lambdaTerm && applyLambda) {
charge *= lambda;
}
}
VDWType vdwType = atom.getVDWType();
double sigma = OpenMM_NmPerAngstrom * vdwType.radius * radScale;
double eps = OpenMM_KJPerKcal * vdwType.wellDepth;
if ((vdwLambdaTerm && applyLambda) || !atoms[i].getUse()) {
eps = 0.0;
charge = 0.0;
}
OpenMM_NonbondedForce_setParticleParameters(fixedChargeNonBondedForce, i, charge, sigma, eps);
}
// OpenMM_NonbondedForce_updateParametersInContext(fixedChargeNonBondedForce, context);
/**
* Update Exceptions.
*/
IntByReference particle1 = new IntByReference();
IntByReference particle2 = new IntByReference();
DoubleByReference chargeProd = new DoubleByReference();
DoubleByReference sigma = new DoubleByReference();
DoubleByReference eps = new DoubleByReference();
int numExceptions = OpenMM_NonbondedForce_getNumExceptions(fixedChargeNonBondedForce);
for (int i = 0; i < numExceptions; i++) {
/**
* Only update exceptions.
*/
if (chargeExclusion[i] && vdWExclusion[i]) {
continue;
}
OpenMM_NonbondedForce_getExceptionParameters(fixedChargeNonBondedForce, i, particle1, particle2, chargeProd, sigma, eps);
int i1 = particle1.getValue();
int i2 = particle2.getValue();
double qq = exceptionChargeProd[i];
double epsilon = exceptionEps[i];
Atom atom1 = atoms[i1];
Atom atom2 = atoms[i2];
double lambdaValue = lambda;
if (lambda == 0.0) {
lambdaValue = 1.0e-6;
}
if (atom1.applyLambda()) {
qq *= lambdaValue;
if (vdwLambdaTerm) {
epsilon = 1.0e-6;
qq = 1.0e-6;
}
}
if (atom2.applyLambda()) {
qq *= lambdaValue;
if (vdwLambdaTerm) {
epsilon = 1.0e-6;
qq = 1.0e-6;
}
}
if (!atom1.getUse() || !atom2.getUse()) {
qq = 1.0e-6;
epsilon = 1.0e-6;
}
OpenMM_NonbondedForce_setExceptionParameters(fixedChargeNonBondedForce, i, i1, i2, qq, sigma.getValue(), epsilon);
/**
* logger.info(format(" B Exception %d %d %d q=%10.8f s=%10.8f
* e=%10.8f.", i, i1, i2, chargeProd.getValue(), sigma.getValue(),
* eps.getValue()));
*
* logger.info(format(" E Exception %d %d %d q=%10.8f s=%10.8f
* e=%10.8f.", i, i1, i2, qq, sigma.getValue(), epsilon));
*/
}
OpenMM_NonbondedForce_updateParametersInContext(fixedChargeNonBondedForce, context);
}
use of ffx.potential.bonded.Atom in project ffx by mjschnie.
the class ForceFieldEnergyOpenMM method updateAmoebaVDWForce.
/**
* Updates the AMOEBA van der Waals force for change in Use flags.
*
* @param atoms Array of all Atoms in the system
*/
private void updateAmoebaVDWForce(Atom[] atoms) {
VanDerWaals vdW = super.getVdwNode();
VanDerWaalsForm vdwForm = vdW.getVDWForm();
double radScale = 1.0;
if (vdwForm.radiusSize == VanDerWaalsForm.RADIUS_SIZE.DIAMETER) {
radScale = 0.5;
}
/**
* Note that the API says it wants a SIGMA value.
*/
if (vdwForm.radiusType == VanDerWaalsForm.RADIUS_TYPE.R_MIN) {
// radScale *= 1.122462048309372981;
}
int[] ired = vdW.getReductionIndex();
int nAtoms = atoms.length;
for (int i = 0; i < nAtoms; i++) {
Atom atom = atoms[i];
VDWType vdwType = atom.getVDWType();
double useFactor = 1.0;
if (!atoms[i].getUse()) {
useFactor = 0.0;
}
double eps = OpenMM_KJPerKcal * vdwType.wellDepth * useFactor;
OpenMM_AmoebaVdwForce_setParticleParameters(amoebaVDWForce, i, ired[i], OpenMM_NmPerAngstrom * vdwType.radius * radScale, eps, vdwType.reductionFactor);
}
OpenMM_AmoebaVdwForce_updateParametersInContext(amoebaVDWForce, context);
}
use of ffx.potential.bonded.Atom in project ffx by mjschnie.
the class ForceFieldEnergyOpenMM method addHarmonicRestraintForce.
/**
* Adds harmonic restraints (CoordRestraint objects) to OpenMM as a custom
* external force.
*/
private void addHarmonicRestraintForce() {
for (CoordRestraint restraint : super.getCoordRestraints()) {
double forceConst = restraint.getForceConstant();
forceConst *= OpenMM_KJPerKcal;
forceConst *= (OpenMM_AngstromsPerNm * OpenMM_AngstromsPerNm);
Atom[] restAtoms = restraint.getAtoms();
int nRestAts = restraint.getNumAtoms();
double[][] oCoords = restraint.getOriginalCoordinates();
for (int i = 0; i < nRestAts; i++) {
oCoords[i][0] *= OpenMM_NmPerAngstrom;
oCoords[i][1] *= OpenMM_NmPerAngstrom;
oCoords[i][2] *= OpenMM_NmPerAngstrom;
}
PointerByReference theRestraint = OpenMM_CustomExternalForce_create("k*periodicdistance(x,y,z,x0,y0,z0)^2");
OpenMM_CustomExternalForce_addGlobalParameter(theRestraint, "k", forceConst);
OpenMM_CustomExternalForce_addPerParticleParameter(theRestraint, "x0");
OpenMM_CustomExternalForce_addPerParticleParameter(theRestraint, "y0");
OpenMM_CustomExternalForce_addPerParticleParameter(theRestraint, "z0");
PointerByReference xyzOrigArray = OpenMM_DoubleArray_create(3);
for (int i = 0; i < nRestAts; i++) {
int ommIndex = restAtoms[i].getXyzIndex() - 1;
for (int j = 0; j < 3; j++) {
OpenMM_DoubleArray_set(xyzOrigArray, j, oCoords[i][j]);
}
OpenMM_CustomExternalForce_addParticle(theRestraint, ommIndex, xyzOrigArray);
}
OpenMM_DoubleArray_destroy(xyzOrigArray);
OpenMM_System_addForce(system, theRestraint);
}
}
Aggregations