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
f6431a42
Unverified
Commit
f6431a42
authored
Dec 21, 2019
by
peastman
Committed by
GitHub
Dec 21, 2019
Browse files
Merge pull request #2351 from andysim/nhc
WIP: Nosé-Hoover Thermostat
parents
2fc77d89
44dca26d
Changes
67
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1512 additions
and
1 deletion
+1512
-1
platforms/reference/tests/TestReferenceNoseHooverThermostat.cpp
...rms/reference/tests/TestReferenceNoseHooverThermostat.cpp
+36
-0
plugins/drude/openmmapi/include/OpenMMDrude.h
plugins/drude/openmmapi/include/OpenMMDrude.h
+1
-0
plugins/drude/openmmapi/include/openmm/DrudeNoseHooverIntegrator.h
...rude/openmmapi/include/openmm/DrudeNoseHooverIntegrator.h
+100
-0
plugins/drude/openmmapi/src/DrudeNoseHooverIntegrator.cpp
plugins/drude/openmmapi/src/DrudeNoseHooverIntegrator.cpp
+145
-0
plugins/drude/platforms/cuda/tests/CMakeLists.txt
plugins/drude/platforms/cuda/tests/CMakeLists.txt
+1
-0
plugins/drude/platforms/cuda/tests/TestCudaDrudeNoseHoover.cpp
...ns/drude/platforms/cuda/tests/TestCudaDrudeNoseHoover.cpp
+61
-0
plugins/drude/platforms/opencl/tests/CMakeLists.txt
plugins/drude/platforms/opencl/tests/CMakeLists.txt
+1
-0
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeNoseHoover.cpp
...rude/platforms/opencl/tests/TestOpenCLDrudeNoseHoover.cpp
+60
-0
plugins/drude/platforms/reference/tests/CMakeLists.txt
plugins/drude/platforms/reference/tests/CMakeLists.txt
+1
-0
plugins/drude/platforms/reference/tests/TestReferenceDrudeNoseHoover.cpp
...latforms/reference/tests/TestReferenceDrudeNoseHoover.cpp
+50
-0
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
+283
-0
serialization/include/openmm/serialization/NoseHooverIntegratorProxy.h
.../include/openmm/serialization/NoseHooverIntegratorProxy.h
+17
-0
serialization/src/NoseHooverIntegratorProxy.cpp
serialization/src/NoseHooverIntegratorProxy.cpp
+128
-0
serialization/src/SerializationProxyRegistration.cpp
serialization/src/SerializationProxyRegistration.cpp
+4
-1
serialization/tests/TestSerializeNoseHooverIntegrator.cpp
serialization/tests/TestSerializeNoseHooverIntegrator.cpp
+124
-0
tests/TestNoseHooverIntegrator.h
tests/TestNoseHooverIntegrator.h
+290
-0
No files found.
platforms/reference/tests/TestReferenceNoseHooverThermostat.cpp
0 → 100644
View file @
f6431a42
/* -------------------------------------------------------------------------- *
* 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) 2019 Stanford University and the Authors. *
* Authors: Andreas Krämer and Andrew C. Simmonett *
* 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 "ReferenceTests.h"
#include "TestNoseHooverThermostat.h"
void
runPlatformTests
()
{
}
plugins/drude/openmmapi/include/OpenMMDrude.h
View file @
f6431a42
...
...
@@ -35,5 +35,6 @@
#include "openmm/DrudeForce.h"
#include "openmm/DrudeLangevinIntegrator.h"
#include "openmm/DrudeSCFIntegrator.h"
#include "openmm/DrudeNoseHooverIntegrator.h"
#endif
/*OPENMM_DRUDE_H_*/
plugins/drude/openmmapi/include/openmm/DrudeNoseHooverIntegrator.h
0 → 100644
View file @
f6431a42
#ifndef OPENMM_DRUDENOSEHOOVERINTEGRATOR_H_
#define OPENMM_DRUDENOSEHOOVERINTEGRATOR_H_
/* -------------------------------------------------------------------------- *
* 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) 2019 Stanford University and the Authors. *
* Authors: Andreas Krämer and Andrew C. Simmonett *
* 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/NoseHooverIntegrator.h"
#include "openmm/Kernel.h"
#include "openmm/internal/windowsExportDrude.h"
namespace
OpenMM
{
/**
* This Integrator simulates systems that include Drude particles. It applies two different Nose-Hoover
* chain thermostats to the different parts of the system. The first is applied to ordinary particles (ones
* that are not part of a Drude particle pair), as well as to the center of mass of each Drude particle pair.
* A second thermostat, typically with a much lower temperature, is applied to the relative internal
* displacement of each pair.
*
* This Integrator requires the System to include a DrudeForce, which it uses to identify the Drude
* particles.
*/
class
OPENMM_EXPORT_DRUDE
DrudeNoseHooverIntegrator
:
public
NoseHooverIntegrator
{
public:
/**
* Create a DrudeNoseHooverIntegrator.
*
* @param temperature the target temperature for the system (in Kelvin).
* @param collisionFrequency the frequency of the system's interaction with the heat bath (in inverse picoseconds).
* @param drudeTemperature the target temperature for the Drude particles, relative to their parent atom (in Kelvin).
* @param drudeCollisionFrequency the frequency of the drude particles' interaction with the heat bath (in inverse picoseconds).
* @param stepSize the step size with which to integrator the system (in picoseconds)
* @param chainLength the number of beads in the Nose-Hoover chain.
* @param numMTS the number of step in the multiple time step chain propagation algorithm.
* @param numYoshidaSuzuki the number of terms in the Yoshida-Suzuki multi time step decomposition
* used in the chain propagation algorithm (must be 1, 3, or 5).
*/
DrudeNoseHooverIntegrator
(
double
temperature
,
double
collisionFrequency
,
double
drudeTemperature
,
double
drudeCollisionFrequency
,
double
stepSize
,
int
chainLength
=
3
,
int
numMTS
=
3
,
int
numYoshidaSuzuki
=
3
);
virtual
~
DrudeNoseHooverIntegrator
();
/**
* This will be called by the Context when it is created. It informs the Integrator
* of what context it will be integrating, and gives it a chance to do any necessary initialization.
* It will also get called again if the application calls reinitialize() on the Context.
*/
void
initialize
(
ContextImpl
&
context
);
/**
* 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
);
/**
* Compute the kinetic energy of the drude particles at the current time.
*/
double
computeDrudeKineticEnergy
();
/**
* Compute the kinetic energy of all (real and drude) particles at the current time.
*/
double
computeTotalKineticEnergy
();
};
}
// namespace OpenMM
#endif
/*OPENMM_DRUDENOSEHOOVERINTEGRATOR_H_*/
plugins/drude/openmmapi/src/DrudeNoseHooverIntegrator.cpp
0 → 100644
View file @
f6431a42
/* -------------------------------------------------------------------------- *
* 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) 2019 Stanford University and the Authors. *
* Authors: Andreas Krämer and Andrew C. Simmonett *
* 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/DrudeNoseHooverIntegrator.h"
#include "openmm/Context.h"
#include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/DrudeKernels.h"
#include "openmm/DrudeForce.h"
#include "openmm/CMMotionRemover.h"
#include "openmm/kernels.h"
#include <ctime>
#include <iostream>
#include <string>
#include <set>
using
namespace
OpenMM
;
using
std
::
string
;
using
std
::
vector
;
DrudeNoseHooverIntegrator
::
DrudeNoseHooverIntegrator
(
double
temperature
,
double
collisionFrequency
,
double
drudeTemperature
,
double
drudeCollisionFrequency
,
double
stepSize
,
int
chainLength
,
int
numMTS
,
int
numYoshidaSuzuki
)
:
NoseHooverIntegrator
(
stepSize
)
{
setMaxDrudeDistance
(
0
);
hasSubsystemThermostats_
=
false
;
addSubsystemThermostat
(
std
::
vector
<
int
>
(),
std
::
vector
<
std
::
pair
<
int
,
int
>>
(),
temperature
,
collisionFrequency
,
drudeTemperature
,
drudeCollisionFrequency
,
chainLength
,
numMTS
,
numYoshidaSuzuki
);
}
DrudeNoseHooverIntegrator
::~
DrudeNoseHooverIntegrator
()
{
}
double
DrudeNoseHooverIntegrator
::
getMaxDrudeDistance
()
const
{
return
maxPairDistance_
;
}
void
DrudeNoseHooverIntegrator
::
setMaxDrudeDistance
(
double
distance
)
{
if
(
distance
<
0
)
throw
OpenMMException
(
"setMaxDrudeDistance: Distance cannot be negative"
);
maxPairDistance_
=
distance
;
}
void
DrudeNoseHooverIntegrator
::
initialize
(
ContextImpl
&
contextRef
)
{
if
(
owner
!=
NULL
&&
&
contextRef
.
getOwner
()
!=
owner
)
throw
OpenMMException
(
"This Integrator is already bound to a context"
);
context
=
&
contextRef
;
owner
=
&
contextRef
.
getOwner
();
vvKernel
=
context
->
getPlatform
().
createKernel
(
IntegrateVelocityVerletStepKernel
::
Name
(),
contextRef
);
vvKernel
.
getAs
<
IntegrateVelocityVerletStepKernel
>
().
initialize
(
contextRef
.
getSystem
(),
*
this
);
nhcKernel
=
context
->
getPlatform
().
createKernel
(
NoseHooverChainKernel
::
Name
(),
contextRef
);
nhcKernel
.
getAs
<
NoseHooverChainKernel
>
().
initialize
();
forcesAreValid
=
false
;
// check for drude particles and build the Nose-Hoover Chains
const
System
&
system
=
context
->
getSystem
();
const
DrudeForce
*
drudeForce
=
NULL
;
bool
hasCMMotionRemover
=
false
;
for
(
int
i
=
0
;
i
<
system
.
getNumForces
();
i
++
){
if
(
dynamic_cast
<
const
DrudeForce
*>
(
&
system
.
getForce
(
i
))
!=
NULL
)
{
if
(
drudeForce
==
NULL
)
drudeForce
=
dynamic_cast
<
const
DrudeForce
*>
(
&
system
.
getForce
(
i
));
else
throw
OpenMMException
(
"The System contains multiple DrudeForces"
);
}
if
(
dynamic_cast
<
const
CMMotionRemover
*>
(
&
system
.
getForce
(
i
)))
{
hasCMMotionRemover
=
true
;
}
}
if
(
drudeForce
==
NULL
)
throw
OpenMMException
(
"The System does not contain a DrudeForce"
);
if
(
!
hasCMMotionRemover
)
{
std
::
cout
<<
"Warning: Did not find a center-of-mass motion remover in the system. "
"This is problematic when using Drude."
<<
std
::
endl
;
}
for
(
auto
&
thermostat
:
noseHooverChains
){
if
(
(
thermostat
.
getThermostatedAtoms
().
size
()
==
0
)
&&
(
thermostat
.
getThermostatedPairs
().
size
()
==
0
)
){
std
::
set
<
int
>
realParticlesSet
;
vector
<
int
>
realParticles
,
drudeParticles
,
drudeParents
;
vector
<
std
::
pair
<
int
,
int
>>
drudePairs
;
for
(
int
i
=
0
;
i
<
system
.
getNumParticles
();
i
++
)
{
if
(
system
.
getParticleMass
(
i
)
>
0.0
)
realParticlesSet
.
insert
(
i
);
}
for
(
int
i
=
0
;
i
<
drudeForce
->
getNumParticles
();
i
++
)
{
int
p
,
p1
,
p2
,
p3
,
p4
;
double
charge
,
polarizability
,
aniso12
,
aniso34
;
drudeForce
->
getParticleParameters
(
i
,
p
,
p1
,
p2
,
p3
,
p4
,
charge
,
polarizability
,
aniso12
,
aniso34
);
realParticlesSet
.
erase
(
p
);
realParticlesSet
.
erase
(
p1
);
drudePairs
.
push_back
({
p
,
p1
});
}
thermostat
.
setThermostatedPairs
(
drudePairs
);
thermostat
.
setThermostatedAtoms
(
std
::
vector
<
int
>
(
realParticlesSet
.
begin
(),
realParticlesSet
.
end
()));
}
}
initializeThermostats
(
system
);
}
double
DrudeNoseHooverIntegrator
::
computeDrudeKineticEnergy
()
{
double
kE
=
0.0
;
for
(
const
auto
&
nhc
:
noseHooverChains
){
if
(
nhc
.
getThermostatedPairs
().
size
()
!=
0
)
{
kE
+=
nhcKernel
.
getAs
<
NoseHooverChainKernel
>
().
computeMaskedKineticEnergy
(
*
context
,
nhc
,
true
).
second
;
}
}
return
kE
;
}
double
DrudeNoseHooverIntegrator
::
computeTotalKineticEnergy
()
{
return
vvKernel
.
getAs
<
IntegrateVelocityVerletStepKernel
>
().
computeKineticEnergy
(
*
context
,
*
this
);
}
plugins/drude/platforms/cuda/tests/CMakeLists.txt
View file @
f6431a42
...
...
@@ -5,6 +5,7 @@
ENABLE_TESTING
()
INCLUDE_DIRECTORIES
(
${
CUDA_INCLUDE_DIR
}
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/plugins/drude/tests
)
# Automatically create tests using files named "Test*.cpp"
FILE
(
GLOB TEST_PROGS
"*Test*.cpp"
)
...
...
plugins/drude/platforms/cuda/tests/TestCudaDrudeNoseHoover.cpp
0 → 100644
View file @
f6431a42
/* -------------------------------------------------------------------------- *
* 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) 2013 Stanford University and the Authors. *
* Authors: Peter Eastman *
* 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 "ReferenceTests.h"
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include "openmm/DrudeForce.h"
#include "CudaPlatform.h"
#include "SimTKOpenMMUtilities.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
extern
"C"
OPENMM_EXPORT
void
registerDrudeCudaKernelFactories
();
void
runPlatformTests
()
{
}
#include "TestDrudeNoseHoover.h"
Platform
&
initializePlatform
(
int
argc
,
char
*
argv
[])
{
registerDrudeCudaKernelFactories
();
if
(
argc
>
1
)
Platform
::
getPlatformByName
(
"CUDA"
).
setPropertyDefaultValue
(
"Precision"
,
std
::
string
(
argv
[
1
]));
return
Platform
::
getPlatformByName
(
"CUDA"
);
}
plugins/drude/platforms/opencl/tests/CMakeLists.txt
View file @
f6431a42
...
...
@@ -5,6 +5,7 @@
ENABLE_TESTING
()
INCLUDE_DIRECTORIES
(
${
OPENCL_INCLUDE_DIR
}
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/plugins/drude/tests
)
# Automatically create tests using files named "Test*.cpp"
FILE
(
GLOB TEST_PROGS
"*Test*.cpp"
)
...
...
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeNoseHoover.cpp
0 → 100644
View file @
f6431a42
/* -------------------------------------------------------------------------- *
* 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) 2013 Stanford University and the Authors. *
* Authors: Peter Eastman *
* 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 "ReferenceTests.h"
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include "openmm/DrudeForce.h"
#include "OpenCLPlatform.h"
#include "SimTKOpenMMUtilities.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
extern
"C"
OPENMM_EXPORT
void
registerDrudeOpenCLKernelFactories
();
void
runPlatformTests
()
{
}
#include "TestDrudeNoseHoover.h"
Platform
&
initializePlatform
(
int
argc
,
char
*
argv
[])
{
registerDrudeOpenCLKernelFactories
();
if
(
argc
>
1
)
Platform
::
getPlatformByName
(
"OpenCL"
).
setPropertyDefaultValue
(
"Precision"
,
std
::
string
(
argv
[
1
]));
return
Platform
::
getPlatformByName
(
"OpenCL"
);
}
plugins/drude/platforms/reference/tests/CMakeLists.txt
View file @
f6431a42
...
...
@@ -5,6 +5,7 @@ ENABLE_TESTING()
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/platforms/reference/include
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/openmmapi/include/openmm
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/platforms/reference/src
)
INCLUDE_DIRECTORIES
(
${
OPENMM_DIR
}
/plugins/drude/tests
)
SET
(
SHARED_OPENMM_DRUDE_TARGET OpenMMDrude
)
...
...
plugins/drude/platforms/reference/tests/TestReferenceDrudeNoseHoover.cpp
0 → 100644
View file @
f6431a42
/* -------------------------------------------------------------------------- *
* 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) 2013 Stanford University and the Authors. *
* Authors: Peter Eastman *
* 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 "ReferenceTests.h"
#include "openmm/Platform.h"
using
namespace
OpenMM
;
using
namespace
std
;
//extern "C" OPENMM_EXPORT void registerDrudeReferenceKernelFactories();
Platform
&
initializePlatform
(
int
argc
,
char
*
argv
[])
{
/* registerDrudeReferenceKernelFactories();
*/
return
Platform
::
getPlatformByName
(
"Reference"
);
}
#include "TestDrudeNoseHoover.h"
void
runPlatformTests
()
{
}
plugins/drude/serialization/include/openmm/serialization/DrudeNoseHooverIntegratorProxy.h
0 → 100644
View file @
f6431a42
#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 @
f6431a42
/* -------------------------------------------------------------------------- *
* 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
.
getThermostat
().
getChainLength
());
node
.
setIntProperty
(
"numMTS"
,
integrator
.
getThermostat
().
getNumMultiTimeSteps
());
node
.
setIntProperty
(
"numYS"
,
integrator
.
getThermostat
().
getNumYoshidaSuzukiTimeSteps
());
}
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 @
f6431a42
...
...
@@ -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 @
f6431a42
/* -------------------------------------------------------------------------- *
* 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
.
getNumThermostats
(),
integrator2
.
getNumThermostats
());
for
(
int
i
=
0
;
i
<
integrator1
.
getNumThermostats
();
i
++
)
{
const
auto
&
thermostat1
=
integrator1
.
getThermostat
(
i
);
const
auto
&
thermostat2
=
integrator2
.
getThermostat
(
i
);
ASSERT_EQUAL
(
thermostat1
.
getTemperature
(),
thermostat2
.
getTemperature
());
ASSERT_EQUAL
(
thermostat1
.
getCollisionFrequency
(),
thermostat2
.
getCollisionFrequency
());
ASSERT_EQUAL
(
thermostat1
.
getRelativeTemperature
(),
thermostat2
.
getRelativeTemperature
());
ASSERT_EQUAL
(
thermostat1
.
getRelativeCollisionFrequency
(),
thermostat2
.
getRelativeCollisionFrequency
());
ASSERT_EQUAL
(
thermostat1
.
getChainLength
(),
thermostat2
.
getChainLength
());
ASSERT_EQUAL
(
thermostat1
.
getNumMultiTimeSteps
(),
thermostat2
.
getNumMultiTimeSteps
());
ASSERT_EQUAL
(
thermostat1
.
getNumYoshidaSuzukiTimeSteps
(),
thermostat2
.
getNumYoshidaSuzukiTimeSteps
());
ASSERT_EQUAL
(
thermostat1
.
getChainID
(),
thermostat2
.
getChainID
());
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
->
getThermostat
(
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
0 → 100644
View file @
f6431a42
/* -------------------------------------------------------------------------- *
* 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) 2019 Stanford University and the Authors. *
* Authors: Andreas Krämer and Andrew C. Simmonett *
* 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/NoseHooverChain.h"
#include "openmm/CMMotionRemover.h"
#include "openmm/DrudeNoseHooverIntegrator.h"
#include "openmm/Context.h"
#include "openmm/State.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/VirtualSite.h"
#include "openmm/NonbondedForce.h"
#include "openmm/CustomExternalForce.h"
#include "openmm/System.h"
#include "openmm/DrudeForce.h"
#include "SimTKOpenMMRealType.h"
#include "sfmt/SFMT.h"
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
using
namespace
OpenMM
;
using
namespace
std
;
extern
"C"
OPENMM_EXPORT
void
registerDrudeReferenceKernelFactories
();
extern
"C"
OPENMM_EXPORT
void
registerKernelFactories
();
Platform
&
initializePlatform
(
int
argc
,
char
*
argv
[]);
void
build_waterbox
(
System
&
system
,
int
gridSize
,
double
polarizability
,
vector
<
Vec3
>
&
positions
)
{
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// and Drude particles.
const
int
numMolecules
=
gridSize
*
gridSize
*
gridSize
;
const
double
spacing
=
0.8
;
const
double
boxSize
=
spacing
*
(
gridSize
+
1
);
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
DrudeForce
*
drude
=
new
DrudeForce
();
CMMotionRemover
*
cmm
=
new
CMMotionRemover
(
1
);
system
.
addForce
(
cmm
);
system
.
addForce
(
nonbonded
);
system
.
addForce
(
drude
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
nonbonded
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
nonbonded
->
setCutoffDistance
(
1.2
);
nonbonded
->
setSwitchingDistance
(
0.8
);
for
(
int
i
=
0
;
i
<
numMolecules
;
i
++
)
{
int
startIndex
=
system
.
getNumParticles
();
system
.
addParticle
(
15.6
);
// O
system
.
addParticle
(
0.4
);
// D
system
.
addParticle
(
1.0
);
// H1
system
.
addParticle
(
1.0
);
// H2
system
.
addParticle
(
0.0
);
// M
nonbonded
->
addParticle
(
1.71636
,
0.318395
,
0.21094
*
4.184
);
nonbonded
->
addParticle
(
-
1.71636
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
0.55733
,
1
,
0
);
nonbonded
->
addParticle
(
-
1.11466
,
1
,
0
);
for
(
int
j
=
0
;
j
<
5
;
j
++
)
for
(
int
k
=
0
;
k
<
j
;
k
++
)
nonbonded
->
addException
(
startIndex
+
j
,
startIndex
+
k
,
0
,
1
,
0
);
system
.
addConstraint
(
startIndex
,
startIndex
+
2
,
0.09572
);
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
polarizability
,
1
,
1
);
}
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
{
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
)
{
for
(
int
k
=
0
;
k
<
gridSize
;
k
++
)
{
Vec3
pos
(
i
*
spacing
,
j
*
spacing
,
k
*
spacing
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
);
positions
.
push_back
(
pos
+
Vec3
(
0.09572
,
0
,
0
));
positions
.
push_back
(
pos
+
Vec3
(
-
0.023999
,
0.092663
,
0
));
positions
.
push_back
(
pos
);
}
}
}
}
void
testWaterBox
(
Platform
&
platform
)
{
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// and Drude particles.
System
system
;
const
int
gridSize
=
3
;
vector
<
Vec3
>
positions
;
double
polarizability
=
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
);
build_waterbox
(
system
,
gridSize
,
polarizability
,
positions
);
const
int
numMolecules
=
gridSize
*
gridSize
*
gridSize
;
int
numStandardDof
=
3
*
3
*
numMolecules
-
system
.
getNumConstraints
();
int
numDrudeDof
=
3
*
numMolecules
;
int
numDof
=
numStandardDof
+
numDrudeDof
;
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
// Simulate it and check the temperature.
int
chainLength
=
4
;
int
numMTS
=
4
;
int
numYS
=
5
;
double
frequency
=
800.0
;
double
frequencyDrude
=
2000.0
;
int
randomSeed
=
100
;
DrudeNoseHooverIntegrator
integ
(
temperature
,
frequency
,
temperatureDrude
,
frequencyDrude
,
0.0005
,
chainLength
,
numMTS
,
numYS
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
temperature
,
randomSeed
);
std
::
vector
<
Vec3
>
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
for
(
int
i
=
0
;
i
<
numMolecules
;
i
++
){
Vec3
noize
;
for
(
int
j
=
0
;
j
<
3
;
j
++
){
noize
[
j
]
=
float
(((
i
+
18311
)
*
(
j
+
18253
)
*
313419097822414
)
%
18313
)
/
float
(
18313
);
noize
[
j
]
*=
sqrt
(
3
*
BOLTZ
*
temperatureDrude
/
0.4
);
}
velocities
[
5
*
i
+
1
]
=
velocities
[
5
*
i
]
+
noize
;
}
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
=
4000
;
double
meanTemp
=
0.0
;
double
meanDrudeTemp
=
0.0
;
double
meanConserved
=
0.0
;
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
1
);
State
state
=
context
.
getState
(
State
::
Energy
);
double
KE
=
state
.
getKineticEnergy
();
double
PE
=
state
.
getPotentialEnergy
();
double
fullKE
=
integ
.
computeTotalKineticEnergy
();
double
drudeKE
=
integ
.
computeDrudeKineticEnergy
();
double
temp
=
KE
/
(
0.5
*
numStandardDof
*
BOLTZ
);
double
drudeTemp
=
drudeKE
/
(
0.5
*
numDrudeDof
*
BOLTZ
);
meanTemp
=
(
i
*
meanTemp
+
temp
)
/
(
i
+
1
);
meanDrudeTemp
=
(
i
*
meanDrudeTemp
+
drudeTemp
)
/
(
i
+
1
);
double
heatBathEnergy
=
integ
.
computeHeatBathEnergy
();
double
conserved
=
PE
+
fullKE
+
heatBathEnergy
;
meanConserved
=
(
i
*
meanConserved
+
conserved
)
/
(
i
+
1
);
totalKE
+=
KE
;
ASSERT
(
fabs
(
meanConserved
-
conserved
)
<
0.6
);
}
totalKE
/=
numSteps
;
ASSERT_USUALLY_EQUAL_TOL
(
temperature
,
meanTemp
,
0.004
);
ASSERT_USUALLY_EQUAL_TOL
(
temperatureDrude
,
meanDrudeTemp
,
0.004
);
}
double
testWaterBoxWithHardWallConstraint
(
Platform
&
platform
,
double
hardWallConstraint
){
// Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites,
// and Drude particles.
System
system
;
const
int
gridSize
=
3
;
vector
<
Vec3
>
positions
;
double
polarizability
=
1e-2
;
build_waterbox
(
system
,
gridSize
,
polarizability
,
positions
);
const
int
numMolecules
=
gridSize
*
gridSize
*
gridSize
;
int
numStandardDof
=
3
*
3
*
numMolecules
-
system
.
getNumConstraints
();
int
numDrudeDof
=
3
*
numMolecules
;
int
numDof
=
numStandardDof
+
numDrudeDof
;
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
// Simulate it and check the temperature.
int
chainLength
=
4
;
int
numMTS
=
3
;
int
numYS
=
3
;
double
frequency
=
25.0
;
double
frequencyDrude
=
25.0
;
int
randomSeed
=
100
;
DrudeNoseHooverIntegrator
integ
(
temperature
,
frequency
,
temperatureDrude
,
frequencyDrude
,
0.0005
,
chainLength
,
numMTS
,
numYS
);
integ
.
setMaxDrudeDistance
(
hardWallConstraint
);
Context
context
(
system
,
integ
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
temperature
,
randomSeed
);
std
::
vector
<
Vec3
>
velocities
=
context
.
getState
(
State
::
Velocities
).
getVelocities
();
for
(
int
i
=
0
;
i
<
numMolecules
;
i
++
){
Vec3
noize
;
for
(
int
j
=
0
;
j
<
3
;
j
++
){
noize
[
j
]
=
float
(((
i
+
18311
)
*
(
j
+
18253
)
*
313419097822414
)
%
18313
)
/
float
(
18313
);
noize
[
j
]
*=
sqrt
(
3
*
BOLTZ
*
temperatureDrude
/
0.4
);
}
velocities
[
5
*
i
+
1
]
=
velocities
[
5
*
i
]
+
noize
;
}
context
.
setVelocities
(
velocities
);
context
.
applyConstraints
(
1e-6
);
// Equilibrate.
integ
.
step
(
10
);
// Compute the internal and center of mass temperatures.
double
totalKE
=
0
;
const
int
numSteps
=
10
;
double
meanTemp
=
0.0
;
double
meanDrudeTemp
=
0.0
;
double
meanConserved
=
0.0
;
double
maxR
=
0.0
;
for
(
int
i
=
0
;
i
<
numSteps
;
i
++
)
{
integ
.
step
(
1
);
State
state
=
context
.
getState
(
State
::
Energy
|
State
::
Positions
);
double
KE
=
state
.
getKineticEnergy
();
double
PE
=
state
.
getPotentialEnergy
();
double
fullKE
=
integ
.
computeTotalKineticEnergy
();
double
drudeKE
=
integ
.
computeDrudeKineticEnergy
();
double
temp
=
KE
/
(
0.5
*
numStandardDof
*
BOLTZ
);
double
drudeTemp
=
drudeKE
/
(
0.5
*
numDrudeDof
*
BOLTZ
);
meanTemp
=
(
i
*
meanTemp
+
temp
)
/
(
i
+
1
);
meanDrudeTemp
=
(
i
*
meanDrudeTemp
+
drudeTemp
)
/
(
i
+
1
);
double
heatBathEnergy
=
integ
.
computeHeatBathEnergy
();
double
conserved
=
PE
+
fullKE
+
heatBathEnergy
;
meanConserved
=
(
i
*
meanConserved
+
conserved
)
/
(
i
+
1
);
const
auto
&
positions
=
state
.
getPositions
();
for
(
int
mol
=
0
;
mol
<
gridSize
*
gridSize
*
gridSize
;
++
mol
)
{
auto
dR
=
positions
[
5
*
mol
+
1
]
-
positions
[
5
*
mol
];
maxR
=
std
::
max
(
maxR
,
std
::
sqrt
(
dR
.
dot
(
dR
)));
}
totalKE
+=
KE
;
}
totalKE
/=
numSteps
;
return
maxR
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
registerKernelFactories
();
Platform
&
platform
=
initializePlatform
(
argc
,
argv
);
testWaterBox
(
platform
);
double
maxDrudeDistance
=
0.005
;
double
observedDrudeDistance
=
testWaterBoxWithHardWallConstraint
(
platform
,
0.0
);
ASSERT
(
observedDrudeDistance
>
maxDrudeDistance
);
observedDrudeDistance
=
testWaterBoxWithHardWallConstraint
(
platform
,
maxDrudeDistance
);
ASSERT
(
observedDrudeDistance
<
maxDrudeDistance
);
}
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
return
1
;
}
cout
<<
"Done"
<<
endl
;
return
0
;
}
serialization/include/openmm/serialization/NoseHooverIntegratorProxy.h
0 → 100644
View file @
f6431a42
#ifndef OPENMM_NOSE_HOOVER_INTEGRATOR_PROXY_H_
#define OPENMM_NOSE_HOOVER_INTEGRATOR_PROXY_H_
#include "openmm/serialization/XmlSerializer.h"
namespace
OpenMM
{
class
NoseHooverIntegratorProxy
:
public
SerializationProxy
{
public:
NoseHooverIntegratorProxy
();
void
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
;
void
*
deserialize
(
const
SerializationNode
&
node
)
const
;
};
}
#endif
/*OPENMM_NOSE_HOOVER_INTEGRATOR_PROXY_H_*/
serialization/src/NoseHooverIntegratorProxy.cpp
0 → 100644
View file @
f6431a42
/* -------------------------------------------------------------------------- *
* 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/NoseHooverIntegratorProxy.h"
#include <vector>
#include <OpenMM.h>
using
namespace
std
;
using
namespace
OpenMM
;
NoseHooverIntegratorProxy
::
NoseHooverIntegratorProxy
()
:
SerializationProxy
(
"NoseHooverIntegrator"
)
{
}
void
NoseHooverIntegratorProxy
::
serialize
(
const
void
*
object
,
SerializationNode
&
node
)
const
{
node
.
setIntProperty
(
"version"
,
1
);
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
for
(
int
i
=
0
;
i
<
integrator
.
getNumThermostats
();
i
++
){
const
auto
&
chain
=
integrator
.
getThermostat
(
i
);
auto
&
chainNode
=
node
.
createChildNode
(
"Thermostat"
);
chainNode
.
setDoubleProperty
(
"temperature"
,
chain
.
getTemperature
());
chainNode
.
setDoubleProperty
(
"collisionFrequency"
,
chain
.
getCollisionFrequency
());
chainNode
.
setDoubleProperty
(
"relativeTemperature"
,
chain
.
getRelativeTemperature
());
chainNode
.
setDoubleProperty
(
"relativeCollisionFrequency"
,
chain
.
getRelativeCollisionFrequency
());
chainNode
.
setIntProperty
(
"chainLength"
,
chain
.
getChainLength
());
chainNode
.
setIntProperty
(
"numMTS"
,
chain
.
getNumMultiTimeSteps
());
chainNode
.
setIntProperty
(
"numYS"
,
chain
.
getNumYoshidaSuzukiTimeSteps
());
auto
&
particlesNode
=
chainNode
.
createChildNode
(
"ThermostatedAtoms"
);
for
(
int
particle
:
chain
.
getThermostatedAtoms
()){
particlesNode
.
createChildNode
(
"Particle"
).
setIntProperty
(
"index"
,
particle
);
}
auto
&
pairsNode
=
chainNode
.
createChildNode
(
"ThermostatedPairs"
);
for
(
auto
&
pair
:
chain
.
getThermostatedPairs
()){
auto
&
pairNode
=
pairsNode
.
createChildNode
(
"Pair"
);
pairNode
.
setIntProperty
(
"index1"
,
pair
.
first
);
pairNode
.
setIntProperty
(
"index2"
,
pair
.
second
);
}
}
}
else
{
// Serialize standard thermostat
node
.
setDoubleProperty
(
"temperature"
,
integrator
.
getTemperature
());
node
.
setDoubleProperty
(
"collisionFrequency"
,
integrator
.
getCollisionFrequency
());
node
.
setIntProperty
(
"chainLength"
,
integrator
.
getThermostat
().
getChainLength
());
node
.
setIntProperty
(
"numMTS"
,
integrator
.
getThermostat
().
getNumMultiTimeSteps
());
node
.
setIntProperty
(
"numYS"
,
integrator
.
getThermostat
().
getNumYoshidaSuzukiTimeSteps
());
}
}
void
*
NoseHooverIntegratorProxy
::
deserialize
(
const
SerializationNode
&
node
)
const
{
if
(
node
.
getIntProperty
(
"version"
)
!=
1
)
throw
OpenMMException
(
"Unsupported version number"
);
NoseHooverIntegrator
*
integrator
;
if
(
node
.
getBoolProperty
(
"hasSubsystemThermostats"
)){
// deserialize all chains
integrator
=
new
NoseHooverIntegrator
(
node
.
getDoubleProperty
(
"stepSize"
));
for
(
auto
&
chainNode
:
node
.
getChildren
())
{
// particles
const
auto
&
particlesNode
=
chainNode
.
getChildNode
(
"ThermostatedAtoms"
);
vector
<
int
>
particles
;
for
(
auto
&
particleNode
:
particlesNode
.
getChildren
()){
particles
.
push_back
(
particleNode
.
getIntProperty
(
"index"
));
}
// pairs
const
auto
&
pairsNode
=
chainNode
.
getChildNode
(
"ThermostatedPairs"
);
vector
<
pair
<
int
,
int
>>
pairs
;
for
(
auto
&
pairNode
:
pairsNode
.
getChildren
()){
pairs
.
emplace_back
(
pairNode
.
getIntProperty
(
"index1"
),
pairNode
.
getIntProperty
(
"index2"
));
}
integrator
->
addSubsystemThermostat
(
particles
,
pairs
,
chainNode
.
getDoubleProperty
(
"temperature"
),
chainNode
.
getDoubleProperty
(
"collisionFrequency"
),
chainNode
.
getDoubleProperty
(
"relativeTemperature"
),
chainNode
.
getDoubleProperty
(
"relativeCollisionFrequency"
),
chainNode
.
getIntProperty
(
"chainLength"
),
chainNode
.
getIntProperty
(
"numMTS"
),
chainNode
.
getIntProperty
(
"numYS"
)
);
}
}
else
{
integrator
=
new
NoseHooverIntegrator
(
node
.
getDoubleProperty
(
"temperature"
),
node
.
getDoubleProperty
(
"collisionFrequency"
),
node
.
getDoubleProperty
(
"stepSize"
),
node
.
getIntProperty
(
"chainLength"
),
node
.
getIntProperty
(
"numMTS"
),
node
.
getIntProperty
(
"numYS"
)
);
}
integrator
->
setConstraintTolerance
(
node
.
getDoubleProperty
(
"constraintTolerance"
));
integrator
->
setMaximumPairDistance
(
node
.
getDoubleProperty
(
"maximumPairDistance"
));
return
integrator
;
}
serialization/src/SerializationProxyRegistration.cpp
View file @
f6431a42
...
...
@@ -56,6 +56,7 @@
#include "openmm/MonteCarloBarostat.h"
#include "openmm/MonteCarloMembraneBarostat.h"
#include "openmm/NonbondedForce.h"
#include "openmm/NoseHooverIntegrator.h"
#include "openmm/PeriodicTorsionForce.h"
#include "openmm/RBTorsionForce.h"
#include "openmm/RMSDForce.h"
...
...
@@ -93,6 +94,7 @@
#include "openmm/serialization/MonteCarloBarostatProxy.h"
#include "openmm/serialization/MonteCarloMembraneBarostatProxy.h"
#include "openmm/serialization/NonbondedForceProxy.h"
#include "openmm/serialization/NoseHooverIntegratorProxy.h"
#include "openmm/serialization/PeriodicTorsionForceProxy.h"
#include "openmm/serialization/RBTorsionForceProxy.h"
#include "openmm/serialization/RMSDForceProxy.h"
...
...
@@ -151,6 +153,7 @@ extern "C" void registerSerializationProxies() {
SerializationProxy
::
registerProxy
(
typeid
(
MonteCarloBarostat
),
new
MonteCarloBarostatProxy
());
SerializationProxy
::
registerProxy
(
typeid
(
MonteCarloMembraneBarostat
),
new
MonteCarloMembraneBarostatProxy
());
SerializationProxy
::
registerProxy
(
typeid
(
NonbondedForce
),
new
NonbondedForceProxy
());
SerializationProxy
::
registerProxy
(
typeid
(
NoseHooverIntegrator
),
new
NoseHooverIntegratorProxy
());
SerializationProxy
::
registerProxy
(
typeid
(
PeriodicTorsionForce
),
new
PeriodicTorsionForceProxy
());
SerializationProxy
::
registerProxy
(
typeid
(
RBTorsionForce
),
new
RBTorsionForceProxy
());
SerializationProxy
::
registerProxy
(
typeid
(
RMSDForce
),
new
RMSDForceProxy
());
...
...
@@ -159,4 +162,4 @@ extern "C" void registerSerializationProxies() {
SerializationProxy
::
registerProxy
(
typeid
(
VariableLangevinIntegrator
),
new
VariableLangevinIntegratorProxy
());
SerializationProxy
::
registerProxy
(
typeid
(
VariableVerletIntegrator
),
new
VariableVerletIntegratorProxy
());
SerializationProxy
::
registerProxy
(
typeid
(
VerletIntegrator
),
new
VerletIntegratorProxy
());
}
\ No newline at end of file
}
serialization/tests/TestSerializeNoseHooverIntegrator.cpp
0 → 100644
View file @
f6431a42
/* -------------------------------------------------------------------------- *
* 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/NoseHooverIntegrator.h"
#include "openmm/serialization/XmlSerializer.h"
#include "openmm/System.h"
#include "openmm/Context.h"
#include <iostream>
#include <sstream>
using
namespace
OpenMM
;
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
.
getNumThermostats
(),
integrator2
.
getNumThermostats
());
for
(
int
i
=
0
;
i
<
integrator1
.
getNumThermostats
();
i
++
)
{
const
auto
&
thermostat1
=
integrator1
.
getThermostat
(
i
);
const
auto
&
thermostat2
=
integrator2
.
getThermostat
(
i
);
ASSERT_EQUAL
(
thermostat1
.
getTemperature
(),
thermostat2
.
getTemperature
());
ASSERT_EQUAL
(
thermostat1
.
getCollisionFrequency
(),
thermostat2
.
getCollisionFrequency
());
ASSERT_EQUAL
(
thermostat1
.
getRelativeTemperature
(),
thermostat2
.
getRelativeTemperature
());
ASSERT_EQUAL
(
thermostat1
.
getRelativeCollisionFrequency
(),
thermostat2
.
getRelativeCollisionFrequency
());
ASSERT_EQUAL
(
thermostat1
.
getChainLength
(),
thermostat2
.
getChainLength
());
ASSERT_EQUAL
(
thermostat1
.
getNumMultiTimeSteps
(),
thermostat2
.
getNumMultiTimeSteps
());
ASSERT_EQUAL
(
thermostat1
.
getNumYoshidaSuzukiTimeSteps
(),
thermostat2
.
getNumYoshidaSuzukiTimeSteps
());
ASSERT_EQUAL
(
thermostat1
.
getChainID
(),
thermostat2
.
getChainID
());
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 custom subsystem thermostats
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
);
// Serialize and then deserialize it.
stringstream
buffer
;
XmlSerializer
::
serialize
<
NoseHooverIntegrator
>
(
&
integrator_sub
,
"Integrator"
,
buffer
);
NoseHooverIntegrator
*
copy
=
XmlSerializer
::
deserialize
<
NoseHooverIntegrator
>
(
buffer
);
assertIntegratorsEqual
(
integrator_sub
,
*
copy
);
// Check with default constructor
System
system
;
for
(
int
i
=
0
;
i
<
10
;
i
++
)
system
.
addParticle
(
1.0
);
NoseHooverIntegrator
integrator
(
331
,
1.1
,
0.004
,
5
,
5
,
5
);
Context
context
(
system
,
integrator
);
// Serialize and then deserialize it.
stringstream
buffer2
;
XmlSerializer
::
serialize
<
NoseHooverIntegrator
>
(
&
integrator
,
"Integrator"
,
buffer2
);
copy
=
XmlSerializer
::
deserialize
<
NoseHooverIntegrator
>
(
buffer2
);
// for thermostats that apply to the whole system, the particles are not serialized ...
ASSERT_EQUAL
(
copy
->
getThermostat
(
0
).
getThermostatedAtoms
().
size
(),
0
);
// ... but assigned when creating a context.
Context
context2
(
system
,
*
copy
);
assertIntegratorsEqual
(
integrator
,
*
copy
);
}
int
main
()
{
try
{
testSerialization
();
}
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
return
1
;
}
cout
<<
"Done"
<<
endl
;
return
0
;
}
tests/TestNoseHooverIntegrator.h
0 → 100644
View file @
f6431a42
/* -------------------------------------------------------------------------- *
* 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) 2019 Stanford University and the Authors. *
* Authors: Andreas Krämer and Andrew C. Simmonett *
* 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/Context.h"
#include "openmm/CustomExternalForce.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/NonbondedForce.h"
#include "openmm/System.h"
#include "openmm/NoseHooverIntegrator.h"
#include "openmm/VirtualSite.h"
#include "SimTKOpenMMRealType.h"
#include "sfmt/SFMT.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
const
double
TOL
=
1e-5
;
void
testVVSingleBond
()
{
System
system
;
system
.
addParticle
(
2.0
);
system
.
addParticle
(
2.0
);
NoseHooverIntegrator
integrator
(
0.01
);
HarmonicBondForce
*
forceField
=
new
HarmonicBondForce
();
forceField
->
addBond
(
0
,
1
,
1.5
,
1
);
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
1
]
=
Vec3
(
1
,
0
,
0
);
context
.
setPositions
(
positions
);
// This is simply a harmonic oscillator, so compare it to the analytical solution.
const
double
freq
=
1.0
;
State
state
=
context
.
getState
(
State
::
Energy
);
const
double
initialEnergy
=
state
.
getKineticEnergy
()
+
state
.
getPotentialEnergy
();
for
(
int
i
=
0
;
i
<
1000
;
++
i
)
{
state
=
context
.
getState
(
State
::
Positions
|
State
::
Velocities
|
State
::
Energy
);
double
time
=
state
.
getTime
();
double
expectedDist
=
1.5
+
0.5
*
std
::
cos
(
freq
*
time
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
0.5
*
expectedDist
,
0
,
0
),
state
.
getPositions
()[
0
],
0.02
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.5
*
expectedDist
,
0
,
0
),
state
.
getPositions
()[
1
],
0.02
);
double
expectedSpeed
=
-
0.5
*
freq
*
std
::
sin
(
freq
*
time
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
0.5
*
expectedSpeed
,
0
,
0
),
state
.
getVelocities
()[
0
],
0.02
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.5
*
expectedSpeed
,
0
,
0
),
state
.
getVelocities
()[
1
],
0.02
);
double
energy
=
state
.
getKineticEnergy
()
+
state
.
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
initialEnergy
,
energy
,
0.01
);
integrator
.
step
(
1
);
}
ASSERT_EQUAL_TOL
(
10.0
,
context
.
getState
(
0
).
getTime
(),
1e-5
);
}
void
testVVConstraints
()
{
const
int
numParticles
=
8
;
const
int
numConstraints
=
5
;
System
system
;
NoseHooverIntegrator
integrator
(
0.001
);
integrator
.
setConstraintTolerance
(
1e-5
);
NonbondedForce
*
forceField
=
new
NonbondedForce
();
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
i
%
2
==
0
?
5.0
:
10.0
);
forceField
->
addParticle
((
i
%
2
==
0
?
0.2
:
-
0.2
),
0.5
,
5.0
);
}
system
.
addConstraint
(
0
,
1
,
1.0
);
system
.
addConstraint
(
1
,
2
,
1.0
);
system
.
addConstraint
(
2
,
3
,
1.0
);
system
.
addConstraint
(
4
,
5
,
1.0
);
system
.
addConstraint
(
6
,
7
,
1.0
);
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
numParticles
);
vector
<
Vec3
>
velocities
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
positions
[
i
]
=
Vec3
(
i
/
2
,
(
i
+
1
)
/
2
,
0
);
velocities
[
i
]
=
Vec3
(
genrand_real2
(
sfmt
)
-
0.5
,
genrand_real2
(
sfmt
)
-
0.5
,
genrand_real2
(
sfmt
)
-
0.5
);
}
context
.
setPositions
(
positions
);
context
.
setVelocities
(
velocities
);
// Simulate it and see whether the constraints remain satisfied.
double
initialEnergy
=
0.0
;
for
(
int
i
=
0
;
i
<
1000
;
++
i
)
{
State
state
=
context
.
getState
(
State
::
Positions
|
State
::
Energy
|
State
::
Velocities
|
State
::
Forces
);
for
(
int
j
=
0
;
j
<
numConstraints
;
++
j
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
j
,
particle1
,
particle2
,
distance
);
Vec3
p1
=
state
.
getPositions
()[
particle1
];
Vec3
p2
=
state
.
getPositions
()[
particle2
];
double
dist
=
std
::
sqrt
((
p1
[
0
]
-
p2
[
0
])
*
(
p1
[
0
]
-
p2
[
0
])
+
(
p1
[
1
]
-
p2
[
1
])
*
(
p1
[
1
]
-
p2
[
1
])
+
(
p1
[
2
]
-
p2
[
2
])
*
(
p1
[
2
]
-
p2
[
2
]));
ASSERT_EQUAL_TOL
(
distance
,
dist
,
1e-4
);
}
double
energy
=
state
.
getPotentialEnergy
()
+
state
.
getKineticEnergy
();
if
(
i
==
1
)
initialEnergy
=
energy
;
else
if
(
i
>
1
)
ASSERT_EQUAL_TOL
(
initialEnergy
,
energy
,
0.01
);
integrator
.
step
(
1
);
}
}
void
testVVConstrainedClusters
()
{
const
int
numParticles
=
7
;
System
system
;
NoseHooverIntegrator
integrator
(
0.001
);
integrator
.
setConstraintTolerance
(
1e-5
);
NonbondedForce
*
forceField
=
new
NonbondedForce
();
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
i
>
1
?
1.0
:
10.0
);
forceField
->
addParticle
((
i
%
2
==
0
?
0.2
:
-
0.2
),
0.5
,
5.0
);
}
system
.
addConstraint
(
0
,
1
,
1.0
);
system
.
addConstraint
(
0
,
2
,
1.0
);
system
.
addConstraint
(
0
,
3
,
1.0
);
system
.
addConstraint
(
0
,
4
,
1.0
);
system
.
addConstraint
(
1
,
5
,
1.0
);
system
.
addConstraint
(
1
,
6
,
1.0
);
system
.
addConstraint
(
2
,
3
,
sqrt
(
2.0
));
system
.
addConstraint
(
2
,
4
,
sqrt
(
2.0
));
system
.
addConstraint
(
3
,
4
,
sqrt
(
2.0
));
system
.
addConstraint
(
5
,
6
,
sqrt
(
2.0
));
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
numParticles
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
1
,
0
,
0
);
positions
[
2
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
3
]
=
Vec3
(
0
,
1
,
0
);
positions
[
4
]
=
Vec3
(
0
,
0
,
1
);
positions
[
5
]
=
Vec3
(
2
,
0
,
0
);
positions
[
6
]
=
Vec3
(
1
,
1
,
0
);
vector
<
Vec3
>
velocities
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
velocities
[
i
]
=
Vec3
(
genrand_real2
(
sfmt
)
-
0.5
,
genrand_real2
(
sfmt
)
-
0.5
,
genrand_real2
(
sfmt
)
-
0.5
);
context
.
setPositions
(
positions
);
context
.
setVelocities
(
velocities
);
// Simulate it and see whether the constraints remain satisfied.
double
initialEnergy
=
0.0
;
for
(
int
i
=
0
;
i
<
1000
;
++
i
)
{
State
state
=
context
.
getState
(
State
::
Positions
|
State
::
Energy
|
State
::
Velocities
|
State
::
Forces
);
for
(
int
j
=
0
;
j
<
system
.
getNumConstraints
();
++
j
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
j
,
particle1
,
particle2
,
distance
);
Vec3
p1
=
state
.
getPositions
()[
particle1
];
Vec3
p2
=
state
.
getPositions
()[
particle2
];
double
dist
=
std
::
sqrt
((
p1
[
0
]
-
p2
[
0
])
*
(
p1
[
0
]
-
p2
[
0
])
+
(
p1
[
1
]
-
p2
[
1
])
*
(
p1
[
1
]
-
p2
[
1
])
+
(
p1
[
2
]
-
p2
[
2
])
*
(
p1
[
2
]
-
p2
[
2
]));
ASSERT_EQUAL_TOL
(
distance
,
dist
,
2e-5
);
}
double
energy
=
state
.
getPotentialEnergy
()
+
state
.
getKineticEnergy
();
if
(
i
==
1
)
initialEnergy
=
energy
;
else
if
(
i
>
1
)
ASSERT_EQUAL_TOL
(
initialEnergy
,
energy
,
0.01
);
integrator
.
step
(
1
);
}
}
void
testVVConstrainedMasslessParticles
()
{
System
system
;
system
.
addParticle
(
0.0
);
system
.
addParticle
(
1.0
);
system
.
addConstraint
(
0
,
1
,
1.5
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
1
]
=
Vec3
(
1
,
0
,
0
);
NoseHooverIntegrator
integrator
(
0.01
);
bool
failed
=
false
;
try
{
// This should throw an exception.
Context
context
(
system
,
integrator
,
platform
);
}
catch
(
exception
&
ex
)
{
failed
=
true
;
}
ASSERT
(
failed
);
// Now make both particles massless, which should work.
system
.
setParticleMass
(
1
,
0.0
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
context
.
setVelocitiesToTemperature
(
300.0
);
integrator
.
step
(
1
);
State
state
=
context
.
getState
(
State
::
Velocities
);
ASSERT_EQUAL
(
0.0
,
state
.
getVelocities
()[
0
][
0
]);
}
/**
* Make sure that virtual sites are updated correctly
*/
void
testThreeParticleVirtualSite
()
{
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
0.0
);
system
.
setVirtualSite
(
3
,
new
ThreeParticleAverageSite
(
0
,
1
,
2
,
0.2
,
0.3
,
0.5
));
CustomExternalForce
*
forceField
=
new
CustomExternalForce
(
"-a*x"
);
system
.
addForce
(
forceField
);
forceField
->
addPerParticleParameter
(
"a"
);
vector
<
double
>
params
(
1
);
params
[
0
]
=
0.1
;
forceField
->
addParticle
(
0
,
params
);
params
[
0
]
=
0.2
;
forceField
->
addParticle
(
1
,
params
);
params
[
0
]
=
0.3
;
forceField
->
addParticle
(
2
,
params
);
params
[
0
]
=
0.4
;
forceField
->
addParticle
(
3
,
params
);
NoseHooverIntegrator
integrator
(
0.002
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
4
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
1
,
0
,
0
);
positions
[
2
]
=
Vec3
(
0
,
1
,
0
);
context
.
setPositions
(
positions
);
context
.
applyConstraints
(
0.0001
);
for
(
int
i
=
0
;
i
<
1000
;
i
++
)
{
State
state
=
context
.
getState
(
State
::
Positions
|
State
::
Forces
);
const
vector
<
Vec3
>&
pos
=
state
.
getPositions
();
ASSERT_EQUAL_VEC
(
pos
[
0
]
*
0.2
+
pos
[
1
]
*
0.3
+
pos
[
2
]
*
0.5
,
pos
[
3
],
1e-5
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.1
+
0.4
*
0.2
,
0
,
0
),
state
.
getForces
()[
0
],
1e-5
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.2
+
0.4
*
0.3
,
0
,
0
),
state
.
getForces
()[
1
],
1e-5
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.3
+
0.4
*
0.5
,
0
,
0
),
state
.
getForces
()[
2
],
1e-5
);
integrator
.
step
(
1
);
}
}
void
runPlatformTests
();
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
initializeTests
(
argc
,
argv
);
testVVSingleBond
();
testVVConstraints
();
testVVConstrainedClusters
();
testVVConstrainedMasslessParticles
();
testThreeParticleVirtualSite
();
runPlatformTests
();
}
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
return
1
;
}
cout
<<
"Done"
<<
endl
;
return
0
;
}
Prev
1
2
3
4
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