Commit 2b1b486c authored by Peter Eastman's avatar Peter Eastman
Browse files

Added the enforcePeriodicBox flag to the C and Fortran wrappers

parent 9f700f0d
......@@ -53,7 +53,7 @@ FOREACH(EX_ROOT ${CPP_EXAMPLES})
ENDFOREACH(EX_ROOT ${CPP_EXAMPLES})
# Only build wrapper examples if wrappers have been built
IF(OPENMM_BUILD_API_WRAPPERS)
IF(OPENMM_BUILD_C_AND_FORTRAN_WRAPPERS)
INCLUDE_DIRECTORIES(BEFORE ${PROJECT_BINARY_DIR}/wrappers)
FOREACH(EX_ROOT ${C_EXAMPLES})
......@@ -83,7 +83,7 @@ IF(OPENMM_BUILD_API_WRAPPERS)
ADD_DEPENDENCIES(${EX_STATIC} ApiWrappers)
ENDIF (BUILD_TESTING_STATIC)
ENDFOREACH(EX_ROOT ${C_EXAMPLES})
ENDIF(OPENMM_BUILD_API_WRAPPERS)
ENDIF(OPENMM_BUILD_C_AND_FORTRAN_WRAPPERS)
FOREACH(EX_ROOT ${C_EXAMPLES})
INSTALL(FILES ${EX_ROOT}.c DESTINATION examples)
......
......@@ -68,7 +68,7 @@ void simulateArgon()
/* Simulate. */
for (frameNum=1; ;++frameNum) {
/* Output current state information. */
OpenMM_State* state = OpenMM_Context_getState(context, OpenMM_State_Positions);
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);
......
! -----------------------------------------------------------------------------
! OpenMM(tm) 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.
! -----------------------------------------------------------------------------
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, 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
! -----------------------------------------------------------------------------
! OpenMM(tm) 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.
! -----------------------------------------------------------------------------
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, state, 0)
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
......@@ -289,7 +289,7 @@ myGetOpenMMState(MyOpenMMData* omm, int wantEnergy,
/* Forces are also available (and cheap). */
/* State object is created here and must be explicitly destroyed below. */
state = OpenMM_Context_getState(omm->context, infoMask);
state = OpenMM_Context_getState(omm->context, infoMask, 0);
*timeInPs = OpenMM_State_getTime(state); /* OpenMM time is in ps already. */
/* Positions are maintained as a Vec3Array inside the State. This will give
......
! -----------------------------------------------------------------------------
! OpenMM(tm) HelloSodiumChloride example in Fortran 95 (June 2009)
! ------------------------------------------------------------------------------
! This is a complete, self-contained "hello world" example demonstrating
! GPU-accelerated constant temperature simulation of a very simple system with
! just nonbonded forces, consisting of several sodium (Na+) and chloride (Cl-)
! ions in implicit solvent. 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.
!
! Pay particular attention to the handling of units in this example. Incorrect
! handling of units is a very common error; this example shows how you can
! continue to work with Amber-style units like Angstroms, kCals, and van der
! Waals radii while correctly communicating with OpenMM in nm, kJ, and sigma.
!
! This example is written entirely in Fortran 95, using the OpenMM Fortran
! interface module.
! ------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
! ATOM, FORCE FIELD, AND SIMULATION PARAMETERS
!-------------------------------------------------------------------------------
! We'll define this module as a simplified example of the kinds of data
! structures that may already be in an MD program that is to be converted
! to use OpenMM. Note that we're using data in Angstrom and kcal units; we'll
! show how to safely convert to and from OpenMM's internal units as we go.
MODULE MyAtomInfo
! Simulation parameters
! ---------------------
real*8 Temperature, FrictionInPerPs, SolventDielectric, SoluteDielectric
parameter(Temperature = 300) !Kelvins
parameter(FrictionInPerPs = 91) !collisions per picosecond
parameter(SolventDielectric = 80) !typical for water
parameter(SoluteDielectric = 2) !typical for protein
real*8 StepSizeInFs, ReportIntervalInFs, SimulationTimeInPs
parameter(StepSizeInFs = 2) !integration step size (fs)
parameter(ReportIntervalInFs = 50) !how often for PDB frame (fs)
parameter(SimulationTimeInPs = 100) !total simulation time (ps)
! Currently energy calculation is not available in the GPU kernels so
! asking for it requires slow Reference Platform computation at
! reporting intervals. If you have a big system you'll want this off.
logical, parameter :: WantEnergy = .true.
! Atom and force field information
! --------------------------------
type Atom
character*4 pdb
real*8 mass, charge, vdwRadiusInAng, vdwEnergyInKcal
real*8 gbsaRadiusInAng, gbsaScaleFactor
real*8 initPosInAng(3)
real*8 posInAng(3) ! leave room for runtime state info
end type
integer, parameter :: NumAtoms = 6
type (Atom) :: atoms(NumAtoms) = (/ &
! pdb mass charge vdwRad vdwEnergy gbRad gbScale initPos runtime
Atom(' NA ',22.99, 1, 1.8680, 0.00277, 1.992, 0.8, (/ 8, 0, 0/), (/0,0,0/)),&
Atom(' CL ',35.45, -1, 2.4700, 0.1000, 1.735, 0.8, (/-8, 0, 0/), (/0,0,0/)),&
Atom(' NA ',22.99, 1, 1.8680, 0.00277, 1.992, 0.8, (/ 0, 9, 0/), (/0,0,0/)),&
Atom(' CL ',35.45, -1, 2.4700, 0.1000, 1.735, 0.8, (/ 0,-9, 0/), (/0,0,0/)),&
Atom(' NA ',22.99, 1, 1.8680, 0.00277, 1.992, 0.8, (/ 0, 0,-10/), (/0,0,0/)),&
Atom(' CL ',35.45, -1, 2.4700, 0.1000, 1.735, 0.8, (/ 0, 0, 10/), (/0,0,0/)) &
/)
END MODULE
!-------------------------------------------------------------------------------
! MAIN PROGRAM
!-------------------------------------------------------------------------------
! This makes use of four subroutines that encapsulate all the OpenMM calls:
! myInitializeOpenMM
! myStepWithOpenMM
! myGetOpenMMState
! myTerminateOpenMM
! and one minimalist PDB file writer that has nothing to do with OpenMM:
! myWritePDBFrame
! All of these subroutines can be found later in this file. For use in a real
! MD code you would need to write your own interface routines along these lines.
! Note that the main program does NOT include the OpenMM module.
PROGRAM HelloSodiumChloride
use MyAtomInfo
! Calculate the number of PDB frames we want to write out and how
! many steps to take on the GPU in between.
integer NumReports, NumSilentSteps
parameter(NumReports = (SimulationTimeInPs*1000 / ReportIntervalInFs + 0.5))
parameter(NumSilentSteps = (ReportIntervalInFs / StepSizeInFs + 0.5))
character*10 platformName; real*8 timeInPs, energyInKcal; integer frame
! This is an opaque handle to a container that holds the OpenMM runtime
! objects. You can use any type for this purpose as long as it is
! big enough to hold a pointer. (If you use a pointer type you'll have
! to declare the subroutine interfaces before calling them.)
integer*8 ommHandle
! Set up OpenMM data structures; returns platform name and handle.
call myInitializeOpenMM(ommHandle, platformName)
! Run the simulation:
! (1) Write the first line of the PDB file and the initial configuration.
! (2) Run silently entirely within OpenMM between reporting intervals.
! (3) Write a PDB frame when the time comes.
print "('REMARK Using OpenMM platform ', A)", platformName
call myGetOpenMMState(ommHandle, timeInPs, energyInKcal)
call myWritePDBFrame(0, timeInPs, energyInKcal)
do frame = 1, NumReports
call myStepWithOpenMM(ommHandle, NumSilentSteps)
call myGetOpenMMState(ommHandle, timeInPs, energyInKcal)
call myWritePDBFrame(frame, timeInPs, energyInKcal)
end do
! Clean up OpenMM data structures.
call myTerminateOpenMM(ommHandle)
END PROGRAM
!-------------------------------------------------------------------------------
! PDB FILE WRITER
!-------------------------------------------------------------------------------
! Given state data which was written into the atoms array of the MyAtomInfo
! module, output a single frame (pdb "model") of the trajectory. This has
! nothing to do with OpenMM.
SUBROUTINE myWritePDBFrame(frameNum, timeInPs, energyInKcal)
use MyAtomInfo; implicit none
integer frameNum; real*8 timeInPs, energyInKcal
integer n
print "('MODEL',5X,I0)", frameNum
print "('REMARK 250 time=', F0.3, ' picoseconds; Energy=', F0.3, ' kcal/mole')", &
timeInPs, energyInKcal
do n = 1,NumAtoms
print "('ATOM ', I5, ' ', A4, ' SLT 1 ', 3F8.3, ' 1.00 0.00')", &
n, atoms(n)%pdb, atoms(n)%posInAng
end do
print "('ENDMDL')"
END SUBROUTINE
!-------------------------------------------------------------------------------
! OpenMM-USING CODE
!-------------------------------------------------------------------------------
! The OpenMM Fortran interface module is included only at this point and below.
! Normally these subroutines would be in a separate compilation module; we're
! including them here for simplicity. We suggest that you write them in C++
! if possible, using extern "C" functions to make then callable from your
! Fortran main program. (See the C++ version of this example program for
! an implementation of very similar routines.) However, these routines are
! reimplemented entirely in Fortran 95 below in case you prefer.
! ------------------------------------------------------------------------------
! INITIALIZE OpenMM DATA STRUCTURES
! ------------------------------------------------------------------------------
! We take these actions here:
! (1) Load any available OpenMM plugins, e.g. Cuda and Brook.
! (2) Fill the OpenMM::System with the force field parameters we want to
! use and the particular set of atoms to be simulated.
! (3) Create an Integrator and a Context associating the Integrator with
! the System.
! (4) Select the OpenMM platform to be used.
! (5) Return an opaque handle to the Context object and the name of the
! Platform in use.
!
! Note that this routine must understand the calling MD code's molecule and
! force field data structures so will need to be customized for each MD code.
SUBROUTINE myInitializeOpenMM(ommHandle, platformName)
use OpenMM; use MyAtomInfo; implicit none
integer*8, intent(out) :: ommHandle
character*10, intent(out) :: platformName
! These are the objects we'll create here thare are stored in the
! Context for later access. Don't forget to delete them at the end.
type (OpenMM_System) system
type (OpenMM_LangevinIntegrator) langevin
type (OpenMM_Context) context
! These are temporary OpenMM objects used and discarded here.
type (OpenMM_StringArray) pluginList
type (OpenMM_Vec3Array) initialPosInNm
type (OpenMM_NonbondedForce) nonbond
type (OpenMM_GBSAOBCForce) gbsa
type (OpenMM_Platform) platform
character*100 dirName
integer*4 n, ix
real*8 posInNm(3)
! Get the name of the default plugins directory,
! and then load all the plugins found there.
call OpenMM_Platform_getDefaultPluginsDirectory(dirName)
call OpenMM_Platform_loadPluginsFromDirectory(dirName, pluginList)
call OpenMM_StringArray_destroy(pluginList)
! Create a System and Force objects for it. The System will take
! over ownership of the Forces; don't destroy them yourself.
call OpenMM_System_create(system)
call OpenMM_NonbondedForce_create(nonbond)
call OpenMM_GBSAOBCForce_create(gbsa)
! Convert specific force types to generic OpenMM_Force so that we can
! add them to the OpenMM_System.
ix = OpenMM_System_addForce(system, transfer(nonbond, OpenMM_Force(0)))
ix = OpenMM_System_addForce(system, transfer(gbsa, OpenMM_Force(0)))
! Specify dielectrics for GBSA implicit solvation.
call OpenMM_GBSAOBCForce_setSolventDielectric(gbsa, SolventDielectric)
call OpenMM_GBSAOBCForce_setSoluteDielectric(gbsa, SoluteDielectric)
! Specify the atoms and their properties:
! (1) System needs to know the masses.
! (2) NonbondedForce needs charges,van der Waals properties (in MD units!).
! (3) GBSA needs charge, radius, and scale factor.
! (4) Collect default positions for initializing the simulation later.
call OpenMM_Vec3Array_create(initialPosInNm, NumAtoms)
do n=1,NumAtoms
ix = OpenMM_System_addParticle(system, atoms(n)%mass)
ix = OpenMM_NonbondedForce_addParticle(nonbond, &
atoms(n)%charge, &
atoms(n)%vdwRadiusInAng * OpenMM_NmPerAngstrom &
* OpenMM_SigmaPerVdwRadius, &
atoms(n)%vdwEnergyInKcal * OpenMM_KJPerKcal)
ix = OpenMM_GBSAOBCForce_addParticle(gbsa, &
atoms(n)%charge, &
atoms(n)%gbsaRadiusInAng * OpenMM_NmPerAngstrom, &
atoms(n)%gbsaScaleFactor)
! Sets initPos(n) = atoms(n)%initPos * nm/Angstrom.
call OpenMM_Vec3_scale(atoms(n)%initPosInAng, &
OpenMM_NmPerAngstrom, posInNm)
call OpenMM_Vec3Array_set(initialPosInNm, n, posInNm)
end do
! Choose an Integrator for advancing time, and a Context connecting the
! System with the Integrator for simulation. Let the Context choose the
! best available Platform. Initialize the configuration from the default
! positions we collected above. Initial velocities will be zero but could
! have been set here.
call OpenMM_LangevinIntegrator_create(langevin, &
Temperature, FrictionInPerPs, &
StepSizeInFs * OpenMM_PsPerFs)
! Convert LangevinIntegrator to generic Integrator type for this call.
call OpenMM_Context_create(context, system, &
transfer(langevin, OpenMM_Integrator(0)))
call OpenMM_Context_setPositions(context, initialPosInNm)
! Get the platform name to return.
call OpenMM_Context_getPlatform(context, platform)
call OpenMM_Platform_getName(platform, platformName)
! References to the System and Integrator are in the Context, so
! we can extract them later for stepping and cleanup. Return an opaque
! reference to the Context for use by the main program.
ommHandle = transfer(context, ommHandle)
END SUBROUTINE
!-------------------------------------------------------------------------------
! COPY STATE BACK TO CPU FROM OpenMM
!-------------------------------------------------------------------------------
SUBROUTINE myGetOpenMMState(ommHandle, timeInPs, energyInKcal)
use OpenMM; use MyAtomInfo; implicit none
integer*8, intent(in) :: ommHandle
real*8, intent(out) :: timeInPs, energyInKcal
type (OpenMM_State) state
type (OpenMM_Vec3Array) posArrayInNm
integer infoMask, n
real*8 posInNm(3)
type (OpenMM_Context) context
context = transfer(ommHandle, context)
infoMask = OpenMM_State_Positions
if (WantEnergy) then
infoMask = infoMask + OpenMM_State_Velocities ! for KE (cheap)
infoMask = infoMask + OpenMM_State_Energy ! for PE (very expensive)
end if
! Forces are also available (and cheap).
! Don't forget to destroy this State when you're done with it.
call OpenMM_Context_getState(context, infoMask, state)
timeInPs = OpenMM_State_getTime(state) ! OpenMM time is in ps already.
! Positions are maintained as a Vec3Array inside the State. This will give
! us access, but don't destroy it yourself -- it will go away with the State.
call OpenMM_State_getPositions(state, posArrayInNm)
do n = 1, NumAtoms
! Sets atoms(n)%pos = posArray(n) * Angstroms/nm.
call OpenMM_Vec3Array_get(posArrayInNm, n, posInNm)
call OpenMM_Vec3_scale(posInNm, OpenMM_AngstromsPerNm, &
atoms(n)%posInAng)
end do
energyInKcal = 0
if (WantEnergy) then
energyInKcal = ( OpenMM_State_getPotentialEnergy(state) &
+ OpenMM_State_getKineticEnergy(state)) &
* OpenMM_KcalPerKJ
end if
! Clean up the State memory
call OpenMM_State_destroy(state)
END SUBROUTINE
!-------------------------------------------------------------------------------
! TAKE MULTIPLE STEPS USING OpenMM
!-------------------------------------------------------------------------------
SUBROUTINE myStepWithOpenMM(ommHandle, numSteps)
use OpenMM; implicit none
integer*8, intent(in) :: ommHandle
integer, intent(in) :: numSteps
type (OpenMM_Context) context
type (OpenMM_Integrator) integrator
context = transfer(ommHandle, context)
call OpenMM_Context_getIntegrator(context, integrator)
call OpenMM_Integrator_step(integrator, numSteps)
END SUBROUTINE
!-------------------------------------------------------------------------------
! DEALLOCATE ALL OpenMM OBJECTS
!-------------------------------------------------------------------------------
SUBROUTINE myTerminateOpenMM(ommHandle)
use OpenMM; implicit none
integer*8, intent(inout) :: ommHandle
type (OpenMM_Context) context
type (OpenMM_Integrator) integrator
type (OpenMM_System) system
context = transfer(ommHandle, context)
call OpenMM_Context_getIntegrator(context, integrator)
call OpenMM_Context_getSystem(context, system)
call OpenMM_Context_destroy(context)
call OpenMM_Integrator_destroy(integrator)
call OpenMM_System_destroy(system)
END SUBROUTINE
! -----------------------------------------------------------------------------
! OpenMM(tm) HelloSodiumChloride example in Fortran 95 (June 2009)
! ------------------------------------------------------------------------------
! This is a complete, self-contained "hello world" example demonstrating
! GPU-accelerated constant temperature simulation of a very simple system with
! just nonbonded forces, consisting of several sodium (Na+) and chloride (Cl-)
! ions in implicit solvent. 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.
!
! Pay particular attention to the handling of units in this example. Incorrect
! handling of units is a very common error; this example shows how you can
! continue to work with Amber-style units like Angstroms, kCals, and van der
! Waals radii while correctly communicating with OpenMM in nm, kJ, and sigma.
!
! This example is written entirely in Fortran 95, using the OpenMM Fortran
! interface module.
! ------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
! ATOM, FORCE FIELD, AND SIMULATION PARAMETERS
!-------------------------------------------------------------------------------
! We'll define this module as a simplified example of the kinds of data
! structures that may already be in an MD program that is to be converted
! to use OpenMM. Note that we're using data in Angstrom and kcal units; we'll
! show how to safely convert to and from OpenMM's internal units as we go.
MODULE MyAtomInfo
! Simulation parameters
! ---------------------
real*8 Temperature, FrictionInPerPs, SolventDielectric, SoluteDielectric
parameter(Temperature = 300) !Kelvins
parameter(FrictionInPerPs = 91) !collisions per picosecond
parameter(SolventDielectric = 80) !typical for water
parameter(SoluteDielectric = 2) !typical for protein
real*8 StepSizeInFs, ReportIntervalInFs, SimulationTimeInPs
parameter(StepSizeInFs = 2) !integration step size (fs)
parameter(ReportIntervalInFs = 50) !how often for PDB frame (fs)
parameter(SimulationTimeInPs = 100) !total simulation time (ps)
! Currently energy calculation is not available in the GPU kernels so
! asking for it requires slow Reference Platform computation at
! reporting intervals. If you have a big system you'll want this off.
logical, parameter :: WantEnergy = .true.
! Atom and force field information
! --------------------------------
type Atom
character*4 pdb
real*8 mass, charge, vdwRadiusInAng, vdwEnergyInKcal
real*8 gbsaRadiusInAng, gbsaScaleFactor
real*8 initPosInAng(3)
real*8 posInAng(3) ! leave room for runtime state info
end type
integer, parameter :: NumAtoms = 6
type (Atom) :: atoms(NumAtoms) = (/ &
! pdb mass charge vdwRad vdwEnergy gbRad gbScale initPos runtime
Atom(' NA ',22.99, 1, 1.8680, 0.00277, 1.992, 0.8, (/ 8, 0, 0/), (/0,0,0/)),&
Atom(' CL ',35.45, -1, 2.4700, 0.1000, 1.735, 0.8, (/-8, 0, 0/), (/0,0,0/)),&
Atom(' NA ',22.99, 1, 1.8680, 0.00277, 1.992, 0.8, (/ 0, 9, 0/), (/0,0,0/)),&
Atom(' CL ',35.45, -1, 2.4700, 0.1000, 1.735, 0.8, (/ 0,-9, 0/), (/0,0,0/)),&
Atom(' NA ',22.99, 1, 1.8680, 0.00277, 1.992, 0.8, (/ 0, 0,-10/), (/0,0,0/)),&
Atom(' CL ',35.45, -1, 2.4700, 0.1000, 1.735, 0.8, (/ 0, 0, 10/), (/0,0,0/)) &
/)
END MODULE
!-------------------------------------------------------------------------------
! MAIN PROGRAM
!-------------------------------------------------------------------------------
! This makes use of four subroutines that encapsulate all the OpenMM calls:
! myInitializeOpenMM
! myStepWithOpenMM
! myGetOpenMMState
! myTerminateOpenMM
! and one minimalist PDB file writer that has nothing to do with OpenMM:
! myWritePDBFrame
! All of these subroutines can be found later in this file. For use in a real
! MD code you would need to write your own interface routines along these lines.
! Note that the main program does NOT include the OpenMM module.
PROGRAM HelloSodiumChloride
use MyAtomInfo
! Calculate the number of PDB frames we want to write out and how
! many steps to take on the GPU in between.
integer NumReports, NumSilentSteps
parameter(NumReports = (SimulationTimeInPs*1000 / ReportIntervalInFs + 0.5))
parameter(NumSilentSteps = (ReportIntervalInFs / StepSizeInFs + 0.5))
character*10 platformName; real*8 timeInPs, energyInKcal; integer frame
! This is an opaque handle to a container that holds the OpenMM runtime
! objects. You can use any type for this purpose as long as it is
! big enough to hold a pointer. (If you use a pointer type you'll have
! to declare the subroutine interfaces before calling them.)
integer*8 ommHandle
! Set up OpenMM data structures; returns platform name and handle.
call myInitializeOpenMM(ommHandle, platformName)
! Run the simulation:
! (1) Write the first line of the PDB file and the initial configuration.
! (2) Run silently entirely within OpenMM between reporting intervals.
! (3) Write a PDB frame when the time comes.
print "('REMARK Using OpenMM platform ', A)", platformName
call myGetOpenMMState(ommHandle, timeInPs, energyInKcal)
call myWritePDBFrame(0, timeInPs, energyInKcal)
do frame = 1, NumReports
call myStepWithOpenMM(ommHandle, NumSilentSteps)
call myGetOpenMMState(ommHandle, timeInPs, energyInKcal)
call myWritePDBFrame(frame, timeInPs, energyInKcal)
end do
! Clean up OpenMM data structures.
call myTerminateOpenMM(ommHandle)
END PROGRAM
!-------------------------------------------------------------------------------
! PDB FILE WRITER
!-------------------------------------------------------------------------------
! Given state data which was written into the atoms array of the MyAtomInfo
! module, output a single frame (pdb "model") of the trajectory. This has
! nothing to do with OpenMM.
SUBROUTINE myWritePDBFrame(frameNum, timeInPs, energyInKcal)
use MyAtomInfo; implicit none
integer frameNum; real*8 timeInPs, energyInKcal
integer n
print "('MODEL',5X,I0)", frameNum
print "('REMARK 250 time=', F0.3, ' picoseconds; Energy=', F0.3, ' kcal/mole')", &
timeInPs, energyInKcal
do n = 1,NumAtoms
print "('ATOM ', I5, ' ', A4, ' SLT 1 ', 3F8.3, ' 1.00 0.00')", &
n, atoms(n)%pdb, atoms(n)%posInAng
end do
print "('ENDMDL')"
END SUBROUTINE
!-------------------------------------------------------------------------------
! OpenMM-USING CODE
!-------------------------------------------------------------------------------
! The OpenMM Fortran interface module is included only at this point and below.
! Normally these subroutines would be in a separate compilation module; we're
! including them here for simplicity. We suggest that you write them in C++
! if possible, using extern "C" functions to make then callable from your
! Fortran main program. (See the C++ version of this example program for
! an implementation of very similar routines.) However, these routines are
! reimplemented entirely in Fortran 95 below in case you prefer.
! ------------------------------------------------------------------------------
! INITIALIZE OpenMM DATA STRUCTURES
! ------------------------------------------------------------------------------
! We take these actions here:
! (1) Load any available OpenMM plugins, e.g. Cuda and Brook.
! (2) Fill the OpenMM::System with the force field parameters we want to
! use and the particular set of atoms to be simulated.
! (3) Create an Integrator and a Context associating the Integrator with
! the System.
! (4) Select the OpenMM platform to be used.
! (5) Return an opaque handle to the Context object and the name of the
! Platform in use.
!
! Note that this routine must understand the calling MD code's molecule and
! force field data structures so will need to be customized for each MD code.
SUBROUTINE myInitializeOpenMM(ommHandle, platformName)
use OpenMM; use MyAtomInfo; implicit none
integer*8, intent(out) :: ommHandle
character*10, intent(out) :: platformName
! These are the objects we'll create here thare are stored in the
! Context for later access. Don't forget to delete them at the end.
type (OpenMM_System) system
type (OpenMM_LangevinIntegrator) langevin
type (OpenMM_Context) context
! These are temporary OpenMM objects used and discarded here.
type (OpenMM_StringArray) pluginList
type (OpenMM_Vec3Array) initialPosInNm
type (OpenMM_NonbondedForce) nonbond
type (OpenMM_GBSAOBCForce) gbsa
type (OpenMM_Platform) platform
character*100 dirName
integer*4 n, ix
real*8 posInNm(3)
! Get the name of the default plugins directory,
! and then load all the plugins found there.
call OpenMM_Platform_getDefaultPluginsDirectory(dirName)
call OpenMM_Platform_loadPluginsFromDirectory(dirName, pluginList)
call OpenMM_StringArray_destroy(pluginList)
! Create a System and Force objects for it. The System will take
! over ownership of the Forces; don't destroy them yourself.
call OpenMM_System_create(system)
call OpenMM_NonbondedForce_create(nonbond)
call OpenMM_GBSAOBCForce_create(gbsa)
! Convert specific force types to generic OpenMM_Force so that we can
! add them to the OpenMM_System.
ix = OpenMM_System_addForce(system, transfer(nonbond, OpenMM_Force(0)))
ix = OpenMM_System_addForce(system, transfer(gbsa, OpenMM_Force(0)))
! Specify dielectrics for GBSA implicit solvation.
call OpenMM_GBSAOBCForce_setSolventDielectric(gbsa, SolventDielectric)
call OpenMM_GBSAOBCForce_setSoluteDielectric(gbsa, SoluteDielectric)
! Specify the atoms and their properties:
! (1) System needs to know the masses.
! (2) NonbondedForce needs charges,van der Waals properties (in MD units!).
! (3) GBSA needs charge, radius, and scale factor.
! (4) Collect default positions for initializing the simulation later.
call OpenMM_Vec3Array_create(initialPosInNm, NumAtoms)
do n=1,NumAtoms
ix = OpenMM_System_addParticle(system, atoms(n)%mass)
ix = OpenMM_NonbondedForce_addParticle(nonbond, &
atoms(n)%charge, &
atoms(n)%vdwRadiusInAng * OpenMM_NmPerAngstrom &
* OpenMM_SigmaPerVdwRadius, &
atoms(n)%vdwEnergyInKcal * OpenMM_KJPerKcal)
ix = OpenMM_GBSAOBCForce_addParticle(gbsa, &
atoms(n)%charge, &
atoms(n)%gbsaRadiusInAng * OpenMM_NmPerAngstrom, &
atoms(n)%gbsaScaleFactor)
! Sets initPos(n) = atoms(n)%initPos * nm/Angstrom.
call OpenMM_Vec3_scale(atoms(n)%initPosInAng, &
OpenMM_NmPerAngstrom, posInNm)
call OpenMM_Vec3Array_set(initialPosInNm, n, posInNm)
end do
! Choose an Integrator for advancing time, and a Context connecting the
! System with the Integrator for simulation. Let the Context choose the
! best available Platform. Initialize the configuration from the default
! positions we collected above. Initial velocities will be zero but could
! have been set here.
call OpenMM_LangevinIntegrator_create(langevin, &
Temperature, FrictionInPerPs, &
StepSizeInFs * OpenMM_PsPerFs)
! Convert LangevinIntegrator to generic Integrator type for this call.
call OpenMM_Context_create(context, system, &
transfer(langevin, OpenMM_Integrator(0)))
call OpenMM_Context_setPositions(context, initialPosInNm)
! Get the platform name to return.
call OpenMM_Context_getPlatform(context, platform)
call OpenMM_Platform_getName(platform, platformName)
! References to the System and Integrator are in the Context, so
! we can extract them later for stepping and cleanup. Return an opaque
! reference to the Context for use by the main program.
ommHandle = transfer(context, ommHandle)
END SUBROUTINE
!-------------------------------------------------------------------------------
! COPY STATE BACK TO CPU FROM OpenMM
!-------------------------------------------------------------------------------
SUBROUTINE myGetOpenMMState(ommHandle, timeInPs, energyInKcal)
use OpenMM; use MyAtomInfo; implicit none
integer*8, intent(in) :: ommHandle
real*8, intent(out) :: timeInPs, energyInKcal
type (OpenMM_State) state
type (OpenMM_Vec3Array) posArrayInNm
integer infoMask, n
real*8 posInNm(3)
type (OpenMM_Context) context
context = transfer(ommHandle, context)
infoMask = OpenMM_State_Positions
if (WantEnergy) then
infoMask = infoMask + OpenMM_State_Velocities ! for KE (cheap)
infoMask = infoMask + OpenMM_State_Energy ! for PE (very expensive)
end if
! Forces are also available (and cheap).
! Don't forget to destroy this State when you're done with it.
call OpenMM_Context_getState(context, infoMask, state, 0)
timeInPs = OpenMM_State_getTime(state) ! OpenMM time is in ps already.
! Positions are maintained as a Vec3Array inside the State. This will give
! us access, but don't destroy it yourself -- it will go away with the State.
call OpenMM_State_getPositions(state, posArrayInNm)
do n = 1, NumAtoms
! Sets atoms(n)%pos = posArray(n) * Angstroms/nm.
call OpenMM_Vec3Array_get(posArrayInNm, n, posInNm)
call OpenMM_Vec3_scale(posInNm, OpenMM_AngstromsPerNm, &
atoms(n)%posInAng)
end do
energyInKcal = 0
if (WantEnergy) then
energyInKcal = ( OpenMM_State_getPotentialEnergy(state) &
+ OpenMM_State_getKineticEnergy(state)) &
* OpenMM_KcalPerKJ
end if
! Clean up the State memory
call OpenMM_State_destroy(state)
END SUBROUTINE
!-------------------------------------------------------------------------------
! TAKE MULTIPLE STEPS USING OpenMM
!-------------------------------------------------------------------------------
SUBROUTINE myStepWithOpenMM(ommHandle, numSteps)
use OpenMM; implicit none
integer*8, intent(in) :: ommHandle
integer, intent(in) :: numSteps
type (OpenMM_Context) context
type (OpenMM_Integrator) integrator
context = transfer(ommHandle, context)
call OpenMM_Context_getIntegrator(context, integrator)
call OpenMM_Integrator_step(integrator, numSteps)
END SUBROUTINE
!-------------------------------------------------------------------------------
! DEALLOCATE ALL OpenMM OBJECTS
!-------------------------------------------------------------------------------
SUBROUTINE myTerminateOpenMM(ommHandle)
use OpenMM; implicit none
integer*8, intent(inout) :: ommHandle
type (OpenMM_Context) context
type (OpenMM_Integrator) integrator
type (OpenMM_System) system
context = transfer(ommHandle, context)
call OpenMM_Context_getIntegrator(context, integrator)
call OpenMM_Context_getSystem(context, system)
call OpenMM_Context_destroy(context)
call OpenMM_Integrator_destroy(integrator)
call OpenMM_System_destroy(system)
END SUBROUTINE
......@@ -356,7 +356,7 @@ myGetOpenMMState(MyOpenMMData* omm, double& timeInPs,
std::vector<double>& atomPositionsInAng)
{
// We don't calculate energy in this example because it would take most of the time
const OpenMM::State state = omm->context->getState(OpenMM::State::Positions);
const OpenMM::State state = omm->context->getState(OpenMM::State::Positions, true);
timeInPs = state.getTime(); // OpenMM time is in ps already
// Copy OpenMM positions into output array and change units from nm to Angstroms.
......
......@@ -68,202 +68,6 @@ static string makeString(const char* fsrc, int length) {
extern "C" {
/* OpenMM_Vec3 */
OPENMM_EXPORT void openmm_vec3_scale_(const OpenMM_Vec3&amp; vec, double const&amp; scale, OpenMM_Vec3&amp; result) {
result = OpenMM_Vec3_scale(vec, scale);
}
OPENMM_EXPORT void OPENMM_VEC3_SCALE(const OpenMM_Vec3&amp; vec, double const&amp; scale, OpenMM_Vec3&amp; result) {
result = OpenMM_Vec3_scale(vec, scale);
}
/* OpenMM_Vec3Array */
OPENMM_EXPORT void openmm_vec3array_create_(OpenMM_Vec3Array*&amp; result, const int&amp; size) {
result = OpenMM_Vec3Array_create(size);
}
OPENMM_EXPORT void OPENMM_VEC3ARRAY_CREATE(OpenMM_Vec3Array*&amp; result, const int&amp; size) {
result = OpenMM_Vec3Array_create(size);
}
OPENMM_EXPORT void openmm_vec3array_destroy_(OpenMM_Vec3Array*&amp; array) {
OpenMM_Vec3Array_destroy(array);
array = 0;
}
OPENMM_EXPORT void OPENMM_VEC3ARRAY_DESTROY(OpenMM_Vec3Array*&amp; array) {
OpenMM_Vec3Array_destroy(array);
array = 0;
}
OPENMM_EXPORT int openmm_vec3array_getsize_(const OpenMM_Vec3Array* const&amp; array) {
return OpenMM_Vec3Array_getSize(array);
}
OPENMM_EXPORT int OPENMM_VEC3ARRAY_GETSIZE(const OpenMM_Vec3Array* const&amp; array) {
return OpenMM_Vec3Array_getSize(array);
}
OPENMM_EXPORT void openmm_vec3array_resize_(OpenMM_Vec3Array* const&amp; array, const int&amp; size) {
OpenMM_Vec3Array_resize(array, size);
}
OPENMM_EXPORT void OPENMM_VEC3ARRAY_RESIZE(OpenMM_Vec3Array* const&amp; array, const int&amp; size) {
OpenMM_Vec3Array_resize(array, size);
}
OPENMM_EXPORT void openmm_vec3array_append_(OpenMM_Vec3Array* const&amp; array, const OpenMM_Vec3&amp; vec) {
OpenMM_Vec3Array_append(array, vec);
}
OPENMM_EXPORT void OPENMM_VEC3ARRAY_APPEND(OpenMM_Vec3Array* const&amp; array, const OpenMM_Vec3&amp; vec) {
OpenMM_Vec3Array_append(array, vec);
}
OPENMM_EXPORT void openmm_vec3array_set_(OpenMM_Vec3Array* const&amp; array, const int&amp; index, const OpenMM_Vec3&amp; vec) {
OpenMM_Vec3Array_set(array, index-1, vec);
}
OPENMM_EXPORT void OPENMM_VEC3ARRAY_SET(OpenMM_Vec3Array* const&amp; array, const int&amp; index, const OpenMM_Vec3&amp; vec) {
OpenMM_Vec3Array_set(array, index-1, vec);
}
OPENMM_EXPORT void openmm_vec3array_get_(const OpenMM_Vec3Array* const&amp; array, const int&amp; index, OpenMM_Vec3&amp; result) {
result = *OpenMM_Vec3Array_get(array, index-1);
}
OPENMM_EXPORT void OPENMM_VEC3ARRAY_GET(const OpenMM_Vec3Array* const&amp; array, const int&amp; index, OpenMM_Vec3&amp; result) {
result = *OpenMM_Vec3Array_get(array, index-1);
}
/* OpenMM_StringArray */
OPENMM_EXPORT void openmm_stringarray_create_(OpenMM_StringArray*&amp; result, const int&amp; size) {
result = OpenMM_StringArray_create(size);
}
OPENMM_EXPORT void OPENMM_STRINGARRAY_CREATE(OpenMM_StringArray*&amp; result, const int&amp; size) {
result = OpenMM_StringArray_create(size);
}
OPENMM_EXPORT void openmm_stringarray_destroy_(OpenMM_StringArray*&amp; array) {
OpenMM_StringArray_destroy(array);
array = 0;
}
OPENMM_EXPORT void OPENMM_STRINGARRAY_DESTROY(OpenMM_StringArray*&amp; array) {
OpenMM_StringArray_destroy(array);
array = 0;
}
OPENMM_EXPORT int openmm_stringarray_getsize_(const OpenMM_StringArray* const&amp; array) {
return OpenMM_StringArray_getSize(array);
}
OPENMM_EXPORT int OPENMM_STRINGARRAY_GETSIZE(const OpenMM_StringArray* const&amp; array) {
return OpenMM_StringArray_getSize(array);
}
OPENMM_EXPORT void openmm_stringarray_resize_(OpenMM_StringArray* const&amp; array, const int&amp; size) {
OpenMM_StringArray_resize(array, size);
}
OPENMM_EXPORT void OPENMM_STRINGARRAY_RESIZE(OpenMM_StringArray* const&amp; array, const int&amp; size) {
OpenMM_StringArray_resize(array, size);
}
OPENMM_EXPORT void openmm_stringarray_append_(OpenMM_StringArray* const&amp; array, const char* str, int length) {
OpenMM_StringArray_append(array, makeString(str, length).c_str());
}
OPENMM_EXPORT void OPENMM_STRINGARRAY_APPEND(OpenMM_StringArray* const&amp; array, const char* str, int length) {
OpenMM_StringArray_append(array, makeString(str, length).c_str());
}
OPENMM_EXPORT void openmm_stringarray_set_(OpenMM_StringArray* const&amp; array, const int&amp; index, const char* str, int length) {
OpenMM_StringArray_set(array, index-1, makeString(str, length).c_str());
}
OPENMM_EXPORT void OPENMM_STRINGARRAY_SET(OpenMM_StringArray* const&amp; array, const int&amp; index, const char* str, int length) {
OpenMM_StringArray_set(array, index-1, makeString(str, length).c_str());
}
OPENMM_EXPORT void openmm_stringarray_get_(const OpenMM_StringArray* const&amp; array, const int&amp; index, char* result, int length) {
const char* str = OpenMM_StringArray_get(array, index-1);
copyAndPadString(result, str, length);
}
OPENMM_EXPORT void OPENMM_STRINGARRAY_GET(const OpenMM_StringArray* const&amp; array, const int&amp; index, char* result, int length) {
const char* str = OpenMM_StringArray_get(array, index-1);
copyAndPadString(result, str, length);
}
/* OpenMM_BondArray */
OPENMM_EXPORT void openmm_bondarray_create_(OpenMM_BondArray*&amp; result, const int&amp; size) {
result = OpenMM_BondArray_create(size);
}
OPENMM_EXPORT void OPENMM_BONDARRAY_CREATE(OpenMM_BondArray*&amp; result, const int&amp; size) {
result = OpenMM_BondArray_create(size);
}
OPENMM_EXPORT void openmm_bondarray_destroy_(OpenMM_BondArray*&amp; array) {
OpenMM_BondArray_destroy(array);
array = 0;
}
OPENMM_EXPORT void OPENMM_BONDARRAY_DESTROY(OpenMM_BondArray*&amp; array) {
OpenMM_BondArray_destroy(array);
array = 0;
}
OPENMM_EXPORT int openmm_bondarray_getsize_(const OpenMM_BondArray* const&amp; array) {
return OpenMM_BondArray_getSize(array);
}
OPENMM_EXPORT int OPENMM_BONDARRAY_GETSIZE(const OpenMM_BondArray* const&amp; array) {
return OpenMM_BondArray_getSize(array);
}
OPENMM_EXPORT void openmm_bondarray_resize_(OpenMM_BondArray* const&amp; array, const int&amp; size) {
OpenMM_BondArray_resize(array, size);
}
OPENMM_EXPORT void OPENMM_BONDARRAY_RESIZE(OpenMM_BondArray* const&amp; array, const int&amp; size) {
OpenMM_BondArray_resize(array, size);
}
OPENMM_EXPORT void openmm_bondarray_append_(OpenMM_BondArray* const&amp; array, const int&amp; particle1, const int&amp; particle2) {
OpenMM_BondArray_append(array, particle1, particle2);
}
OPENMM_EXPORT void OPENMM_BONDARRAY_APPEND(OpenMM_BondArray* const&amp; array, const int&amp; particle1, const int&amp; particle2) {
OpenMM_BondArray_append(array, particle1, particle2);
}
OPENMM_EXPORT void openmm_bondarray_set_(OpenMM_BondArray* const&amp; array, const int&amp; index, const int&amp; particle1, const int&amp; particle2) {
OpenMM_BondArray_set(array, index-1, particle1, particle2);
}
OPENMM_EXPORT void OPENMM_BONDARRAY_SET(OpenMM_BondArray* const&amp; array, const int&amp; index, const int&amp; particle1, const int&amp; particle2) {
OpenMM_BondArray_set(array, index-1, particle1, particle2);
}
OPENMM_EXPORT void openmm_bondarray_get_(const OpenMM_BondArray* const&amp; array, const int&amp; index, int* particle1, int* particle2) {
OpenMM_BondArray_get(array, index-1, particle1, particle2);
}
OPENMM_EXPORT void OPENMM_BONDARRAY_GET(const OpenMM_BondArray* const&amp; array, const int&amp; index, int* particle1, int* particle2) {
OpenMM_BondArray_get(array, index-1, particle1, particle2);
}
/* OpenMM_ParameterArray */
OPENMM_EXPORT int openmm_parameterarray_getsize_(const OpenMM_ParameterArray* const&amp; array) {
return OpenMM_ParameterArray_getSize(array);
}
OPENMM_EXPORT int OPENMM_PARAMETERARRAY_GETSIZE(const OpenMM_ParameterArray* const&amp; array) {
return OpenMM_ParameterArray_getSize(array);
}
OPENMM_EXPORT double openmm_parameterarray_get_(const OpenMM_ParameterArray* const&amp; array, const char* name, int length) {
return OpenMM_ParameterArray_get(array, makeString(name, length).c_str());
}
OPENMM_EXPORT double OPENMM_PARAMETERARRAY_GET(const OpenMM_ParameterArray* const&amp; array, const char* name, int length) {
return OpenMM_ParameterArray_get(array, makeString(name, length).c_str());
}
/* OpenMM_PropertyArray */
OPENMM_EXPORT int openmm_propertyarray_getsize_(const OpenMM_PropertyArray* const&amp; array) {
return OpenMM_PropertyArray_getSize(array);
}
OPENMM_EXPORT int OPENMM_PROPERTYARRAY_GETSIZE(const OpenMM_PropertyArray* const&amp; array) {
return OpenMM_PropertyArray_getSize(array);
}
OPENMM_EXPORT const char* openmm_propertyarray_get_(const OpenMM_PropertyArray* const&amp; array, const char* name, int length) {
return OpenMM_PropertyArray_get(array, makeString(name, length).c_str());
}
OPENMM_EXPORT const char* OPENMM_PROPERTYARRAY_GET(const OpenMM_PropertyArray* const&amp; array, const char* name, int length) {
return OpenMM_PropertyArray_get(array, makeString(name, length).c_str());
}
<xsl:call-template name="primitive_array">
<xsl:with-param name="element_type" select="'int'"/>
<xsl:with-param name="name" select="'OpenMM_IntArray'"/>
</xsl:call-template>
/* These methods need to be handled specially, since their C++ APIs cannot be directly translated to C.
Unlike the C++ versions, the return value is allocated on the heap, and you must delete it yourself. */
OPENMM_EXPORT void openmm_context_getstate_(const OpenMM_Context*&amp; target, int const&amp; types, OpenMM_State*&amp; result) {
result = OpenMM_Context_getState(target, types);
};
OPENMM_EXPORT void OPENMM_CONTEXT_GETSTATE(const OpenMM_Context*&amp; target, int const&amp; types, OpenMM_State*&amp; result) {
result = OpenMM_Context_getState(target, types);
};
OPENMM_EXPORT void openmm_platform_loadpluginsfromdirectory_(const char* directory, OpenMM_StringArray*&amp; result, int length) {
result = OpenMM_Platform_loadPluginsFromDirectory(makeString(directory, length).c_str());
};
OPENMM_EXPORT void OPENMM_PLATFORM_LOADPLUGINSFROMDIRECTORY(const char* directory, OpenMM_StringArray*&amp; result, int length) {
result = OpenMM_Platform_loadPluginsFromDirectory(makeString(directory, length).c_str());
};
<!-- Class members -->
<xsl:for-each select="Class[@context=$openmm_namespace_id and empty(index-of($skip_classes, @name))]">
<xsl:call-template name="class"/>
......
......@@ -100,7 +100,7 @@ extern OPENMM_EXPORT const char* OpenMM_PropertyArray_get(const OpenMM_PropertyA
/* These methods need to be handled specially, since their C++ APIs cannot be directly translated to C.
Unlike the C++ versions, the return value is allocated on the heap, and you must delete it yourself. */
extern OPENMM_EXPORT OpenMM_State* OpenMM_Context_getState(const OpenMM_Context* target, int types);
extern OPENMM_EXPORT OpenMM_State* OpenMM_Context_getState(const OpenMM_Context* target, int types, int enforcePeriodicBox);
extern OPENMM_EXPORT OpenMM_StringArray* OpenMM_Platform_loadPluginsFromDirectory(const char* directory);
<!-- Class members -->
......
......@@ -150,8 +150,8 @@ OPENMM_EXPORT const char* OpenMM_PropertyArray_get(const OpenMM_PropertyArray* a
/* These methods need to be handled specially, since their C++ APIs cannot be directly translated to C.
Unlike the C++ versions, the return value is allocated on the heap, and you must delete it yourself. */
OPENMM_EXPORT OpenMM_State* OpenMM_Context_getState(const OpenMM_Context* target, int types) {
State result = reinterpret_cast&lt;const Context*&gt;(target)->getState(types);
OPENMM_EXPORT OpenMM_State* OpenMM_Context_getState(const OpenMM_Context* target, int types, int enforcePeriodicBox) {
State result = reinterpret_cast&lt;const Context*&gt;(target)->getState(types, enforcePeriodicBox);
return reinterpret_cast&lt;OpenMM_State*&gt;(new State(result));
};
OPENMM_EXPORT OpenMM_StringArray* OpenMM_Platform_loadPluginsFromDirectory(const char* directory) {
......
......@@ -245,11 +245,11 @@ OPENMM_EXPORT const char* OPENMM_PROPERTYARRAY_GET(const OpenMM_PropertyArray* c
/* These methods need to be handled specially, since their C++ APIs cannot be directly translated to C.
Unlike the C++ versions, the return value is allocated on the heap, and you must delete it yourself. */
OPENMM_EXPORT void openmm_context_getstate_(const OpenMM_Context*&amp; target, int const&amp; types, OpenMM_State*&amp; result) {
result = OpenMM_Context_getState(target, types);
OPENMM_EXPORT void openmm_context_getstate_(const OpenMM_Context*&amp; target, int const&amp; types, int const&amp; enforcePeriodicBox, OpenMM_State*&amp; result) {
result = OpenMM_Context_getState(target, types, enforcePeriodicBox);
};
OPENMM_EXPORT void OPENMM_CONTEXT_GETSTATE(const OpenMM_Context*&amp; target, int const&amp; types, OpenMM_State*&amp; result) {
result = OpenMM_Context_getState(target, types);
OPENMM_EXPORT void OPENMM_CONTEXT_GETSTATE(const OpenMM_Context*&amp; target, int const&amp; types, int const&amp; enforcePeriodicBox, OpenMM_State*&amp; result) {
result = OpenMM_Context_getState(target, types, enforcePeriodicBox);
};
OPENMM_EXPORT void openmm_platform_loadpluginsfromdirectory_(const char* directory, OpenMM_StringArray*&amp; result, int length) {
result = OpenMM_Platform_loadPluginsFromDirectory(makeString(directory, length).c_str());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment