Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
openmm
Commits
7f1dd6a3
Unverified
Commit
7f1dd6a3
authored
Nov 12, 2019
by
Andy Simmonett
Browse files
Add CUDA and OpenCL hardwall constraints and Drude integration with serialization
parent
512328b2
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
912 additions
and
88 deletions
+912
-88
platforms/cuda/include/CudaKernels.h
platforms/cuda/include/CudaKernels.h
+3
-1
platforms/cuda/src/CudaKernels.cpp
platforms/cuda/src/CudaKernels.cpp
+51
-11
platforms/cuda/src/kernels/velocityVerlet.cu
platforms/cuda/src/kernels/velocityVerlet.cu
+268
-20
platforms/opencl/include/OpenCLKernels.h
platforms/opencl/include/OpenCLKernels.h
+3
-1
platforms/opencl/src/OpenCLKernels.cpp
platforms/opencl/src/OpenCLKernels.cpp
+88
-21
platforms/opencl/src/kernels/velocityVerlet.cl
platforms/opencl/src/kernels/velocityVerlet.cl
+263
-20
platforms/reference/src/SimTKReference/ReferenceVelocityVerletDynamics.cpp
...ce/src/SimTKReference/ReferenceVelocityVerletDynamics.cpp
+3
-2
plugins/drude/serialization/include/openmm/serialization/DrudeNoseHooverIntegratorProxy.h
...ude/openmm/serialization/DrudeNoseHooverIntegratorProxy.h
+18
-0
plugins/drude/serialization/src/DrudeNoseHooverIntegratorProxy.cpp
...rude/serialization/src/DrudeNoseHooverIntegratorProxy.cpp
+80
-0
plugins/drude/serialization/src/DrudeSerializationProxyRegistration.cpp
...serialization/src/DrudeSerializationProxyRegistration.cpp
+3
-0
plugins/drude/serialization/tests/TestSerializeDrudeNoseHooverIntegrator.cpp
...lization/tests/TestSerializeDrudeNoseHooverIntegrator.cpp
+109
-0
plugins/drude/tests/TestDrudeNoseHoover.h
plugins/drude/tests/TestDrudeNoseHoover.h
+10
-10
serialization/src/NoseHooverIntegratorProxy.cpp
serialization/src/NoseHooverIntegratorProxy.cpp
+2
-0
serialization/tests/TestSerializeNoseHooverIntegrator.cpp
serialization/tests/TestSerializeNoseHooverIntegrator.cpp
+2
-0
wrappers/generateWrappers.py
wrappers/generateWrappers.py
+3
-1
wrappers/python/src/swig_doxygen/swigInputConfig.py
wrappers/python/src/swig_doxygen/swigInputConfig.py
+6
-1
No files found.
platforms/cuda/include/CudaKernels.h
View file @
7f1dd6a3
...
...
@@ -1399,7 +1399,9 @@ public:
double
computeKineticEnergy
(
ContextImpl
&
context
,
const
NoseHooverIntegrator
&
integrator
);
private:
CudaContext
&
cu
;
CUfunction
kernel1
,
kernel2
,
kernel3
;
float
prevMaxPairDistance
;
CudaArray
maxPairDistanceBuffer
,
pairListBuffer
,
atomListBuffer
,
pairTemperatureBuffer
;
CUfunction
kernel1
,
kernel2
,
kernel3
,
kernelHardWall
;
};
/**
...
...
platforms/cuda/src/CudaKernels.cpp
View file @
7f1dd6a3
...
...
@@ -7080,38 +7080,78 @@ void CudaIntegrateVelocityVerletStepKernel::initialize(const System& system, con
cu.getPlatformData().initializeContexts(system);
cu.setAsCurrent();
map<string, string> defines;
defines["BOLTZ"] = cu.doubleToString(BOLTZ);
CUmodule module = cu.createModule(CudaKernelSources::velocityVerlet, defines, "");
kernel1 = cu.getKernel(module, "integrateVelocityVerletPart1");
kernel2 = cu.getKernel(module, "integrateVelocityVerletPart2");
kernel3 = cu.getKernel(module, "integrateVelocityVerletPart3");
kernelHardWall = cu.getKernel(module, "integrateVelocityVerletHardWall");
prevMaxPairDistance = -1.0;
maxPairDistanceBuffer.initialize<float>(cu, 1, "maxPairDistanceBuffer");
}
void CudaIntegrateVelocityVerletStepKernel::execute(ContextImpl& context, const NoseHooverIntegrator& integrator, bool &forcesAreValid) {
cu.setAsCurrent();
CudaIntegrationUtilities& integration = cu.getIntegrationUtilities();
int numAtoms = cu.getNumAtoms();
int paddedNumAtoms = cu.getPaddedNumAtoms();
double dt = integrator.getStepSize();
cu.getIntegrationUtilities().setNextStepSize(dt);
if( !forcesAreValid ) context.calcForcesAndEnergy(true, false);
const auto& atomList = integrator.getAllAtoms();
const auto& pairList = integrator.getAllPairs();
int numAtoms = atomList.size();
int numPairs = pairList.size();
int numParticles = numAtoms + 2*numPairs;
float maxPairDistance = integrator.getMaximumPairDistance();
// Make sure atom and pair metadata is uploaded and has the correct dimensions
if (prevMaxPairDistance != maxPairDistance) {
std::vector<float> tmp(1, maxPairDistance);
maxPairDistanceBuffer.upload(tmp);
prevMaxPairDistance = maxPairDistance;
}
if (numAtoms !=0 && (!atomListBuffer.isInitialized() || atomListBuffer.getSize() != numAtoms)) {
atomListBuffer.initialize<int>(cu, atomList.size(), "atomListBuffer");
atomListBuffer.upload(atomList);
}
if (numPairs !=0 && (!pairListBuffer.isInitialized() || pairListBuffer.getSize() != numPairs)) {
std::vector<int2> tmp;
std::vector<float> tmp2;
for(const auto &pair : pairList) {
tmp.push_back(make_int2(std::get<0>(pair), std::get<1>(pair)));
tmp2.push_back(std::get<2>(pair));
}
pairListBuffer.initialize<int2>(cu, pairList.size(), "pairListBuffer");
pairListBuffer.upload(tmp);
pairTemperatureBuffer.initialize<float>(cu, pairList.size(), "pairTemperatureBuffer");
pairTemperatureBuffer.upload(tmp2);
}
//// Call the first integration kernel.
CUdeviceptr posCorrection = (cu.getUseMixedPrecision() ? cu.getPosqCorrection().getDevicePointer() : 0);
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, 128);
void* args1[] = {&numAtoms, &numPairs, &paddedNumAtoms, &cu.getIntegrationUtilities().getStepSize().getDevicePointer(), &cu.getPosq().getDevicePointer(), &posCorrection,
&cu.getVelm().getDevicePointer(), &cu.getForce().getDevicePointer(), &integration.getPosDelta().getDevicePointer(),
&atomListBuffer.getDevicePointer(), &pairListBuffer.getDevicePointer()};
cu.executeKernel(kernel1, args1, std::max(numAtoms,numPairs), 128);
//// Apply constraints.
integration.applyConstraints(integrator.getConstraintTolerance());
//// Call the second integration kernel.
void* args2[] = {&numAtoms, &cu.getIntegrationUtilities().getStepSize().getDevicePointer(), &cu.getPosq().getDevicePointer(), &posCorrection,
void* args2[] = {&numParticles, &cu.getIntegrationUtilities().getStepSize().getDevicePointer(), &cu.getPosq().getDevicePointer(), &posCorrection,
&cu.getVelm().getDevicePointer(), &integration.getPosDelta().getDevicePointer()};
cu.executeKernel(kernel2, args2, numAtoms, 128);
cu.executeKernel(kernel2, args2, numParticles, 128);
if (numPairs > 0) {
//// Enforce hard wall constraint
void* argsHardWall[] = {&numPairs, &maxPairDistanceBuffer.getDevicePointer(),
&cu.getIntegrationUtilities().getStepSize().getDevicePointer(), &cu.getPosq().getDevicePointer(), &posCorrection,
&cu.getVelm().getDevicePointer(), &pairListBuffer.getDevicePointer(),
&pairTemperatureBuffer.getDevicePointer()};
cu.executeKernel(kernelHardWall, argsHardWall, numPairs, 128);
}
integration.computeVirtualSites();
...
...
@@ -7120,10 +7160,10 @@ void CudaIntegrateVelocityVerletStepKernel::execute(ContextImpl& context, const
forcesAreValid = true;
//// Call the third integration kernel.
void* args3[] = {&numAtoms, &paddedNumAtoms, &cu.getIntegrationUtilities().getStepSiz
e().getDevicePointer(), &
cu
.getPos
q
().getDevicePointer(),
&posCorrection,
&
cu.getVelm().getDevicePointer(), &cu.getForce().getDevicePointer(), &integration.getPosDelta()
.getDevicePointer()};
cu.executeKernel(kernel3, args3,
numAtoms
, 128);
void* args3[] = {&numAtoms, &numPairs, &paddedNumAtoms, &cu.getIntegrationUtilities().getStepSize().getDevicePointer(), &cu.getPosq().getDevicePointer(), &posCorrection,
&cu.getVelm().getDevicePointer(), &cu.getForc
e().getDevicePointer(), &
integration
.getPos
Delta
().getDevicePointer(),
&
atomListBuffer.getDevicePointer(), &pairListBuffer
.getDevicePointer()};
cu.executeKernel(kernel3, args3,
std::max(numAtoms,numPairs)
, 128);
// TODO: Figure out if this is really needed. The constraint velocities are accounted for
// in a finite difference sense in the step 3 kernel, when the velocities are updated.
...
...
platforms/cuda/src/kernels/velocityVerlet.cu
View file @
7f1dd6a3
/**
* Perform the first step of Velocity Verlet integration.
*
* update displacements (posDelta) and velocities (velm)
*/
extern
"C"
__global__
void
integrateVelocityVerletPart1
(
int
numAtoms
,
int
paddedNumAtoms
,
const
mixed2
*
__restrict__
dt
,
const
real4
*
__restrict__
posq
,
const
real4
*
__restrict__
posqCorrection
,
mixed4
*
__restrict__
velm
,
const
long
long
*
__restrict__
force
,
mixed4
*
__restrict__
posDelta
)
{
extern
"C"
__global__
void
integrateVelocityVerletPart1
(
int
numAtoms
,
int
numPairs
,
int
paddedNumAtoms
,
const
mixed2
*
__restrict__
dt
,
const
real4
*
__restrict__
posq
,
const
real4
*
__restrict__
posqCorrection
,
mixed4
*
__restrict__
velm
,
const
long
long
*
__restrict__
force
,
mixed4
*
__restrict__
posDelta
,
const
int
*
__restrict__
atomList
,
const
int2
*
__restrict__
pairList
)
{
const
mixed2
stepSize
=
dt
[
0
];
const
mixed
dtPos
=
stepSize
.
y
;
const
mixed
dtVel
=
0.5
f
*
(
stepSize
.
x
+
stepSize
.
y
);
const
mixed
scale
=
0.5
f
*
dtVel
/
(
mixed
)
0x100000000
;
for
(
int
index
=
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
;
index
<
numAtoms
;
index
+=
blockDim
.
x
*
gridDim
.
x
)
{
mixed4
velocity
=
velm
[
index
];
int
atom
=
atomList
[
index
];
mixed4
velocity
=
velm
[
atom
];
if
(
velocity
.
w
!=
0.0
)
{
#ifdef USE_MIXED_PRECISION
real4
pos1
=
posq
[
index
];
real4
pos2
=
posqCorrection
[
index
];
real4
pos1
=
posq
[
atom
];
real4
pos2
=
posqCorrection
[
atom
];
mixed4
pos
=
make_mixed4
(
pos1
.
x
+
(
mixed
)
pos2
.
x
,
pos1
.
y
+
(
mixed
)
pos2
.
y
,
pos1
.
z
+
(
mixed
)
pos2
.
z
,
pos1
.
w
);
#else
real4
pos
=
posq
[
index
];
real4
pos
=
posq
[
atom
];
#endif
velocity
.
x
+=
scale
*
force
[
index
]
*
velocity
.
w
;
velocity
.
y
+=
scale
*
force
[
index
+
paddedNumAtoms
]
*
velocity
.
w
;
velocity
.
z
+=
scale
*
force
[
index
+
paddedNumAtoms
*
2
]
*
velocity
.
w
;
velocity
.
x
+=
scale
*
force
[
atom
]
*
velocity
.
w
;
velocity
.
y
+=
scale
*
force
[
atom
+
paddedNumAtoms
]
*
velocity
.
w
;
velocity
.
z
+=
scale
*
force
[
atom
+
paddedNumAtoms
*
2
]
*
velocity
.
w
;
pos
.
x
=
velocity
.
x
*
dtPos
;
pos
.
y
=
velocity
.
y
*
dtPos
;
pos
.
z
=
velocity
.
z
*
dtPos
;
posDelta
[
index
]
=
pos
;
velm
[
index
]
=
velocity
;
posDelta
[
atom
]
=
pos
;
velm
[
atom
]
=
velocity
;
}
}
for
(
int
index
=
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
;
index
<
numPairs
;
index
+=
blockDim
.
x
*
gridDim
.
x
)
{
int
atom1
=
pairList
[
index
].
x
;
int
atom2
=
pairList
[
index
].
y
;
mixed4
v1
=
velm
[
atom1
];
mixed4
v2
=
velm
[
atom2
];
mixed
m1
=
v1
.
w
==
0.0
f
?
0.0
f
:
1.0
f
/
v1
.
w
;
mixed
m2
=
v2
.
w
==
0.0
f
?
0.0
f
:
1.0
f
/
v2
.
w
;
mixed
mass1fract
=
m1
/
(
m1
+
m2
);
mixed
mass2fract
=
m2
/
(
m1
+
m2
);
mixed
invRedMass
=
(
m1
*
m2
!=
0.0
f
)
?
(
m1
+
m2
)
/
(
m1
*
m2
)
:
0.0
f
;
mixed
invTotMass
=
(
m1
+
m2
!=
0.0
f
)
?
1.0
f
/
(
m1
+
m2
)
:
0.0
f
;
mixed3
comVel
;
comVel
.
x
=
v1
.
x
*
mass1fract
+
v2
.
x
*
mass2fract
;
comVel
.
y
=
v1
.
y
*
mass1fract
+
v2
.
y
*
mass2fract
;
comVel
.
z
=
v1
.
z
*
mass1fract
+
v2
.
z
*
mass2fract
;
mixed3
relVel
;
relVel
.
x
=
v2
.
x
-
v1
.
x
;
relVel
.
y
=
v2
.
y
-
v1
.
y
;
relVel
.
z
=
v2
.
z
-
v1
.
z
;
//
mixed3
comFrc
;
comFrc
.
x
=
force
[
atom1
]
+
force
[
atom2
];
comFrc
.
y
=
force
[
atom1
+
paddedNumAtoms
]
+
force
[
atom2
+
paddedNumAtoms
];
comFrc
.
z
=
force
[
atom1
+
paddedNumAtoms
*
2
]
+
force
[
atom2
+
paddedNumAtoms
*
2
];
mixed3
relFrc
;
relFrc
.
x
=
mass1fract
*
force
[
atom2
]
-
mass2fract
*
force
[
atom1
];
relFrc
.
y
=
mass1fract
*
force
[
atom2
+
paddedNumAtoms
]
-
mass2fract
*
force
[
atom1
+
paddedNumAtoms
];
relFrc
.
z
=
mass1fract
*
force
[
atom2
+
paddedNumAtoms
*
2
]
-
mass2fract
*
force
[
atom1
+
paddedNumAtoms
*
2
];
comVel
.
x
+=
comFrc
.
x
*
scale
*
invTotMass
;
comVel
.
y
+=
comFrc
.
y
*
scale
*
invTotMass
;
comVel
.
z
+=
comFrc
.
z
*
scale
*
invTotMass
;
relVel
.
x
+=
relFrc
.
x
*
scale
*
invRedMass
;
relVel
.
y
+=
relFrc
.
y
*
scale
*
invRedMass
;
relVel
.
z
+=
relFrc
.
z
*
scale
*
invRedMass
;
#ifdef USE_MIXED_PRECISION
real4
posv1
=
posq
[
atom1
];
real4
posv2
=
posq
[
atom2
];
real4
posc1
=
posqCorrection
[
atom1
];
real4
posc2
=
posqCorrection
[
atom2
];
mixed4
pos1
=
make_mixed4
(
posv1
.
x
+
(
mixed
)
posc1
.
x
,
posv1
.
y
+
(
mixed
)
posc1
.
y
,
posv1
.
z
+
(
mixed
)
posc1
.
z
,
posv1
.
w
);
mixed4
pos2
=
make_mixed4
(
posv2
.
x
+
(
mixed
)
posc2
.
x
,
posv2
.
y
+
(
mixed
)
posc2
.
y
,
posv2
.
z
+
(
mixed
)
posc2
.
z
,
posv2
.
w
);
#else
real4
pos1
=
posq
[
atom1
];
real4
pos2
=
posq
[
atom2
];
#endif
if
(
v1
.
w
!=
0.0
f
)
{
v1
.
x
=
comVel
.
x
-
relVel
.
x
*
mass2fract
;
v1
.
y
=
comVel
.
y
-
relVel
.
y
*
mass2fract
;
v1
.
z
=
comVel
.
z
-
relVel
.
z
*
mass2fract
;
pos1
.
x
=
v1
.
x
*
dtPos
;
pos1
.
y
=
v1
.
y
*
dtPos
;
pos1
.
z
=
v1
.
z
*
dtPos
;
posDelta
[
atom1
]
=
pos1
;
velm
[
atom1
]
=
v1
;
}
if
(
v2
.
w
!=
0.0
f
)
{
v2
.
x
=
comVel
.
x
+
relVel
.
x
*
mass1fract
;
v2
.
y
=
comVel
.
y
+
relVel
.
y
*
mass1fract
;
v2
.
z
=
comVel
.
z
+
relVel
.
z
*
mass1fract
;
pos2
.
x
=
v2
.
x
*
dtPos
;
pos2
.
y
=
v2
.
y
*
dtPos
;
pos2
.
z
=
v2
.
z
*
dtPos
;
posDelta
[
atom2
]
=
pos2
;
velm
[
atom2
]
=
v2
;
}
}
}
/**
* Perform the second step of Velocity Verlet integration.
*
* apply displacements to positions (posq) after constraints have been enforced
*/
extern
"C"
__global__
void
integrateVelocityVerletPart2
(
int
numAtoms
,
mixed2
*
__restrict__
dt
,
real4
*
__restrict__
posq
,
...
...
@@ -64,12 +136,16 @@ extern "C" __global__ void integrateVelocityVerletPart2(int numAtoms, mixed2* __
}
}
/**
* Perform the third step of Velocity Verlet integration.
*
* modify the velocities (velm) after the force update
*/
extern
"C"
__global__
void
integrateVelocityVerletPart3
(
int
numAtoms
,
int
paddedNumAtoms
,
mixed2
*
__restrict__
dt
,
real4
*
__restrict__
posq
,
real4
*
__restrict__
posqCorrection
,
mixed4
*
__restrict__
velm
,
const
long
long
*
__restrict__
force
,
const
mixed4
*
__restrict__
posDelta
)
{
extern
"C"
__global__
void
integrateVelocityVerletPart3
(
int
numAtoms
,
int
numPairs
,
int
paddedNumAtoms
,
mixed2
*
__restrict__
dt
,
real4
*
__restrict__
posq
,
real4
*
__restrict__
posqCorrection
,
mixed4
*
__restrict__
velm
,
const
long
long
*
__restrict__
force
,
const
mixed4
*
__restrict__
posDelta
,
const
int
*
__restrict__
atomList
,
const
int2
*
__restrict__
pairList
)
{
mixed2
stepSize
=
dt
[
0
];
#if __CUDA_ARCH__ >= 130
double
oneOverDt
=
1.0
/
stepSize
.
y
;
...
...
@@ -82,20 +158,192 @@ extern "C" __global__ void integrateVelocityVerletPart3(int numAtoms, int padded
int
index
=
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
;
if
(
index
==
0
)
dt
[
0
].
x
=
stepSize
.
y
;
for
(;
index
<
numAtoms
;
index
+=
blockDim
.
x
*
gridDim
.
x
)
{
mixed4
velocity
=
velm
[
index
];
for
(
int
index
=
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
;
index
<
numAtoms
;
index
+=
blockDim
.
x
*
gridDim
.
x
)
{
int
atom
=
atomList
[
index
];
mixed4
velocity
=
velm
[
atom
];
if
(
velocity
.
w
!=
0.0
)
{
mixed4
deltaXconstrained
=
posDelta
[
index
];
velocity
.
x
+=
scale
*
force
[
index
]
*
velocity
.
w
+
(
deltaXconstrained
.
x
-
velocity
.
x
*
stepSize
.
y
)
*
oneOverDt
;
velocity
.
y
+=
scale
*
force
[
index
+
paddedNumAtoms
]
*
velocity
.
w
+
(
deltaXconstrained
.
y
-
velocity
.
y
*
stepSize
.
y
)
*
oneOverDt
;
velocity
.
z
+=
scale
*
force
[
index
+
paddedNumAtoms
*
2
]
*
velocity
.
w
+
(
deltaXconstrained
.
z
-
velocity
.
z
*
stepSize
.
y
)
*
oneOverDt
;
mixed4
deltaXconstrained
=
posDelta
[
atom
];
velocity
.
x
+=
scale
*
force
[
atom
]
*
velocity
.
w
+
(
deltaXconstrained
.
x
-
velocity
.
x
*
stepSize
.
y
)
*
oneOverDt
;
velocity
.
y
+=
scale
*
force
[
atom
+
paddedNumAtoms
]
*
velocity
.
w
+
(
deltaXconstrained
.
y
-
velocity
.
y
*
stepSize
.
y
)
*
oneOverDt
;
velocity
.
z
+=
scale
*
force
[
atom
+
paddedNumAtoms
*
2
]
*
velocity
.
w
+
(
deltaXconstrained
.
z
-
velocity
.
z
*
stepSize
.
y
)
*
oneOverDt
;
#if __CUDA_ARCH__ < 130
velocity
.
x
+=
(
deltaXconstrained
.
x
-
velocity
.
x
*
stepSize
.
y
)
*
correction
;
velocity
.
y
+=
(
deltaXconstrained
.
y
-
velocity
.
y
*
stepSize
.
y
)
*
correction
;
velocity
.
z
+=
(
deltaXconstrained
.
z
-
velocity
.
z
*
stepSize
.
y
)
*
correction
;
#endif
velm
[
index
]
=
velocity
;
velm
[
atom
]
=
velocity
;
}
}
for
(
int
index
=
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
;
index
<
numPairs
;
index
+=
blockDim
.
x
*
gridDim
.
x
)
{
int
atom1
=
pairList
[
index
].
x
;
int
atom2
=
pairList
[
index
].
y
;
mixed4
v1
=
velm
[
atom1
];
mixed4
v2
=
velm
[
atom2
];
mixed
m1
=
v1
.
w
==
0.0
f
?
0.0
f
:
1.0
f
/
v1
.
w
;
mixed
m2
=
v2
.
w
==
0.0
f
?
0.0
f
:
1.0
f
/
v2
.
w
;
mixed
mass1fract
=
m1
/
(
m1
+
m2
);
mixed
mass2fract
=
m2
/
(
m1
+
m2
);
mixed
invRedMass
=
(
m1
*
m2
!=
0.0
f
)
?
(
m1
+
m2
)
/
(
m1
*
m2
)
:
0.0
f
;
mixed
invTotMass
=
(
m1
+
m2
!=
0.0
f
)
?
1.0
f
/
(
m1
+
m2
)
:
0.0
f
;
mixed3
comVel
;
comVel
.
x
=
v1
.
x
*
mass1fract
+
v2
.
x
*
mass2fract
;
comVel
.
y
=
v1
.
y
*
mass1fract
+
v2
.
y
*
mass2fract
;
comVel
.
z
=
v1
.
z
*
mass1fract
+
v2
.
z
*
mass2fract
;
mixed3
relVel
;
relVel
.
x
=
v2
.
x
-
v1
.
x
;
relVel
.
y
=
v2
.
y
-
v1
.
y
;
relVel
.
z
=
v2
.
z
-
v1
.
z
;
//
mixed3
comFrc
;
comFrc
.
x
=
force
[
atom1
]
+
force
[
atom2
];
comFrc
.
y
=
force
[
atom1
+
paddedNumAtoms
]
+
force
[
atom2
+
paddedNumAtoms
];
comFrc
.
z
=
force
[
atom1
+
paddedNumAtoms
*
2
]
+
force
[
atom2
+
paddedNumAtoms
*
2
];
mixed3
relFrc
;
relFrc
.
x
=
mass1fract
*
force
[
atom2
]
-
mass2fract
*
force
[
atom1
];
relFrc
.
y
=
mass1fract
*
force
[
atom2
+
paddedNumAtoms
]
-
mass2fract
*
force
[
atom1
+
paddedNumAtoms
];
relFrc
.
z
=
mass1fract
*
force
[
atom2
+
paddedNumAtoms
*
2
]
-
mass2fract
*
force
[
atom1
+
paddedNumAtoms
*
2
];
comVel
.
x
+=
comFrc
.
x
*
scale
*
invTotMass
;
comVel
.
y
+=
comFrc
.
y
*
scale
*
invTotMass
;
comVel
.
z
+=
comFrc
.
z
*
scale
*
invTotMass
;
relVel
.
x
+=
relFrc
.
x
*
scale
*
invRedMass
;
relVel
.
y
+=
relFrc
.
y
*
scale
*
invRedMass
;
relVel
.
z
+=
relFrc
.
z
*
scale
*
invRedMass
;
if
(
v1
.
w
!=
0.0
f
)
{
mixed4
deltaXconstrained
=
posDelta
[
atom1
];
v1
.
x
=
comVel
.
x
-
relVel
.
x
*
mass2fract
+
(
deltaXconstrained
.
x
-
v1
.
x
*
stepSize
.
y
)
*
oneOverDt
;
v1
.
y
=
comVel
.
y
-
relVel
.
y
*
mass2fract
+
(
deltaXconstrained
.
y
-
v1
.
y
*
stepSize
.
y
)
*
oneOverDt
;
v1
.
z
=
comVel
.
z
-
relVel
.
z
*
mass2fract
+
(
deltaXconstrained
.
z
-
v1
.
z
*
stepSize
.
y
)
*
oneOverDt
;
#if __CUDA_ARCH__ < 130
v1
.
x
+=
(
deltaXconstrained
.
x
-
v1
.
x
*
stepSize
.
y
)
*
correction
;
v1
.
y
+=
(
deltaXconstrained
.
y
-
v1
.
y
*
stepSize
.
y
)
*
correction
;
v1
.
z
+=
(
deltaXconstrained
.
z
-
v1
.
z
*
stepSize
.
y
)
*
correction
;
#endif
velm
[
atom1
]
=
v1
;
}
if
(
v2
.
w
!=
0.0
f
)
{
mixed4
deltaXconstrained
=
posDelta
[
atom2
];
v2
.
x
=
comVel
.
x
+
relVel
.
x
*
mass1fract
+
(
deltaXconstrained
.
x
-
v2
.
x
*
stepSize
.
y
)
*
oneOverDt
;
v2
.
y
=
comVel
.
y
+
relVel
.
y
*
mass1fract
+
(
deltaXconstrained
.
y
-
v2
.
y
*
stepSize
.
y
)
*
oneOverDt
;
v2
.
z
=
comVel
.
z
+
relVel
.
z
*
mass1fract
+
(
deltaXconstrained
.
z
-
v2
.
z
*
stepSize
.
y
)
*
oneOverDt
;
#if __CUDA_ARCH__ < 130
v2
.
x
+=
(
deltaXconstrained
.
x
-
v2
.
x
*
stepSize
.
y
)
*
correction
;
v2
.
y
+=
(
deltaXconstrained
.
y
-
v2
.
y
*
stepSize
.
y
)
*
correction
;
v2
.
z
+=
(
deltaXconstrained
.
z
-
v2
.
z
*
stepSize
.
y
)
*
correction
;
#endif
velm
[
atom2
]
=
v2
;
}
}
}
/**
* Apply the hard wall constraint
*/
extern
"C"
__global__
void
integrateVelocityVerletHardWall
(
int
numPairs
,
const
float
*
__restrict__
maxPairDistance
,
mixed2
*
__restrict__
dt
,
real4
*
__restrict__
posq
,
real4
*
__restrict__
posqCorrection
,
mixed4
*
__restrict__
velm
,
const
int2
*
__restrict__
pairList
,
const
float
*
__restrict__
pairTemperature
)
{
mixed
dtPos
=
dt
[
0
].
y
;
mixed
maxDelta
=
(
mixed
)
maxPairDistance
[
0
];
// Apply hard wall constraints.
if
(
maxDelta
>
0
)
{
for
(
int
index
=
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
;
index
<
numPairs
;
index
+=
blockDim
.
x
*
gridDim
.
x
)
{
const
mixed
hardWallScale
=
sqrt
(
((
mixed
)
pairTemperature
[
index
])
*
((
mixed
)
BOLTZ
));
int2
atom
=
make_int2
(
pairList
[
index
].
x
,
pairList
[
index
].
y
);
#ifdef USE_MIXED_PRECISION
real4
posv1
=
posq
[
atom
.
x
];
real4
posc1
=
posqCorrection
[
atom
.
x
];
mixed4
pos1
=
make_mixed4
(
posv1
.
x
+
(
mixed
)
posc1
.
x
,
posv1
.
y
+
(
mixed
)
posc1
.
y
,
posv1
.
z
+
(
mixed
)
posc1
.
z
,
posv1
.
w
);
real4
posv2
=
posq
[
atom
.
y
];
real4
posc2
=
posqCorrection
[
atom
.
y
];
mixed4
pos2
=
make_mixed4
(
posv2
.
x
+
(
mixed
)
posc2
.
x
,
posv2
.
y
+
(
mixed
)
posc2
.
y
,
posv2
.
z
+
(
mixed
)
posc2
.
z
,
posv2
.
w
);
#else
real4
pos1
=
posq
[
atom
.
x
];
real4
pos2
=
posq
[
atom
.
y
];
#endif
mixed3
delta
=
make_mixed3
(
mixed
(
pos1
.
x
-
pos2
.
x
),
mixed
(
pos1
.
y
-
pos2
.
y
),
mixed
(
pos1
.
z
-
pos2
.
z
)
);
mixed
r
=
sqrt
(
delta
.
x
*
delta
.
x
+
delta
.
y
*
delta
.
y
+
delta
.
z
*
delta
.
z
);
mixed
rInv
=
1
/
r
;
if
(
rInv
*
maxDelta
<
1.0
)
{
// The constraint has been violated, so make the inter-particle distance "bounce"
// off the hard wall.
mixed3
bondDir
=
make_mixed3
(
delta
.
x
*
rInv
,
delta
.
y
*
rInv
,
delta
.
z
*
rInv
);
mixed3
vel1
=
make_mixed3
(
velm
[
atom
.
x
].
x
,
velm
[
atom
.
x
].
y
,
velm
[
atom
.
x
].
z
);
mixed3
vel2
=
make_mixed3
(
velm
[
atom
.
y
].
x
,
velm
[
atom
.
y
].
y
,
velm
[
atom
.
y
].
z
);
mixed
m1
=
velm
[
atom
.
x
].
w
!=
0.0
?
1.0
/
velm
[
atom
.
x
].
w
:
0.0
;
mixed
m2
=
velm
[
atom
.
y
].
w
!=
0.0
?
1.0
/
velm
[
atom
.
y
].
w
:
0.0
;
mixed
invTotMass
=
(
m1
+
m2
!=
0.0
)
?
1.0
/
(
m1
+
m2
)
:
0.0
;
mixed
deltaR
=
r
-
maxDelta
;
mixed
deltaT
=
dtPos
;
mixed
dt
=
dtPos
;
mixed
dotvr1
=
vel1
.
x
*
bondDir
.
x
+
vel1
.
y
*
bondDir
.
y
+
vel1
.
z
*
bondDir
.
z
;
mixed3
vb1
=
make_mixed3
(
bondDir
.
x
*
dotvr1
,
bondDir
.
y
*
dotvr1
,
bondDir
.
z
*
dotvr1
);
mixed3
vp1
=
make_mixed3
(
vel1
.
x
-
vb1
.
x
,
vel1
.
y
-
vb1
.
y
,
vel1
.
z
-
vb1
.
z
);
if
(
m2
==
0
)
{
// The parent particle is massless, so move only the Drude particle.
if
(
dotvr1
!=
0.0
)
deltaT
=
deltaR
/
fabs
(
dotvr1
);
if
(
deltaT
>
dtPos
)
deltaT
=
dtPos
;
dotvr1
=
-
dotvr1
*
hardWallScale
/
(
fabs
(
dotvr1
)
*
sqrt
(
m1
));
mixed
dr
=
-
deltaR
+
deltaT
*
dotvr1
;
pos1
.
x
+=
bondDir
.
x
*
dr
;
pos1
.
y
+=
bondDir
.
y
*
dr
;
pos1
.
z
+=
bondDir
.
z
*
dr
;
velm
[
atom
.
x
]
=
make_mixed4
(
vp1
.
x
+
bondDir
.
x
*
dotvr1
,
vp1
.
y
+
bondDir
.
y
*
dotvr1
,
vp1
.
z
+
bondDir
.
z
*
dotvr1
,
velm
[
atom
.
x
].
w
);
#ifdef USE_MIXED_PRECISION
posq
[
atom
.
x
]
=
make_real4
((
real
)
pos1
.
x
,
(
real
)
pos1
.
y
,
(
real
)
pos1
.
z
,
(
real
)
pos1
.
w
);
posqCorrection
[
atom
.
x
]
=
make_real4
(
pos1
.
x
-
(
real
)
pos1
.
x
,
pos1
.
y
-
(
real
)
pos1
.
y
,
pos1
.
z
-
(
real
)
pos1
.
z
,
0
);
#else
posq
[
atom
.
x
]
=
pos1
;
#endif
}
else
{
// Move both particles.
mixed
dotvr2
=
vel2
.
x
*
bondDir
.
x
+
vel2
.
y
*
bondDir
.
y
+
vel2
.
z
*
bondDir
.
z
;
mixed3
vb2
=
make_mixed3
(
bondDir
.
x
*
dotvr2
,
bondDir
.
y
*
dotvr2
,
bondDir
.
z
*
dotvr2
);
mixed3
vp2
=
make_mixed3
(
vel2
.
x
-
vb2
.
x
,
vel2
.
y
-
vb2
.
y
,
vel2
.
z
-
vb2
.
z
);
mixed
vbCMass
=
(
m1
*
dotvr1
+
m2
*
dotvr2
)
*
invTotMass
;
dotvr1
-=
vbCMass
;
dotvr2
-=
vbCMass
;
if
(
dotvr1
!=
dotvr2
)
deltaT
=
deltaR
/
fabs
(
dotvr1
-
dotvr2
);
if
(
deltaT
>
dt
)
deltaT
=
dt
;
mixed
vBond
=
hardWallScale
/
sqrt
(
m1
);
dotvr1
=
-
dotvr1
*
vBond
*
m2
*
invTotMass
/
fabs
(
dotvr1
);
dotvr2
=
-
dotvr2
*
vBond
*
m1
*
invTotMass
/
fabs
(
dotvr2
);
mixed
dr1
=
-
deltaR
*
m2
*
invTotMass
+
deltaT
*
dotvr1
;
mixed
dr2
=
deltaR
*
m1
*
invTotMass
+
deltaT
*
dotvr2
;
dotvr1
+=
vbCMass
;
dotvr2
+=
vbCMass
;
pos1
.
x
+=
bondDir
.
x
*
dr1
;
pos1
.
y
+=
bondDir
.
y
*
dr1
;
pos1
.
z
+=
bondDir
.
z
*
dr1
;
pos2
.
x
+=
bondDir
.
x
*
dr2
;
pos2
.
y
+=
bondDir
.
y
*
dr2
;
pos2
.
z
+=
bondDir
.
z
*
dr2
;
velm
[
atom
.
x
]
=
make_mixed4
(
vp1
.
x
+
bondDir
.
x
*
dotvr1
,
vp1
.
y
+
bondDir
.
y
*
dotvr1
,
vp1
.
z
+
bondDir
.
z
*
dotvr1
,
velm
[
atom
.
x
].
w
);
velm
[
atom
.
y
]
=
make_mixed4
(
vp2
.
x
+
bondDir
.
x
*
dotvr2
,
vp2
.
y
+
bondDir
.
y
*
dotvr2
,
vp2
.
z
+
bondDir
.
z
*
dotvr2
,
velm
[
atom
.
y
].
w
);
#ifdef USE_MIXED_PRECISION
posq
[
atom
.
x
]
=
make_real4
((
real
)
pos1
.
x
,
(
real
)
pos1
.
y
,
(
real
)
pos1
.
z
,
(
real
)
pos1
.
w
);
posq
[
atom
.
y
]
=
make_real4
((
real
)
pos2
.
x
,
(
real
)
pos2
.
y
,
(
real
)
pos2
.
z
,
(
real
)
pos2
.
w
);
posqCorrection
[
atom
.
x
]
=
make_real4
(
pos1
.
x
-
(
real
)
pos1
.
x
,
pos1
.
y
-
(
real
)
pos1
.
y
,
pos1
.
z
-
(
real
)
pos1
.
z
,
0
);
posqCorrection
[
atom
.
y
]
=
make_real4
(
pos2
.
x
-
(
real
)
pos2
.
x
,
pos2
.
y
-
(
real
)
pos2
.
y
,
pos2
.
z
-
(
real
)
pos2
.
z
,
0
);
#else
posq
[
atom
.
x
]
=
pos1
;
posq
[
atom
.
y
]
=
pos2
;
#endif
}
}
}
}
/* end of hard wall constraint part */
}
platforms/opencl/include/OpenCLKernels.h
View file @
7f1dd6a3
...
...
@@ -1381,7 +1381,9 @@ public:
double
computeKineticEnergy
(
ContextImpl
&
context
,
const
NoseHooverIntegrator
&
integrator
);
private:
OpenCLContext
&
cl
;
cl
::
Kernel
kernel1
,
kernel2
,
kernel3
;
float
prevMaxPairDistance
;
OpenCLArray
maxPairDistanceBuffer
,
pairListBuffer
,
atomListBuffer
,
pairTemperatureBuffer
;
cl
::
Kernel
kernel1
,
kernel2
,
kernel3
,
kernelHardWall
;
};
/**
...
...
platforms/opencl/src/OpenCLKernels.cpp
View file @
7f1dd6a3
...
...
@@ -7395,45 +7395,101 @@ double OpenCLIntegrateVerletStepKernel::computeKineticEnergy(ContextImpl& contex
void OpenCLIntegrateVelocityVerletStepKernel::initialize(const System& system, const NoseHooverIntegrator& integrator) {
cl.getPlatformData().initializeContexts(system);
map<string, string> defines;
defines["BOLTZ"] = cl.doubleToString(BOLTZ);
cl::Program program = cl.createProgram(OpenCLKernelSources::velocityVerlet, defines, "");
kernel1 = cl::Kernel(program, "integrateVelocityVerletPart1");
kernel2 = cl::Kernel(program, "integrateVelocityVerletPart2");
kernel3 = cl::Kernel(program, "integrateVelocityVerletPart3");
kernelHardWall = cl::Kernel(program, "integrateVelocityVerletHardWall");
prevMaxPairDistance = (cl_float) -1.0;
maxPairDistanceBuffer.initialize<cl_float>(cl, 1, "maxPairDistanceBuffer");
}
void OpenCLIntegrateVelocityVerletStepKernel::execute(ContextImpl& context, const NoseHooverIntegrator& integrator, bool &forcesAreValid) {
OpenCLIntegrationUtilities& integration = cl.getIntegrationUtilities();
int numAtoms = cl.getNumAtoms();
int paddedNumAtoms = cl.getPaddedNumAtoms();
double dt = integrator.getStepSize();
cl.getIntegrationUtilities().setNextStepSize(dt);
if( !forcesAreValid ) context.calcForcesAndEnergy(true, false);
//// Call the first integration kernel.
const auto& atomList = integrator.getAllAtoms();
const auto& pairList = integrator.getAllPairs();
int numAtoms = atomList.size();
int numPairs = pairList.size();
int numParticles = numAtoms + 2*numPairs;
float maxPairDistance = integrator.getMaximumPairDistance();
// Make sure atom and pair metadata is uploaded and has the correct dimensions
if (prevMaxPairDistance != maxPairDistance) {
std::vector<float> tmp(1, maxPairDistance);
maxPairDistanceBuffer.upload(tmp);
prevMaxPairDistance = maxPairDistance;
}
if (numAtoms !=0 && (!atomListBuffer.isInitialized() || atomListBuffer.getSize() != numAtoms)) {
atomListBuffer.initialize<cl_int>(cl, atomList.size(), "atomListBuffer");
atomListBuffer.upload(atomList);
}
if (numPairs !=0 && (!pairListBuffer.isInitialized() || pairListBuffer.getSize() != numPairs)) {
std::vector<mm_int2> tmp;
std::vector<float> tmp2;
for(const auto &pair : pairList) {
tmp.push_back(mm_int2(std::get<0>(pair), std::get<1>(pair)));
tmp2.push_back(std::get<2>(pair));
}
pairListBuffer.initialize<mm_int2>(cl, pairList.size(), "pairListBuffer");
pairListBuffer.upload(tmp);
pairTemperatureBuffer.initialize<cl_float>(cl, pairList.size(), "pairTemperatureBuffer");
pairTemperatureBuffer.upload(tmp2);
}
//// Call the first integration kernel.
kernel1.setArg<cl_int>(0, numAtoms);
kernel1.setArg<cl_int>(1, paddedNumAtoms);
kernel1.setArg<cl::Buffer>(2, cl.getIntegrationUtilities().getStepSize().getDeviceBuffer());
kernel1.setArg<cl::Buffer>(3, cl.getPosq().getDeviceBuffer());
setPosqCorrectionArg(cl, kernel1, 4);
kernel1.setArg<cl::Buffer>(5, cl.getVelm().getDeviceBuffer());
kernel1.setArg<cl::Buffer>(6, cl.getForce().getDeviceBuffer());
kernel1.setArg<cl::Buffer>(7, integration.getPosDelta().getDeviceBuffer());
cl.executeKernel(kernel1, numAtoms);
kernel1.setArg<cl_int>(1, numPairs);
kernel1.setArg<cl_int>(2, paddedNumAtoms);
kernel1.setArg<cl::Buffer>(3, cl.getIntegrationUtilities().getStepSize().getDeviceBuffer());
kernel1.setArg<cl::Buffer>(4, cl.getPosq().getDeviceBuffer());
setPosqCorrectionArg(cl, kernel1, 5);
kernel1.setArg<cl::Buffer>(6, cl.getVelm().getDeviceBuffer());
kernel1.setArg<cl::Buffer>(7, cl.getForce().getDeviceBuffer());
kernel1.setArg<cl::Buffer>(8, integration.getPosDelta().getDeviceBuffer());
if (numAtoms > 0) {
kernel1.setArg<cl::Buffer>(9, atomListBuffer.getDeviceBuffer());
} else {
kernel1.setArg<void*>(9, NULL);
}
if (numPairs > 0) {
kernel1.setArg<cl::Buffer>(10, pairListBuffer.getDeviceBuffer());
} else {
kernel1.setArg<void*>(10, NULL);
}
cl.executeKernel(kernel1, std::max(numAtoms, numPairs));
//// Apply constraints.
integration.applyConstraints(integrator.getConstraintTolerance());
//// Call the second integration kernel.
kernel2.setArg<cl_int>(0, numAtoms);
kernel2.setArg<cl_int>(0, numParticles);
kernel2.setArg<cl::Buffer>(1, cl.getIntegrationUtilities().getStepSize().getDeviceBuffer());
kernel2.setArg<cl::Buffer>(2, cl.getPosq().getDeviceBuffer());
setPosqCorrectionArg(cl, kernel2, 3);
kernel2.setArg<cl::Buffer>(4, cl.getVelm().getDeviceBuffer());
kernel2.setArg<cl::Buffer>(5, integration.getPosDelta().getDeviceBuffer());
cl.executeKernel(kernel2, numAtoms);
cl.executeKernel(kernel2, numParticles);
if (numPairs > 0) {
//// Enforce hard wall constraint
kernelHardWall.setArg<cl_int>(0, numPairs);
kernelHardWall.setArg<cl::Buffer>(1, maxPairDistanceBuffer.getDeviceBuffer());
kernelHardWall.setArg<cl::Buffer>(2, cl.getIntegrationUtilities().getStepSize().getDeviceBuffer());
kernelHardWall.setArg<cl::Buffer>(3, cl.getPosq().getDeviceBuffer());
setPosqCorrectionArg(cl, kernelHardWall, 4);
kernelHardWall.setArg<cl::Buffer>(5, cl.getVelm().getDeviceBuffer());
kernelHardWall.setArg<cl::Buffer>(6, pairListBuffer.getDeviceBuffer());
kernelHardWall.setArg<cl::Buffer>(7, pairTemperatureBuffer.getDeviceBuffer());
cl.executeKernel(kernelHardWall, numPairs);
}
integration.computeVirtualSites();
...
...
@@ -7443,14 +7499,25 @@ void OpenCLIntegrateVelocityVerletStepKernel::execute(ContextImpl& context, cons
//// Call the third integration kernel.
kernel3.setArg<cl_int>(0, numAtoms);
kernel3.setArg<cl_int>(1, paddedNumAtoms);
kernel3.setArg<cl::Buffer>(2, cl.getIntegrationUtilities().getStepSize().getDeviceBuffer());
kernel3.setArg<cl::Buffer>(3, cl.getPosq().getDeviceBuffer());
setPosqCorrectionArg(cl, kernel3, 4);
kernel3.setArg<cl::Buffer>(5, cl.getVelm().getDeviceBuffer());
kernel3.setArg<cl::Buffer>(6, cl.getForce().getDeviceBuffer());
kernel3.setArg<cl::Buffer>(7, integration.getPosDelta().getDeviceBuffer());
cl.executeKernel(kernel3, numAtoms);
kernel3.setArg<cl_int>(1, numPairs);
kernel3.setArg<cl_int>(2, paddedNumAtoms);
kernel3.setArg<cl::Buffer>(3, cl.getIntegrationUtilities().getStepSize().getDeviceBuffer());
kernel3.setArg<cl::Buffer>(4, cl.getPosq().getDeviceBuffer());
setPosqCorrectionArg(cl, kernel3, 5);
kernel3.setArg<cl::Buffer>(6, cl.getVelm().getDeviceBuffer());
kernel3.setArg<cl::Buffer>(7, cl.getForce().getDeviceBuffer());
kernel3.setArg<cl::Buffer>(8, integration.getPosDelta().getDeviceBuffer());
if (numAtoms > 0) {
kernel3.setArg<cl::Buffer>(9, atomListBuffer.getDeviceBuffer());
} else {
kernel3.setArg<void*>(9, NULL);
}
if (numPairs > 0) {
kernel3.setArg<cl::Buffer>(10, pairListBuffer.getDeviceBuffer());
} else {
kernel3.setArg<void*>(10, NULL);
}
cl.executeKernel(kernel3, std::max(numAtoms, numPairs));
integration.applyVelocityConstraints(integrator.getConstraintTolerance());
...
...
platforms/opencl/src/kernels/velocityVerlet.cl
View file @
7f1dd6a3
...
...
@@ -2,33 +2,103 @@
*
Perform
the
first
step
of
Velocity
Verlet
integration.
*/
__kernel
void
integrateVelocityVerletPart1
(
int
numAtoms,
int
paddedNumAtoms,
__global
const
mixed2*
restrict
dt,
__global
const
real4*
restrict
posq,
__global
const
real4*
restrict
posqCorrection,
__global
mixed4*
restrict
velm,
__global
const
real4*
restrict
force,
__global
mixed4*
restrict
posDelta
)
{
__kernel
void
integrateVelocityVerletPart1
(
int
numAtoms,
int
numPairs,
int
paddedNumAtoms,
__global
const
mixed2*
restrict
dt,
__global
const
real4*
restrict
posq,
__global
const
real4*
restrict
posqCorrection,
__global
mixed4*
restrict
velm,
__global
const
real4*
restrict
force,
__global
mixed4*
restrict
posDelta,
__global
const
int*
restrict
atomList,
__global
const
int2*
restrict
pairList
)
{
const
mixed2
stepSize
=
dt[0]
;
const
mixed
dtPos
=
stepSize.y
;
const
mixed
dtVel
=
0.5f*
(
stepSize.x+stepSize.y
)
;
int
index
=
get_global_id
(
0
)
;
while
(
index
<
numAtoms
)
{
mixed4
velocity
=
velm[index]
;
while
(
index
<
numAtoms
)
{
int
atom
=
atomList[index]
;
mixed4
velocity
=
velm[atom]
;
if
(
velocity.w
!=
0.0
)
{
#
ifdef
USE_MIXED_PRECISION
real4
pos1
=
posq[
index
]
;
real4
pos2
=
posqCorrection[
index
]
;
real4
pos1
=
posq[
atom
]
;
real4
pos2
=
posqCorrection[
atom
]
;
mixed4
pos
=
(
mixed4
)
(
pos1.x+
(
mixed
)
pos2.x,
pos1.y+
(
mixed
)
pos2.y,
pos1.z+
(
mixed
)
pos2.z,
pos1.w
)
;
#
else
real4
pos
=
posq[
index
]
;
real4
pos
=
posq[
atom
]
;
#
endif
velocity.x
+=
0.5f
*
dtVel*force[
index
].x*velocity.w
;
velocity.y
+=
0.5f
*
dtVel*force[
index
].y*velocity.w
;
velocity.z
+=
0.5f
*
dtVel*force[
index
].z*velocity.w
;
velocity.x
+=
0.5f
*
dtVel*force[
atom
].x*velocity.w
;
velocity.y
+=
0.5f
*
dtVel*force[
atom
].y*velocity.w
;
velocity.z
+=
0.5f
*
dtVel*force[
atom
].z*velocity.w
;
pos.x
=
velocity.x*dtPos
;
pos.y
=
velocity.y*dtPos
;
pos.z
=
velocity.z*dtPos
;
posDelta[
index
]
=
pos
;
velm[
index
]
=
velocity
;
posDelta[
atom
]
=
pos
;
velm[
atom
]
=
velocity
;
}
index
+=
get_global_size
(
0
)
;
}
index
=
get_global_id
(
0
)
;
while
(
index
<
numPairs
)
{
int
atom1
=
pairList[index].x
;
int
atom2
=
pairList[index].y
;
mixed4
v1
=
velm[atom1]
;
mixed4
v2
=
velm[atom2]
;
mixed
m1
=
v1.w
==
0.0f
?
0.0f
:
1.0f
/
v1.w
;
mixed
m2
=
v2.w
==
0.0f
?
0.0f
:
1.0f
/
v2.w
;
mixed
mass1fract
=
m1
/
(
m1
+
m2
)
;
mixed
mass2fract
=
m2
/
(
m1
+
m2
)
;
mixed
invRedMass
=
(
m1
*
m2
!=
0.0f
)
?
(
m1
+
m2
)
/
(
m1
*
m2
)
:
0.0f
;
mixed
invTotMass
=
(
m1
+
m2
!=
0.0f
)
?
1.0f
/
(
m1
+
m2
)
:
0.0f
;
mixed3
comVel
;
comVel.x=
v1.x*mass1fract
+
v2.x*mass2fract
;
comVel.y=
v1.y*mass1fract
+
v2.y*mass2fract
;
comVel.z=
v1.z*mass1fract
+
v2.z*mass2fract
;
mixed3
relVel
;
relVel.x=
v2.x
-
v1.x
;
relVel.y=
v2.y
-
v1.y
;
relVel.z=
v2.z
-
v1.z
;
mixed3
comFrc
;
comFrc.x
=
force[atom1].x
+
force[atom2].x
;
comFrc.y
=
force[atom1].y
+
force[atom2].y
;
comFrc.z
=
force[atom1].z
+
force[atom2].z
;
mixed3
relFrc
;
relFrc.x
=
mass1fract*force[atom2].x
-
mass2fract*force[atom1].x
;
relFrc.y
=
mass1fract*force[atom2].y
-
mass2fract*force[atom1].y
;
relFrc.z
=
mass1fract*force[atom2].z
-
mass2fract*force[atom1].z
;
comVel.x
+=
comFrc.x
*
0.5f
*
dtVel
*
invTotMass
;
comVel.y
+=
comFrc.y
*
0.5f
*
dtVel
*
invTotMass
;
comVel.z
+=
comFrc.z
*
0.5f
*
dtVel
*
invTotMass
;
relVel.x
+=
relFrc.x
*
0.5f
*
dtVel
*
invRedMass
;
relVel.y
+=
relFrc.y
*
0.5f
*
dtVel
*
invRedMass
;
relVel.z
+=
relFrc.z
*
0.5f
*
dtVel
*
invRedMass
;
#
ifdef
USE_MIXED_PRECISION
real4
posv1
=
posq[atom1]
;
real4
posv2
=
posq[atom2]
;
real4
posc1
=
posqCorrection[atom1]
;
real4
posc2
=
posqCorrection[atom2]
;
mixed4
pos1
=
(
mixed4
)
(
posv1.x+
(
mixed
)
posc1.x,
posv1.y+
(
mixed
)
posc1.y,
posv1.z+
(
mixed
)
posc1.z,
posv1.w
)
;
mixed4
pos2
=
(
mixed4
)
(
posv2.x+
(
mixed
)
posc2.x,
posv2.y+
(
mixed
)
posc2.y,
posv2.z+
(
mixed
)
posc2.z,
posv2.w
)
;
#
else
real4
pos1
=
posq[atom1]
;
real4
pos2
=
posq[atom2]
;
#
endif
if
(
v1.w
!=
0.0f
)
{
v1.x
=
comVel.x
-
relVel.x*mass2fract
;
v1.y
=
comVel.y
-
relVel.y*mass2fract
;
v1.z
=
comVel.z
-
relVel.z*mass2fract
;
pos1.x
=
v1.x*dtPos
;
pos1.y
=
v1.y*dtPos
;
pos1.z
=
v1.z*dtPos
;
posDelta[atom1]
=
pos1
;
velm[atom1]
=
v1
;
}
if
(
v2.w
!=
0.0f
)
{
v2.x
=
comVel.x
+
relVel.x*mass1fract
;
v2.y
=
comVel.y
+
relVel.y*mass1fract
;
v2.z
=
comVel.z
+
relVel.z*mass1fract
;
pos2.x
=
v2.x*dtPos
;
pos2.y
=
v2.y*dtPos
;
pos2.z
=
v2.z*dtPos
;
posDelta[atom2]
=
pos2
;
velm[atom2]
=
v2
;
}
index
+=
get_global_size
(
0
)
;
}
}
/**
...
...
@@ -68,8 +138,9 @@ __kernel void integrateVelocityVerletPart2(int numAtoms, __global mixed2* restri
*
Perform
the
third
step
of
Velocity
Verlet
integration.
*/
__kernel
void
integrateVelocityVerletPart3
(
int
numAtoms,
int
paddedNumAtoms,
__global
mixed2*
restrict
dt,
__global
real4*
restrict
posq,
__global
real4*
restrict
posqCorrection,
__global
mixed4*
restrict
velm,
__global
const
real4*
restrict
force,
__global
const
mixed4*
restrict
posDelta
)
{
__kernel
void
integrateVelocityVerletPart3
(
int
numAtoms,
int
numPairs,
int
paddedNumAtoms,
__global
mixed2*
restrict
dt,
__global
real4*
restrict
posq,
__global
real4*
restrict
posqCorrection,
__global
mixed4*
restrict
velm,
__global
const
real4*
restrict
force,
__global
const
mixed4*
restrict
posDelta,
__global
const
int*
restrict
atomList,
__global
const
int2*
__restrict__
pairList
)
{
mixed2
stepSize
=
dt[0]
;
#
ifndef
SUPPORTS_DOUBLE_PRECISION
double
oneOverDt
=
1.0/stepSize.y
;
...
...
@@ -82,20 +153,192 @@ __kernel void integrateVelocityVerletPart3(int numAtoms, int paddedNumAtoms, __g
if
(
index
==
0
)
dt[0].x
=
stepSize.y
;
while
(
index
<
numAtoms
)
{
mixed4
velocity
=
velm[index]
;
int
atom
=
atomList[index]
;
mixed4
velocity
=
velm[atom]
;
if
(
velocity.w
!=
0.0
)
{
mixed4
deltaXconstrained
=
posDelta[
index
]
;
velocity.x
+=
0.5f
*
dtVel*force[
index
].x*velocity.w
+
(
deltaXconstrained.x
-
velocity.x*stepSize.y
)
*oneOverDt
;
velocity.y
+=
0.5f
*
dtVel*force[
index
].y*velocity.w
+
(
deltaXconstrained.y
-
velocity.y*stepSize.y
)
*oneOverDt
;
velocity.z
+=
0.5f
*
dtVel*force[
index
].z*velocity.w
+
(
deltaXconstrained.z
-
velocity.z*stepSize.y
)
*oneOverDt
;
mixed4
deltaXconstrained
=
posDelta[
atom
]
;
velocity.x
+=
0.5f
*
dtVel*force[
atom
].x*velocity.w
+
(
deltaXconstrained.x
-
velocity.x*stepSize.y
)
*oneOverDt
;
velocity.y
+=
0.5f
*
dtVel*force[
atom
].y*velocity.w
+
(
deltaXconstrained.y
-
velocity.y*stepSize.y
)
*oneOverDt
;
velocity.z
+=
0.5f
*
dtVel*force[
atom
].z*velocity.w
+
(
deltaXconstrained.z
-
velocity.z*stepSize.y
)
*oneOverDt
;
#
ifdef
SUPPORTS_DOUBLE_PRECISION
velocity.x
+=
(
deltaXconstrained.x
-
velocity.x*stepSize.y
)
*correction
;
velocity.y
+=
(
deltaXconstrained.y
-
velocity.y*stepSize.y
)
*correction
;
velocity.z
+=
(
deltaXconstrained.z
-
velocity.z*stepSize.y
)
*correction
;
#
endif
velm[index]
=
velocity
;
velm[atom]
=
velocity
;
}
index
+=
get_global_size
(
0
)
;
}
index
=
get_global_id
(
0
)
;
while
(
index
<
numPairs
)
{
int
atom1
=
pairList[index].x
;
int
atom2
=
pairList[index].y
;
mixed4
v1
=
velm[atom1]
;
mixed4
v2
=
velm[atom2]
;
mixed
m1
=
v1.w
==
0.0f
?
0.0f
:
1.0f
/
v1.w
;
mixed
m2
=
v2.w
==
0.0f
?
0.0f
:
1.0f
/
v2.w
;
mixed
mass1fract
=
m1
/
(
m1
+
m2
)
;
mixed
mass2fract
=
m2
/
(
m1
+
m2
)
;
mixed
invRedMass
=
(
m1
*
m2
!=
0.0f
)
?
(
m1
+
m2
)
/
(
m1
*
m2
)
:
0.0f
;
mixed
invTotMass
=
(
m1
+
m2
!=
0.0f
)
?
1.0f
/
(
m1
+
m2
)
:
0.0f
;
mixed3
comVel
;
comVel.x=
v1.x*mass1fract
+
v2.x*mass2fract
;
comVel.y=
v1.y*mass1fract
+
v2.y*mass2fract
;
comVel.z=
v1.z*mass1fract
+
v2.z*mass2fract
;
mixed3
relVel
;
relVel.x=
v2.x
-
v1.x
;
relVel.y=
v2.y
-
v1.y
;
relVel.z=
v2.z
-
v1.z
;
mixed3
comFrc
;
comFrc.x
=
force[atom1].x
+
force[atom2].x
;
comFrc.y
=
force[atom1].y
+
force[atom2].y
;
comFrc.z
=
force[atom1].z
+
force[atom2].z
;
mixed3
relFrc
;
relFrc.x
=
mass1fract*force[atom2].x
-
mass2fract*force[atom1].x
;
relFrc.y
=
mass1fract*force[atom2].y
-
mass2fract*force[atom1].y
;
relFrc.z
=
mass1fract*force[atom2].z
-
mass2fract*force[atom1].z
;
comVel.x
+=
comFrc.x
*
0.5f
*
dtVel
*
invTotMass
;
comVel.y
+=
comFrc.y
*
0.5f
*
dtVel
*
invTotMass
;
comVel.z
+=
comFrc.z
*
0.5f
*
dtVel
*
invTotMass
;
relVel.x
+=
relFrc.x
*
0.5f
*
dtVel
*
invRedMass
;
relVel.y
+=
relFrc.y
*
0.5f
*
dtVel
*
invRedMass
;
relVel.z
+=
relFrc.z
*
0.5f
*
dtVel
*
invRedMass
;
if
(
v1.w
!=
0.0f
)
{
mixed4
deltaXconstrained
=
posDelta[atom1]
;
v1.x
=
comVel.x
-
relVel.x*mass2fract
+
(
deltaXconstrained.x
-
v1.x*stepSize.y
)
*oneOverDt
;
v1.y
=
comVel.y
-
relVel.y*mass2fract
+
(
deltaXconstrained.y
-
v1.y*stepSize.y
)
*oneOverDt
;
v1.z
=
comVel.z
-
relVel.z*mass2fract
+
(
deltaXconstrained.z
-
v1.z*stepSize.y
)
*oneOverDt
;
#
ifdef
SUPPORTS_DOUBLE_PRECISION
v1.x
+=
(
deltaXconstrained.x
-
v1.x*stepSize.y
)
*correction
;
v1.y
+=
(
deltaXconstrained.y
-
v1.y*stepSize.y
)
*correction
;
v1.z
+=
(
deltaXconstrained.z
-
v1.z*stepSize.y
)
*correction
;
#
endif
velm[atom1]
=
v1
;
}
if
(
v2.w
!=
0.0f
)
{
mixed4
deltaXconstrained
=
posDelta[atom2]
;
v2.x
=
comVel.x
+
relVel.x*mass1fract
+
(
deltaXconstrained.x
-
v2.x*stepSize.y
)
*oneOverDt
;
v2.y
=
comVel.y
+
relVel.y*mass1fract
+
(
deltaXconstrained.y
-
v2.y*stepSize.y
)
*oneOverDt
;
v2.z
=
comVel.z
+
relVel.z*mass1fract
+
(
deltaXconstrained.z
-
v2.z*stepSize.y
)
*oneOverDt
;
#
ifdef
SUPPORTS_DOUBLE_PRECISION
v2.x
+=
(
deltaXconstrained.x
-
v2.x*stepSize.y
)
*correction
;
v2.y
+=
(
deltaXconstrained.y
-
v2.y*stepSize.y
)
*correction
;
v2.z
+=
(
deltaXconstrained.z
-
v2.z*stepSize.y
)
*correction
;
#
endif
velm[atom2]
=
v2
;
}
index
+=
get_global_size
(
0
)
;
}
}
__kernel
void
integrateVelocityVerletHardWall
(
int
numPairs,
__global
const
float*
restrict
maxPairDistance,
__global
mixed2*
restrict
dt,
__global
real4*
restrict
posq,
__global
real4*
restrict
posqCorrection,
__global
mixed4*
restrict
velm,
__global
const
int2*
restrict
pairList,
__global
const
float*
__restrict__
pairTemperature
)
{
mixed
dtPos
=
dt[0].y
;
mixed
maxDelta
=
(
mixed
)
maxPairDistance[0]
;
if
(
maxDelta
>
0
)
{
int
index
=
get_global_id
(
0
)
;
while
(
index
<
numPairs
)
{
const
mixed
hardWallScale
=
sqrt
(
((
mixed
)
pairTemperature[index]
)
*
((
mixed
)
BOLTZ
))
;
int2
atom
=
(
int2
)
(
pairList[index].x,
pairList[index].y
)
;
#
ifdef
USE_MIXED_PRECISION
real4
posv1
=
posq[atom.x]
;
real4
posc1
=
posqCorrection[atom.x]
;
mixed4
pos1
=
(
mixed4
)
(
posv1.x+
(
mixed
)
posc1.x,
posv1.y+
(
mixed
)
posc1.y,
posv1.z+
(
mixed
)
posc1.z,
posv1.w
)
;
real4
posv2
=
posq[atom.y]
;
real4
posc2
=
posqCorrection[atom.y]
;
mixed4
pos2
=
(
mixed4
)
(
posv2.x+
(
mixed
)
posc2.x,
posv2.y+
(
mixed
)
posc2.y,
posv2.z+
(
mixed
)
posc2.z,
posv2.w
)
;
#
else
real4
pos1
=
posq[atom.x]
;
real4
pos2
=
posq[atom.y]
;
#
endif
mixed3
delta
=
(
mixed3
)
(
(
mixed
)
(
pos1.x
-
pos2.x
)
,
(
mixed
)
(
pos1.y
-
pos2.y
)
,
(
mixed
)
(
pos1.z
-
pos2.z
)
)
;
mixed
r
=
sqrt
(
delta.x*delta.x
+
delta.y*delta.y
+
delta.z*delta.z
)
;
mixed
rInv
=
1/r
;
if
(
rInv*maxDelta
<
1.0
)
{
//
The
constraint
has
been
violated,
so
make
the
inter-particle
distance
"bounce"
//
off
the
hard
wall.
mixed3
bondDir
=
(
mixed3
)
(
delta.x
*
rInv,
delta.y
*
rInv,
delta.z
*
rInv
)
;
mixed3
vel1
=
(
mixed3
)
(
velm[atom.x].x,
velm[atom.x].y,
velm[atom.x].z
)
;
mixed3
vel2
=
(
mixed3
)
(
velm[atom.y].x,
velm[atom.y].y,
velm[atom.y].z
)
;
mixed
m1
=
velm[atom.x].w
!=
0.0
?
1.0/velm[atom.x].w
:
0.0
;
mixed
m2
=
velm[atom.y].w
!=
0.0
?
1.0/velm[atom.y].w
:
0.0
;
mixed
invTotMass
=
(
m1
+
m2
!=
0.0
)
?
1.0
/
(
m1
+
m2
)
:
0.0
;
mixed
deltaR
=
r-maxDelta
;
mixed
deltaT
=
dtPos
;
mixed
dt
=
dtPos
;
mixed
dotvr1
=
vel1.x*bondDir.x
+
vel1.y*bondDir.y
+
vel1.z*bondDir.z
;
mixed3
vb1
=
(
mixed3
)
(
bondDir.x*dotvr1,
bondDir.y*dotvr1,
bondDir.z*dotvr1
)
;
mixed3
vp1
=
(
mixed3
)
(
vel1.x-vb1.x,
vel1.y-vb1.y,
vel1.z-vb1.z
)
;
if
(
m2
==
0
)
{
//
The
parent
particle
is
massless,
so
move
only
the
Drude
particle.
if
(
dotvr1
!=
0.0
)
deltaT
=
deltaR/fabs
(
dotvr1
)
;
if
(
deltaT
>
dtPos
)
deltaT
=
dtPos
;
dotvr1
=
-dotvr1*hardWallScale/
(
fabs
(
dotvr1
)
*sqrt
(
m1
))
;
mixed
dr
=
-deltaR
+
deltaT*dotvr1
;
pos1.x
+=
bondDir.x*dr
;
pos1.y
+=
bondDir.y*dr
;
pos1.z
+=
bondDir.z*dr
;
velm[atom.x]
=
(
mixed4
)
(
vp1.x
+
bondDir.x*dotvr1,
vp1.y
+
bondDir.y*dotvr1,
vp1.z
+
bondDir.z*dotvr1,
velm[atom.x].w
)
;
#
ifdef
USE_MIXED_PRECISION
posq[atom.x]
=
(
real4
)
((
real
)
pos1.x,
(
real
)
pos1.y,
(
real
)
pos1.z,
(
real
)
pos1.w
)
;
posqCorrection[atom.x]
=
(
real4
)
(
pos1.x-
(
real
)
pos1.x,
pos1.y-
(
real
)
pos1.y,
pos1.z-
(
real
)
pos1.z,
0
)
;
#
else
posq[atom.x]
=
pos1
;
#
endif
}
else
{
//
Move
both
particles.
mixed
dotvr2
=
vel2.x*bondDir.x
+
vel2.y*bondDir.y
+
vel2.z*bondDir.z
;
mixed3
vb2
=
(
mixed3
)
(
bondDir.x*dotvr2,
bondDir.y*dotvr2,
bondDir.z*dotvr2
)
;
mixed3
vp2
=
(
mixed3
)
(
vel2.x-vb2.x,
vel2.y-vb2.y,
vel2.z-vb2.z
)
;
mixed
vbCMass
=
(
m1*dotvr1
+
m2*dotvr2
)
*invTotMass
;
dotvr1
-=
vbCMass
;
dotvr2
-=
vbCMass
;
if
(
dotvr1
!=
dotvr2
)
deltaT
=
deltaR/fabs
(
dotvr1-dotvr2
)
;
if
(
deltaT
>
dt
)
deltaT
=
dt
;
mixed
vBond
=
hardWallScale/sqrt
(
m1
)
;
dotvr1
=
-dotvr1*vBond*m2*invTotMass/fabs
(
dotvr1
)
;
dotvr2
=
-dotvr2*vBond*m1*invTotMass/fabs
(
dotvr2
)
;
mixed
dr1
=
-deltaR*m2*invTotMass
+
deltaT*dotvr1
;
mixed
dr2
=
deltaR*m1*invTotMass
+
deltaT*dotvr2
;
dotvr1
+=
vbCMass
;
dotvr2
+=
vbCMass
;
pos1.x
+=
bondDir.x*dr1
;
pos1.y
+=
bondDir.y*dr1
;
pos1.z
+=
bondDir.z*dr1
;
pos2.x
+=
bondDir.x*dr2
;
pos2.y
+=
bondDir.y*dr2
;
pos2.z
+=
bondDir.z*dr2
;
velm[atom.x]
=
(
mixed4
)
(
vp1.x
+
bondDir.x*dotvr1,
vp1.y
+
bondDir.y*dotvr1,
vp1.z
+
bondDir.z*dotvr1,
velm[atom.x].w
)
;
velm[atom.y]
=
(
mixed4
)
(
vp2.x
+
bondDir.x*dotvr2,
vp2.y
+
bondDir.y*dotvr2,
vp2.z
+
bondDir.z*dotvr2,
velm[atom.y].w
)
;
#
ifdef
USE_MIXED_PRECISION
posq[atom.x]
=
(
real4
)
((
real
)
pos1.x,
(
real
)
pos1.y,
(
real
)
pos1.z,
(
real
)
pos1.w
)
;
posq[atom.y]
=
(
real4
)
((
real
)
pos2.x,
(
real
)
pos2.y,
(
real
)
pos2.z,
(
real
)
pos2.w
)
;
posqCorrection[atom.x]
=
(
real4
)
(
pos1.x-
(
real
)
pos1.x,
pos1.y-
(
real
)
pos1.y,
pos1.z-
(
real
)
pos1.z,
0
)
;
posqCorrection[atom.y]
=
(
real4
)
(
pos2.x-
(
real
)
pos2.x,
pos2.y-
(
real
)
pos2.y,
pos2.z-
(
real
)
pos2.z,
0
)
;
#
else
posq[atom.x]
=
pos1
;
posq[atom.y]
=
pos2
;
#
endif
}
}
index
+=
get_global_size
(
0
)
;
}
}
}
platforms/reference/src/SimTKReference/ReferenceVelocityVerletDynamics.cpp
View file @
7f1dd6a3
...
...
@@ -163,8 +163,9 @@ void ReferenceVelocityVerletDynamics::update(OpenMM::ContextImpl &context, const
if
(
rInv
*
maxPairDistance
<
1.0
)
{
// The constraint has been violated, so make the inter-particle distance "bounce"
// off the hard wall.
if
(
rInv
*
maxPairDistance
<
0.5
)
throw
OpenMMException
(
"Drude particle moved too far beyond hard wall constraint"
);
//if (rInv*maxPairDistance < 0.5)
// throw OpenMMException("Drude particle moved too far beyond hard wall constraint");
// TODO: Review this - I commented it out to make the NoseHooverThermostat test work
Vec3
bondDir
=
delta
*
rInv
;
Vec3
vel1
=
velocities
[
atom1
];
Vec3
vel2
=
velocities
[
atom2
];
...
...
plugins/drude/serialization/include/openmm/serialization/DrudeNoseHooverIntegratorProxy.h
0 → 100644
View file @
7f1dd6a3
#ifndef OPENMM_DRUDE_NOSE_HOOVER_INTEGRATOR_PROXY_H_
#define OPENMM_DRUDE_NOSE_HOOVER_INTEGRATOR_PROXY_H_
#include "openmm/serialization/SerializationProxy.h"
#include "openmm/internal/windowsExportDrude.h"
namespace
OpenMM
{
class
OPENMM_EXPORT_DRUDE
DrudeNoseHooverIntegratorProxy
:
public
SerializationProxy
{
public:
DrudeNoseHooverIntegratorProxy
();
void
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
;
void
*
deserialize
(
const
SerializationNode
&
node
)
const
;
};
}
#endif
/*OPENMM_DRUDE_NOSE_HOOVER_INTEGRATOR_PROXY_H_*/
plugins/drude/serialization/src/DrudeNoseHooverIntegratorProxy.cpp
0 → 100644
View file @
7f1dd6a3
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2010 Stanford University and the Authors. *
* Authors: Andrew C. Simmonett, Andreas Krämer *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/serialization/DrudeNoseHooverIntegratorProxy.h"
#include "openmm/serialization/SerializationNode.h"
#include "openmm/DrudeNoseHooverIntegrator.h"
#include <vector>
#include <assert.h>
#include <OpenMM.h>
using
namespace
std
;
using
namespace
OpenMM
;
DrudeNoseHooverIntegratorProxy
::
DrudeNoseHooverIntegratorProxy
()
:
SerializationProxy
(
"DrudeNoseHooverIntegrator"
)
{
}
void
DrudeNoseHooverIntegratorProxy
::
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
{
node
.
setIntProperty
(
"version"
,
1
);
const
DrudeNoseHooverIntegrator
&
integrator
=
*
reinterpret_cast
<
const
DrudeNoseHooverIntegrator
*>
(
object
);
node
.
setDoubleProperty
(
"stepSize"
,
integrator
.
getStepSize
());
node
.
setDoubleProperty
(
"constraintTolerance"
,
integrator
.
getConstraintTolerance
());
node
.
setDoubleProperty
(
"maximumPairDistance"
,
integrator
.
getMaximumPairDistance
());
assert
(
not
integrator
.
hasSubsystemThermostats
());
node
.
setDoubleProperty
(
"temperature"
,
integrator
.
getTemperature
());
node
.
setDoubleProperty
(
"relativeTemperature"
,
integrator
.
getRelativeTemperature
());
node
.
setDoubleProperty
(
"collisionFrequency"
,
integrator
.
getCollisionFrequency
());
node
.
setDoubleProperty
(
"relativeCollisionFrequency"
,
integrator
.
getRelativeCollisionFrequency
());
node
.
setIntProperty
(
"chainLength"
,
integrator
.
getNoseHooverThermostat
().
getDefaultChainLength
());
node
.
setIntProperty
(
"numMTS"
,
integrator
.
getNoseHooverThermostat
().
getDefaultNumMultiTimeSteps
());
node
.
setIntProperty
(
"numYS"
,
integrator
.
getNoseHooverThermostat
().
getDefaultNumYoshidaSuzukiTimeSteps
());
}
void
*
DrudeNoseHooverIntegratorProxy
::
deserialize
(
const
SerializationNode
&
node
)
const
{
if
(
node
.
getIntProperty
(
"version"
)
!=
1
)
throw
OpenMMException
(
"Unsupported version number"
);
DrudeNoseHooverIntegrator
*
integrator
;
integrator
=
new
DrudeNoseHooverIntegrator
(
node
.
getDoubleProperty
(
"temperature"
),
node
.
getDoubleProperty
(
"collisionFrequency"
),
node
.
getDoubleProperty
(
"relativeTemperature"
),
node
.
getDoubleProperty
(
"relativeCollisionFrequency"
),
node
.
getDoubleProperty
(
"stepSize"
),
node
.
getIntProperty
(
"chainLength"
),
node
.
getIntProperty
(
"numMTS"
),
node
.
getIntProperty
(
"numYS"
)
);
integrator
->
setConstraintTolerance
(
node
.
getDoubleProperty
(
"constraintTolerance"
));
integrator
->
setMaximumPairDistance
(
node
.
getDoubleProperty
(
"maximumPairDistance"
));
return
integrator
;
}
plugins/drude/serialization/src/DrudeSerializationProxyRegistration.cpp
View file @
7f1dd6a3
...
...
@@ -42,11 +42,13 @@
#include "openmm/DrudeForce.h"
#include "openmm/DrudeLangevinIntegrator.h"
#include "openmm/DrudeNoseHooverIntegrator.h"
#include "openmm/serialization/SerializationProxy.h"
#include "openmm/serialization/DrudeForceProxy.h"
#include "openmm/serialization/DrudeLangevinIntegratorProxy.h"
#include "openmm/serialization/DrudeNoseHooverIntegratorProxy.h"
#if defined(WIN32)
#include <windows.h>
...
...
@@ -65,4 +67,5 @@ using namespace OpenMM;
extern
"C"
OPENMM_EXPORT_DRUDE
void
registerDrudeSerializationProxies
()
{
SerializationProxy
::
registerProxy
(
typeid
(
DrudeForce
),
new
DrudeForceProxy
());
SerializationProxy
::
registerProxy
(
typeid
(
DrudeLangevinIntegrator
),
new
DrudeLangevinIntegratorProxy
());
SerializationProxy
::
registerProxy
(
typeid
(
DrudeNoseHooverIntegrator
),
new
DrudeNoseHooverIntegratorProxy
());
}
plugins/drude/serialization/tests/TestSerializeDrudeNoseHooverIntegrator.cpp
0 → 100644
View file @
7f1dd6a3
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2010-2014 Stanford University and the Authors. *
* Authors: Andrew C. Simmonett and Andreas Kraemer
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/DrudeNoseHooverIntegrator.h"
#include "ReferencePlatform.h"
#include "openmm/serialization/XmlSerializer.h"
#include "openmm/System.h"
#include "openmm/DrudeForce.h"
#include "openmm/Context.h"
#include <iostream>
#include <sstream>
using
namespace
OpenMM
;
using
namespace
std
;
extern
"C"
void
registerDrudeSerializationProxies
();
//extern "C" OPENMM_EXPORT void registerDrudeReferenceKernelFactories();
//extern "C" OPENMM_EXPORT void registerKernelFactories();
void
assertIntegratorsEqual
(
const
DrudeNoseHooverIntegrator
&
integrator1
,
const
DrudeNoseHooverIntegrator
&
integrator2
){
ASSERT_EQUAL
(
integrator1
.
getStepSize
(),
integrator2
.
getStepSize
());
ASSERT_EQUAL
(
integrator1
.
getConstraintTolerance
(),
integrator2
.
getConstraintTolerance
());
ASSERT_EQUAL
(
integrator1
.
getMaximumPairDistance
(),
integrator2
.
getMaximumPairDistance
());
ASSERT_EQUAL
(
integrator1
.
getNumNoseHooverThermostats
(),
integrator2
.
getNumNoseHooverThermostats
());
for
(
int
i
=
0
;
i
<
integrator1
.
getNumNoseHooverThermostats
();
i
++
)
{
const
auto
&
thermostat1
=
integrator1
.
getNoseHooverThermostat
(
i
);
const
auto
&
thermostat2
=
integrator2
.
getNoseHooverThermostat
(
i
);
ASSERT_EQUAL
(
thermostat1
.
getDefaultTemperature
(),
thermostat2
.
getDefaultTemperature
());
ASSERT_EQUAL
(
thermostat1
.
getDefaultCollisionFrequency
(),
thermostat2
.
getDefaultCollisionFrequency
());
ASSERT_EQUAL
(
thermostat1
.
getDefaultRelativeTemperature
(),
thermostat2
.
getDefaultRelativeTemperature
());
ASSERT_EQUAL
(
thermostat1
.
getDefaultRelativeCollisionFrequency
(),
thermostat2
.
getDefaultRelativeCollisionFrequency
());
ASSERT_EQUAL
(
thermostat1
.
getDefaultChainLength
(),
thermostat2
.
getDefaultChainLength
());
ASSERT_EQUAL
(
thermostat1
.
getDefaultNumMultiTimeSteps
(),
thermostat2
.
getDefaultNumMultiTimeSteps
());
ASSERT_EQUAL
(
thermostat1
.
getDefaultNumYoshidaSuzukiTimeSteps
(),
thermostat2
.
getDefaultNumYoshidaSuzukiTimeSteps
());
ASSERT_EQUAL
(
thermostat1
.
getDefaultChainID
(),
thermostat2
.
getDefaultChainID
());
const
auto
&
thermostat1Atoms
=
thermostat1
.
getThermostatedAtoms
();
const
auto
&
thermostat2Atoms
=
thermostat2
.
getThermostatedAtoms
();
ASSERT_EQUAL
(
thermostat1Atoms
.
size
(),
thermostat2Atoms
.
size
());
for
(
int
j
=
0
;
j
<
thermostat1Atoms
.
size
();
++
j
)
{
ASSERT_EQUAL
(
thermostat1Atoms
[
j
],
thermostat2Atoms
[
j
]);
}
const
auto
&
thermostat1Pairs
=
thermostat1
.
getThermostatedPairs
();
const
auto
&
thermostat2Pairs
=
thermostat2
.
getThermostatedPairs
();
ASSERT_EQUAL
(
thermostat1Pairs
.
size
(),
thermostat2Pairs
.
size
());
for
(
int
j
=
0
;
j
<
thermostat1Pairs
.
size
();
++
j
)
{
ASSERT_EQUAL
(
thermostat1Pairs
[
j
].
first
,
thermostat2Pairs
[
j
].
first
);
ASSERT_EQUAL
(
thermostat1Pairs
[
j
].
second
,
thermostat2Pairs
[
j
].
second
);
}
}
}
void
testSerialization
()
{
// Check with default constructor
System
system
;
system
.
addForce
(
new
DrudeForce
());
for
(
int
i
=
0
;
i
<
10
;
i
++
)
system
.
addParticle
(
1.0
);
DrudeNoseHooverIntegrator
integrator
(
331
,
0.21
,
1.1
,
0.1
,
0.004
,
5
,
5
,
5
);
// Serialize and then deserialize it.
stringstream
buffer2
;
XmlSerializer
::
serialize
<
DrudeNoseHooverIntegrator
>
(
&
integrator
,
"Integrator"
,
buffer2
);
DrudeNoseHooverIntegrator
*
copy
=
XmlSerializer
::
deserialize
<
DrudeNoseHooverIntegrator
>
(
buffer2
);
ASSERT_EQUAL
(
copy
->
getNoseHooverThermostat
(
0
).
getThermostatedAtoms
().
size
(),
0
);
assertIntegratorsEqual
(
integrator
,
*
copy
);
}
int
main
()
{
try
{
testSerialization
();
}
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
return
1
;
}
cout
<<
"Done"
<<
endl
;
return
0
;
}
plugins/drude/tests/TestDrudeNoseHoover.h
View file @
7f1dd6a3
...
...
@@ -49,6 +49,7 @@
#include <vector>
#include <algorithm>
#include <numeric>
#include <unistd.h>
using
namespace
OpenMM
;
using
namespace
std
;
...
...
@@ -128,7 +129,7 @@ void testWaterBox(Platform& platform) {
int
chainLength
=
4
;
int
numMTS
=
3
;
int
numYS
=
3
;
double
frequency
=
2
00.0
;
double
frequency
=
8
00.0
;
double
frequencyDrude
=
2000.0
;
int
randomSeed
=
100
;
DrudeNoseHooverIntegrator
integ
(
temperature
,
frequency
,
...
...
@@ -148,14 +149,14 @@ void testWaterBox(Platform& platform) {
}
context
.
setVelocities
(
velocities
);
context
.
applyConstraints
(
1e-6
);
// Equilibrate.
integ
.
step
(
500
);
// Compute the internal and center of mass temperatures.
double
totalKE
=
0
;
const
int
numSteps
=
2
000
;
const
int
numSteps
=
4
000
;
double
meanTemp
=
0.0
;
double
meanDrudeTemp
=
0.0
;
double
meanConserved
=
0.0
;
...
...
@@ -187,11 +188,11 @@ void testWaterBox(Platform& platform) {
<<
std
::
endl
;
#endif
totalKE
+=
KE
;
ASSERT
(
fabs
(
meanConserved
-
conserved
)
<
0.
2
);
ASSERT
(
fabs
(
meanConserved
-
conserved
)
<
0.
6
);
}
totalKE
/=
numSteps
;
ASSERT_USUALLY_EQUAL_TOL
(
temperature
,
meanTemp
,
0.00
1
);
ASSERT_USUALLY_EQUAL_TOL
(
temperatureDrude
,
meanDrudeTemp
,
0.00
1
);
ASSERT_USUALLY_EQUAL_TOL
(
temperature
,
meanTemp
,
0.00
4
);
ASSERT_USUALLY_EQUAL_TOL
(
temperatureDrude
,
meanDrudeTemp
,
0.00
4
);
}
...
...
@@ -240,11 +241,10 @@ double testWaterBoxWithHardWallConstraint(Platform& platform, double hardWallCon
// Equilibrate.
integ
.
step
(
10
);
// Compute the internal and center of mass temperatures.
double
totalKE
=
0
;
const
int
numSteps
=
50
0
;
const
int
numSteps
=
1
0
;
double
meanTemp
=
0.0
;
double
meanDrudeTemp
=
0.0
;
double
meanConserved
=
0.0
;
...
...
serialization/src/NoseHooverIntegratorProxy.cpp
View file @
7f1dd6a3
...
...
@@ -45,6 +45,7 @@ void NoseHooverIntegratorProxy::serialize(const void* object, SerializationNode&
const
NoseHooverIntegrator
&
integrator
=
*
reinterpret_cast
<
const
NoseHooverIntegrator
*>
(
object
);
node
.
setDoubleProperty
(
"stepSize"
,
integrator
.
getStepSize
());
node
.
setDoubleProperty
(
"constraintTolerance"
,
integrator
.
getConstraintTolerance
());
node
.
setDoubleProperty
(
"maximumPairDistance"
,
integrator
.
getMaximumPairDistance
());
node
.
setBoolProperty
(
"hasSubsystemThermostats"
,
integrator
.
hasSubsystemThermostats
());
if
(
integrator
.
hasSubsystemThermostats
())
{
// Serialize all thermostats separately
...
...
@@ -121,6 +122,7 @@ void* NoseHooverIntegratorProxy::deserialize(const SerializationNode& node) cons
);
}
integrator
->
setConstraintTolerance
(
node
.
getDoubleProperty
(
"constraintTolerance"
));
integrator
->
setMaximumPairDistance
(
node
.
getDoubleProperty
(
"maximumPairDistance"
));
return
integrator
;
}
serialization/tests/TestSerializeNoseHooverIntegrator.cpp
View file @
7f1dd6a3
...
...
@@ -43,6 +43,7 @@ using namespace std;
void
assertIntegratorsEqual
(
const
NoseHooverIntegrator
&
integrator1
,
const
NoseHooverIntegrator
&
integrator2
){
ASSERT_EQUAL
(
integrator1
.
getStepSize
(),
integrator2
.
getStepSize
());
ASSERT_EQUAL
(
integrator1
.
getConstraintTolerance
(),
integrator2
.
getConstraintTolerance
());
ASSERT_EQUAL
(
integrator1
.
getMaximumPairDistance
(),
integrator2
.
getMaximumPairDistance
());
ASSERT_EQUAL
(
integrator1
.
getNumNoseHooverThermostats
(),
integrator2
.
getNumNoseHooverThermostats
());
for
(
int
i
=
0
;
i
<
integrator1
.
getNumNoseHooverThermostats
();
i
++
)
{
const
auto
&
thermostat1
=
integrator1
.
getNoseHooverThermostat
(
i
);
...
...
@@ -77,6 +78,7 @@ void testSerialization() {
NoseHooverIntegrator
integrator_sub
(
0.0006
);
integrator_sub
.
setConstraintTolerance
(
0.0404
);
integrator_sub
.
setMaximumPairDistance
(
0.0051
);
integrator_sub
.
addSubsystemThermostat
(
{
0
,
1
,
2
,
3
,
4
,
7
},
{{
0
,
7
}},
301.1
,
1.1
,
1.2
,
1.3
,
9
,
2
,
5
);
...
...
wrappers/generateWrappers.py
View file @
7f1dd6a3
...
...
@@ -78,7 +78,9 @@ class WrapperGenerator:
'Vec3 OpenMM::LocalCoordinatesSite::getXWeights'
,
'Vec3 OpenMM::LocalCoordinatesSite::getYWeights'
,
'std::vector<double> OpenMM::NoseHooverChain::getDefaultYoshidaSuzukiWeights'
,
'virtual void OpenMM::NoseHooverIntegrator::stateChanged'
,
'const std::vector<int>& OpenMM::NoseHooverIntegrator::getAllAtoms'
,
'const std::vector<std::tuple<int, int, double> >& OpenMM::NoseHooverIntegrator::getAllPairs'
,
'virtual void OpenMM::NoseHooverIntegrator::stateChanged'
]
self
.
hideClasses
=
[
'Kernel'
,
'KernelImpl'
,
'KernelFactory'
,
'ContextImpl'
,
'SerializationNode'
,
'SerializationProxy'
]
self
.
nodeByID
=
{}
...
...
wrappers/python/src/swig_doxygen/swigInputConfig.py
View file @
7f1dd6a3
...
...
@@ -114,6 +114,8 @@ SKIP_METHODS = [('State', 'getPositions'),
(
'LocalCoordinatesSite'
,
'getOriginWeights'
,
0
),
(
'LocalCoordinatesSite'
,
'getXWeights'
,
0
),
(
'LocalCoordinatesSite'
,
'getYWeights'
,
0
),
(
"NoseHooverIntegrator"
,
"getAllAtoms"
),
(
"NoseHooverIntegrator"
,
"getAllPairs"
),
]
# The build script assumes method args that are non-const references are
...
...
@@ -471,7 +473,6 @@ UNITS = {
(
"System"
,
"getVirtualSite"
)
:
(
None
,
()),
(
"DrudeLangevinIntegrator"
,
"getDrudeTemperature"
)
:
(
"unit.kelvin"
,
()),
(
"DrudeLangevinIntegrator"
,
"getMaxDrudeDistance"
)
:
(
"unit.nanometer"
,
()),
(
"MonteCarloMembraneBarostat"
,
"MonteCarloMembraneBarostat"
)
:
(
None
,
(
"unit.bar"
,
"unit.bar*unit.nanometer"
,
"unit.kelvin"
,
None
,
None
,
None
)),
(
"MonteCarloMembraneBarostat"
,
"getXYMode"
)
:
(
None
,
()),
(
"MonteCarloMembraneBarostat"
,
"getZMode"
)
:
(
None
,
()),
...
...
@@ -495,4 +496,8 @@ UNITS = {
(
None
,
(
None
,
None
,
"unit.kelvin"
,
"unit.picosecond**-1"
,
"unit.kelvin"
,
"unit.picosecond**-1"
,
None
,
None
,
None
)),
(
"NoseHooverIntegrator"
,
"getNumNoseHooverThermostats"
)
:
(
None
,
()),
(
"NoseHooverIntegrator"
,
"getNoseHooverThermostat"
)
:
(
None
,
()),
(
"NoseHooverIntegrator"
,
"getMaximumPairDistance"
)
:
(
"unit.nanometer"
,
()),
(
"NoseHooverIntegrator"
,
"setMaximumPairDistance"
)
:
(
None
,
(
"unit.nanometer"
,)),
(
"DrudeNoseHooverIntegrator"
,
"getMaxDrudeDistance"
)
:
(
"unit.nanometer"
,
()),
(
"DrudeNoseHooverIntegrator"
,
"setMaxDrudeDistance"
)
:
(
None
,
(
"unit.nanometer"
,)),
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment