HelloArgon.cpp 3.84 KB
Newer Older
1
2
3
4
// -----------------------------------------------------------------------------
//           OpenMM(tm) HelloArgon example in C++ (June 2009)
// -----------------------------------------------------------------------------
// This program demonstrates a simple molecular simulation using the OpenMM
5
6
7
8
9
// API for GPU-accelerated molecular dynamics simulation. The primary goal is
// to make sure you can compile, link, and run with OpenMM and view the output.
// The example is available in C++, C, and Fortran 95.
//
// The system modeled here is a small number of argon atoms in a vacuum.
10
11
12
13
// A multi-frame PDB file is written to stdout which  can be read by VMD or 
// other visualization tool to produce an animation of the resulting trajectory.
// -----------------------------------------------------------------------------

14
15
16
17
18
// Suppress irrelevant warning from Microsoft's compiler.
#ifdef _MSC_VER
    #pragma warning(disable:4251)   // no dll interface for some classes
#endif

Michael Sherman's avatar
Michael Sherman committed
19
20
21
#include "OpenMM.h"
#include <cstdio>

22
23
24
// Forward declaration of routine for printing one frame of the
// trajectory, defined later in this source file.
void writePdbFrame(int frameNum, const OpenMM::State&);
Michael Sherman's avatar
Michael Sherman committed
25
26
27

void simulateArgon()
{
28
    // Load any shared libraries containing GPU implementations.
Michael Sherman's avatar
Michael Sherman committed
29
30
31
    OpenMM::Platform::loadPluginsFromDirectory(
        OpenMM::Platform::getDefaultPluginsDirectory());

32
    // Create a system with nonbonded forces.
Michael Sherman's avatar
Michael Sherman committed
33
34
35
36
    OpenMM::System system;
    OpenMM::NonbondedForce* nonbond = new OpenMM::NonbondedForce(); 
    system.addForce(nonbond);

37
38
    // Create three atoms.
    std::vector<OpenMM::Vec3> initPosInNm(3);
Michael Sherman's avatar
Michael Sherman committed
39
40
    for (int a = 0; a < 3; ++a) 
    {
41
        initPosInNm[a] = OpenMM::Vec3(a/2.,0,0); // location, nm
Michael Sherman's avatar
Michael Sherman committed
42

43
        system.addParticle(39.95); // mass of Ar, grams per mole
Michael Sherman's avatar
Michael Sherman committed
44

45
46
        // charge, L-J sigma (nm), well depth (kJ)
        nonbond->addParticle(0.0, 0.3350, 0.996); // vdWRad(Ar)=.188 nm
Michael Sherman's avatar
Michael Sherman committed
47
48
    }

49
    OpenMM::VerletIntegrator integrator(0.004); // step size in ps
Michael Sherman's avatar
Michael Sherman committed
50
51
52
53
54
55

    // Let OpenMM Context choose best platform.
    OpenMM::OpenMMContext context(system, integrator);
    printf( "REMARK  Using OpenMM platform %s\n", 
        context.getPlatform().getName().c_str() );

56
57
58
59
60
61
62
63
64
    // Set starting positions of the atoms. Leave time and velocity zero.
    context.setPositions(initPosInNm);

    // Simulate.
    for (int frameNum=1; ;++frameNum) {
        // Output current state information.
        OpenMM::State state    = context.getState(OpenMM::State::Positions);
        const double  timeInPs = state.getTime();
        writePdbFrame(frameNum, state); // output coordinates
Michael Sherman's avatar
Michael Sherman committed
65

66
67
68
69
70
        if (timeInPs >= 10.)
            break;

        // Advance state many steps at a time, for efficient use of OpenMM.
        integrator.step(10); // (use a lot more than this normally)
Michael Sherman's avatar
Michael Sherman committed
71
72
73
74
75
76
77
78
79
    }
}

int main() 
{
    try {
        simulateArgon();
        return 0; // success!
    }
80
81
82
83
84
    // Catch and report usage and runtime errors detected by OpenMM and fail.
    catch(const std::exception& e) {
        printf("EXCEPTION: %s\n", e.what());
        return 1; // failure!
    }
Michael Sherman's avatar
Michael Sherman committed
85
86
}

87
88
// Handy homebrew PDB writer for quick-and-dirty trajectory output.
void writePdbFrame(int frameNum, const OpenMM::State& state) 
Michael Sherman's avatar
Michael Sherman committed
89
{
90
91
    // Reference atomic positions in the OpenMM State.
    const std::vector<OpenMM::Vec3>& posInNm = state.getPositions();
Michael Sherman's avatar
Michael Sherman committed
92
93

    // Use PDB MODEL cards to number trajectory frames
94
95
    printf("MODEL     %d\n", frameNum); // start of frame
    for (int a = 0; a < (int)posInNm.size(); ++a)
Michael Sherman's avatar
Michael Sherman committed
96
    {
97
98
        printf("ATOM  %5d  AR   AR     1    ", a+1); // atom number
        printf("%8.3f%8.3f%8.3f  1.00  0.00\n",      // coordinates
Michael Sherman's avatar
Michael Sherman committed
99
            // "*10" converts nanometers to Angstroms
100
            posInNm[a][0]*10, posInNm[a][1]*10, posInNm[a][2]*10);
Michael Sherman's avatar
Michael Sherman committed
101
102
103
    }
    printf("ENDMDL\n"); // end of frame
}