Commit 81d60b1e authored by Lee-Ping Wang's avatar Lee-Ping Wang
Browse files

Merge branch 'master' of github.com:SimTk/openmm

parents d58cc041 68632d78
......@@ -34,6 +34,9 @@
* This tests all the different force terms in the reference implementation of CustomNonbondedForce.
*/
#ifdef WIN32
#define _USE_MATH_DEFINES // Needed to get M_PI
#endif
#include "openmm/internal/AssertionUtilities.h"
#include "sfmt/SFMT.h"
#include "openmm/Context.h"
......@@ -42,7 +45,9 @@
#include "openmm/NonbondedForce.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include <cmath>
#include <iostream>
#include <set>
#include <vector>
using namespace OpenMM;
......@@ -470,6 +475,182 @@ void testLongRangeCorrection() {
ASSERT_EQUAL_TOL(standardEnergy1-standardEnergy2, customEnergy1-customEnergy2, 1e-4);
}
void testInteractionGroups() {
const int numParticles = 6;
ReferencePlatform platform;
System system;
VerletIntegrator integrator(0.01);
CustomNonbondedForce* nonbonded = new CustomNonbondedForce("v1+v2");
nonbonded->addPerParticleParameter("v");
vector<double> params(1, 0.001);
for (int i = 0; i < numParticles; i++) {
system.addParticle(1.0);
nonbonded->addParticle(params);
params[0] *= 10;
}
set<int> set1, set2, set3, set4;
set1.insert(2);
set2.insert(0);
set2.insert(1);
set2.insert(2);
set2.insert(3);
set2.insert(4);
set2.insert(5);
nonbonded->addInteractionGroup(set1, set2); // Particle 2 interacts with every other particle.
set3.insert(0);
set3.insert(1);
set4.insert(4);
set4.insert(5);
nonbonded->addInteractionGroup(set3, set4); // Particles 0 and 1 interact with 4 and 5.
nonbonded->addExclusion(1, 2); // Add an exclusion to make sure it gets skipped.
system.addForce(nonbonded);
Context context(system, integrator, platform);
vector<Vec3> positions(numParticles);
context.setPositions(positions);
State state = context.getState(State::Energy);
double expectedEnergy = 331.423; // Each digit is the number of interactions a particle particle is involved in.
ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), TOL);
}
void testLargeInteractionGroup() {
const int numMolecules = 300;
const int numParticles = numMolecules*2;
const double boxSize = 20.0;
// Create a large system.
ReferencePlatform platform;
System system;
system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize));
for (int i = 0; i < numParticles; i++)
system.addParticle(1.0);
CustomNonbondedForce* nonbonded = new CustomNonbondedForce("4*eps*((sigma/r)^12-(sigma/r)^6)+138.935456*q/r; q=q1*q2; sigma=0.5*(sigma1+sigma2); eps=sqrt(eps1*eps2)");
nonbonded->addPerParticleParameter("q");
nonbonded->addPerParticleParameter("sigma");
nonbonded->addPerParticleParameter("eps");
vector<Vec3> positions(numParticles);
OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt);
vector<double> params(3);
for (int i = 0; i < numMolecules; i++) {
if (i < numMolecules/2) {
params[0] = 1.0;
params[1] = 0.2;
params[2] = 0.1;
nonbonded->addParticle(params);
params[0] = -1.0;
params[1] = 0.1;
nonbonded->addParticle(params);
}
else {
params[0] = 1.0;
params[1] = 0.2;
params[2] = 0.2;
nonbonded->addParticle(params);
params[0] = -1.0;
params[1] = 0.1;
nonbonded->addParticle(params);
}
positions[2*i] = Vec3(boxSize*genrand_real2(sfmt), boxSize*genrand_real2(sfmt), boxSize*genrand_real2(sfmt));
positions[2*i+1] = Vec3(positions[2*i][0]+1.0, positions[2*i][1], positions[2*i][2]);
nonbonded->addExclusion(2*i, 2*i+1);
}
nonbonded->setNonbondedMethod(CustomNonbondedForce::CutoffPeriodic);
system.addForce(nonbonded);
// Compute the forces.
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
context.setPositions(positions);
State state1 = context.getState(State::Forces);
// Modify the force so only one particle interacts with everything else.
set<int> set1, set2;
set1.insert(151);
for (int i = 0; i < numParticles; i++)
set2.insert(i);
nonbonded->addInteractionGroup(set1, set2);
context.reinitialize();
context.setPositions(positions);
State state2 = context.getState(State::Forces);
// The force on that one particle should be the same.
ASSERT_EQUAL_VEC(state1.getForces()[151], state2.getForces()[151], 1e-4);
// Modify the interaction group so it includes all interactions. This should now reproduce the original forces
// on all atoms.
for (int i = 0; i < numParticles; i++)
set1.insert(i);
nonbonded->setInteractionGroupParameters(0, set1, set2);
context.reinitialize();
context.setPositions(positions);
State state3 = context.getState(State::Forces);
for (int i = 0; i < numParticles; i++)
ASSERT_EQUAL_VEC(state1.getForces()[i], state3.getForces()[i], 1e-4);
}
void testInteractionGroupLongRangeCorrection() {
const int numParticles = 10;
const double boxSize = 10.0;
const double cutoff = 0.5;
ReferencePlatform platform;
System system;
system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize));
CustomNonbondedForce* nonbonded = new CustomNonbondedForce("c1*c2*r^-4");
nonbonded->addPerParticleParameter("c");
vector<Vec3> positions(numParticles);
vector<double> params(1);
for (int i = 0; i < numParticles; i++) {
system.addParticle(1.0);
params[0] = (i%2 == 0 ? 1.1 : 2.0);
nonbonded->addParticle(params);
positions[i] = Vec3(0.5*i, 0, 0);
}
nonbonded->setNonbondedMethod(CustomNonbondedForce::CutoffPeriodic);
nonbonded->setCutoffDistance(cutoff);
system.addForce(nonbonded);
// Setup nonbonded groups. They involve 1 interaction of type AA,
// 2 of type BB, and 5 of type AB.
set<int> set1, set2, set3, set4, set5;
set1.insert(0);
set1.insert(1);
set1.insert(2);
nonbonded->addInteractionGroup(set1, set1);
set2.insert(3);
set3.insert(4);
set3.insert(6);
set3.insert(8);
nonbonded->addInteractionGroup(set2, set3);
set4.insert(5);
set5.insert(7);
set5.insert(9);
nonbonded->addInteractionGroup(set4, set5);
// Compute energy with and without the correction.
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
context.setPositions(positions);
double energy1 = context.getState(State::Energy).getPotentialEnergy();
nonbonded->setUseLongRangeCorrection(true);
context.reinitialize();
context.setPositions(positions);
double energy2 = context.getState(State::Energy).getPotentialEnergy();
// Check the result.
double sum = (1.1*1.1 + 2*2.0*2.0 + 5*1.1*2.0)*2.0;
int numPairs = (numParticles*(numParticles+1))/2;
double expected = 2*M_PI*numParticles*numParticles*sum/(numPairs*boxSize*boxSize*boxSize);
ASSERT_EQUAL_TOL(expected, energy2-energy1, 1e-4);
}
int main() {
try {
testSimpleExpression();
......@@ -481,6 +662,9 @@ int main() {
testCoulombLennardJones();
testSwitchingFunction();
testLongRangeCorrection();
testInteractionGroups();
testLargeInteractionGroup();
testInteractionGroupLongRangeCorrection();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
......
......@@ -406,6 +406,7 @@ void CudaIntegrateDrudeSCFStepKernel::execute(ContextImpl& context, const DrudeS
cu.setAsCurrent();
CudaIntegrationUtilities& integration = cu.getIntegrationUtilities();
int numAtoms = cu.getNumAtoms();
int paddedNumAtoms = cu.getPaddedNumAtoms();
double dt = integrator.getStepSize();
if (dt != prevStepSize) {
if (cu.getUseDoublePrecision() || cu.getUseMixedPrecision()) {
......@@ -424,7 +425,7 @@ void CudaIntegrateDrudeSCFStepKernel::execute(ContextImpl& context, const DrudeS
// Call the first integration kernel.
CUdeviceptr posCorrection = (cu.getUseMixedPrecision() ? cu.getPosqCorrection().getDevicePointer() : 0);
void* args1[] = {&cu.getIntegrationUtilities().getStepSize().getDevicePointer(), &cu.getPosq().getDevicePointer(), &posCorrection,
void* args1[] = {&numAtoms, &paddedNumAtoms, &cu.getIntegrationUtilities().getStepSize().getDevicePointer(), &cu.getPosq().getDevicePointer(), &posCorrection,
&cu.getVelm().getDevicePointer(), &cu.getForce().getDevicePointer(), &integration.getPosDelta().getDevicePointer()};
cu.executeKernel(kernel1, args1, numAtoms);
......@@ -434,7 +435,7 @@ void CudaIntegrateDrudeSCFStepKernel::execute(ContextImpl& context, const DrudeS
// Call the second integration kernel.
void* args2[] = {&cu.getIntegrationUtilities().getStepSize().getDevicePointer(), &cu.getPosq().getDevicePointer(), &posCorrection,
void* args2[] = {&numAtoms, &cu.getIntegrationUtilities().getStepSize().getDevicePointer(), &cu.getPosq().getDevicePointer(), &posCorrection,
&cu.getVelm().getDevicePointer(), &integration.getPosDelta().getDevicePointer()};
cu.executeKernel(kernel2, args2, numAtoms);
......
......@@ -391,7 +391,7 @@ void testContractions() {
map<int, int> contractions;
contractions[1] = 3;
contractions[2] = 1;
RPMDIntegrator integ(numCopies, temperature, 10.0, 0.001, contractions);
RPMDIntegrator integ(numCopies, temperature, 50.0, 0.001, contractions);
Platform& platform = Platform::getPlatformByName("CUDA");
Context context(system, integ, platform);
for (int copy = 0; copy < numCopies; copy++) {
......
......@@ -392,7 +392,7 @@ void testContractions() {
map<int, int> contractions;
contractions[1] = 3;
contractions[2] = 1;
RPMDIntegrator integ(numCopies, temperature, 10.0, 0.001, contractions);
RPMDIntegrator integ(numCopies, temperature, 50.0, 0.001, contractions);
Platform& platform = Platform::getPlatformByName("OpenCL");
Context context(system, integ, platform);
for (int copy = 0; copy < numCopies; copy++) {
......
......@@ -273,7 +273,7 @@ void testContractions() {
map<int, int> contractions;
contractions[1] = 3;
contractions[2] = 1;
RPMDIntegrator integ(numCopies, temperature, 10.0, 0.001, contractions);
RPMDIntegrator integ(numCopies, temperature, 50.0, 0.001, contractions);
Platform& platform = Platform::getPlatformByName("Reference");
Context context(system, integ, platform);
for (int copy = 0; copy < numCopies; copy++) {
......
......@@ -17,6 +17,7 @@
<xsl:variable name="map_property_type_id" select="/GCC_XML/Class[starts-with(@name, 'map&lt;std::basic_string') and not(contains(@name, 'double'))]/@id"/>
<xsl:variable name="vector_double_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;double')]/@id"/>
<xsl:variable name="vector_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;int')]/@id"/>
<xsl:variable name="set_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'set&lt;int')]/@id"/>
<!-- Do not generate functions for the following classes -->
<xsl:variable name="skip_classes" select="('Vec3', 'Kernel', 'Stream', 'KernelImpl', 'StreamImpl', 'KernelFactory', 'StreamFactory')"/>
......@@ -50,6 +51,7 @@ typedef struct OpenMM_ParameterArray_struct OpenMM_ParameterArray;
typedef struct OpenMM_PropertyArray_struct OpenMM_PropertyArray;
typedef struct OpenMM_DoubleArray_struct OpenMM_DoubleArray;
typedef struct OpenMM_IntArray_struct OpenMM_IntArray;
typedef struct OpenMM_IntSet_struct OpenMM_IntSet;
typedef struct {double x, y, z;} OpenMM_Vec3;
typedef enum {OpenMM_False = 0, OpenMM_True = 1} OpenMM_Boolean;
......@@ -103,6 +105,10 @@ extern OPENMM_EXPORT const char* OpenMM_PropertyArray_get(const OpenMM_PropertyA
<xsl:with-param name="element_type" select="'int'"/>
<xsl:with-param name="name" select="'OpenMM_IntArray'"/>
</xsl:call-template>
<xsl:call-template name="primitive_set">
<xsl:with-param name="element_type" select="'int'"/>
<xsl:with-param name="name" select="'OpenMM_IntSet'"/>
</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. */
......@@ -135,6 +141,17 @@ extern OPENMM_EXPORT void <xsl:value-of select="$name"/>_set(<xsl:value-of selec
extern OPENMM_EXPORT <xsl:value-of select="concat($element_type, ' ', $name)"/>_get(const <xsl:value-of select="$name"/>* array, int index);
</xsl:template>
<!-- Print out the declarations for a (Primitive)Set type -->
<xsl:template name="primitive_set">
<xsl:param name="element_type"/>
<xsl:param name="name"/>
/* <xsl:value-of select="$name"/> */
extern OPENMM_EXPORT <xsl:value-of select="$name"/>* <xsl:value-of select="$name"/>_create();
extern OPENMM_EXPORT void <xsl:value-of select="$name"/>_destroy(<xsl:value-of select="$name"/>* set);
extern OPENMM_EXPORT int <xsl:value-of select="$name"/>_getSize(const <xsl:value-of select="$name"/>* set);
extern OPENMM_EXPORT void <xsl:value-of select="$name"/>_insert(<xsl:value-of select="$name"/>* set, <xsl:value-of select="$element_type"/> value);
</xsl:template>
<!-- Print out information for a class -->
<xsl:template name="class">
<xsl:variable name="class_name" select="@name"/>
......@@ -252,6 +269,9 @@ extern OPENMM_EXPORT <xsl:call-template name="wrap_type"><xsl:with-param name="t
<xsl:when test="$type_id=$vector_int_type_id">
<xsl:value-of select="'OpenMM_IntArray'"/>
</xsl:when>
<xsl:when test="$type_id=$set_int_type_id">
<xsl:value-of select="'OpenMM_IntSet'"/>
</xsl:when>
<xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType'">
<xsl:call-template name="wrap_type">
<xsl:with-param name="type_id" select="$node/@type"/>
......
......@@ -19,6 +19,7 @@
<xsl:variable name="map_property_type_id" select="/GCC_XML/Class[starts-with(@name, 'map&lt;std::basic_string') and not(contains(@name, 'double'))]/@id"/>
<xsl:variable name="vector_double_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;double')]/@id"/>
<xsl:variable name="vector_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;int')]/@id"/>
<xsl:variable name="set_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'set&lt;int')]/@id"/>
<xsl:variable name="newline">
<xsl:text>
</xsl:text>
......@@ -152,6 +153,10 @@ OPENMM_EXPORT const char* OpenMM_PropertyArray_get(const OpenMM_PropertyArray* a
<xsl:with-param name="element_type" select="'int'"/>
<xsl:with-param name="name" select="'OpenMM_IntArray'"/>
</xsl:call-template>
<xsl:call-template name="primitive_set">
<xsl:with-param name="element_type" select="'int'"/>
<xsl:with-param name="name" select="'OpenMM_IntSet'"/>
</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. */
......@@ -200,6 +205,25 @@ OPENMM_EXPORT <xsl:value-of select="concat($element_type, ' ')"/> <xsl:value-of
}
</xsl:template>
<!-- Print out the definitions for a (Primitive)Set type -->
<xsl:template name="primitive_set">
<xsl:param name="element_type"/>
<xsl:param name="name"/>
/* <xsl:value-of select="$name"/> */
OPENMM_EXPORT <xsl:value-of select="$name"/>* <xsl:value-of select="$name"/>_create() {
return reinterpret_cast&lt;<xsl:value-of select="$name"/>*&gt;(new set&lt;<xsl:value-of select="$element_type"/>&gt;());
}
OPENMM_EXPORT void <xsl:value-of select="$name"/>_destroy(<xsl:value-of select="$name"/>* s) {
delete reinterpret_cast&lt;set&lt;<xsl:value-of select="$element_type"/>&gt;*&gt;(s);
}
OPENMM_EXPORT int <xsl:value-of select="$name"/>_getSize(const <xsl:value-of select="$name"/>* s) {
return reinterpret_cast&lt;const set&lt;<xsl:value-of select="$element_type"/>&gt;*&gt;(s)->size();
}
OPENMM_EXPORT void <xsl:value-of select="$name"/>_insert(<xsl:value-of select="$name"/>* s, <xsl:value-of select="$element_type"/> value) {
reinterpret_cast&lt;set&lt;<xsl:value-of select="$element_type"/>&gt;*&gt;(s)->insert(value);
}
</xsl:template>
<!-- Print out information for a class -->
<xsl:template name="class">
<xsl:variable name="class_name" select="@name"/>
......@@ -355,6 +379,9 @@ OPENMM_EXPORT <xsl:call-template name="wrap_type"><xsl:with-param name="type_id"
<xsl:when test="$type_id=$vector_int_type_id">
<xsl:value-of select="'OpenMM_IntArray'"/>
</xsl:when>
<xsl:when test="$type_id=$set_int_type_id">
<xsl:value-of select="'OpenMM_IntSet'"/>
</xsl:when>
<xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType'">
<xsl:call-template name="wrap_type">
<xsl:with-param name="type_id" select="$node/@type"/>
......
......@@ -21,6 +21,7 @@
<xsl:variable name="map_property_type_id" select="/GCC_XML/Class[starts-with(@name, 'map&lt;std::basic_string') and not(contains(@name, 'double'))]/@id"/>
<xsl:variable name="vector_double_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;double')]/@id"/>
<xsl:variable name="vector_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;int')]/@id"/>
<xsl:variable name="set_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'set&lt;int')]/@id"/>
<xsl:variable name="newline">
<xsl:text>
</xsl:text>
......@@ -514,6 +515,9 @@ END MODULE OpenMM
<xsl:when test="$type_id=$vector_int_type_id">
<xsl:value-of select="concat('type (OpenMM_IntArray) ', $value)"/>
</xsl:when>
<xsl:when test="$type_id=$set_int_type_id">
<xsl:value-of select="concat('type (OpenMM_IntSet) ', $value)"/>
</xsl:when>
<xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType'">
<xsl:call-template name="declare_argument">
<xsl:with-param name="type_id" select="$node/@type"/>
......
......@@ -23,6 +23,7 @@
<xsl:variable name="map_property_type_id" select="/GCC_XML/Class[starts-with(@name, 'map&lt;std::basic_string') and not(contains(@name, 'double'))]/@id"/>
<xsl:variable name="vector_double_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;double')]/@id"/>
<xsl:variable name="vector_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;int')]/@id"/>
<xsl:variable name="set_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'set&lt;int')]/@id"/>
<xsl:variable name="newline">
<xsl:text>
</xsl:text>
......@@ -243,6 +244,14 @@ OPENMM_EXPORT const char* OPENMM_PROPERTYARRAY_GET(const OpenMM_PropertyArray* c
<xsl:with-param name="element_type" select="'double'"/>
<xsl:with-param name="name" select="'OpenMM_DoubleArray'"/>
</xsl:call-template>
<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>
<xsl:call-template name="primitive_set">
<xsl:with-param name="element_type" select="'int'"/>
<xsl:with-param name="name" select="'OpenMM_IntSet'"/>
</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. */
......@@ -320,6 +329,41 @@ OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_GET(const <xsl:value-of
}
</xsl:template>
<!-- Print out the definitions for a (Primitive)Set type -->
<xsl:template name="primitive_set">
<xsl:param name="element_type"/>
<xsl:param name="name"/>
<xsl:variable name="name_lower" select="lower-case($name)"/>
<xsl:variable name="name_upper" select="upper-case($name)"/>
/* <xsl:value-of select="$name"/> */
OPENMM_EXPORT void <xsl:value-of select="$name_lower"/>_create_(<xsl:value-of select="$name"/>*&amp; result) {
result = <xsl:value-of select="$name"/>_create();
}
OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_CREATE(<xsl:value-of select="$name"/>*&amp; result) {
result = <xsl:value-of select="$name"/>_create();
}
OPENMM_EXPORT void <xsl:value-of select="$name_lower"/>_destroy_(<xsl:value-of select="$name"/>*&amp; array) {
<xsl:value-of select="$name"/>_destroy(array);
array = 0;
}
OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_DESTROY(<xsl:value-of select="$name"/>*&amp; array) {
<xsl:value-of select="$name"/>_destroy(array);
array = 0;
}
OPENMM_EXPORT int <xsl:value-of select="$name_lower"/>_getsize_(const <xsl:value-of select="$name"/>* const&amp; array) {
return <xsl:value-of select="$name"/>_getSize(array);
}
OPENMM_EXPORT int <xsl:value-of select="$name_upper"/>_GETSIZE(const <xsl:value-of select="$name"/>* const&amp; array) {
return <xsl:value-of select="$name"/>_getSize(array);
}
OPENMM_EXPORT void <xsl:value-of select="$name_lower"/>_insert_(<xsl:value-of select="$name"/>* const&amp; array, const <xsl:value-of select="$element_type"/>&amp; value) {
<xsl:value-of select="$name"/>_insert(array, value);
}
OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_INSERT(<xsl:value-of select="$name"/>* const&amp; array, const <xsl:value-of select="$element_type"/>&amp; value) {
<xsl:value-of select="$name"/>_insert(array, value);
}
</xsl:template>
<!-- Print out information for a class -->
<xsl:template name="class">
<xsl:variable name="class_name" select="@name"/>
......@@ -565,6 +609,9 @@ OPENMM_EXPORT <xsl:if test="$has_return">
<xsl:when test="$type_id=$vector_int_type_id">
<xsl:value-of select="'OpenMM_IntArray'"/>
</xsl:when>
<xsl:when test="$type_id=$set_int_type_id">
<xsl:value-of select="'OpenMM_IntSet'"/>
</xsl:when>
<xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType'">
<xsl:call-template name="wrap_type">
<xsl:with-param name="type_id" select="$node/@type"/>
......@@ -605,6 +652,7 @@ OPENMM_EXPORT <xsl:if test="$has_return">
<xsl:when test="$type_id=$vector_double_type_id">1</xsl:when>
<xsl:when test="$type_id=$vector_int_type_id">1</xsl:when>
<xsl:when test="$type_id=$vector_string_type_id">1</xsl:when>
<xsl:when test="$type_id=$set_int_type_id">1</xsl:when>
<xsl:when test="local-name($node)='Class' and $node/@context=$openmm_namespace_id">1</xsl:when>
<xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType'">
<xsl:call-template name="is_handle_type">
......
......@@ -12,7 +12,6 @@ It also tries to load any plugin modules it can find.
"""
__author__ = "Randall J. Radmer"
__version__ = "1.0"
import os, sys, glob
if sys.platform == "win32":
......@@ -36,3 +35,4 @@ else:
from simtk.openmm.openmm import *
from simtk.openmm.vec3 import Vec3
pluginLoadedLibNames = Platform.loadPluginsFromDirectory(Platform.getDefaultPluginsDirectory())
__version__ = Platform.getOpenMMVersion()
......@@ -122,7 +122,7 @@ class GromacsGroFile(object):
na = int(line.strip())
elif _is_gro_coord(line):
if frame == 0: # Create the list of residues, atom names etc. only if it's the first frame.
(thisresnum, thisresname, thisatomname, thisatomnum) = [line[i*5:i*5+5].strip() for i in range(4)]
(thisresnum, thisresname, thisatomname) = [line[i*5:i*5+5].strip() for i in range(3)]
resname.append(thisresname)
resid.append(int(thisresnum))
atomname.append(thisatomname)
......@@ -133,7 +133,10 @@ class GromacsGroFile(object):
elements.append(elem.get_by_symbol(thiselem))
except KeyError:
elements.append(None)
pos = [float(line[20+i*8:28+i*8]) for i in range(3)]
firstDecimalPos = line.index('.', 20)
secondDecimalPos = line.index('.', firstDecimalPos+1)
digits = secondDecimalPos-firstDecimalPos
pos = [float(line[20+i*digits:20+(i+1)*digits]) for i in range(3)]
xyz.append(Vec3(pos[0], pos[1], pos[2]))
elif _is_gro_box(line) and ln == na + 2:
sline = line.split()
......
......@@ -270,8 +270,19 @@ class GromacsTopFile(object):
def _processAtomType(self, line):
"""Process a line in the [ atomtypes ] category."""
fields = line.split()
if len(fields) < 7:
if len(fields) < 6:
raise ValueError('Too few fields in [ atomtypes ] line: '+line);
if len(fields[3]) == 1:
# Bonded type and atomic number are both missing.
fields.insert(1, None)
fields.insert(1, None)
elif len(fields[4]) == 1 and len(fields[5]) > 1:
if fields[1][0].isalpha():
# Atomic number is missing.
fields.insert(2, None)
else:
# Bonded type is missing.
fields.insert(1, None)
self._atomTypes[fields[0]] = fields
def _processBondType(self, line):
......@@ -492,9 +503,10 @@ class GromacsTopFile(object):
baseAtomIndex = sys.getNumParticles()
atomTypes = [atom[1] for atom in moleculeType.atoms]
try:
[self._atomTypes[t][1] for t in atomTypes]
bondedTypes = [self._atomTypes[t][1] for t in atomTypes]
except KeyError as e:
raise ValueError('Unknown atom type: '+e.message)
bondedTypes = [b if b is not None else a for a, b in zip(atomTypes, bondedTypes)]
# Add atoms.
......@@ -502,7 +514,7 @@ class GromacsTopFile(object):
if len(fields) >= 8:
mass = float(fields[7])
else:
mass = float(self._atomTypes[fields[1]][2])
mass = float(self._atomTypes[fields[1]][3])
sys.addParticle(mass)
# Add bonds.
......@@ -510,7 +522,7 @@ class GromacsTopFile(object):
atomBonds = [{} for x in range(len(moleculeType.atoms))]
for fields in moleculeType.bonds:
atoms = [int(x)-1 for x in fields[:2]]
types = tuple(atomTypes[i] for i in atoms)
types = tuple(bondedTypes[i] for i in atoms)
if len(fields) >= 5:
params = fields[3:5]
elif types in self._bondTypes:
......@@ -547,7 +559,7 @@ class GromacsTopFile(object):
degToRad = math.pi/180
for fields in moleculeType.angles:
atoms = [int(x)-1 for x in fields[:3]]
types = tuple(atomTypes[i] for i in atoms)
types = tuple(bondedTypes[i] for i in atoms)
if len(fields) >= 6:
params = fields[4:]
elif types in self._angleTypes:
......@@ -593,7 +605,7 @@ class GromacsTopFile(object):
for fields in moleculeType.dihedrals:
atoms = [int(x)-1 for x in fields[:4]]
types = tuple(atomTypes[i] for i in atoms)
types = tuple(bondedTypes[i] for i in atoms)
dihedralType = fields[4]
reversedTypes = types[::-1]+(dihedralType,)
types = types+(dihedralType,)
......@@ -645,7 +657,7 @@ class GromacsTopFile(object):
for fields in moleculeType.cmaps:
atoms = [int(x)-1 for x in fields[:5]]
types = tuple(atomTypes[i] for i in atoms)
types = tuple(bondedTypes[i] for i in atoms)
if len(fields) >= 8 and len(fields) >= 8+int(fields[6])*int(fields[7]):
params = fields
elif types in self._cmapTypes:
......@@ -677,8 +689,8 @@ class GromacsTopFile(object):
if len(fields) > 6:
q = float(fields[6])
else:
q = float(params[3])
nb.addParticle(q, float(params[5]), float(params[6]))
q = float(params[4])
nb.addParticle(q, float(params[6]), float(params[7]))
if implicitSolvent is OBC2:
if fields[1] not in self._implicitTypes:
raise ValueError('No implicit solvent parameters specified for atom type: '+fields[1])
......
......@@ -163,7 +163,7 @@ class PdbStructure(object):
elif (pdb_line.find("TER") == 0 and pdb_line.split()[0] == "TER"):
self._current_model._current_chain._add_ter_record()
elif (pdb_line.find("CRYST1") == 0):
self._unit_cell_dimensions = (float(pdb_line[6:15]), float(pdb_line[15:24]), float(pdb_line[24:33]))*unit.angstroms
self._unit_cell_dimensions = Vec3(float(pdb_line[6:15]), float(pdb_line[15:24]), float(pdb_line[24:33]))*unit.angstroms
elif (pdb_line.find("CONECT") == 0):
atoms = [int(pdb_line[6:11])]
for pos in (11,16,21,26):
......
......@@ -20,6 +20,7 @@ See https://simtk.org/home/pyopenmm for details"
%include "std_map.i"
%include "std_pair.i"
%include "std_set.i"
%include "std_vector.i"
namespace std {
%template(pairii) pair<int,int>;
......@@ -32,6 +33,7 @@ namespace std {
%template(mapstringstring) map<string,string>;
%template(mapstringdouble) map<string,double>;
%template(mapii) map<int,int>;
%template(seti) set<int>;
};
%include "windows.i"
......
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