TEST(TestControlBerendsenBins,SingleBin){
    std::ifstream file("../foam-1728.json");
    if(!file.is_open()){
        std::cout<<"File not found"<<std::endl;
        exit(0);
    }
    
    std::string jsonstr;
    std::string line;
    while (!file.eof()) {
        getline(file, line);
        jsonstr += line;
    }
    file.close();
    
    rapidjson::Document document;
    if(document.Parse<0>(jsonstr.c_str()).HasParseError()){
        std::cout<<"Parsing error "<<std::endl;
        exit(0);
    }
    
    const double stepSizeInFs = document["StepSizeInFs"].GetDouble();
    const int numParticles = document["NumberAtoms"].GetInt();
    std::string equationStr = document["Equation"].GetString();
    const double rCut = document["rCut"].GetDouble();
    const rapidjson::Value& b = document["Boxsize"];
    double bx = b[(rapidjson::SizeType)0].GetDouble();
    double by = b[(rapidjson::SizeType)1].GetDouble();
    double bz = b[(rapidjson::SizeType)2].GetDouble();
    int numSpecies = document["NumberSpecies"].GetInt();
    std::vector<OpenMM::Vec3> posInNm;
    std::vector<OpenMM::Vec3> velInNm;
    
    OpenMM::Platform::loadPluginsFromDirectory(
           OpenMM::Platform::getDefaultPluginsDirectory());
    
    OpenMM::System system;
    //add particles to the system by reading from json file
    system.setDefaultPeriodicBoxVectors(OpenMM::Vec3(bx,0,0),OpenMM::Vec3(0,by,0),OpenMM::Vec3(0,0,bz));
    const rapidjson::Value& mass = document["masses"];
    const rapidjson::Value& pos = document["Positions"];
    const rapidjson::Value& vel = document["Velocities"];
    
    posInNm.clear();
    velInNm.clear();
    for(rapidjson::SizeType m=0;m<mass.Size();m++){
        double tm = mass[(rapidjson::SizeType) m].GetDouble();
        system.addParticle(tm);
        posInNm.push_back(OpenMM::Vec3(pos[(rapidjson::SizeType) m]["0"].GetDouble(),
                                       pos[(rapidjson::SizeType) m]["1"].GetDouble(),
                                       pos[(rapidjson::SizeType) m]["2"].GetDouble()
                                       ));
        velInNm.push_back(OpenMM::Vec3(vel[(rapidjson::SizeType) m]["0"].GetDouble(),
                                       vel[(rapidjson::SizeType) m]["1"].GetDouble(),
                                       vel[(rapidjson::SizeType) m]["2"].GetDouble()
                                       ));
    }
    std::cout<<"Initialized System with "<<system.getNumParticles()<<" Particles."<<std::endl;
    
    OpenMM::CustomNonbondedForce* nonbonded = new OpenMM::CustomNonbondedForce(equationStr);
    nonbonded->setNonbondedMethod(OpenMM::CustomNonbondedForce::CutoffPeriodic);
    nonbonded->setCutoffDistance(rCut);// * OpenMM::NmPerAngstrom
    nonbonded->addPerParticleParameter("Ar");//later on collect it from json string based on OF
    for(int p=0;p<numParticles;p++){
        std::vector<double> params(numSpecies);
        params[0] = (double) 1;
        nonbonded->addParticle(params);
    }
    system.addForce(nonbonded);
    std::vector<std::string> ctools(1);
    ctools[0] = "ControlBerendsenInBins";
    OpenMM::Vec3 startPoint = OpenMM::Vec3((10*0.34),(0*0.34),(10*0.34));
    OpenMM::Vec3 endPoint = OpenMM::Vec3((10*0.34),(20*0.34),(10*0.34));
    OpenMM::ControlTools controls(ctools,(double)292,0.001,
                                  startPoint,endPoint);
    int num_plat = OpenMM::Platform::getNumPlatforms();
    std::cout<<"Number of registered platforms: "<< num_plat <<std::endl;
    for(int i=0;i<num_plat;i++)
    {
	    OpenMM::Platform& tempPlatform = OpenMM::Platform::getPlatform(i);
	    std::string tempPlatformName = tempPlatform.getName();
	    std::cout<<"Platform "<<(i+1)<<" is "<<tempPlatformName.c_str()<<std::endl;
    }
    OpenMM::Platform& platform = OpenMM::Platform::getPlatformByName("OpenCL");
    OpenMM::VelocityVerletIntegrator integrator(stepSizeInFs * OpenMM::PsPerFs);
    OpenMM::Context context(system,integrator,platform,controls);
    string Platformname = context.getPlatform().getName();
    std::cout<<"Using OpenMM "<<Platformname.c_str()<<" Platform"<<std::endl;

    context.setPositions(posInNm);
    context.setVelocities(velInNm);
    
    int nbs = context.getControls().getNBins();
    printf("Using %d bins for the system\n",nbs);
    //start the simulation loop
    integrator.step(1);
    printf("Finished initial integration\n");
    int counter=0;
    std::cout<<"starting the loop\n";
    for(int frame=1;frame<400;++frame){
//        OpenMM::State state = context.getState(OpenMM::State::Velocities);
//        const double time = state.getTime();
            double* mola = context.getControls().getBinTemperature();
//            OpenMM::Vec3* tv = context.getControls().getTestVariable();
            double gpuMol = 0.0;
            for(int k=0;k<nbs;k++){
                gpuMol += mola[k];
            }
        EXPECT_EQ((double) numParticles,gpuMol);
        integrator.step(1);
    }
    std::cout<<"Simulation completed with counter value "<<counter<<std::endl;
}
예제 #2
0
OpenMM::System* AmberParm::createSystem(
                OpenMM::NonbondedForce::NonbondedMethod nonbondedMethod,
                double nonbondedCutoff,
                std::string constraints,
                bool rigidWater,
                std::string implicitSolvent,
                double implicitSolventKappa,
                double implicitSolventSaltConc,
                double temperature,
                double soluteDielectric,
                double solventDielectric,
                bool removeCMMotion,
                double ewaldErrorTolerance,
                bool flexibleConstraints,
                bool useSASA) {

    OpenMM::System* system = new OpenMM::System();

    // Make sure we have a legal choice for constraints and implicitSolvent
    if (constraints != "None" && constraints != "HBonds" &&
            constraints != "AllBonds") {
        string msg = "constraints must be None, HBonds, or AllBonds; not " +
                     constraints;
        throw AmberParmError(msg.c_str());
    }

    if (implicitSolvent != "None" && implicitSolvent != "HCT" &&
            implicitSolvent != "OBC1" && implicitSolvent != "OBC2" &&
            implicitSolvent != "GBn" && implicitSolvent != "GBn2") {
        string msg = "implicitSolvent must be None, HCT, OBC1, OBC2, GBn, or "
                     "GBn2; not " + implicitSolvent;
        throw AmberParmError(msg.c_str());
    }

    if (rigidWater && (constraints != "HBonds" && constraints != "AllBonds")) {
        cerr << "rigidWater is incompatible with constraints=None; setting to "
             << "false" << endl;
    }

    // Catch illegal nonbonded choice for system

    if (isPeriodic()) {
        if (nonbondedMethod == OpenMM::NonbondedForce::CutoffNonPeriodic ||
                nonbondedMethod == OpenMM::NonbondedForce::NoCutoff)
            throw AmberParmError("Illegal nonbondedForce choice for periodic system");
    } else {
        if (nonbondedMethod == OpenMM::NonbondedForce::CutoffPeriodic ||
                nonbondedMethod == OpenMM::NonbondedForce::PME ||
                nonbondedMethod == OpenMM::NonbondedForce::Ewald)
            throw AmberParmError("Illegal nonbondedForce choice for non-periodic system");
    }

    // Add all particles
    for (atom_iterator it = AtomBegin(); it != AtomEnd(); it++) {
        system->addParticle(it->getMass());
    }

    // Add constraints
    bool hcons = constraints == "HBonds" || constraints == "AllBonds";
    bool allcons = constraints == "AllBonds";
    for (bond_iterator it = BondBegin(); it != BondEnd(); it++) {
        Atom a1 = atoms_[it->getAtomI()];
        Atom a2 = atoms_[it->getAtomJ()];
        if (hcons && (a1.getElement() == 1 || a2.getElement() == 1)) {
            system->addConstraint(it->getAtomI(), it->getAtomJ(),
                                  it->getEquilibriumDistance()*NANOMETER_PER_ANGSTROM);
        } else if (allcons) {
            system->addConstraint(it->getAtomI(), it->getAtomJ(),
                                  it->getEquilibriumDistance()*NANOMETER_PER_ANGSTROM);
        }
    }
    
    // Add all bonds
    if (!allcons || flexibleConstraints) {
        OpenMM::HarmonicBondForce *bond_force = new OpenMM::HarmonicBondForce();
        bond_force->setForceGroup(BOND_FORCE_GROUP);
        double conv = ANGSTROM_PER_NANOMETER*ANGSTROM_PER_NANOMETER*JOULE_PER_CALORIE;
        for (bond_iterator it=BondBegin(); it != BondEnd(); it++) {
            // See if this bond needs to be skipped due to constraints
            Atom a1 = atoms_[it->getAtomI()];
            Atom a2 = atoms_[it->getAtomJ()];
            if (hcons && (a1.getElement() == 1 || a2.getElement() == 1) &&
                        !flexibleConstraints) continue;

            bond_force->addBond(it->getAtomI(), it->getAtomJ(),
                                it->getEquilibriumDistance()*NANOMETER_PER_ANGSTROM,
                                2*it->getForceConstant()*conv);
        }
        system->addForce(bond_force);
    }

    // Add all angles
    OpenMM::HarmonicAngleForce *angle_force = new OpenMM::HarmonicAngleForce();
    angle_force->setForceGroup(ANGLE_FORCE_GROUP);
    for (angle_iterator it = AngleBegin(); it != AngleEnd(); it++) {
        angle_force->addAngle(it->getAtomI(), it->getAtomJ(), it->getAtomK(),
                              it->getEquilibriumAngle()*RADIAN_PER_DEGREE,
                              2*it->getForceConstant()*JOULE_PER_CALORIE);
    }
    system->addForce(angle_force);

    // Add all torsions
    OpenMM::PeriodicTorsionForce *dihedral_force = new OpenMM::PeriodicTorsionForce();
    dihedral_force->setForceGroup(DIHEDRAL_FORCE_GROUP);
    for (dihedral_iterator it = DihedralBegin(); it != DihedralEnd(); it++) {
        dihedral_force->addTorsion(it->getAtomI(), it->getAtomJ(),
                                   it->getAtomK(), it->getAtomL(),
                                   it->getPeriodicity(),
                                   it->getPhase()*RADIAN_PER_DEGREE,
                                   it->getForceConstant()*JOULE_PER_CALORIE);
    }
    system->addForce(dihedral_force);

    // Add nonbonded force
    OpenMM::NonbondedForce *nonb_frc = new OpenMM::NonbondedForce();
    nonb_frc->setForceGroup(NONBONDED_FORCE_GROUP);
    nonb_frc->setNonbondedMethod(nonbondedMethod);
    if (nonbondedMethod != OpenMM::NonbondedForce::NoCutoff)
        nonb_frc->setCutoffDistance(nonbondedCutoff*NANOMETER_PER_ANGSTROM);
    const double ONE_SIXTH = 1.0 / 6.0;
    const double SIGMA_SCALE = pow(2, -ONE_SIXTH) * 2 * NANOMETER_PER_ANGSTROM;
    for (atom_iterator it = AtomBegin(); it != AtomEnd(); it++) {
        nonb_frc->addParticle(it->getCharge(),
                              it->getLJRadius()*SIGMA_SCALE,
                              it->getLJEpsilon()*JOULE_PER_CALORIE);
    }
    // Now do exceptions
    const double SIGMA_SCALE2 = pow(2, -ONE_SIXTH) * NANOMETER_PER_ANGSTROM;
    for (dihedral_iterator it = DihedralBegin(); it != DihedralEnd(); it++) {
        if (it->ignoreEndGroups()) continue;
        Atom a1 = atoms_[it->getAtomI()];
        Atom a2 = atoms_[it->getAtomL()];
        double eps = sqrt(a1.getLJEpsilon() * a2.getLJEpsilon()) *
                     JOULE_PER_CALORIE / it->getScnb();
        double sig = (a1.getLJRadius() + a2.getLJRadius()) * SIGMA_SCALE2;
        nonb_frc->addException(it->getAtomI(), it->getAtomL(),
                               a1.getCharge()*a2.getCharge()/it->getScee(),
                               sig, eps);
    }
    // Now do exclusions
    for (int i = 0; i < atoms_.size(); i++) {
        if (exclusion_list_[i].size() == 0) continue; // No exclusions here
        for (set<int>::const_iterator it = exclusion_list_[i].begin();
                it != exclusion_list_[i].end(); it++) {
            nonb_frc->addException(i, *it, 0.0, 1.0, 0.0);
        }
    }
    // Set the ewald error tolerance
    if (nonbondedMethod == OpenMM::NonbondedForce::PME ||
            nonbondedMethod == OpenMM::NonbondedForce::Ewald)
        nonb_frc->setEwaldErrorTolerance(ewaldErrorTolerance);
    system->addForce(nonb_frc);
    // See about removing the center of mass motion
    if (removeCMMotion)
        system->addForce(new OpenMM::CMMotionRemover());
    // Add a box if necessary
    if (isPeriodic())
        system->setDefaultPeriodicBoxVectors(unit_cell_.getVectorA()/10,
                                             unit_cell_.getVectorB()/10,
                                             unit_cell_.getVectorC()/10);

    // If no implicit solvent, we can return system now
    if (implicitSolvent == "None")
        return system;

    // Otherwise, we need to add the GB force
    if (implicitSolventKappa <= 0 && implicitSolventSaltConc > 0)
        implicitSolventKappa = 50.33355 * 0.73 *
                sqrt(implicitSolventSaltConc/(solventDielectric*temperature));

    OpenMM::CustomGBForce *gb_frc = 0;
    if (implicitSolvent == "HCT") {
        gb_frc = GB_HCT(*this, solventDielectric, soluteDielectric, useSASA,
                        nonbondedCutoff, implicitSolventKappa);
    } else if (implicitSolvent == "OBC1") {
        gb_frc = GB_OBC1(*this, solventDielectric, soluteDielectric, useSASA,
                         nonbondedCutoff, implicitSolventKappa);
    } else if (implicitSolvent == "OBC2") {
        gb_frc = GB_OBC2(*this, solventDielectric, soluteDielectric, useSASA,
                         nonbondedCutoff, implicitSolventKappa);
    } else if (implicitSolvent == "GBn") {
        gb_frc = GB_GBn(*this, solventDielectric, soluteDielectric, useSASA,
                        nonbondedCutoff, implicitSolventKappa);
    } else if (implicitSolvent == "GBn2") {
        gb_frc = GB_GBn2(*this, solventDielectric, soluteDielectric, useSASA,
                         nonbondedCutoff, implicitSolventKappa);
    } else {
        stringstream iss;
        iss << "Should not be here; bad GB model " << implicitSolvent;
        throw InternalError(iss.str());
    }

    if (nonbondedMethod == OpenMM::NonbondedForce::NoCutoff)
        gb_frc->setNonbondedMethod(OpenMM::CustomGBForce::NoCutoff);
    else if (nonbondedMethod == OpenMM::NonbondedForce::CutoffNonPeriodic)
        gb_frc->setNonbondedMethod(OpenMM::CustomGBForce::CutoffNonPeriodic);
    else // all remaining options are periodic cutoff...
        gb_frc->setNonbondedMethod(OpenMM::CustomGBForce::CutoffPeriodic);

    gb_frc->setForceGroup(NONBONDED_FORCE_GROUP);

    // Since we're using GB, we need to turn off the reaction field dielectric
    nonb_frc->setReactionFieldDielectric(1.0);

    system->addForce(gb_frc);

    return system;
}