HelloWorld.cpp 4.52 KB
Newer Older
Michael Sherman's avatar
Michael Sherman committed
1
2
3
4
5
6
// Suppress irrelevant warnings from Microsoft's compiler.
#ifdef _MSC_VER
    #pragma warning(disable:4996)   // sprintf is unsafe 
    #pragma warning(disable:4251)   // no dll interface for some classes
#endif

7
8
9
10
#include "OpenMM.h"

#include <iostream>
#include <string>
11
#include <limits>
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

using namespace OpenMM;

Vec3 operator*(const Vec3& v, double r) {
    return Vec3(v[0]*r, v[1]*r, v[2]*r);
}

Vec3 operator*(double r, const Vec3& v) {
    return Vec3(r*v[0], r*v[1], r*v[2]);
}

// This is not part of OpenMM; just a struct we can use to collect
// atom parameters for this example. Normally atom parameters would
// come from the force field's parameterization file.
// We're going to use data in Angstrom and Kilocalorie units and
// show how to safely convert to OpenMM's internal unit system
// which uses nanometers and kilojoules.
struct AtomInfo {
    char*  symbol;
    double mass, charge, vdwRadiusAng, vdwEnergyKcal;
    Vec3   startPosAng;
};

static AtomInfo atoms[] = {
    {"Na+", 22.99,  1, 1.8680, 0.00277, Vec3(-3,0,0)},
    {"Cl-", 35.45, -1, 2.4700, 0.1000,  Vec3( 3,0,0)},
    {""} // end of list
};

41
42
static const double Temperature         = 100;   // Kelvins
static const double FrictionInPerPs     = 91.;   // collisions per ps
43
static const double StepSizeFs          = 2;     // femtoseconds
44
45
46
47
48
static const double ReportIntervalFs    = 1000;
static const double SimulationTimePs    = 1000;  // total simulation time (ps)

static const double SigmaPerVdwRadius = 2*std::pow(2., -1./6.);

Michael Sherman's avatar
Michael Sherman committed
49
static double showState(const OpenMMContext&);
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

int main() {
try {
    // Load all available OpenMM plugins from their default location.
    Platform::loadPluginsFromDirectory(Platform::getDefaultPluginsDirectory());

    // Create a System and a NonbondedForce object within the System. 
    System system;
    NonbondedForce* nonbond = new NonbondedForce();
    system.addForce(nonbond);

    int numAtoms = 0;
    for (; *atoms[numAtoms].symbol; ++numAtoms) {
        const AtomInfo& atom = atoms[numAtoms];
        system.addParticle(atom.mass);
        nonbond->addParticle(atom.charge,
                             atom.vdwRadiusAng  * NmPerAngstrom * SigmaPerVdwRadius,
                             atom.vdwEnergyKcal * KJPerKcal);
    }

    // Create an integrator object for advancing time.
    //LangevinIntegrator integrator(Temperature, Friction, StepSizeFs * PsPerFs);
    VerletIntegrator integrator(StepSizeFs * PsPerFs);

    // Create an OpenMM Context for execution; let it choose best platform.
    OpenMMContext context(system, integrator);

    std::cout << "Will use OpenMM platform " << context.getPlatform().getName() << std::endl;
78
    std::cout << "eps(float)=" << std::numeric_limits<float>::epsilon() << std::endl;
79
80
81
82
83
84
85
86
87
88

    // Fill in a vector of starting positions, one per atom.
    std::vector<Vec3> positions(numAtoms);
    for (int i=0; i < numAtoms; ++i)
        positions[i] = atoms[i].startPosAng * NmPerAngstrom;

    // Set the starting positions in the OpenMM context. Velocities will be zero.
    context.setPositions(positions);

    // Output the initial state.
Michael Sherman's avatar
Michael Sherman committed
89
    double time = showState(context);
90
91
92
93

    const int NumSilentSteps = (int)(ReportIntervalFs / StepSizeFs + 0.5);
    do {
        integrator.step(NumSilentSteps);
Michael Sherman's avatar
Michael Sherman committed
94
95
        time = showState(context);
    } while (time < SimulationTimePs);
96
97
98
99
100
101
102
103
104

    } catch(const std::exception& e) {
        std::cout << "EXCEPTION: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

Michael Sherman's avatar
Michael Sherman committed
105
static double
106
107
showState(const OpenMMContext& context) {
    // Caution: at the moment asking for energy requires use of slow reference calculation.
108
109
    const State                 state       = context.getState(  State::Positions | State::Velocities 
                                                               | State::Forces    | State::Energy);
110
111
    const double                energy      = state.getPotentialEnergy() + state.getKineticEnergy();
    const std::vector<Vec3>&    positions   = state.getPositions();
112
    const std::vector<Vec3>&    forces      = state.getForces();
113
114

    std::cout << "t=" << state.getTime() << " E=" << energy << std::endl;
115
116
117
118
119
120
    const double dt = StepSizeFs*PsPerFs;
    for (unsigned i=0; i < positions.size(); ++i) {
        const Vec3 dq = dt*dt/(2*atoms[i].mass) * forces[i];
        std::cout << i << " " << positions[i] * AngstromsPerNm << std::endl;
        std::cout << "f=" << forces[i] << " dq=" << dq << std::endl;
    }
Michael Sherman's avatar
Michael Sherman committed
121
122

    return state.getTime();
123
124
}