Пример #1
0
void testSingleParticle() {
    ReferencePlatform platform;
    System system;
    system.addParticle(2.0);
    LangevinIntegrator integrator(0, 0.1, 0.01);

    GBVIForce* forceField = new GBVIForce();

    double charge         = -1.0;
    double radius         =  0.15;
    double gamma          =  1.0;
    forceField->addParticle(charge, radius, gamma);
    system.addForce(forceField);
    ASSERT(!forceField->usesPeriodicBoundaryConditions());
    ASSERT(!system.usesPeriodicBoundaryConditions());

    Context context(system, integrator, platform);
    vector<Vec3> positions(1);
    positions[0] = Vec3(0, 0, 0);
    context.setPositions(positions);
    State state = context.getState(State::Energy);

    double bornRadius     = radius; 
    double eps0           = EPSILON0;
    double tau            = (1.0/forceField->getSoluteDielectric()-1.0/forceField->getSolventDielectric());

    double bornEnergy     = (-charge*charge/(8*PI_M*eps0))*tau/bornRadius;
    double nonpolarEnergy = -gamma*tau*std::pow(radius/bornRadius, 3.0);

    double expectedE      = (bornEnergy+nonpolarEnergy); 
    double obtainedE      = state.getPotentialEnergy(); 
    double diff           = fabs((obtainedE - expectedE)/expectedE);

    ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01);
}
Пример #2
0
void ValidateOpenMM::writeGBVIForce( FILE* filePtr, const GBVIForce& gbviForce ) const {

    (void) fprintf( filePtr, "GBVIForce %d\n", gbviForce.getNumParticles() );
    for(int ii = 0; ii <  gbviForce.getNumParticles(); ii++ ){
       double charge, radius, gamma;
       gbviForce.getParticleParameters( ii, charge, radius, gamma );
       (void) fprintf( filePtr, "%8d  %14.7e %14.7e %14.7e\n", ii, charge, radius, gamma );
    }

    (void) fprintf( filePtr, "GBVIBonds  %d\n", gbviForce.getNumBonds() );
    for(int ii = 0; ii <  gbviForce.getNumBonds(); ii++ ){
       int atomI, atomJ;
       double bondLength;
       gbviForce.getBondParameters( ii, atomI, atomJ, bondLength );
       (void) fprintf( filePtr, "%8d %8d %8d %14.7e\n", ii, atomI, atomJ, bondLength );
    }
    (void) fprintf( filePtr, "SoluteDielectric %14.7e\n", gbviForce.getSoluteDielectric() );
    (void) fprintf( filePtr, "SolventDielectric %14.7e\n", gbviForce.getSolventDielectric() );

}
Пример #3
0
void testEnergyEthane(int applyBornRadiiScaling) {

    ReferencePlatform platform;
    const int numParticles = 8;
    System system;
    LangevinIntegrator integrator(0, 0.1, 0.01);

    // harmonic bond

    double C_HBondDistance   = 0.1097;
    double C_CBondDistance   = 0.1504;
    HarmonicBondForce* bonds = new HarmonicBondForce();
    bonds->addBond(0, 1, C_HBondDistance, 0.0);
    bonds->addBond(2, 1, C_HBondDistance, 0.0);
    bonds->addBond(3, 1, C_HBondDistance, 0.0);

    bonds->addBond(1, 4, C_CBondDistance, 0.0);

    bonds->addBond(5, 4, C_HBondDistance, 0.0);
    bonds->addBond(6, 4, C_HBondDistance, 0.0);
    bonds->addBond(7, 4, C_HBondDistance, 0.0);

    system.addForce(bonds);

    double C_radius, C_gamma, C_charge, H_radius, H_gamma, H_charge;

    int AM1_BCC = 1;
    H_charge    = -0.053;
    C_charge    = -3.0*H_charge;
    if (AM1_BCC) {
       C_radius =  0.180;
       C_gamma  = -0.2863;
       H_radius =  0.125;
       H_gamma  =  0.2437;
    }
    else {
       C_radius =  0.215;
       C_gamma  = -1.1087;
       H_radius =  0.150;
       H_gamma  =  0.1237;
    }

    NonbondedForce* nonbonded = new NonbondedForce();
    nonbonded->setNonbondedMethod(NonbondedForce::NoCutoff);

    GBVIForce* forceField = new GBVIForce();
    if (applyBornRadiiScaling) {
        forceField->setBornRadiusScalingMethod(GBVIForce::QuinticSpline);
    }
    else {
        forceField->setBornRadiusScalingMethod(GBVIForce::NoScaling);
    }
    for (int i = 0; i < numParticles; i++) {
       system.addParticle(1.0);
       forceField->addParticle(H_charge, H_radius, H_gamma);
       nonbonded->addParticle( H_charge, H_radius, 0.0);
    }
 
    forceField->setParticleParameters(1, C_charge, C_radius, C_gamma);
    forceField->setParticleParameters(4, C_charge, C_radius, C_gamma);
 
    nonbonded->setParticleParameters( 1, C_charge, C_radius, 0.0);
    nonbonded->setParticleParameters( 4, C_charge, C_radius, 0.0);
 
    forceField->addBond(0, 1, C_HBondDistance);
    forceField->addBond(2, 1, C_HBondDistance);
    forceField->addBond(3, 1, C_HBondDistance);
    forceField->addBond(1, 4, C_CBondDistance);
    forceField->addBond(5, 4, C_HBondDistance);
    forceField->addBond(6, 4, C_HBondDistance);
    forceField->addBond(7, 4, C_HBondDistance);
    
    std::vector<pair<int, int> > bondExceptions;
    std::vector<double> bondDistances;
    
    bondExceptions.push_back(pair<int, int>(0, 1)); 
    bondDistances.push_back(C_HBondDistance);
    
    bondExceptions.push_back(pair<int, int>(2, 1)); 
    bondDistances.push_back(C_HBondDistance);
    
    bondExceptions.push_back(pair<int, int>(3, 1)); 
    bondDistances.push_back(C_HBondDistance);
    
    bondExceptions.push_back(pair<int, int>(1, 4)); 
    bondDistances.push_back(C_CBondDistance);
    
    bondExceptions.push_back(pair<int, int>(5, 4)); 
    bondDistances.push_back(C_HBondDistance);
    
    bondExceptions.push_back(pair<int, int>(6, 4)); 
    bondDistances.push_back(C_HBondDistance);
 
    bondExceptions.push_back(pair<int, int>(7, 4));
    bondDistances.push_back(C_HBondDistance);
 
    nonbonded->createExceptionsFromBonds(bondExceptions, 0.0, 0.0);
 
    system.addForce(forceField);
    system.addForce(nonbonded);

    Context context(system, integrator, platform);
    
    vector<Vec3> positions(numParticles);
    positions[0] = Vec3(0.5480,    1.7661,    0.0000);
    positions[1] = Vec3(0.7286,    0.8978,    0.6468);
    positions[2] = Vec3(0.4974,    0.0000,    0.0588);
    positions[3] = Vec3(0.0000,    0.9459,    1.4666);
    positions[4] = Vec3(2.1421,    0.8746,    1.1615);
    positions[5] = Vec3(2.3239,    0.0050,    1.8065);
    positions[6] = Vec3(2.8705,    0.8295,    0.3416);
    positions[7] = Vec3(2.3722,    1.7711,    1.7518);
    context.setPositions(positions);

    State state = context.getState(State::Forces | State::Energy);
    
    // Take a small step in the direction of the energy gradient.
    
    double norm        = 0.0;
    double forceSum[3] = { 0.0, 0.0, 0.0 };
    for (int i = 0; i < numParticles; ++i) {
        Vec3 f  = state.getForces()[i];
        norm        += f[0]*f[0] + f[1]*f[1] + f[2]*f[2];
        forceSum[0] += f[0];
        forceSum[1] += f[1];
        forceSum[2] += f[2];
    }
    norm               = std::sqrt(norm);

    const double delta = 1e-4;
    double step = delta/norm;
    for (int i = 0; i < numParticles; ++i) {
        Vec3 p = positions[i];
        Vec3 f = state.getForces()[i];
        positions[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step);
    }
    context.setPositions(positions);
    
    State state2 = context.getState(State::Energy);

    // See whether the potential energy changed by the expected amount.
    
    ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/delta, 0.01)
}
void testGBVI(GBVIForce::NonbondedMethod gbviMethod, CustomGBForce::NonbondedMethod customGbviMethod, std::string molecule) {

    const int numMolecules = 1;
    const double boxSize   = 10.0;
    ReferencePlatform platform;

    GBVIForce*        gbvi = new GBVIForce();
    std::vector<Vec3> positions;

    // select molecule

    if( molecule == "Monomer" ){
        buildMonomer( gbvi, positions );
    } else if( molecule == "Dimer" ){
        buildDimer( gbvi, positions );
    } else {
        buildEthane( gbvi, positions );
    }

    int numParticles = gbvi->getNumParticles();
    System standardSystem;
    System customGbviSystem;
    for (int i = 0; i < numParticles; i++) {
        standardSystem.addParticle(1.0);
        customGbviSystem.addParticle(1.0);
    }
    standardSystem.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0.0, 0.0), Vec3(0.0, boxSize, 0.0), Vec3(0.0, 0.0, boxSize));
    customGbviSystem.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0.0, 0.0), Vec3(0.0, boxSize, 0.0), Vec3(0.0, 0.0, boxSize));
    gbvi->setCutoffDistance(2.0);

    // create customGbviForce GBVI force

    CustomGBForce* customGbviForce  = createCustomGBVI( gbvi->getSolventDielectric(), gbvi->getSoluteDielectric() );
    customGbviForce->setCutoffDistance(2.0);

    // load parameters from gbvi to customGbviForce

    loadGbviParameters( gbvi, customGbviForce );

    OpenMM_SFMT::SFMT sfmt;
    init_gen_rand(0, sfmt);

    vector<Vec3> velocities(numParticles);
    for (int ii = 0; ii < numParticles; ii++) {
        velocities[ii] = Vec3(genrand_real2(sfmt), genrand_real2(sfmt), genrand_real2(sfmt));
    }
    gbvi->setNonbondedMethod(gbviMethod);
    customGbviForce->setNonbondedMethod(customGbviMethod);

    standardSystem.addForce(gbvi);
    customGbviSystem.addForce(customGbviForce);

    VerletIntegrator integrator1(0.01);
    VerletIntegrator integrator2(0.01);

    Context context1(standardSystem, integrator1, platform);
    context1.setPositions(positions);
    context1.setVelocities(velocities);
    State state1 = context1.getState(State::Forces | State::Energy);

    Context context2(customGbviSystem, integrator2, platform);
    context2.setPositions(positions);
    context2.setVelocities(velocities);
    State state2 = context2.getState(State::Forces | State::Energy);

    ASSERT_EQUAL_TOL(state1.getPotentialEnergy(), state2.getPotentialEnergy(), 1e-4);

    for (int i = 0; i < numParticles; i++) {
        ASSERT_EQUAL_VEC(state1.getForces()[i], state2.getForces()[i], 1e-4);
    }
}
static void findScaledRadii( GBVIForce& gbviForce, std::vector<double> & scaledRadii) {

    int     numberOfParticles = gbviForce.getNumParticles();
    int numberOfBonds         = gbviForce.getNumBonds();
    
    // load 1-2 atom pairs along w/ bond distance using HarmonicBondForce & constraints
    // numberOfBonds < 1, indicating they were not set by the user
    
    if( numberOfBonds < 1 && numberOfParticles > 1 ){
        (void) fprintf( stderr, "Warning: no covalent bonds set for GB/VI force!\n" );
    }
    
    std::vector< std::vector<int> > bondIndices;
    bondIndices.resize( numberOfBonds );
    
    std::vector<double> bondLengths;
    bondLengths.resize( numberOfBonds );

    scaledRadii.resize(numberOfParticles);
    for (int i = 0; i < numberOfParticles; i++) {
        double charge, radius, gamma;
        gbviForce.getParticleParameters(i, charge, radius, gamma);
        scaledRadii[i] = radius;
    }

    for (int i = 0; i < numberOfBonds; i++) {
        int particle1, particle2;
        double bondLength;
        gbviForce.getBondParameters(i, particle1, particle2, bondLength);
        if (particle1 < 0 || particle1 >= gbviForce.getNumParticles()) {
            std::stringstream msg;
            msg << "GBVISoftcoreForce: Illegal particle index: ";
            msg << particle1;
            throw OpenMMException(msg.str());
        }
        if (particle2 < 0 || particle2 >= gbviForce.getNumParticles()) {
            std::stringstream msg;
            msg << "GBVISoftcoreForce: Illegal particle index: ";
            msg << particle2;
            throw OpenMMException(msg.str());
        }
        if (bondLength < 0 ) {
            std::stringstream msg;
            msg << "GBVISoftcoreForce: negative bondlength: ";
            msg << bondLength;
            throw OpenMMException(msg.str());
        }
        bondIndices[i].push_back( particle1 );
        bondIndices[i].push_back( particle2 );
        bondLengths[i] = bondLength;
    }


    // load 1-2 indicies for each atom 

    std::vector<std::vector<int> > bonded12(numberOfParticles);

    for (int i = 0; i < (int) bondIndices.size(); ++i) {
        bonded12[bondIndices[i][0]].push_back(i);
        bonded12[bondIndices[i][1]].push_back(i);
    }

    int errors = 0;

    // compute scaled radii (Eq. 5 of Labute paper [JCC 29 p. 1693-1698 2008])

    for (int j = 0; j < (int) bonded12.size(); ++j){

        double charge;
        double gamma;
        double radiusJ;
        double scaledRadiusJ;
     
        gbviForce.getParticleParameters(j, charge, radiusJ, gamma); 

        if(  bonded12[j].size() == 0 ){
            if( numberOfParticles > 1 ){
                (void) fprintf( stderr, "Warning GBVIForceImpl::findScaledRadii atom %d has no covalent bonds; using atomic radius=%.3f.\n", j, radiusJ );
            }
            scaledRadiusJ = radiusJ;
//             errors++;
        } else {

            double rJ2    = radiusJ*radiusJ;
    
            // loop over bonded neighbors of atom j, applying Eq. 5 in Labute

            scaledRadiusJ = 0.0;
            for (int i = 0; i < (int) bonded12[j].size(); ++i){
    
               int index            = bonded12[j][i];
               int bondedAtomIndex  = (j == bondIndices[index][0]) ? bondIndices[index][1] : bondIndices[index][0];
              
               double radiusI;
               gbviForce.getParticleParameters(bondedAtomIndex, charge, radiusI, gamma); 
               double rI2           = radiusI*radiusI;
    
               double a_ij          = (radiusI - bondLengths[index]);
                      a_ij         *= a_ij;
                      a_ij          = (rJ2 - a_ij)/(2.0*bondLengths[index]);
    
               double a_ji          = radiusJ - bondLengths[index];
                      a_ji         *= a_ji;
                      a_ji          = (rI2 - a_ji)/(2.0*bondLengths[index]);
    
               scaledRadiusJ       += a_ij*a_ij*(3.0*radiusI - a_ij) + a_ji*a_ji*( 3.0*radiusJ - a_ji );
            }
    
            scaledRadiusJ  = (radiusJ*radiusJ*radiusJ) - 0.125*scaledRadiusJ; 
            if( scaledRadiusJ > 0.0 ){
                scaledRadiusJ  = 0.95*pow( scaledRadiusJ, (1.0/3.0) );
            } else {
                scaledRadiusJ  = 0.0;
            }
        }
        //(void) fprintf( stderr, "scaledRadii %d %12.4f\n", j, scaledRadiusJ );
        scaledRadii[j] = scaledRadiusJ;

    }

    // abort if errors

    if( errors ){
        throw OpenMMException("GBVIForceImpl::findScaledRadii errors -- aborting");
    }

#if GBVIDebug
    (void) fprintf( stderr, "                  R              q          gamma   scaled radii no. bnds\n" );
    double totalQ = 0.0;
    for( int i = 0; i < (int) scaledRadii.size(); i++ ){

        double charge;
        double gamma;
        double radiusI;
     
        gbviForce.getParticleParameters(i, charge, radiusI, gamma); 
        totalQ += charge;
        (void) fprintf( stderr, "%4d %14.5e %14.5e %14.5e %14.5e %d\n", i, radiusI, charge, gamma, scaledRadii[i], (int) bonded12[i].size() );
    }
    (void) fprintf( stderr, "Total charge=%e\n", totalQ );
    (void) fflush( stderr );
#endif

#undef GBVIDebug

}
void testSerialization() {
    // Create a Force.

    GBVIForce force;
    force.setNonbondedMethod(GBVIForce::CutoffPeriodic);
    force.setBornRadiusScalingMethod(GBVIForce::QuinticSpline);
    force.setQuinticLowerLimitFactor(0.123);
    force.setQuinticUpperBornRadiusLimit(5.123);
    force.setCutoffDistance(2.0);
    force.setSoluteDielectric(5.1);
    force.setSolventDielectric(50.0);
    force.addParticle(1, 0.1, 0.01);
    force.addParticle(0.5, 0.2, 0.02);
    force.addParticle(-0.5, 0.3, 0.03);
    force.addBond(0, 1, 2.0);
    force.addBond(3, 5, 1.2);

    // Serialize and then deserialize it.

    stringstream buffer;
    XmlSerializer::serialize<GBVIForce>(&force, "Force", buffer);
    GBVIForce* copy = XmlSerializer::deserialize<GBVIForce>(buffer);

    // Compare the two forces to see if they are identical.

    GBVIForce& force2 = *copy;
    ASSERT_EQUAL(force.getNonbondedMethod(), force2.getNonbondedMethod());
    ASSERT_EQUAL(force.getCutoffDistance(), force2.getCutoffDistance());
    ASSERT_EQUAL(force.getSoluteDielectric(), force2.getSoluteDielectric());
    ASSERT_EQUAL(force.getSolventDielectric(), force2.getSolventDielectric());
    ASSERT_EQUAL(force.getNumParticles(), force2.getNumParticles());
    ASSERT_EQUAL(force.getQuinticUpperBornRadiusLimit(), force2.getQuinticUpperBornRadiusLimit());
    ASSERT_EQUAL(force.getQuinticLowerLimitFactor(), force2.getQuinticLowerLimitFactor());
    ASSERT_EQUAL(force.getBornRadiusScalingMethod(), force2.getBornRadiusScalingMethod());
    for (int i = 0; i < force.getNumParticles(); i++) {
        double charge1, radius1, scale1;
        double charge2, radius2, scale2;
        force.getParticleParameters(i, charge1, radius1, scale1);
        force2.getParticleParameters(i, charge2, radius2, scale2);
        ASSERT_EQUAL(charge1, charge2);
        ASSERT_EQUAL(radius1, radius2);
        ASSERT_EQUAL(scale1, scale2);
    }
    ASSERT_EQUAL(force.getNumBonds(), force2.getNumBonds());
    for (int i = 0; i < force.getNumBonds(); i++) {
        int a1, a2, b1, b2;
        double da, db;
        force.getBondParameters(i, a1, a2, da);
        force2.getBondParameters(i, b1, b2, db);
        ASSERT_EQUAL(a1, b1);
        ASSERT_EQUAL(a2, b2);
        ASSERT_EQUAL(da, db);
    }
}