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
2d2f05ce
Commit
2d2f05ce
authored
Dec 08, 2015
by
Andy Simmonett
Browse files
Merge branch 'master' of github.com:pandegroup/openmm into genpt
parents
94823d84
4d32047c
Changes
235
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
420 additions
and
69 deletions
+420
-69
plugins/amoeba/platforms/reference/CMakeLists.txt
plugins/amoeba/platforms/reference/CMakeLists.txt
+2
-2
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
...ence/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
+1
-1
plugins/cpupme/src/CpuPmeKernels.cpp
plugins/cpupme/src/CpuPmeKernels.cpp
+25
-24
plugins/cpupme/src/CpuPmeKernels.h
plugins/cpupme/src/CpuPmeKernels.h
+3
-1
plugins/drude/CMakeLists.txt
plugins/drude/CMakeLists.txt
+2
-2
plugins/drude/openmmapi/include/openmm/DrudeForce.h
plugins/drude/openmmapi/include/openmm/DrudeForce.h
+21
-21
plugins/drude/openmmapi/include/openmm/DrudeLangevinIntegrator.h
.../drude/openmmapi/include/openmm/DrudeLangevinIntegrator.h
+16
-2
plugins/drude/openmmapi/src/DrudeLangevinIntegrator.cpp
plugins/drude/openmmapi/src/DrudeLangevinIntegrator.cpp
+12
-1
plugins/drude/platforms/cuda/src/CudaDrudeKernels.cpp
plugins/drude/platforms/cuda/src/CudaDrudeKernels.cpp
+17
-2
plugins/drude/platforms/cuda/src/CudaDrudeKernels.h
plugins/drude/platforms/cuda/src/CudaDrudeKernels.h
+2
-2
plugins/drude/platforms/cuda/src/kernels/drudeLangevin.cu
plugins/drude/platforms/cuda/src/kernels/drudeLangevin.cu
+108
-0
plugins/drude/platforms/cuda/tests/TestCudaDrudeLangevinIntegrator.cpp
.../platforms/cuda/tests/TestCudaDrudeLangevinIntegrator.cpp
+7
-2
plugins/drude/platforms/opencl/src/OpenCLDrudeKernels.cpp
plugins/drude/platforms/opencl/src/OpenCLDrudeKernels.cpp
+20
-1
plugins/drude/platforms/opencl/src/OpenCLDrudeKernels.h
plugins/drude/platforms/opencl/src/OpenCLDrudeKernels.h
+2
-2
plugins/drude/platforms/opencl/src/kernels/drudeLangevin.cl
plugins/drude/platforms/opencl/src/kernels/drudeLangevin.cl
+96
-0
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp
...tforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp
+7
-2
plugins/drude/platforms/reference/CMakeLists.txt
plugins/drude/platforms/reference/CMakeLists.txt
+2
-2
plugins/drude/platforms/reference/src/ReferenceDrudeKernels.cpp
...s/drude/platforms/reference/src/ReferenceDrudeKernels.cpp
+69
-1
plugins/drude/platforms/reference/src/ReferenceDrudeKernels.h
...ins/drude/platforms/reference/src/ReferenceDrudeKernels.h
+2
-0
plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp
.../reference/tests/TestReferenceDrudeLangevinIntegrator.cpp
+6
-1
No files found.
plugins/amoeba/platforms/reference/CMakeLists.txt
View file @
2d2f05ce
...
...
@@ -75,6 +75,6 @@ SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_LINK_FLAGS
INSTALL
(
TARGETS
${
SHARED_TARGET
}
DESTINATION
${
CMAKE_INSTALL_PREFIX
}
/lib/plugins
)
IF
(
BUILD_TESTING
)
IF
(
BUILD_TESTING
AND OPENMM_BUILD_REFERENCE_TESTS
)
SUBDIRS
(
tests
)
ENDIF
(
BUILD_TESTING
)
ENDIF
(
BUILD_TESTING
AND OPENMM_BUILD_REFERENCE_TESTS
)
plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp
View file @
2d2f05ce
...
...
@@ -6317,7 +6317,7 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::calculatePmeSelfEnergy(const vector
cii
+=
particleI
.
charge
*
particleI
.
charge
;
RealVec
dipole
(
particleI
.
sphericalDipole
[
1
],
particleI
.
sphericalDipole
[
2
],
particleI
.
sphericalDipole
[
0
]);
dii
+=
dipole
.
dot
(
dipole
+
(
_inducedDipole
[
ii
]
+
_inducedDipolePolar
[
ii
])
*
0.5
);
dii
+=
dipole
.
dot
(
dipole
+
(
_inducedDipole
[
ii
]
+
_inducedDipolePolar
[
ii
])
*
0.5
);
qii
+=
(
particleI
.
sphericalQuadrupole
[
0
]
*
particleI
.
sphericalQuadrupole
[
0
]
+
particleI
.
sphericalQuadrupole
[
1
]
*
particleI
.
sphericalQuadrupole
[
1
]
...
...
plugins/cpupme/src/CpuPmeKernels.cpp
View file @
2d2f05ce
...
...
@@ -49,7 +49,7 @@ static const int PME_ORDER = 5;
bool
CpuCalcPmeReciprocalForceKernel
::
hasInitializedThreads
=
false
;
int
CpuCalcPmeReciprocalForceKernel
::
numThreads
=
0
;
static
void
spreadCharge
(
int
start
,
int
end
,
float
*
posq
,
float
*
grid
,
int
gridx
,
int
gridy
,
int
gridz
,
int
numParticles
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
)
{
static
void
spreadCharge
(
float
*
posq
,
float
*
grid
,
int
gridx
,
int
gridy
,
int
gridz
,
int
numParticles
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
,
gmx_atomic_t
&
atomicCounter
)
{
float
temp
[
4
];
fvec4
boxSize
((
float
)
periodicBoxVectors
[
0
][
0
],
(
float
)
periodicBoxVectors
[
1
][
1
],
(
float
)
periodicBoxVectors
[
2
][
2
],
0
);
fvec4
invBoxSize
((
float
)
recipBoxVectors
[
0
][
0
],
(
float
)
recipBoxVectors
[
1
][
1
],
(
float
)
recipBoxVectors
[
2
][
2
],
0
);
...
...
@@ -64,7 +64,11 @@ static void spreadCharge(int start, int end, float* posq, float* grid, int gridx
const
float
epsilonFactor
=
sqrt
(
ONE_4PI_EPS0
);
memset
(
grid
,
0
,
sizeof
(
float
)
*
gridx
*
gridy
*
gridz
);
for
(
int
i
=
start
;
i
<
end
;
i
++
)
{
while
(
true
)
{
int
i
=
gmx_atomic_fetch_add
(
&
atomicCounter
,
1
);
if
(
i
>=
numParticles
)
break
;
// Find the position relative to the nearest grid point.
fvec4
pos
(
&
posq
[
4
*
i
]);
...
...
@@ -225,25 +229,15 @@ static double reciprocalEnergy(int start, int end, fftwf_complex* grid, int grid
return
0.5
*
energy
;
}
static
void
reciprocalConvolution
(
int
start
,
int
end
,
fftwf_complex
*
grid
,
int
gridx
,
int
gridy
,
int
gridz
,
vector
<
float
>&
recipEterm
)
{
const
unsigned
int
zsize
=
gridz
/
2
+
1
;
const
unsigned
int
yzsize
=
gridy
*
zsize
;
int
firstz
=
(
start
==
0
?
1
:
0
);
for
(
int
kx
=
start
;
kx
<
end
;
kx
++
)
{
for
(
int
ky
=
0
;
ky
<
gridy
;
ky
++
)
{
for
(
int
kz
=
firstz
;
kz
<
zsize
;
kz
++
)
{
int
index
=
kx
*
yzsize
+
ky
*
zsize
+
kz
;
static
void
reciprocalConvolution
(
int
start
,
int
end
,
fftwf_complex
*
grid
,
vector
<
float
>&
recipEterm
)
{
for
(
int
index
=
start
;
index
<
end
;
index
++
)
{
float
eterm
=
recipEterm
[
index
];
grid
[
index
][
0
]
*=
eterm
;
grid
[
index
][
1
]
*=
eterm
;
}
firstz
=
0
;
}
}
}
static
void
interpolateForces
(
int
start
,
int
end
,
float
*
posq
,
float
*
force
,
float
*
grid
,
int
gridx
,
int
gridy
,
int
gridz
,
int
numParticles
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
)
{
static
void
interpolateForces
(
float
*
posq
,
float
*
force
,
float
*
grid
,
int
gridx
,
int
gridy
,
int
gridz
,
int
numParticles
,
Vec3
*
periodicBoxVectors
,
Vec3
*
recipBoxVectors
,
gmx_atomic_t
&
atomicCounter
)
{
fvec4
boxSize
((
float
)
periodicBoxVectors
[
0
][
0
],
(
float
)
periodicBoxVectors
[
1
][
1
],
(
float
)
periodicBoxVectors
[
2
][
2
],
0
);
fvec4
invBoxSize
((
float
)
recipBoxVectors
[
0
][
0
],
(
float
)
recipBoxVectors
[
1
][
1
],
(
float
)
recipBoxVectors
[
2
][
2
],
0
);
fvec4
recipBoxVec0
((
float
)
recipBoxVectors
[
0
][
0
],
(
float
)
recipBoxVectors
[
0
][
1
],
(
float
)
recipBoxVectors
[
0
][
2
],
0
);
...
...
@@ -254,7 +248,11 @@ static void interpolateForces(int start, int end, float* posq, float* force, flo
fvec4
one
(
1
);
fvec4
scale
(
1.0
f
/
(
PME_ORDER
-
1
));
const
float
epsilonFactor
=
sqrt
(
ONE_4PI_EPS0
);
for
(
int
i
=
start
;
i
<
end
;
i
++
)
{
while
(
true
)
{
int
i
=
gmx_atomic_fetch_add
(
&
atomicCounter
,
1
);
if
(
i
>=
numParticles
)
break
;
// Find the position relative to the nearest grid point.
fvec4
pos
(
&
posq
[
4
*
i
]);
...
...
@@ -485,6 +483,7 @@ void CpuCalcPmeReciprocalForceKernel::runMainThread() {
break
;
posq
=
io
->
getPosq
();
ComputeTask
task
(
*
this
);
gmx_atomic_set
(
&
atomicCounter
,
0
);
threads
.
execute
(
task
);
// Signal threads to perform charge spreading.
threads
.
waitForThreads
();
threads
.
resumeThreads
();
// Signal threads to sum the charge grids.
...
...
@@ -503,6 +502,7 @@ void CpuCalcPmeReciprocalForceKernel::runMainThread() {
threads
.
resumeThreads
();
// Signal threads to perform reciprocal convolution.
threads
.
waitForThreads
();
fftwf_execute_dft_c2r
(
backwardFFT
,
complexGrid
,
realGrid
);
gmx_atomic_set
(
&
atomicCounter
,
0
);
threads
.
resumeThreads
();
// Signal threads to interpolate forces.
threads
.
waitForThreads
();
isFinished
=
true
;
...
...
@@ -515,14 +515,15 @@ void CpuCalcPmeReciprocalForceKernel::runMainThread() {
}
void
CpuCalcPmeReciprocalForceKernel
::
runWorkerThread
(
ThreadPool
&
threads
,
int
index
)
{
int
particleStart
=
(
index
*
numParticles
)
/
numThreads
;
int
particleEnd
=
((
index
+
1
)
*
numParticles
)
/
numThreads
;
int
gridxStart
=
(
index
*
gridx
)
/
numThreads
;
int
gridxEnd
=
((
index
+
1
)
*
gridx
)
/
numThreads
;
int
gridSize
=
(
gridx
*
gridy
*
gridz
+
3
)
/
4
;
int
gridStart
=
4
*
((
index
*
gridSize
)
/
numThreads
);
int
gridEnd
=
4
*
(((
index
+
1
)
*
gridSize
)
/
numThreads
);
spreadCharge
(
particleStart
,
particleEnd
,
posq
,
tempGrid
[
index
],
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
);
int
complexSize
=
gridx
*
gridy
*
(
gridz
/
2
+
1
);
int
complexStart
=
max
(
1
,
((
index
*
complexSize
)
/
numThreads
));
int
complexEnd
=
(((
index
+
1
)
*
complexSize
)
/
numThreads
);
spreadCharge
(
posq
,
tempGrid
[
index
],
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
,
atomicCounter
);
threads
.
syncThreads
();
int
numGrids
=
tempGrid
.
size
();
for
(
int
i
=
gridStart
;
i
<
gridEnd
;
i
+=
4
)
{
...
...
@@ -540,9 +541,9 @@ void CpuCalcPmeReciprocalForceKernel::runWorkerThread(ThreadPool& threads, int i
threadEnergy
[
index
]
=
reciprocalEnergy
(
gridxStart
,
gridxEnd
,
complexGrid
,
gridx
,
gridy
,
gridz
,
alpha
,
bsplineModuli
,
periodicBoxVectors
,
recipBoxVectors
);
threads
.
syncThreads
();
}
reciprocalConvolution
(
grid
xStart
,
grid
xEnd
,
complexGrid
,
gridx
,
gridy
,
gridz
,
recipEterm
);
reciprocalConvolution
(
comple
xStart
,
comple
xEnd
,
complexGrid
,
recipEterm
);
threads
.
syncThreads
();
interpolateForces
(
particleStart
,
particleEnd
,
posq
,
&
force
[
0
],
realGrid
,
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
);
interpolateForces
(
posq
,
&
force
[
0
],
realGrid
,
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
,
atomicCounter
);
}
void
CpuCalcPmeReciprocalForceKernel
::
beginComputation
(
IO
&
io
,
const
Vec3
*
periodicBoxVectors
,
bool
includeEnergy
)
{
...
...
plugins/cpupme/src/CpuPmeKernels.h
View file @
2d2f05ce
...
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013-201
4
Stanford University and the Authors. *
* Portions copyright (c) 2013-201
5
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -36,6 +36,7 @@
#include "internal/windowsExportPme.h"
#include "openmm/kernels.h"
#include "openmm/Vec3.h"
#include "openmm/internal/gmx_atomic.h"
#include "openmm/internal/ThreadPool.h"
#include <fftw3.h>
#include <pthread.h>
...
...
@@ -130,6 +131,7 @@ private:
float
*
posq
;
Vec3
periodicBoxVectors
[
3
],
recipBoxVectors
[
3
];
bool
includeEnergy
;
gmx_atomic_t
atomicCounter
;
};
}
// namespace OpenMM
...
...
plugins/drude/CMakeLists.txt
View file @
2d2f05ce
...
...
@@ -145,6 +145,6 @@ ENDIF (EXECUTABLE_OUTPUT_PATH)
#INCLUDE(ApiDoxygen.cmake)
IF
(
BUILD_TESTING
)
IF
(
BUILD_TESTING
AND OPENMM_BUILD_SERIALIZATION_TESTS
)
ADD_SUBDIRECTORY
(
serialization/tests
)
ENDIF
(
BUILD_TESTING
)
ENDIF
(
BUILD_TESTING
AND OPENMM_BUILD_SERIALIZATION_TESTS
)
plugins/drude/openmmapi/include/openmm/DrudeForce.h
View file @
2d2f05ce
...
...
@@ -92,18 +92,18 @@ public:
* Get the parameters for a Drude particle.
*
* @param index the index of the Drude particle for which to get parameters
* @param particle the index within the System of the Drude particle
* @param particle1 the index within the System of the particle to which the Drude particle is attached
* @param particle2 the index within the System of the second particle used for defining anisotropic polarizability.
* @param
[out]
particle the index within the System of the Drude particle
* @param
[out]
particle1 the index within the System of the particle to which the Drude particle is attached
* @param
[out]
particle2 the index within the System of the second particle used for defining anisotropic polarizability.
* This may be set to -1, in which case aniso12 will be ignored.
* @param particle3 the index within the System of the third particle used for defining anisotropic polarizability.
* @param
[out]
particle3 the index within the System of the third particle used for defining anisotropic polarizability.
* This may be set to -1, in which case aniso34 will be ignored.
* @param particle4 the index within the System of the fourth particle used for defining anisotropic polarizability.
* @param
[out]
particle4 the index within the System of the fourth particle used for defining anisotropic polarizability.
* This may be set to -1, in which case aniso34 will be ignored.
* @param charge The charge on the Drude particle
* @param polarizability The isotropic polarizability
* @param aniso12 The scale factor for the polarizability along the direction defined by particle1 and particle2
* @param aniso34 The scale factor for the polarizability along the direction defined by particle3 and particle4
* @param
[out]
charge The charge on the Drude particle
* @param
[out]
polarizability The isotropic polarizability
* @param
[out]
aniso12 The scale factor for the polarizability along the direction defined by particle1 and particle2
* @param
[out]
aniso34 The scale factor for the polarizability along the direction defined by particle3 and particle4
*/
void
getParticleParameters
(
int
index
,
int
&
particle
,
int
&
particle1
,
int
&
particle2
,
int
&
particle3
,
int
&
particle4
,
double
&
charge
,
double
&
polarizability
,
double
&
aniso12
,
double
&
aniso34
)
const
;
/**
...
...
@@ -137,9 +137,9 @@ public:
* Get the force field parameters for screened pair.
*
* @param index the index of the pair for which to get parameters
* @param particle1 the index within this Force of the first particle involved in the interaction
* @param particle2 the index within this Force of the second particle involved in the interaction
* @param thole the Thole screening factor
* @param
[out]
particle1 the index within this Force of the first particle involved in the interaction
* @param
[out]
particle2 the index within this Force of the second particle involved in the interaction
* @param
[out]
thole the Thole screening factor
*/
void
getScreenedPairParameters
(
int
index
,
int
&
particle1
,
int
&
particle2
,
double
&
thole
)
const
;
/**
...
...
plugins/drude/openmmapi/include/openmm/DrudeLangevinIntegrator.h
View file @
2d2f05ce
...
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-201
3
Stanford University and the Authors. *
* Portions copyright (c) 2008-201
5
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -45,6 +45,10 @@ namespace OpenMM {
* A second thermostat, typically with a much lower temperature, is applied to the relative internal
* displacement of each pair.
*
* This integrator can optionally set an upper limit on how far any Drude particle is ever allowed to
* get from its parent particle. This can sometimes help to improve stability. The limit is enforced
* with a hard wall constraint.
*
* This Integrator requires the System to include a DrudeForce, which it uses to identify the Drude
* particles.
*/
...
...
@@ -129,6 +133,16 @@ public:
void
setDrudeFriction
(
double
coeff
)
{
drudeFriction
=
coeff
;
}
/**
* Get the maximum distance a Drude particle can ever move from its parent particle, measured in nm. This is implemented
* with a hard wall constraint. If this distance is set to 0 (the default), the hard wall constraint is omitted.
*/
double
getMaxDrudeDistance
()
const
;
/**
* Set the maximum distance a Drude particle can ever move from its parent particle, measured in nm. This is implemented
* with a hard wall constraint. If this distance is set to 0 (the default), the hard wall constraint is omitted.
*/
void
setMaxDrudeDistance
(
double
distance
);
/**
* Get the random number seed. See setRandomNumberSeed() for details.
*/
...
...
@@ -181,7 +195,7 @@ protected:
*/
double
computeKineticEnergy
();
private:
double
temperature
,
friction
,
drudeTemperature
,
drudeFriction
;
double
temperature
,
friction
,
drudeTemperature
,
drudeFriction
,
maxDrudeDistance
;
int
randomNumberSeed
;
Kernel
kernel
;
};
...
...
plugins/drude/openmmapi/src/DrudeLangevinIntegrator.cpp
View file @
2d2f05ce
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-201
3
Stanford University and the Authors. *
* Portions copyright (c) 2008-201
5
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -46,11 +46,22 @@ DrudeLangevinIntegrator::DrudeLangevinIntegrator(double temperature, double fric
setFriction
(
frictionCoeff
);
setDrudeTemperature
(
drudeTemperature
);
setDrudeFriction
(
drudeFrictionCoeff
);
setMaxDrudeDistance
(
0
);
setStepSize
(
stepSize
);
setConstraintTolerance
(
1e-5
);
setRandomNumberSeed
(
0
);
}
double
DrudeLangevinIntegrator
::
getMaxDrudeDistance
()
const
{
return
maxDrudeDistance
;
}
void
DrudeLangevinIntegrator
::
setMaxDrudeDistance
(
double
distance
)
{
if
(
distance
<
0
)
throw
OpenMMException
(
"setMaxDrudeDistance: Distance cannot be negative"
);
maxDrudeDistance
=
distance
;
}
void
DrudeLangevinIntegrator
::
initialize
(
ContextImpl
&
contextRef
)
{
if
(
owner
!=
NULL
&&
&
contextRef
.
getOwner
()
!=
owner
)
throw
OpenMMException
(
"This Integrator is already bound to a context"
);
...
...
plugins/drude/platforms/cuda/src/CudaDrudeKernels.cpp
View file @
2d2f05ce
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013 Stanford University and the Authors.
*
* Portions copyright (c) 2013
-2015
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -279,6 +279,7 @@ void CudaIntegrateDrudeLangevinStepKernel::initialize(const System& system, cons
CUmodule
module
=
cu
.
createModule
(
CudaKernelSources
::
vectorOps
+
CudaDrudeKernelSources
::
drudeLangevin
,
defines
,
""
);
kernel1
=
cu
.
getKernel
(
module
,
"integrateDrudeLangevinPart1"
);
kernel2
=
cu
.
getKernel
(
module
,
"integrateDrudeLangevinPart2"
);
hardwallKernel
=
cu
.
getKernel
(
module
,
"applyHardWallConstraints"
);
prevStepSize
=
-
1.0
;
}
...
...
@@ -296,6 +297,8 @@ void CudaIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const D
double
vscaleDrude
=
exp
(
-
stepSize
*
integrator
.
getDrudeFriction
());
double
fscaleDrude
=
(
1
-
vscaleDrude
)
/
integrator
.
getDrudeFriction
()
/
(
double
)
0x100000000
;
double
noisescaleDrude
=
sqrt
(
2
*
BOLTZ
*
integrator
.
getDrudeTemperature
()
*
integrator
.
getDrudeFriction
())
*
sqrt
(
0.5
*
(
1
-
vscaleDrude
*
vscaleDrude
)
/
integrator
.
getDrudeFriction
());
double
maxDrudeDistance
=
integrator
.
getMaxDrudeDistance
();
double
hardwallscaleDrude
=
sqrt
(
BOLTZ
*
integrator
.
getDrudeTemperature
());
if
(
stepSize
!=
prevStepSize
)
{
if
(
cu
.
getUseDoublePrecision
()
||
cu
.
getUseMixedPrecision
())
{
double2
ss
=
make_double2
(
0
,
stepSize
);
...
...
@@ -316,7 +319,9 @@ void CudaIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const D
float
vscaleDrudeFloat
=
(
float
)
vscaleDrude
;
float
fscaleDrudeFloat
=
(
float
)
fscaleDrude
;
float
noisescaleDrudeFloat
=
(
float
)
noisescaleDrude
;
void
*
vscalePtr
,
*
fscalePtr
,
*
noisescalePtr
,
*
vscaleDrudePtr
,
*
fscaleDrudePtr
,
*
noisescaleDrudePtr
;
float
maxDrudeDistanceFloat
=
(
float
)
maxDrudeDistance
;
float
hardwallscaleDrudeFloat
=
(
float
)
hardwallscaleDrude
;
void
*
vscalePtr
,
*
fscalePtr
,
*
noisescalePtr
,
*
vscaleDrudePtr
,
*
fscaleDrudePtr
,
*
noisescaleDrudePtr
,
*
maxDrudeDistancePtr
,
*
hardwallscaleDrudePtr
;
if
(
cu
.
getUseDoublePrecision
()
||
cu
.
getUseMixedPrecision
())
{
vscalePtr
=
&
vscale
;
fscalePtr
=
&
fscale
;
...
...
@@ -324,6 +329,8 @@ void CudaIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const D
vscaleDrudePtr
=
&
vscaleDrude
;
fscaleDrudePtr
=
&
fscaleDrude
;
noisescaleDrudePtr
=
&
noisescaleDrude
;
maxDrudeDistancePtr
=
&
maxDrudeDistance
;
hardwallscaleDrudePtr
=
&
hardwallscaleDrude
;
}
else
{
vscalePtr
=
&
vscaleFloat
;
...
...
@@ -332,6 +339,8 @@ void CudaIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const D
vscaleDrudePtr
=
&
vscaleDrudeFloat
;
fscaleDrudePtr
=
&
fscaleDrudeFloat
;
noisescaleDrudePtr
=
&
noisescaleDrudeFloat
;
maxDrudeDistancePtr
=
&
maxDrudeDistanceFloat
;
hardwallscaleDrudePtr
=
&
hardwallscaleDrudeFloat
;
}
// Call the first integration kernel.
...
...
@@ -352,6 +361,12 @@ void CudaIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const D
void
*
args2
[]
=
{
&
cu
.
getPosq
().
getDevicePointer
(),
&
posCorrection
,
&
integration
.
getPosDelta
().
getDevicePointer
(),
&
cu
.
getVelm
().
getDevicePointer
(),
&
integration
.
getStepSize
().
getDevicePointer
()};
cu
.
executeKernel
(
kernel2
,
args2
,
numAtoms
);
// Apply hard wall constraints.
void
*
hardwallArgs
[]
=
{
&
cu
.
getPosq
().
getDevicePointer
(),
&
posCorrection
,
&
cu
.
getVelm
().
getDevicePointer
(),
&
pairParticles
->
getDevicePointer
(),
&
integration
.
getStepSize
().
getDevicePointer
(),
maxDrudeDistancePtr
,
hardwallscaleDrudePtr
};
cu
.
executeKernel
(
hardwallKernel
,
hardwallArgs
,
pairParticles
->
getSize
());
integration
.
computeVirtualSites
();
// Update the time and step count.
...
...
plugins/drude/platforms/cuda/src/CudaDrudeKernels.h
View file @
2d2f05ce
...
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013 Stanford University and the Authors.
*
* Portions copyright (c) 2013
-2015
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -113,7 +113,7 @@ private:
double
prevStepSize
;
CudaArray
*
normalParticles
;
CudaArray
*
pairParticles
;
CUfunction
kernel1
,
kernel2
;
CUfunction
kernel1
,
kernel2
,
hardwallKernel
;
};
/**
...
...
plugins/drude/platforms/cuda/src/kernels/drudeLangevin.cu
View file @
2d2f05ce
...
...
@@ -101,3 +101,111 @@ extern "C" __global__ void integrateDrudeLangevinPart2(real4* __restrict__ posq,
index
+=
blockDim
.
x
*
gridDim
.
x
;
}
}
/**
* Apply hard wall constraints
*/
extern
"C"
__global__
void
applyHardWallConstraints
(
real4
*
__restrict__
posq
,
real4
*
__restrict__
posqCorrection
,
mixed4
*
__restrict__
velm
,
const
int2
*
__restrict__
pairParticles
,
const
mixed2
*
__restrict__
dt
,
mixed
maxDrudeDistance
,
mixed
hardwallscaleDrude
)
{
mixed
stepSize
=
dt
[
0
].
y
;
for
(
int
i
=
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
;
i
<
NUM_PAIRS
;
i
+=
blockDim
.
x
*
gridDim
.
x
)
{
int2
particles
=
pairParticles
[
i
];
#ifdef USE_MIXED_PRECISION
real4
posReal1
=
posq
[
particles
.
x
];
real4
posReal2
=
posq
[
particles
.
y
];
real4
posCorr1
=
posqCorrection
[
particles
.
x
];
real4
posCorr2
=
posqCorrection
[
particles
.
y
];
mixed4
pos1
=
make_mixed4
(
posReal1
.
x
+
(
mixed
)
posCorr1
.
x
,
posReal1
.
y
+
(
mixed
)
posCorr1
.
y
,
posReal1
.
z
+
(
mixed
)
posCorr1
.
z
,
posReal1
.
w
);
mixed4
pos2
=
make_mixed4
(
posReal2
.
x
+
(
mixed
)
posCorr2
.
x
,
posReal2
.
y
+
(
mixed
)
posCorr2
.
y
,
posReal2
.
z
+
(
mixed
)
posCorr2
.
z
,
posReal2
.
w
);
#else
mixed4
pos1
=
posq
[
particles
.
x
];
mixed4
pos2
=
posq
[
particles
.
y
];
#endif
mixed4
delta
=
pos1
-
pos2
;
mixed
r
=
SQRT
(
delta
.
x
*
delta
.
x
+
delta
.
y
*
delta
.
y
+
delta
.
z
*
delta
.
z
);
mixed
rInv
=
RECIP
(
r
);
if
(
rInv
*
maxDrudeDistance
<
1
)
{
// The constraint has been violated, so make the inter-particle distance "bounce"
// off the hard wall.
mixed4
bondDir
=
delta
*
rInv
;
mixed4
vel1
=
velm
[
particles
.
x
];
mixed4
vel2
=
velm
[
particles
.
y
];
mixed
mass1
=
RECIP
(
vel1
.
w
);
mixed
mass2
=
RECIP
(
vel2
.
w
);
mixed
deltaR
=
r
-
maxDrudeDistance
;
mixed
deltaT
=
stepSize
;
mixed
dotvr1
=
vel1
.
x
*
bondDir
.
x
+
vel1
.
y
*
bondDir
.
y
+
vel1
.
z
*
bondDir
.
z
;
mixed4
vb1
=
bondDir
*
dotvr1
;
mixed4
vp1
=
vel1
-
vb1
;
if
(
vel2
.
w
==
0
)
{
// The parent particle is massless, so move only the Drude particle.
if
(
dotvr1
!=
0
)
deltaT
=
deltaR
/
fabs
(
dotvr1
);
if
(
deltaT
>
stepSize
)
deltaT
=
stepSize
;
dotvr1
=
-
dotvr1
*
hardwallscaleDrude
/
(
fabs
(
dotvr1
)
*
SQRT
(
mass1
));
mixed
dr
=
-
deltaR
+
deltaT
*
dotvr1
;
pos1
.
x
+=
bondDir
.
x
*
dr
;
pos1
.
y
+=
bondDir
.
y
*
dr
;
pos1
.
z
+=
bondDir
.
z
*
dr
;
#ifdef USE_MIXED_PRECISION
posq
[
particles
.
x
]
=
make_real4
((
real
)
pos1
.
x
,
(
real
)
pos1
.
y
,
(
real
)
pos1
.
z
,
(
real
)
pos1
.
w
);
posqCorrection
[
particles
.
x
]
=
make_real4
(
pos1
.
x
-
(
real
)
pos1
.
x
,
pos1
.
y
-
(
real
)
pos1
.
y
,
pos1
.
z
-
(
real
)
pos1
.
z
,
0
);
#else
posq
[
particles
.
x
]
=
pos1
;
#endif
vel1
.
x
=
vp1
.
x
+
bondDir
.
x
*
dotvr1
;
vel1
.
y
=
vp1
.
y
+
bondDir
.
y
*
dotvr1
;
vel1
.
z
=
vp1
.
z
+
bondDir
.
z
*
dotvr1
;
velm
[
particles
.
x
]
=
vel1
;
}
else
{
// Move both particles.
mixed
invTotalMass
=
RECIP
(
mass1
+
mass2
);
mixed
dotvr2
=
vel2
.
x
*
bondDir
.
x
+
vel2
.
y
*
bondDir
.
y
+
vel2
.
z
*
bondDir
.
z
;
mixed4
vb2
=
bondDir
*
dotvr2
;
mixed4
vp2
=
vel2
-
vb2
;
mixed
vbCMass
=
(
mass1
*
dotvr1
+
mass2
*
dotvr2
)
*
invTotalMass
;
dotvr1
-=
vbCMass
;
dotvr2
-=
vbCMass
;
if
(
dotvr1
!=
dotvr2
)
deltaT
=
deltaR
/
fabs
(
dotvr1
-
dotvr2
);
if
(
deltaT
>
stepSize
)
deltaT
=
stepSize
;
mixed
vBond
=
hardwallscaleDrude
/
SQRT
(
mass1
);
dotvr1
=
-
dotvr1
*
vBond
*
mass2
*
invTotalMass
/
fabs
(
dotvr1
);
dotvr2
=
-
dotvr2
*
vBond
*
mass1
*
invTotalMass
/
fabs
(
dotvr2
);
mixed
dr1
=
-
deltaR
*
mass2
*
invTotalMass
+
deltaT
*
dotvr1
;
mixed
dr2
=
deltaR
*
mass1
*
invTotalMass
+
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
;
#ifdef USE_MIXED_PRECISION
posq
[
particles
.
x
]
=
make_real4
((
real
)
pos1
.
x
,
(
real
)
pos1
.
y
,
(
real
)
pos1
.
z
,
(
real
)
pos1
.
w
);
posq
[
particles
.
y
]
=
make_real4
((
real
)
pos2
.
x
,
(
real
)
pos2
.
y
,
(
real
)
pos2
.
z
,
(
real
)
pos2
.
w
);
posqCorrection
[
particles
.
x
]
=
make_real4
(
pos1
.
x
-
(
real
)
pos1
.
x
,
pos1
.
y
-
(
real
)
pos1
.
y
,
pos1
.
z
-
(
real
)
pos1
.
z
,
0
);
posqCorrection
[
particles
.
y
]
=
make_real4
(
pos2
.
x
-
(
real
)
pos2
.
x
,
pos2
.
y
-
(
real
)
pos2
.
y
,
pos2
.
z
-
(
real
)
pos2
.
z
,
0
);
#else
posq
[
particles
.
x
]
=
pos1
;
posq
[
particles
.
y
]
=
pos2
;
#endif
vel1
.
x
=
vp1
.
x
+
bondDir
.
x
*
dotvr1
;
vel1
.
y
=
vp1
.
y
+
bondDir
.
y
*
dotvr1
;
vel1
.
z
=
vp1
.
z
+
bondDir
.
z
*
dotvr1
;
vel2
.
x
=
vp2
.
x
+
bondDir
.
x
*
dotvr2
;
vel2
.
y
=
vp2
.
y
+
bondDir
.
y
*
dotvr2
;
vel2
.
z
=
vp2
.
z
+
bondDir
.
z
*
dotvr2
;
velm
[
particles
.
x
]
=
vel1
;
velm
[
particles
.
y
]
=
vel2
;
}
}
}
}
plugins/drude/platforms/cuda/tests/TestCudaDrudeLangevinIntegrator.cpp
View file @
2d2f05ce
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013 Stanford University and the Authors.
*
* Portions copyright (c) 2013
-2015
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -60,6 +60,7 @@ void testSinglePair() {
const
double
mass2
=
0.1
;
const
double
totalMass
=
mass1
+
mass2
;
const
double
reducedMass
=
(
mass1
*
mass2
)
/
(
mass1
+
mass2
);
const
double
maxDistance
=
0.05
;
System
system
;
system
.
addParticle
(
mass1
);
system
.
addParticle
(
mass2
);
...
...
@@ -70,6 +71,7 @@ void testSinglePair() {
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0
,
0
,
0
);
DrudeLangevinIntegrator
integ
(
temperature
,
20.0
,
temperatureDrude
,
20.0
,
0.003
);
integ
.
setMaxDrudeDistance
(
maxDistance
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"CUDA"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
...
...
@@ -84,12 +86,15 @@ void testSinglePair() {
int
numSteps
=
10000
;
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
10
);
State
state
=
context
.
getState
(
State
::
Velocities
);
State
state
=
context
.
getState
(
State
::
Velocities
|
State
::
Positions
);
const
vector
<
Vec3
>&
vel
=
state
.
getVelocities
();
Vec3
velCM
=
vel
[
0
]
*
(
mass1
/
totalMass
)
+
vel
[
1
]
*
(
mass2
/
totalMass
);
keCM
+=
0.5
*
totalMass
*
velCM
.
dot
(
velCM
);
Vec3
velInternal
=
vel
[
0
]
-
vel
[
1
];
keInternal
+=
0.5
*
reducedMass
*
velInternal
.
dot
(
velInternal
);
Vec3
delta
=
state
.
getPositions
()[
0
]
-
state
.
getPositions
()[
1
];
double
distance
=
sqrt
(
delta
.
dot
(
delta
));
ASSERT
(
distance
<=
maxDistance
*
(
1
+
1e-6
));
}
ASSERT_USUALLY_EQUAL_TOL
(
3
*
0.5
*
BOLTZ
*
temperature
,
keCM
/
numSteps
,
0.1
);
ASSERT_USUALLY_EQUAL_TOL
(
3
*
0.5
*
BOLTZ
*
temperatureDrude
,
keInternal
/
numSteps
,
0.01
);
...
...
plugins/drude/platforms/opencl/src/OpenCLDrudeKernels.cpp
View file @
2d2f05ce
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013 Stanford University and the Authors.
*
* Portions copyright (c) 2013
-2015
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -284,6 +284,7 @@ void OpenCLIntegrateDrudeLangevinStepKernel::initialize(const System& system, co
cl
::
Program
program
=
cl
.
createProgram
(
OpenCLDrudeKernelSources
::
drudeLangevin
,
defines
,
""
);
kernel1
=
cl
::
Kernel
(
program
,
"integrateDrudeLangevinPart1"
);
kernel2
=
cl
::
Kernel
(
program
,
"integrateDrudeLangevinPart2"
);
hardwallKernel
=
cl
::
Kernel
(
program
,
"applyHardWallConstraints"
);
prevStepSize
=
-
1.0
;
}
...
...
@@ -307,6 +308,14 @@ void OpenCLIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const
kernel2
.
setArg
<
cl
::
Buffer
>
(
2
,
integration
.
getPosDelta
().
getDeviceBuffer
());
kernel2
.
setArg
<
cl
::
Buffer
>
(
3
,
cl
.
getVelm
().
getDeviceBuffer
());
kernel2
.
setArg
<
cl
::
Buffer
>
(
4
,
integration
.
getStepSize
().
getDeviceBuffer
());
hardwallKernel
.
setArg
<
cl
::
Buffer
>
(
0
,
cl
.
getPosq
().
getDeviceBuffer
());
if
(
cl
.
getUseMixedPrecision
())
hardwallKernel
.
setArg
<
cl
::
Buffer
>
(
1
,
cl
.
getPosqCorrection
().
getDeviceBuffer
());
else
hardwallKernel
.
setArg
<
void
*>
(
1
,
NULL
);
hardwallKernel
.
setArg
<
cl
::
Buffer
>
(
2
,
cl
.
getVelm
().
getDeviceBuffer
());
hardwallKernel
.
setArg
<
cl
::
Buffer
>
(
3
,
pairParticles
->
getDeviceBuffer
());
hardwallKernel
.
setArg
<
cl
::
Buffer
>
(
4
,
integration
.
getStepSize
().
getDeviceBuffer
());
}
// Compute integrator coefficients.
...
...
@@ -318,6 +327,8 @@ void OpenCLIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const
double
vscaleDrude
=
exp
(
-
stepSize
*
integrator
.
getDrudeFriction
());
double
fscaleDrude
=
(
1
-
vscaleDrude
)
/
integrator
.
getDrudeFriction
();
double
noisescaleDrude
=
sqrt
(
2
*
BOLTZ
*
integrator
.
getDrudeTemperature
()
*
integrator
.
getDrudeFriction
())
*
sqrt
(
0.5
*
(
1
-
vscaleDrude
*
vscaleDrude
)
/
integrator
.
getDrudeFriction
());
double
maxDrudeDistance
=
integrator
.
getMaxDrudeDistance
();
double
hardwallscaleDrude
=
sqrt
(
BOLTZ
*
integrator
.
getDrudeTemperature
());
if
(
stepSize
!=
prevStepSize
)
{
if
(
cl
.
getUseDoublePrecision
()
||
cl
.
getUseMixedPrecision
())
{
mm_double2
ss
=
mm_double2
(
0
,
stepSize
);
...
...
@@ -336,6 +347,8 @@ void OpenCLIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const
kernel1
.
setArg
<
cl_double
>
(
9
,
vscaleDrude
);
kernel1
.
setArg
<
cl_double
>
(
10
,
fscaleDrude
);
kernel1
.
setArg
<
cl_double
>
(
11
,
noisescaleDrude
);
hardwallKernel
.
setArg
<
cl_double
>
(
5
,
maxDrudeDistance
);
hardwallKernel
.
setArg
<
cl_double
>
(
6
,
hardwallscaleDrude
);
}
else
{
kernel1
.
setArg
<
cl_float
>
(
6
,
(
cl_float
)
vscale
);
...
...
@@ -344,6 +357,8 @@ void OpenCLIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const
kernel1
.
setArg
<
cl_float
>
(
9
,
(
cl_float
)
vscaleDrude
);
kernel1
.
setArg
<
cl_float
>
(
10
,
(
cl_float
)
fscaleDrude
);
kernel1
.
setArg
<
cl_float
>
(
11
,
(
cl_float
)
noisescaleDrude
);
hardwallKernel
.
setArg
<
cl_float
>
(
5
,
(
cl_float
)
maxDrudeDistance
);
hardwallKernel
.
setArg
<
cl_float
>
(
6
,
(
cl_float
)
hardwallscaleDrude
);
}
// Call the first integration kernel.
...
...
@@ -358,6 +373,10 @@ void OpenCLIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const
// Call the second integration kernel.
cl
.
executeKernel
(
kernel2
,
numAtoms
);
// Apply hard wall constraints.
cl
.
executeKernel
(
hardwallKernel
,
pairParticles
->
getSize
());
integration
.
computeVirtualSites
();
// Update the time and step count.
...
...
plugins/drude/platforms/opencl/src/OpenCLDrudeKernels.h
View file @
2d2f05ce
...
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013 Stanford University and the Authors.
*
* Portions copyright (c) 2013
-2015
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -114,7 +114,7 @@ private:
double
prevStepSize
;
OpenCLArray
*
normalParticles
;
OpenCLArray
*
pairParticles
;
cl
::
Kernel
kernel1
,
kernel2
;
cl
::
Kernel
kernel1
,
kernel2
,
hardwallKernel
;
};
/**
...
...
plugins/drude/platforms/opencl/src/kernels/drudeLangevin.cl
View file @
2d2f05ce
...
...
@@ -101,3 +101,99 @@ __kernel void integrateDrudeLangevinPart2(__global real4* restrict posq, __globa
index
+=
get_global_size
(
0
)
;
}
}
/**
*
Apply
hard
wall
constraints
*/
__kernel
void
applyHardWallConstraints
(
__global
real4*
restrict
posq,
__global
real4*
restrict
posqCorrection,
__global
mixed4*
restrict
velm,
__global
const
int2*
restrict
pairParticles,
__global
const
mixed2*
restrict
dt,
mixed
maxDrudeDistance,
mixed
hardwallscaleDrude
)
{
mixed
stepSize
=
dt[0].y
;
for
(
int
i
=
get_global_id
(
0
)
; i < NUM_PAIRS; i += get_global_size(0)) {
int2
particles
=
pairParticles[i]
;
#
ifdef
USE_MIXED_PRECISION
real4
posReal1
=
posq[particles.x]
;
real4
posReal2
=
posq[particles.y]
;
real4
posCorr1
=
posqCorrection[particles.x]
;
real4
posCorr2
=
posqCorrection[particles.y]
;
mixed4
pos1
=
(
mixed4
)
(
posReal1.x+
(
mixed
)
posCorr1.x,
posReal1.y+
(
mixed
)
posCorr1.y,
posReal1.z+
(
mixed
)
posCorr1.z,
posReal1.w
)
;
mixed4
pos2
=
(
mixed4
)
(
posReal2.x+
(
mixed
)
posCorr2.x,
posReal2.y+
(
mixed
)
posCorr2.y,
posReal2.z+
(
mixed
)
posCorr2.z,
posReal2.w
)
;
#
else
mixed4
pos1
=
posq[particles.x]
;
mixed4
pos2
=
posq[particles.y]
;
#
endif
mixed4
delta
=
pos1-pos2
;
mixed
r
=
sqrt
(
delta.x*delta.x
+
delta.y*delta.y
+
delta.z*delta.z
)
;
mixed
rInv
=
1/r
;
if
(
rInv*maxDrudeDistance
<
1
)
{
//
The
constraint
has
been
violated,
so
make
the
inter-particle
distance
"bounce"
//
off
the
hard
wall.
mixed4
bondDir
=
delta*rInv
;
mixed4
vel1
=
velm[particles.x]
;
mixed4
vel2
=
velm[particles.y]
;
mixed
mass1
=
1/vel1.w
;
mixed
mass2
=
1/vel2.w
;
mixed
deltaR
=
r-maxDrudeDistance
;
mixed
deltaT
=
stepSize
;
mixed
dotvr1
=
vel1.x*bondDir.x
+
vel1.y*bondDir.y
+
vel1.z*bondDir.z
;
mixed4
vb1
=
bondDir*dotvr1
;
mixed4
vp1
=
vel1-vb1
;
if
(
vel2.w
==
0
)
{
//
The
parent
particle
is
massless,
so
move
only
the
Drude
particle.
if
(
dotvr1
!=
0
)
deltaT
=
deltaR/fabs
(
dotvr1
)
;
if
(
deltaT
>
stepSize
)
deltaT
=
stepSize
;
dotvr1
=
-dotvr1*hardwallscaleDrude/
(
fabs
(
dotvr1
)
*sqrt
(
mass1
))
;
mixed
dr
=
-deltaR
+
deltaT*dotvr1
;
pos1.xyz
+=
bondDir.xyz*dr
;
#
ifdef
USE_MIXED_PRECISION
posq[particles.x]
=
(
real4
)
((
real
)
pos1.x,
(
real
)
pos1.y,
(
real
)
pos1.z,
(
real
)
pos1.w
)
;
posqCorrection[particles.x]
=
(
real4
)
(
pos1.x-
(
real
)
pos1.x,
pos1.y-
(
real
)
pos1.y,
pos1.z-
(
real
)
pos1.z,
0
)
;
#
else
posq[particles.x]
=
pos1
;
#
endif
vel1.xyz
=
vp1.xyz
+
bondDir.xyz*dotvr1
;
velm[particles.x]
=
vel1
;
}
else
{
//
Move
both
particles.
mixed
invTotalMass
=
1/
(
mass1+mass2
)
;
mixed
dotvr2
=
vel2.x*bondDir.x
+
vel2.y*bondDir.y
+
vel2.z*bondDir.z
;
mixed4
vb2
=
bondDir*dotvr2
;
mixed4
vp2
=
vel2-vb2
;
mixed
vbCMass
=
(
mass1*dotvr1
+
mass2*dotvr2
)
*invTotalMass
;
dotvr1
-=
vbCMass
;
dotvr2
-=
vbCMass
;
if
(
dotvr1
!=
dotvr2
)
deltaT
=
deltaR/fabs
(
dotvr1-dotvr2
)
;
if
(
deltaT
>
stepSize
)
deltaT
=
stepSize
;
mixed
vBond
=
hardwallscaleDrude/sqrt
(
mass1
)
;
dotvr1
=
-dotvr1*vBond*mass2*invTotalMass/fabs
(
dotvr1
)
;
dotvr2
=
-dotvr2*vBond*mass1*invTotalMass/fabs
(
dotvr2
)
;
mixed
dr1
=
-deltaR*mass2*invTotalMass
+
deltaT*dotvr1
;
mixed
dr2
=
deltaR*mass1*invTotalMass
+
deltaT*dotvr2
;
dotvr1
+=
vbCMass
;
dotvr2
+=
vbCMass
;
pos1.xyz
+=
bondDir.xyz*dr1
;
pos2.xyz
+=
bondDir.xyz*dr2
;
#
ifdef
USE_MIXED_PRECISION
posq[particles.x]
=
(
real4
)
((
real
)
pos1.x,
(
real
)
pos1.y,
(
real
)
pos1.z,
(
real
)
pos1.w
)
;
posq[particles.y]
=
(
real4
)
((
real
)
pos2.x,
(
real
)
pos2.y,
(
real
)
pos2.z,
(
real
)
pos2.w
)
;
posqCorrection[particles.x]
=
(
real4
)
(
pos1.x-
(
real
)
pos1.x,
pos1.y-
(
real
)
pos1.y,
pos1.z-
(
real
)
pos1.z,
0
)
;
posqCorrection[particles.y]
=
(
real4
)
(
pos2.x-
(
real
)
pos2.x,
pos2.y-
(
real
)
pos2.y,
pos2.z-
(
real
)
pos2.z,
0
)
;
#
else
posq[particles.x]
=
pos1
;
posq[particles.y]
=
pos2
;
#
endif
vel1.xyz
=
vp1.xyz
+
bondDir.xyz*dotvr1
;
vel2.xyz
=
vp2.xyz
+
bondDir.xyz*dotvr2
;
velm[particles.x]
=
vel1
;
velm[particles.y]
=
vel2
;
}
}
}
}
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp
View file @
2d2f05ce
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013 Stanford University and the Authors.
*
* Portions copyright (c) 2013
-2015
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -60,6 +60,7 @@ void testSinglePair() {
const
double
mass2
=
0.1
;
const
double
totalMass
=
mass1
+
mass2
;
const
double
reducedMass
=
(
mass1
*
mass2
)
/
(
mass1
+
mass2
);
const
double
maxDistance
=
0.05
;
System
system
;
system
.
addParticle
(
mass1
);
system
.
addParticle
(
mass2
);
...
...
@@ -70,6 +71,7 @@ void testSinglePair() {
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0
,
0
,
0
);
DrudeLangevinIntegrator
integ
(
temperature
,
20.0
,
temperatureDrude
,
20.0
,
0.003
);
integ
.
setMaxDrudeDistance
(
maxDistance
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"OpenCL"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
...
...
@@ -84,12 +86,15 @@ void testSinglePair() {
int
numSteps
=
10000
;
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
10
);
State
state
=
context
.
getState
(
State
::
Velocities
);
State
state
=
context
.
getState
(
State
::
Velocities
|
State
::
Positions
);
const
vector
<
Vec3
>&
vel
=
state
.
getVelocities
();
Vec3
velCM
=
vel
[
0
]
*
(
mass1
/
totalMass
)
+
vel
[
1
]
*
(
mass2
/
totalMass
);
keCM
+=
0.5
*
totalMass
*
velCM
.
dot
(
velCM
);
Vec3
velInternal
=
vel
[
0
]
-
vel
[
1
];
keInternal
+=
0.5
*
reducedMass
*
velInternal
.
dot
(
velInternal
);
Vec3
delta
=
state
.
getPositions
()[
0
]
-
state
.
getPositions
()[
1
];
double
distance
=
sqrt
(
delta
.
dot
(
delta
));
ASSERT
(
distance
<=
maxDistance
*
(
1
+
1e-6
));
}
ASSERT_USUALLY_EQUAL_TOL
(
3
*
0.5
*
BOLTZ
*
temperature
,
keCM
/
numSteps
,
0.1
);
ASSERT_USUALLY_EQUAL_TOL
(
3
*
0.5
*
BOLTZ
*
temperatureDrude
,
keInternal
/
numSteps
,
0.01
);
...
...
plugins/drude/platforms/reference/CMakeLists.txt
View file @
2d2f05ce
...
...
@@ -75,6 +75,6 @@ SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_LINK_FLAGS
INSTALL
(
TARGETS
${
SHARED_TARGET
}
DESTINATION
${
CMAKE_INSTALL_PREFIX
}
/lib/plugins
)
IF
(
BUILD_TESTING
)
IF
(
BUILD_TESTING
AND OPENMM_BUILD_REFERENCE_TESTS
)
SUBDIRS
(
tests
)
ENDIF
(
BUILD_TESTING
)
ENDIF
(
BUILD_TESTING
AND OPENMM_BUILD_REFERENCE_TESTS
)
plugins/drude/platforms/reference/src/ReferenceDrudeKernels.cpp
View file @
2d2f05ce
...
...
@@ -235,7 +235,6 @@ void ReferenceIntegrateDrudeLangevinStepKernel::initialize(const System& system,
// Identify particle pairs and ordinary particles.
set
<
int
>
particles
;
vector
<
RealOpenMM
>
particleMass
;
for
(
int
i
=
0
;
i
<
system
.
getNumParticles
();
i
++
)
{
particles
.
insert
(
i
);
double
mass
=
system
.
getParticleMass
(
i
);
...
...
@@ -325,6 +324,75 @@ void ReferenceIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, co
pos
[
i
]
=
xPrime
[
i
];
}
}
// Apply hard wall constraints.
const
RealOpenMM
maxDrudeDistance
=
integrator
.
getMaxDrudeDistance
();
if
(
maxDrudeDistance
>
0
)
{
const
RealOpenMM
hardwallscaleDrude
=
sqrt
(
kTDrude
);
for
(
int
i
=
0
;
i
<
(
int
)
pairParticles
.
size
();
i
++
)
{
int
p1
=
pairParticles
[
i
].
first
;
int
p2
=
pairParticles
[
i
].
second
;
RealVec
delta
=
pos
[
p1
]
-
pos
[
p2
];
RealOpenMM
r
=
sqrt
(
delta
.
dot
(
delta
));
RealOpenMM
rInv
=
1
/
r
;
if
(
rInv
*
maxDrudeDistance
<
1.0
)
{
// The constraint has been violated, so make the inter-particle distance "bounce"
// off the hard wall.
if
(
rInv
*
maxDrudeDistance
<
0.5
)
throw
OpenMMException
(
"Drude particle moved too far beyond hard wall constraint"
);
RealVec
bondDir
=
delta
*
rInv
;
RealVec
vel1
=
vel
[
p1
];
RealVec
vel2
=
vel
[
p2
];
RealOpenMM
mass1
=
particleMass
[
p1
];
RealOpenMM
mass2
=
particleMass
[
p2
];
RealOpenMM
deltaR
=
r
-
maxDrudeDistance
;
RealOpenMM
deltaT
=
dt
;
RealOpenMM
dotvr1
=
vel1
.
dot
(
bondDir
);
RealVec
vb1
=
bondDir
*
dotvr1
;
RealVec
vp1
=
vel1
-
vb1
;
if
(
mass2
==
0
)
{
// The parent particle is massless, so move only the Drude particle.
if
(
dotvr1
!=
0.0
)
deltaT
=
deltaR
/
abs
(
dotvr1
);
if
(
deltaT
>
dt
)
deltaT
=
dt
;
dotvr1
=
-
dotvr1
*
hardwallscaleDrude
/
(
abs
(
dotvr1
)
*
sqrt
(
mass1
));
RealOpenMM
dr
=
-
deltaR
+
deltaT
*
dotvr1
;
pos
[
p1
]
+=
bondDir
*
dr
;
vel
[
p1
]
=
vp1
+
bondDir
*
dotvr1
;
}
else
{
// Move both particles.
RealOpenMM
invTotalMass
=
pairInvTotalMass
[
i
];
RealOpenMM
dotvr2
=
vel2
.
dot
(
bondDir
);
RealVec
vb2
=
bondDir
*
dotvr2
;
RealVec
vp2
=
vel2
-
vb2
;
RealOpenMM
vbCMass
=
(
mass1
*
dotvr1
+
mass2
*
dotvr2
)
*
invTotalMass
;
dotvr1
-=
vbCMass
;
dotvr2
-=
vbCMass
;
if
(
dotvr1
!=
dotvr2
)
deltaT
=
deltaR
/
abs
(
dotvr1
-
dotvr2
);
if
(
deltaT
>
dt
)
deltaT
=
dt
;
RealOpenMM
vBond
=
hardwallscaleDrude
/
sqrt
(
mass1
);
dotvr1
=
-
dotvr1
*
vBond
*
mass2
*
invTotalMass
/
abs
(
dotvr1
);
dotvr2
=
-
dotvr2
*
vBond
*
mass1
*
invTotalMass
/
abs
(
dotvr2
);
RealOpenMM
dr1
=
-
deltaR
*
mass2
*
invTotalMass
+
deltaT
*
dotvr1
;
RealOpenMM
dr2
=
deltaR
*
mass1
*
invTotalMass
+
deltaT
*
dotvr2
;
dotvr1
+=
vbCMass
;
dotvr2
+=
vbCMass
;
pos
[
p1
]
+=
bondDir
*
dr1
;
pos
[
p2
]
+=
bondDir
*
dr2
;
vel
[
p1
]
=
vp1
+
bondDir
*
dotvr1
;
vel
[
p2
]
=
vp2
+
bondDir
*
dotvr2
;
}
}
}
}
ReferenceVirtualSites
::
computePositions
(
context
.
getSystem
(),
pos
);
data
.
time
+=
integrator
.
getStepSize
();
data
.
stepCount
++
;
...
...
plugins/drude/platforms/reference/src/ReferenceDrudeKernels.h
View file @
2d2f05ce
...
...
@@ -115,6 +115,7 @@ private:
ReferencePlatform
::
PlatformData
&
data
;
std
::
vector
<
int
>
normalParticles
;
std
::
vector
<
std
::
pair
<
int
,
int
>
>
pairParticles
;
std
::
vector
<
double
>
particleMass
;
std
::
vector
<
double
>
particleInvMass
;
std
::
vector
<
double
>
pairInvTotalMass
;
std
::
vector
<
double
>
pairInvReducedMass
;
...
...
@@ -158,6 +159,7 @@ private:
std
::
vector
<
double
>
particleInvMass
;
lbfgsfloatval_t
*
minimizerPos
;
lbfgs_parameter_t
minimizerParams
;
double
maxDrudeDistance
;
};
}
// namespace OpenMM
...
...
plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp
View file @
2d2f05ce
...
...
@@ -60,6 +60,7 @@ void testSinglePair() {
const
double
mass2
=
0.1
;
const
double
totalMass
=
mass1
+
mass2
;
const
double
reducedMass
=
(
mass1
*
mass2
)
/
(
mass1
+
mass2
);
const
double
maxDistance
=
0.05
;
System
system
;
system
.
addParticle
(
mass1
);
system
.
addParticle
(
mass2
);
...
...
@@ -70,6 +71,7 @@ void testSinglePair() {
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0
,
0
,
0
);
DrudeLangevinIntegrator
integ
(
temperature
,
20.0
,
temperatureDrude
,
20.0
,
0.003
);
integ
.
setMaxDrudeDistance
(
maxDistance
);
Platform
&
platform
=
Platform
::
getPlatformByName
(
"Reference"
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
...
...
@@ -84,12 +86,15 @@ void testSinglePair() {
int
numSteps
=
10000
;
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
10
);
State
state
=
context
.
getState
(
State
::
Velocities
);
State
state
=
context
.
getState
(
State
::
Velocities
|
State
::
Positions
);
const
vector
<
Vec3
>&
vel
=
state
.
getVelocities
();
Vec3
velCM
=
vel
[
0
]
*
(
mass1
/
totalMass
)
+
vel
[
1
]
*
(
mass2
/
totalMass
);
keCM
+=
0.5
*
totalMass
*
velCM
.
dot
(
velCM
);
Vec3
velInternal
=
vel
[
0
]
-
vel
[
1
];
keInternal
+=
0.5
*
reducedMass
*
velInternal
.
dot
(
velInternal
);
Vec3
delta
=
state
.
getPositions
()[
0
]
-
state
.
getPositions
()[
1
];
double
distance
=
sqrt
(
delta
.
dot
(
delta
));
ASSERT
(
distance
<=
maxDistance
*
(
1
+
1e-6
));
}
ASSERT_USUALLY_EQUAL_TOL
(
3
*
0.5
*
BOLTZ
*
temperature
,
keCM
/
numSteps
,
0.1
);
ASSERT_USUALLY_EQUAL_TOL
(
3
*
0.5
*
BOLTZ
*
temperatureDrude
,
keInternal
/
numSteps
,
0.01
);
...
...
Prev
1
…
4
5
6
7
8
9
10
11
12
Next
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