mirror of
https://github.com/openmm/openmm
synced 2026-06-03 06:39:48 +09:00
116 lines
4.7 KiB
Fortran
116 lines
4.7 KiB
Fortran
! -----------------------------------------------------------------------------
|
|
! OpenMM HelloArgon example in Fortran 95 (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 'OpenMMFortranModule.f90'
|
|
|
|
PROGRAM HelloArgon
|
|
use OpenMM; implicit none
|
|
type(OpenMM_System) system
|
|
type(OpenMM_VerletIntegrator) verlet
|
|
type(OpenMM_Context) context
|
|
type(OpenMM_Platform) platform
|
|
type(OpenMM_NonbondedForce) nonbond
|
|
type(OpenMM_Vec3Array) initPosInNm
|
|
type(OpenMM_State) state
|
|
type(OpenMM_StringArray) pluginList
|
|
real*8 timeInPs
|
|
integer*4 a, ix, frameNum
|
|
character*10 platformName
|
|
character*100 dirName
|
|
|
|
! Load any shared libraries containing GPU implementations.
|
|
call OpenMM_Platform_getDefaultPluginsDirectory(dirName)
|
|
call OpenMM_Platform_loadPluginsFromDirectory(dirName, pluginList)
|
|
call OpenMM_StringArray_destroy(pluginList)
|
|
|
|
! Create a system with nonbonded forces. System takes ownership
|
|
! of Force; don't destroy it yourself. (We're using transfer here
|
|
! to recast the specific NonbondedForce to a general Force.)
|
|
call OpenMM_System_create(system)
|
|
call OpenMM_NonbondedForce_create(nonbond)
|
|
ix = OpenMM_System_addForce(system, transfer(nonbond, OpenMM_Force(0)))
|
|
|
|
! Create three atoms.
|
|
call OpenMM_Vec3Array_create(initPosInNm, 3)
|
|
do a=1,3
|
|
! Space the atoms out evenly by atom index.
|
|
call OpenMM_Vec3Array_set(initPosInNm, a, (/ 0.5d0*(a-1), 0d0, 0d0 /))
|
|
|
|
ix = OpenMM_System_addParticle(system, 39.95d0) !mass of Ar, grams/mole
|
|
|
|
! charge, L-J sigma (nm), well depth (kJ) (vdWRad(Ar)=.188 nm)
|
|
ix = OpenMM_NonbondedForce_addParticle(nonbond, 0d0, 0.3350d0, 0.996d0)
|
|
end do
|
|
|
|
! Create particular integrator, and recast to generic one.
|
|
call OpenMM_VerletIntegrator_create(verlet, 4d-3) !step size in ps
|
|
|
|
! Let OpenMM Context choose best platform.
|
|
call OpenMM_Context_create(context, system, &
|
|
transfer(verlet, OpenMM_Integrator(0)))
|
|
call OpenMM_Context_getPlatform(context, platform)
|
|
call OpenMM_Platform_getName(platform, platformName)
|
|
print "('REMARK Using OpenMM platform ', A)", platformName
|
|
|
|
! Set starting positions of the atoms. Leave time and velocity zero.
|
|
call OpenMM_Context_setPositions(context, initPosInNm)
|
|
|
|
! Simulate.
|
|
frameNum = 1
|
|
do
|
|
! Output current state information.
|
|
call OpenMM_Context_getState(context, OpenMM_State_Positions, OpenMM_False, state)
|
|
timeInPs = OpenMM_State_getTime(state)
|
|
call writePdbFrame(frameNum, state) !output coordinates
|
|
call OpenMM_State_destroy(state)
|
|
|
|
if (timeInPs .ge. 10.) then
|
|
exit
|
|
end if
|
|
|
|
! Advance state many steps at a time, for efficient use of OpenMM.
|
|
! (use a lot more than 10 normally)
|
|
call OpenMM_VerletIntegrator_step(verlet, 10)
|
|
frameNum = frameNum + 1
|
|
end do
|
|
|
|
! Free heap space for all the objects created above.
|
|
call OpenMM_Vec3Array_destroy(initPosInNm)
|
|
call OpenMM_Context_destroy(context)
|
|
call OpenMM_VerletIntegrator_destroy(verlet)
|
|
call OpenMM_System_destroy(system)
|
|
END PROGRAM
|
|
|
|
! Handy homebrew PDB writer for quick-and-dirty trajectory output.
|
|
SUBROUTINE writePDBFrame(frameNum, state)
|
|
use OpenMM; implicit none
|
|
integer frameNum
|
|
type(OpenMM_State) state
|
|
|
|
type(OpenMM_Vec3Array) allPosInNm
|
|
real*8 posInNm(3), posInAng(3)
|
|
integer n
|
|
|
|
! Reference atomic positions in the OpenMM State.
|
|
call OpenMM_State_getPositions(state, allPosInNm)
|
|
|
|
print "('MODEL',5X,I0)", frameNum ! start of frame
|
|
do n = 1,OpenMM_Vec3Array_getSize(allPosInNm)
|
|
call OpenMM_Vec3Array_get(allPosInNm, n, posInNm)
|
|
call OpenMM_Vec3_scale(posInNm, 10d0, posInAng)
|
|
print "('ATOM ', I5, ' AR AR 1 ', 3F8.3, ' 1.00 0.00')", &
|
|
n, posInAng
|
|
end do
|
|
print "('ENDMDL')"
|
|
END SUBROUTINE
|