void NonbondedForceImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(CalcNonbondedForceKernel::Name(), context); // Check for errors in the specification of exceptions. const System& system = context.getSystem(); if (owner.getNumParticles() != system.getNumParticles()) throw OpenMMException("NonbondedForce must have exactly as many particles as the System it belongs to."); if (owner.getUseSwitchingFunction()) { if (owner.getSwitchingDistance() < 0 || owner.getSwitchingDistance() >= owner.getCutoffDistance()) throw OpenMMException("NonbondedForce: Switching distance must satisfy 0 <= r_switch < r_cutoff"); } vector<set<int> > exceptions(owner.getNumParticles()); for (int i = 0; i < owner.getNumExceptions(); i++) { int particle1, particle2; double chargeProd, sigma, epsilon; owner.getExceptionParameters(i, particle1, particle2, chargeProd, sigma, epsilon); if (particle1 < 0 || particle1 >= owner.getNumParticles()) { stringstream msg; msg << "NonbondedForce: Illegal particle index for an exception: "; msg << particle1; throw OpenMMException(msg.str()); } if (particle2 < 0 || particle2 >= owner.getNumParticles()) { stringstream msg; msg << "NonbondedForce: Illegal particle index for an exception: "; msg << particle2; throw OpenMMException(msg.str()); } if (exceptions[particle1].count(particle2) > 0 || exceptions[particle2].count(particle1) > 0) { stringstream msg; msg << "NonbondedForce: Multiple exceptions are specified for particles "; msg << particle1; msg << " and "; msg << particle2; throw OpenMMException(msg.str()); } exceptions[particle1].insert(particle2); exceptions[particle2].insert(particle1); } if (owner.getNonbondedMethod() != NonbondedForce::NoCutoff && owner.getNonbondedMethod() != NonbondedForce::CutoffNonPeriodic) { Vec3 boxVectors[3]; system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); double cutoff = owner.getCutoffDistance(); if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2]) throw OpenMMException("NonbondedForce: The cutoff distance cannot be greater than half the periodic box size."); if (owner.getNonbondedMethod() == NonbondedForce::Ewald && (boxVectors[1][0] != 0.0 || boxVectors[2][0] != 0.0 || boxVectors[2][1] != 0)) throw OpenMMException("NonbondedForce: Ewald is not supported with non-rectangular boxes. Use PME instead."); } kernel.getAs<CalcNonbondedForceKernel>().initialize(context.getSystem(), owner); }
void MonteCarloBarostatImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context); kernel.getAs<ApplyMonteCarloBarostatKernel>().initialize(context.getSystem(), owner); Vec3 box[3]; context.getPeriodicBoxVectors(box[0], box[1], box[2]); double volume = box[0][0]*box[1][1]*box[2][2]; volumeScale = 0.01*volume; numAttempted = 0; numAccepted = 0; int randSeed = owner.getRandomNumberSeed(); // A random seed of 0 means use a unique one if (randSeed == 0) randSeed = osrngseed(); init_gen_rand(randSeed, random); }
void CustomHbondForceImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(CalcCustomHbondForceKernel::Name(), context); // Check for errors in the specification of parameters and exclusions. const System& system = context.getSystem(); vector<set<int> > exclusions(owner.getNumDonors()); vector<double> parameters; int numDonorParameters = owner.getNumPerDonorParameters(); for (int i = 0; i < owner.getNumDonors(); i++) { int d1, d2, d3; owner.getDonorParameters(i, d1, d2, d3, parameters); if (d1 < 0 || d1 >= system.getNumParticles()) { stringstream msg; msg << "CustomHbondForce: Illegal particle index for a donor: "; msg << d1; throw OpenMMException(msg.str()); } if (d2 < -1 || d2 >= system.getNumParticles()) { stringstream msg; msg << "CustomHbondForce: Illegal particle index for a donor: "; msg << d2; throw OpenMMException(msg.str()); } if (d3 < -1 || d3 >= system.getNumParticles()) { stringstream msg; msg << "CustomHbondForce: Illegal particle index for a donor: "; msg << d3; throw OpenMMException(msg.str()); } if (parameters.size() != numDonorParameters) { stringstream msg; msg << "CustomHbondForce: Wrong number of parameters for donor "; msg << i; throw OpenMMException(msg.str()); } } int numAcceptorParameters = owner.getNumPerAcceptorParameters(); for (int i = 0; i < owner.getNumAcceptors(); i++) { int a1, a2, a3; owner.getAcceptorParameters(i, a1, a2, a3, parameters); if (a1 < 0 || a1 >= system.getNumParticles()) { stringstream msg; msg << "CustomHbondForce: Illegal particle index for an acceptor: "; msg << a1; throw OpenMMException(msg.str()); } if (a2 < -1 || a2 >= system.getNumParticles()) { stringstream msg; msg << "CustomHbondForce: Illegal particle index for an acceptor: "; msg << a2; throw OpenMMException(msg.str()); } if (a3 < -1 || a3 >= system.getNumParticles()) { stringstream msg; msg << "CustomHbondForce: Illegal particle index for an acceptor: "; msg << a3; throw OpenMMException(msg.str()); } if (parameters.size() != numAcceptorParameters) { stringstream msg; msg << "CustomHbondForce: Wrong number of parameters for acceptor "; msg << i; throw OpenMMException(msg.str()); } } for (int i = 0; i < owner.getNumExclusions(); i++) { int donor, acceptor; owner.getExclusionParticles(i, donor, acceptor); if (donor < 0 || donor >= owner.getNumDonors()) { stringstream msg; msg << "CustomHbondForce: Illegal donor index for an exclusion: "; msg << donor; throw OpenMMException(msg.str()); } if (acceptor < 0 || acceptor >= owner.getNumAcceptors()) { stringstream msg; msg << "CustomHbondForce: Illegal acceptor index for an exclusion: "; msg << acceptor; throw OpenMMException(msg.str()); } if (exclusions[donor].count(acceptor) > 0) { stringstream msg; msg << "CustomHbondForce: Multiple exclusions are specified for donor "; msg << donor; msg << " and acceptor "; msg << acceptor; throw OpenMMException(msg.str()); } exclusions[donor].insert(acceptor); } if (owner.getNonbondedMethod() == CustomHbondForce::CutoffPeriodic) { Vec3 boxVectors[3]; system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); double cutoff = owner.getCutoffDistance(); if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2]) throw OpenMMException("CustomHbondForce: The cutoff distance cannot be greater than half the periodic box size."); } kernel.getAs<CalcCustomHbondForceKernel>().initialize(context.getSystem(), owner); }
void CustomNonbondedForceImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(CalcCustomNonbondedForceKernel::Name(), context); // Check for errors in the specification of parameters and exclusions. const System& system = context.getSystem(); if (owner.getNumParticles() != system.getNumParticles()) throw OpenMMException("CustomNonbondedForce must have exactly as many particles as the System it belongs to."); if (owner.getUseSwitchingFunction()) { if (owner.getSwitchingDistance() < 0 || owner.getSwitchingDistance() >= owner.getCutoffDistance()) throw OpenMMException("CustomNonbondedForce: Switching distance must satisfy 0 <= r_switch < r_cutoff"); } vector<set<int> > exclusions(owner.getNumParticles()); vector<double> parameters; int numParameters = owner.getNumPerParticleParameters(); for (int i = 0; i < owner.getNumParticles(); i++) { owner.getParticleParameters(i, parameters); if (parameters.size() != numParameters) { stringstream msg; msg << "CustomNonbondedForce: Wrong number of parameters for particle "; msg << i; throw OpenMMException(msg.str()); } } for (int i = 0; i < owner.getNumExclusions(); i++) { int particle1, particle2; owner.getExclusionParticles(i, particle1, particle2); if (particle1 < 0 || particle1 >= owner.getNumParticles()) { stringstream msg; msg << "CustomNonbondedForce: Illegal particle index for an exclusion: "; msg << particle1; throw OpenMMException(msg.str()); } if (particle2 < 0 || particle2 >= owner.getNumParticles()) { stringstream msg; msg << "CustomNonbondedForce: Illegal particle index for an exclusion: "; msg << particle2; throw OpenMMException(msg.str()); } if (exclusions[particle1].count(particle2) > 0 || exclusions[particle2].count(particle1) > 0) { stringstream msg; msg << "CustomNonbondedForce: Multiple exclusions are specified for particles "; msg << particle1; msg << " and "; msg << particle2; throw OpenMMException(msg.str()); } exclusions[particle1].insert(particle2); exclusions[particle2].insert(particle1); } if (owner.getNonbondedMethod() == CustomNonbondedForce::CutoffPeriodic) { Vec3 boxVectors[3]; system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); double cutoff = owner.getCutoffDistance(); if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2]) throw OpenMMException("CustomNonbondedForce: The cutoff distance cannot be greater than half the periodic box size."); } // Check that all interaction groups only specify particles that have been defined. for (int group = 0; group < owner.getNumInteractionGroups(); group++) { set<int> set1, set2; owner.getInteractionGroupParameters(group, set1, set2); for (set<int>::iterator it = set1.begin(); it != set1.end(); ++it) if ((*it < 0) || (*it >= owner.getNumParticles())) { stringstream msg; msg << "CustomNonbondedForce: Interaction group " << group << " set1 contains a particle index (" << *it << ") " << "not present in system (" << owner.getNumParticles() << " particles)."; throw OpenMMException(msg.str()); } for (set<int>::iterator it = set2.begin(); it != set2.end(); ++it) if ((*it < 0) || (*it >= owner.getNumParticles())) { stringstream msg; msg << "CustomNonbondedForce: Interaction group " << group << " set2 contains a particle index (" << *it << ") " << "not present in system (" << owner.getNumParticles() << " particles)."; throw OpenMMException(msg.str()); } } kernel.getAs<CalcCustomNonbondedForceKernel>().initialize(context.getSystem(), owner); }
void RBTorsionForceImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(CalcRBTorsionForceKernel::Name(), context); kernel.getAs<CalcRBTorsionForceKernel>().initialize(context.getSystem(), owner); }
void AmoebaMultipoleForceImpl::initialize(ContextImpl& context) { const System& system = context.getSystem(); if (owner.getNumMultipoles() != system.getNumParticles()) throw OpenMMException("AmoebaMultipoleForce must have exactly as many particles as the System it belongs to."); // check cutoff < 0.5*boxSize if (owner.getNonbondedMethod() == AmoebaMultipoleForce::PME) { Vec3 boxVectors[3]; system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); double cutoff = owner.getCutoffDistance(); if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2]) throw OpenMMException("AmoebaMultipoleForce: The cutoff distance cannot be greater than half the periodic box size."); } double quadrupoleValidationTolerance = 1.0e-05; for( int ii = 0; ii < system.getNumParticles(); ii++ ){ int axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY; double charge, thole, dampingFactor, polarity ; std::vector<double> molecularDipole; std::vector<double> molecularQuadrupole; owner.getMultipoleParameters( ii, charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity ); // check quadrupole is traceless and symmetric double trace = fabs( molecularQuadrupole[0] + molecularQuadrupole[4] + molecularQuadrupole[8] ); if( trace > quadrupoleValidationTolerance ){ std::stringstream buffer; buffer << "AmoebaMultipoleForce: qudarupole for particle=" << ii; buffer << " has nonzero trace: " << trace << "; AMOEBA plugin assumes traceless quadrupole."; throw OpenMMException(buffer.str()); } if( fabs( molecularQuadrupole[1] - molecularQuadrupole[3] ) > quadrupoleValidationTolerance ){ std::stringstream buffer; buffer << "AmoebaMultipoleForce: XY and YX components of quadrupole for particle=" << ii; buffer << " are not equal: [" << molecularQuadrupole[1] << " " << molecularQuadrupole[3] << "];"; buffer << " AMOEBA plugin assumes symmetric quadrupole tensor."; throw OpenMMException(buffer.str()); } if( fabs( molecularQuadrupole[2] - molecularQuadrupole[6] ) > quadrupoleValidationTolerance ){ std::stringstream buffer; buffer << "AmoebaMultipoleForce: XZ and ZX components of quadrupole for particle=" << ii; buffer << " are not equal: [" << molecularQuadrupole[2] << " " << molecularQuadrupole[6] << "];"; buffer << " AMOEBA plugin assumes symmetric quadrupole tensor."; throw OpenMMException(buffer.str()); } if( fabs( molecularQuadrupole[5] - molecularQuadrupole[7] ) > quadrupoleValidationTolerance ){ std::stringstream buffer; buffer << "AmoebaMultipoleForce: YZ and ZY components of quadrupole for particle=" << ii; buffer << " are not equal: [" << molecularQuadrupole[5] << " " << molecularQuadrupole[7] << "];"; buffer << " AMOEBA plugin assumes symmetric quadrupole tensor."; throw OpenMMException(buffer.str()); } // only 'Z-then-X', 'Bisector', Z-Bisect, ThreeFold currently handled if( axisType != AmoebaMultipoleForce::ZThenX && axisType != AmoebaMultipoleForce::Bisector && axisType != AmoebaMultipoleForce::ZBisect && axisType != AmoebaMultipoleForce::ThreeFold && axisType != AmoebaMultipoleForce::ZOnly && axisType != AmoebaMultipoleForce::NoAxisType ) { std::stringstream buffer; buffer << "AmoebaMultipoleForce: axis type=" << axisType; buffer << " not currently handled - only axisTypes[ "; buffer << AmoebaMultipoleForce::ZThenX << ", " << AmoebaMultipoleForce::Bisector << ", "; buffer << AmoebaMultipoleForce::ZBisect << ", " << AmoebaMultipoleForce::ThreeFold << ", "; buffer << AmoebaMultipoleForce::NoAxisType; buffer << "] (ZThenX, Bisector, Z-Bisect, ThreeFold, NoAxisType) currently handled ."; throw OpenMMException(buffer.str()); } } kernel = context.getPlatform().createKernel(CalcAmoebaMultipoleForceKernel::Name(), context); kernel.getAs<CalcAmoebaMultipoleForceKernel>().initialize(context.getSystem(), owner); }
void DrudeForceImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(CalcDrudeForceKernel::Name(), context); const System& system = context.getSystem(); // Check for errors in the specification of particles. set<int> usedParticles; for (int i = 0; i < owner.getNumParticles(); i++) { int particle, particle1, particle2, particle3, particle4; double charge, k, k2, k3; owner.getParticleParameters(i, particle, particle1, particle2, particle3, particle4, charge, k, k2, k3); if (particle < 0 || particle >= system.getNumParticles()) { stringstream msg; msg << "DrudeForce: Illegal particle index: "; msg << particle; throw OpenMMException(msg.str()); } if (particle1 < 0 || particle1 >= system.getNumParticles()) { stringstream msg; msg << "DrudeForce: Illegal particle index: "; msg << particle1; throw OpenMMException(msg.str()); } if (particle2 < -1 || particle2 >= system.getNumParticles()) { stringstream msg; msg << "DrudeForce: Illegal particle index: "; msg << particle2; throw OpenMMException(msg.str()); } if (particle3 < -1 || particle3 >= system.getNumParticles()) { stringstream msg; msg << "DrudeForce: Illegal particle index: "; msg << particle3; throw OpenMMException(msg.str()); } if (particle4 < -1 || particle4 >= system.getNumParticles()) { stringstream msg; msg << "DrudeForce: Illegal particle index: "; msg << particle4; throw OpenMMException(msg.str()); } if (usedParticles.find(particle) != usedParticles.end()) { stringstream msg; msg << "DrudeForce: Particle index is used by two different Drude particles: "; msg << particle; throw OpenMMException(msg.str()); } usedParticles.insert(particle); if (usedParticles.find(particle1) != usedParticles.end()) { stringstream msg; msg << "DrudeForce: Particle index is used by two different Drude particles: "; msg << particle1; throw OpenMMException(msg.str()); } usedParticles.insert(particle1); } // Check for errors in the specification of screened pairs. vector<set<int> > screenedPairs(owner.getNumParticles()); for (int i = 0; i < owner.getNumScreenedPairs(); i++) { int particle1, particle2; double thole; owner.getScreenedPairParameters(i, particle1, particle2, thole); if (particle1 < 0 || particle1 >= owner.getNumParticles()) { stringstream msg; msg << "DrudeForce: Illegal particle index for a screened pair: "; msg << particle1; throw OpenMMException(msg.str()); } if (particle2 < 0 || particle2 >= owner.getNumParticles()) { stringstream msg; msg << "DrudeForce: Illegal particle index for a screened pair: "; msg << particle2; throw OpenMMException(msg.str()); } if (screenedPairs[particle1].count(particle2) > 0 || screenedPairs[particle2].count(particle1) > 0) { stringstream msg; msg << "DrudeForce: Multiple screened pairs are specified for particles "; msg << particle1; msg << " and "; msg << particle2; throw OpenMMException(msg.str()); } screenedPairs[particle1].insert(particle2); screenedPairs[particle2].insert(particle1); } kernel.getAs<CalcDrudeForceKernel>().initialize(context.getSystem(), owner); }