mirror of
https://github.com/openmm/openmm
synced 2026-06-03 06:39:48 +09:00
117 lines
4.6 KiB
C
117 lines
4.6 KiB
C
/* -----------------------------------------------------------------------------
|
|
* OpenMM HelloArgon example in C (June 2009)
|
|
* -----------------------------------------------------------------------------
|
|
* This program demonstrates a simple molecular simulation using the OpenMM
|
|
* 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.
|
|
* 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.
|
|
* -------------------------------------------------------------------------- */
|
|
|
|
#include "OpenMMCWrapper.h"
|
|
#include <stdio.h>
|
|
|
|
/* Forward declaration of routine for printing one frame of the
|
|
trajectory, defined later in this source file. */
|
|
void writePdbFrame(int frameNum, const OpenMM_State*);
|
|
|
|
void simulateArgon()
|
|
{
|
|
OpenMM_System* system;
|
|
OpenMM_Integrator* integrator;
|
|
OpenMM_Context* context;
|
|
OpenMM_Platform* platform;
|
|
OpenMM_NonbondedForce* nonbond;
|
|
OpenMM_Vec3Array* initPosInNm;
|
|
OpenMM_StringArray* pluginList;
|
|
int a, frameNum;
|
|
|
|
/* Load any shared libraries containing GPU implementations. */
|
|
pluginList = OpenMM_Platform_loadPluginsFromDirectory(
|
|
OpenMM_Platform_getDefaultPluginsDirectory());
|
|
OpenMM_StringArray_destroy(pluginList);
|
|
|
|
/* Create a system with nonbonded forces. System takes ownership
|
|
of Force; don't destroy it yourself. */
|
|
system = OpenMM_System_create();
|
|
nonbond = OpenMM_NonbondedForce_create();
|
|
OpenMM_System_addForce(system, (OpenMM_Force*)nonbond);
|
|
|
|
/* Create three atoms. */
|
|
initPosInNm = OpenMM_Vec3Array_create(3);
|
|
for (a = 0; a < 3; ++a)
|
|
{
|
|
const OpenMM_Vec3 posNm = {0.5*a, 0, 0}; /*location, nm*/
|
|
OpenMM_Vec3Array_set(initPosInNm, a, posNm);
|
|
|
|
OpenMM_System_addParticle(system, 39.95); /*mass of Ar, grams/mole*/
|
|
|
|
/* charge, L-J sigma (nm), well depth (kJ) */
|
|
OpenMM_NonbondedForce_addParticle(nonbond, 0.0, 0.3350, 0.996); /*vdWRad(Ar)=.188 nm*/
|
|
}
|
|
|
|
/* Create particular integrator, and recast to generic one. */
|
|
integrator = (OpenMM_Integrator*)OpenMM_VerletIntegrator_create(0.004); /*step size in ps*/
|
|
|
|
/* Let OpenMM Context choose best platform. */
|
|
context = OpenMM_Context_create(system, integrator);
|
|
platform = OpenMM_Context_getPlatform(context);
|
|
printf( "REMARK Using OpenMM platform %s\n",
|
|
OpenMM_Platform_getName(platform));
|
|
|
|
/* Set starting positions of the atoms. Leave time and velocity zero. */
|
|
OpenMM_Context_setPositions(context, initPosInNm);
|
|
|
|
/* Simulate. */
|
|
for (frameNum=1; ;++frameNum) {
|
|
/* Output current state information. */
|
|
OpenMM_State* state = OpenMM_Context_getState(context, OpenMM_State_Positions, 0);
|
|
const double timeInPs = OpenMM_State_getTime(state);
|
|
writePdbFrame(frameNum, state); /*output coordinates*/
|
|
OpenMM_State_destroy(state);
|
|
|
|
if (timeInPs >= 10.)
|
|
break;
|
|
|
|
/* Advance state many steps at a time, for efficient use of OpenMM. */
|
|
OpenMM_Integrator_step(integrator, 10); /*(use a lot more than this normally)*/
|
|
}
|
|
|
|
/* Free heap space for all the objects created above. */
|
|
OpenMM_Vec3Array_destroy(initPosInNm);
|
|
OpenMM_Context_destroy(context);
|
|
OpenMM_Integrator_destroy(integrator);
|
|
OpenMM_System_destroy(system);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
simulateArgon();
|
|
return 0;
|
|
}
|
|
|
|
/* Handy homebrew PDB writer for quick-and-dirty trajectory output. */
|
|
void writePdbFrame(int frameNum, const OpenMM_State* state)
|
|
{
|
|
int a;
|
|
|
|
/* Reference atomic positions in the OpenMM State. */
|
|
const OpenMM_Vec3Array* posInNm = OpenMM_State_getPositions(state);
|
|
|
|
/* Use PDB MODEL cards to number trajectory frames. */
|
|
printf("MODEL %d\n", frameNum); /*start of frame*/
|
|
for (a = 0; a < OpenMM_Vec3Array_getSize(posInNm); ++a)
|
|
{
|
|
OpenMM_Vec3 posInAng;
|
|
/* "10" here converts nanometers to Angstroms */
|
|
posInAng = OpenMM_Vec3_scale(*OpenMM_Vec3Array_get(posInNm, a), 10.);
|
|
printf("ATOM %5d AR AR 1 ", a+1); /*atom number*/
|
|
printf("%8.3f%8.3f%8.3f 1.00 0.00\n", /*coordinates*/
|
|
posInAng.x, posInAng.y, posInAng.z);
|
|
}
|
|
printf("ENDMDL\n"); /*end of frame*/
|
|
}
|