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
49d60231
Commit
49d60231
authored
Jul 12, 2013
by
Lee-Ping Wang
Browse files
Merge branch 'master' of
https://github.com/leeping/openmm
parents
5587fac9
3a2f4643
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
509 additions
and
391 deletions
+509
-391
openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h
openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h
+17
-28
openmmapi/include/openmm/MonteCarloBarostat.h
openmmapi/include/openmm/MonteCarloBarostat.h
+1
-9
openmmapi/include/openmm/internal/AssertionUtilities.h
openmmapi/include/openmm/internal/AssertionUtilities.h
+3
-1
openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp
openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp
+18
-17
platforms/cuda/tests/TestCudaMonteCarloAnisotropicBarostat.cpp
...orms/cuda/tests/TestCudaMonteCarloAnisotropicBarostat.cpp
+152
-159
platforms/opencl/tests/TestOpenCLMonteCarloAnisotropicBarostat.cpp
.../opencl/tests/TestOpenCLMonteCarloAnisotropicBarostat.cpp
+153
-160
platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp
...ence/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp
+165
-17
No files found.
openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h
View file @
49d60231
...
@@ -9,8 +9,8 @@
...
@@ -9,8 +9,8 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2010 Stanford University and the Authors.
*
* Portions copyright (c) 2010
-2013
Stanford University and the Authors. *
* Authors: Peter Eastman
*
* Authors: Peter Eastman
, Lee-Ping Wang
*
* Contributors: *
* Contributors: *
* *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* Permission is hereby granted, free of charge, to any person obtaining a *
...
@@ -43,9 +43,12 @@ namespace OpenMM {
...
@@ -43,9 +43,12 @@ namespace OpenMM {
* This class uses a Monte Carlo algorithm to adjust the size of the periodic box, simulating the
* This class uses a Monte Carlo algorithm to adjust the size of the periodic box, simulating the
* effect of constant pressure.
* effect of constant pressure.
*
*
* Compared to MonteCarloBarostat, this class scales the three axes of the simulation cell independently.
* This class is similar to MonteCarloBarostat, but each Monte Carlo move is applied to only one axis
* The user supplies three doubles to specify the pressure along each axis.
* of the periodic box (unlike MonteCarloBarostat, which scales the entire box isotropically). This
*
* means that the box may change shape as well as size over the course of the simulation. It also
* allows you to specify a different pressure for each axis of the box, or to keep the box size fixed
* along certain axes while still allowing it to change along others.
*
* This class assumes the simulation is also being run at constant temperature, and requires you
* This class assumes the simulation is also being run at constant temperature, and requires you
* to specify the system temperature (since it affects the acceptance probability for Monte Carlo
* to specify the system temperature (since it affects the acceptance probability for Monte Carlo
* moves). It does not actually perform temperature regulation, however. You must use another
* moves). It does not actually perform temperature regulation, however. You must use another
...
@@ -84,39 +87,33 @@ public:
...
@@ -84,39 +87,33 @@ public:
* @param defaultPressure The default pressure acting on each axis (in bar)
* @param defaultPressure The default pressure acting on each axis (in bar)
* @param temperature the temperature at which the system is being maintained (in Kelvin)
* @param temperature the temperature at which the system is being maintained (in Kelvin)
* @param frequency the frequency at which Monte Carlo pressure changes should be attempted (in time steps)
* @param frequency the frequency at which Monte Carlo pressure changes should be attempted (in time steps)
* @param scaleX
on/off switch for
whether to
scale
the X
axis
* @param scaleX whether to
allow
the X
dimension of the periodic box to change size
* @param scaleY
on/off switch for
whether to
scale
the Y
axis
* @param scaleY whether to
allow
the Y
dimension of the periodic box to change size
* @param scaleZ
on/off switch for
whether to
scale
the Z
axis
* @param scaleZ whether to
allow
the Z
dimension of the periodic box to change size
*/
*/
MonteCarloAnisotropicBarostat
(
const
Vec3
&
defaultPressure
,
double
temperature
,
int
frequency
=
25
,
bool
scaleX
=
1
,
bool
scaleY
=
1
,
bool
scaleZ
=
1
);
MonteCarloAnisotropicBarostat
(
const
Vec3
&
defaultPressure
,
double
temperature
,
int
frequency
=
25
,
bool
scaleX
=
1
,
bool
scaleY
=
1
,
bool
scaleZ
=
1
);
/**
/**
* Get the default pressure (in bar).
* Get the default pressure (in bar).
*
*
* @return the default pressure acting
on the system
, measured in bar.
* @return the default pressure acting
along each axis
, measured in bar.
*/
*/
Vec3
getDefaultPressure
()
const
{
const
Vec3
&
getDefaultPressure
()
const
{
return
defaultPressure
;
return
defaultPressure
;
}
}
/**
/**
* Get the true/false flag for scaling the X-axis.
* Get whether to allow the X dimension of the periodic box to change size.
*
* @return the true/false flag for scaling the X-axis.
*/
*/
bool
getScaleX
()
const
{
bool
getScaleX
()
const
{
return
scaleX
;
return
scaleX
;
}
}
/**
/**
* Get the true/false flag for scaling the Y-axis.
* Get whether to allow the Y dimension of the periodic box to change size.
*
* @return the true/false flag for scaling the Y-axis.
*/
*/
bool
getScaleY
()
const
{
bool
getScaleY
()
const
{
return
scaleY
;
return
scaleY
;
}
}
/**
/**
* Get the true/false flag for scaling the Z-axis.
* Get whether to allow the Z dimension of the periodic box to change size.
*
* @return the true/false flag for scaling the Z-axis.
*/
*/
bool
getScaleZ
()
const
{
bool
getScaleZ
()
const
{
return
scaleZ
;
return
scaleZ
;
...
@@ -172,15 +169,7 @@ private:
...
@@ -172,15 +169,7 @@ private:
double
temperature
;
double
temperature
;
bool
scaleX
,
scaleY
,
scaleZ
;
bool
scaleX
,
scaleY
,
scaleZ
;
int
frequency
,
randomNumberSeed
;
int
frequency
,
randomNumberSeed
;
};
double
GetTemperature
()
const
{
return
temperature
;
}
void
SetTemperature
(
double
temperature
)
{
this
->
temperature
=
temperature
;
}
};
}
// namespace OpenMM
}
// namespace OpenMM
...
...
openmmapi/include/openmm/MonteCarloBarostat.h
View file @
49d60231
...
@@ -123,15 +123,7 @@ protected:
...
@@ -123,15 +123,7 @@ protected:
private:
private:
double
defaultPressure
,
temperature
;
double
defaultPressure
,
temperature
;
int
frequency
,
randomNumberSeed
;
int
frequency
,
randomNumberSeed
;
};
double
GetTemperature
()
const
{
return
temperature
;
}
void
SetTemperature
(
double
temperature
)
{
this
->
temperature
=
temperature
;
}
};
}
// namespace OpenMM
}
// namespace OpenMM
...
...
openmmapi/include/openmm/internal/AssertionUtilities.h
View file @
49d60231
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2008-201
2
Stanford University and the Authors. *
* Portions copyright (c) 2008-201
3
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -54,6 +54,8 @@ void OPENMM_EXPORT throwException(const char* file, int line, const std::string&
...
@@ -54,6 +54,8 @@ void OPENMM_EXPORT throwException(const char* file, int line, const std::string&
#define ASSERT_EQUAL_VEC(expected, found, tol) {double _norm_ = std::sqrt((expected).dot(expected)); double _scale_ = _norm_ > 1.0 ? _norm_ : 1.0; if ((std::abs(((expected)[0])-((found)[0]))/_scale_ > (tol)) || (std::abs(((expected)[1])-((found)[1]))/_scale_ > (tol)) || (std::abs(((expected)[2])-((found)[2]))/_scale_ > (tol))) {std::stringstream details; details << " Expected "<<(expected)<<", found "<<(found); throwException(__FILE__, __LINE__, details.str());}};
#define ASSERT_EQUAL_VEC(expected, found, tol) {double _norm_ = std::sqrt((expected).dot(expected)); double _scale_ = _norm_ > 1.0 ? _norm_ : 1.0; if ((std::abs(((expected)[0])-((found)[0]))/_scale_ > (tol)) || (std::abs(((expected)[1])-((found)[1]))/_scale_ > (tol)) || (std::abs(((expected)[2])-((found)[2]))/_scale_ > (tol))) {std::stringstream details; details << " Expected "<<(expected)<<", found "<<(found); throwException(__FILE__, __LINE__, details.str());}};
#define ASSERT_USUALLY_TRUE(cond) {if (!(cond)) throwException(__FILE__, __LINE__, "(This test is stochastic and may occasionally fail)");};
#define ASSERT_USUALLY_EQUAL_TOL(expected, found, tol) {double _scale_ = std::abs(expected) > 1.0 ? std::abs(expected) : 1.0; if (!(std::abs((expected)-(found))/_scale_ <= (tol))) {std::stringstream details; details << "Expected "<<(expected)<<", found "<<(found)<<" (This test is stochastic and may occasionally fail)"; throwException(__FILE__, __LINE__, details.str());}};
#define ASSERT_USUALLY_EQUAL_TOL(expected, found, tol) {double _scale_ = std::abs(expected) > 1.0 ? std::abs(expected) : 1.0; if (!(std::abs((expected)-(found))/_scale_ <= (tol))) {std::stringstream details; details << "Expected "<<(expected)<<", found "<<(found)<<" (This test is stochastic and may occasionally fail)"; throwException(__FILE__, __LINE__, details.str());}};
#define ASSERT_VALID_INDEX(index, vector) {if (index < 0 || index >= (int) vector.size()) throwException(__FILE__, __LINE__, "Index out of range");};
#define ASSERT_VALID_INDEX(index, vector) {if (index < 0 || index >= (int) vector.size()) throwException(__FILE__, __LINE__, "Index out of range");};
...
...
openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp
View file @
49d60231
...
@@ -6,8 +6,8 @@
...
@@ -6,8 +6,8 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2010 Stanford University and the Authors.
*
* Portions copyright (c) 2010
-2013
Stanford University and the Authors. *
* Authors: Peter Eastman
*
* Authors: Peter Eastman
, Lee-Ping Wang
*
* Contributors: *
* Contributors: *
* *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* Permission is hereby granted, free of charge, to any person obtaining a *
...
@@ -65,7 +65,7 @@ void MonteCarloAnisotropicBarostatImpl::initialize(ContextImpl& context) {
...
@@ -65,7 +65,7 @@ void MonteCarloAnisotropicBarostatImpl::initialize(ContextImpl& context) {
void
MonteCarloAnisotropicBarostatImpl
::
updateContextState
(
ContextImpl
&
context
)
{
void
MonteCarloAnisotropicBarostatImpl
::
updateContextState
(
ContextImpl
&
context
)
{
if
(
++
step
<
owner
.
getFrequency
()
||
owner
.
getFrequency
()
==
0
)
if
(
++
step
<
owner
.
getFrequency
()
||
owner
.
getFrequency
()
==
0
)
return
;
return
;
if
(
owner
.
getScaleX
()
==
0
&&
owner
.
getScaleY
()
==
0
&&
owner
.
getScaleZ
()
==
0
)
if
(
!
owner
.
getScaleX
()
&&
!
owner
.
getScaleY
()
&&
!
owner
.
getScaleZ
())
return
;
return
;
step
=
0
;
step
=
0
;
...
@@ -75,23 +75,26 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context)
...
@@ -75,23 +75,26 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context)
double
pressure
;
double
pressure
;
// Choose which axis to modify at random.
// Choose which axis to modify at random.
double
rnd
=
genrand_real2
(
random
)
*
3.0
;
int
axis
;
int
axis
;
while
(
1
)
{
while
(
true
)
{
if
(
rnd
<
1.0
&&
owner
.
getScaleX
())
{
double
rnd
=
genrand_real2
(
random
)
*
3.0
;
axis
=
0
;
if
(
rnd
<
1.0
)
{
pressure
=
context
.
getParameter
(
MonteCarloAnisotropicBarostat
::
PressureX
())
*
(
AVOGADRO
*
1e-25
);
if
(
owner
.
getScaleX
())
{
break
;
axis
=
0
;
}
else
if
(
rnd
<
2.0
&&
owner
.
getScaleY
())
{
pressure
=
context
.
getParameter
(
MonteCarloAnisotropicBarostat
::
PressureX
())
*
(
AVOGADRO
*
1e-25
);
axis
=
1
;
break
;
pressure
=
context
.
getParameter
(
MonteCarloAnisotropicBarostat
::
PressureY
())
*
(
AVOGADRO
*
1e-25
);
}
break
;
}
else
if
(
rnd
<
2.0
)
{
if
(
owner
.
getScaleY
())
{
axis
=
1
;
pressure
=
context
.
getParameter
(
MonteCarloAnisotropicBarostat
::
PressureY
())
*
(
AVOGADRO
*
1e-25
);
break
;
}
}
else
if
(
owner
.
getScaleZ
())
{
}
else
if
(
owner
.
getScaleZ
())
{
axis
=
2
;
axis
=
2
;
pressure
=
context
.
getParameter
(
MonteCarloAnisotropicBarostat
::
PressureZ
())
*
(
AVOGADRO
*
1e-25
);
pressure
=
context
.
getParameter
(
MonteCarloAnisotropicBarostat
::
PressureZ
())
*
(
AVOGADRO
*
1e-25
);
break
;
break
;
}
}
rnd
=
genrand_real2
(
random
)
*
3.0
;
}
}
// Modify the periodic box size.
// Modify the periodic box size.
...
@@ -101,9 +104,7 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context)
...
@@ -101,9 +104,7 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context)
double
volume
=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
double
volume
=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
double
deltaVolume
=
volumeScale
[
axis
]
*
2
*
(
genrand_real2
(
random
)
-
0.5
);
double
deltaVolume
=
volumeScale
[
axis
]
*
2
*
(
genrand_real2
(
random
)
-
0.5
);
double
newVolume
=
volume
+
deltaVolume
;
double
newVolume
=
volume
+
deltaVolume
;
Vec3
lengthScale
;
Vec3
lengthScale
(
1.0
,
1.0
,
1.0
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
lengthScale
[
i
]
=
1.0
;
lengthScale
[
axis
]
=
newVolume
/
volume
;
lengthScale
[
axis
]
=
newVolume
/
volume
;
kernel
.
getAs
<
ApplyMonteCarloBarostatKernel
>
().
scaleCoordinates
(
context
,
lengthScale
[
0
],
lengthScale
[
1
],
lengthScale
[
2
]);
kernel
.
getAs
<
ApplyMonteCarloBarostatKernel
>
().
scaleCoordinates
(
context
,
lengthScale
[
0
],
lengthScale
[
1
],
lengthScale
[
2
]);
context
.
getOwner
().
setPeriodicBoxVectors
(
box
[
0
]
*
lengthScale
[
0
],
box
[
1
]
*
lengthScale
[
1
],
box
[
2
]
*
lengthScale
[
2
]);
context
.
getOwner
().
setPeriodicBoxVectors
(
box
[
0
]
*
lengthScale
[
0
],
box
[
1
]
*
lengthScale
[
1
],
box
[
2
]
*
lengthScale
[
2
]);
...
...
platforms/cuda/tests/TestCudaMonteCarloAnisotropicBarostat.cpp
View file @
49d60231
...
@@ -6,8 +6,8 @@
...
@@ -6,8 +6,8 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2008-201
2
Stanford University and the Authors. *
* Portions copyright (c) 2008-201
3
Stanford University and the Authors. *
* Authors: Peter Eastman
*
* Authors: Peter Eastman
, Lee-Ping Wang
*
* Contributors: *
* Contributors: *
* *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* Permission is hereby granted, free of charge, to any person obtaining a *
...
@@ -191,24 +191,24 @@ void testIdealGasAxis(int axis) {
...
@@ -191,24 +191,24 @@ void testIdealGasAxis(int axis) {
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
Vec3
box
[
3
];
Vec3
box
[
3
];
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
boxX
=
box
[
0
][
0
];
boxX
=
box
[
0
][
0
];
boxY
=
box
[
1
][
1
];
boxY
=
box
[
1
][
1
];
boxZ
=
box
[
2
][
2
];
boxZ
=
box
[
2
][
2
];
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
integrator
.
step
(
frequency
);
integrator
.
step
(
frequency
);
}
}
volume
/=
steps
;
volume
/=
steps
;
double
expected
=
(
numParticles
+
1
)
*
BOLTZ
*
temp
[
i
]
/
pressureInMD
;
double
expected
=
(
numParticles
+
1
)
*
BOLTZ
*
temp
[
i
]
/
pressureInMD
;
ASSERT_USUALLY_EQUAL_TOL
(
expected
,
volume
,
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
expected
,
volume
,
3
/
std
::
sqrt
((
double
)
steps
));
if
(
!
scaleX
)
{
if
(
!
scaleX
)
{
ASSERT
(
boxX
==
initialLength
);
ASSERT
(
boxX
==
initialLength
);
}
}
if
(
!
scaleY
)
{
if
(
!
scaleY
)
{
ASSERT
(
boxY
==
0.5
*
initialLength
);
ASSERT
(
boxY
==
0.5
*
initialLength
);
}
}
if
(
!
scaleZ
)
{
if
(
!
scaleZ
)
{
ASSERT
(
boxZ
==
2
*
initialLength
);
ASSERT
(
boxZ
==
2
*
initialLength
);
}
}
}
}
}
}
...
@@ -274,155 +274,148 @@ void testRandomSeed() {
...
@@ -274,155 +274,148 @@ void testRandomSeed() {
}
}
}
}
/**
* Run a constant pressure simulation on an anisotropic Einstein crystal
* using isotropic and anisotropic barostats. There are a total of 15 simulations:
*
* 1) 3 pressures: 9.0, 10.0, 11.0 bar, for each of the following groups:
* 2) 3 groups of simulations that scale just one axis: x, y, z
* 3) 1 group of simulations that scales all three axes in the anisotropic barostat
* 4) 1 group of simulations that scales all three axes in the isotropic barostat
*
* Results that we will check:
*
* a) In each group of simulations, the volume should decrease with increasing pressure
* b) In the three simulation groups that scale just one axis, the compressibility (i.e. incremental volume change
* with increasing pressure) should go like kx > ky > kz (because the spring constant is largest in the z-direction)
* c) The anisotropic barostat should produce the same result as the isotropic barostat when all three axes are scaled
*/
void
testEinsteinCrystal
()
{
void
testEinsteinCrystal
()
{
/*
const
int
numParticles
=
64
;
const
int
frequency
=
2
;
Run a constant pressure simulation on an anisotropic Einstein crystal
const
int
equil
=
10000
;
using isotropic and anisotropic barostats. There are a total of 15 simulations:
const
int
steps
=
5000
;
const
double
pressure
=
10.0
;
1) 3 pressures: 9.0, 10.0, 11.0 bar, for each of the following groups:
const
double
pressureInMD
=
pressure
*
(
AVOGADRO
*
1e-25
);
// pressure in kJ/mol/nm^3
2) 3 groups of simulations that scale just one axis: x, y, z
const
double
temp
=
300.0
;
// Only test one temperature since we're looking at three pressures.
3) 1 group of simulations that scales all three axes in the anisotropic barostat
const
double
pres3
[]
=
{
2.0
,
8.0
,
15.0
};
4) 1 group of simulations that scales all three axes in the isotropic barostat
const
double
initialVolume
=
numParticles
*
BOLTZ
*
temp
/
pressureInMD
;
const
double
initialLength
=
std
::
pow
(
initialVolume
,
1.0
/
3.0
);
Results that we will check:
vector
<
double
>
initialPositions
(
3
);
vector
<
double
>
results
;
a) In each group of simulations, the volume should decrease with increasing pressure
// Run four groups of anisotropic simulations; scaling just x, y, z, then all three.
b) In the three simulation groups that scale just one axis, the compressibility (i.e. incremental volume change
for
(
int
a
=
0
;
a
<
4
;
a
++
)
{
with increasing pressure) should go like kx > ky > kz (because the spring constant is largest in the z-direction)
// Test barostat for three different pressures.
c) The anisotropic barostat should produce the same result as the isotropic barostat when all three axes are scaled
for
(
int
p
=
0
;
p
<
3
;
p
++
)
{
// Create a system of noninteracting particles attached by harmonic springs to their initial positions.
*/
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
initialLength
,
0
,
0
),
Vec3
(
0
,
initialLength
,
0
),
Vec3
(
0
,
0
,
initialLength
));
const
int
numParticles
=
64
;
vector
<
Vec3
>
positions
(
numParticles
);
const
int
frequency
=
10
;
OpenMM_SFMT
::
SFMT
sfmt
;
const
int
equil
=
10000
;
init_gen_rand
(
0
,
sfmt
);
const
int
steps
=
10000
;
// Anisotropic force constants.
const
double
pressure
=
10.0
;
CustomExternalForce
*
force
=
new
CustomExternalForce
(
"0.005*(x-x0)^2 + 0.01*(y-y0)^2 + 0.02*(z-z0)^2"
);
const
double
pressureInMD
=
pressure
*
(
AVOGADRO
*
1e-25
);
// pressure in kJ/mol/nm^3
force
->
addPerParticleParameter
(
"x0"
);
const
double
temp
=
300.0
;
// Only test one temperature since we're looking at three pressures.
force
->
addPerParticleParameter
(
"y0"
);
const
double
pres3
[]
=
{
9.0
,
10.0
,
11.0
};
force
->
addPerParticleParameter
(
"z0"
);
const
double
initialVolume
=
numParticles
*
BOLTZ
*
temp
/
pressureInMD
;
NonbondedForce
*
nb
=
new
NonbondedForce
();
const
double
initialLength
=
std
::
pow
(
initialVolume
,
1.0
/
3.0
);
nb
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
vector
<
double
>
initialPositions
(
3
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
// All results.
system
.
addParticle
(
1.0
);
double
results
[]
=
{
0.0
,
0.0
,
0.0
,
0.0
,
0.0
,
positions
[
i
]
=
Vec3
(((
i
/
16
)
%
4
+
0.5
)
*
initialLength
/
4
,
((
i
/
4
)
%
4
+
0.5
)
*
initialLength
/
4
,
(
i
%
4
+
0.5
)
*
initialLength
/
4
);
0.0
,
0.0
,
0.0
,
0.0
,
0.0
,
initialPositions
[
0
]
=
positions
[
i
][
0
];
0.0
,
0.0
,
0.0
,
0.0
,
0.0
};
initialPositions
[
1
]
=
positions
[
i
][
1
];
int
simNum
=
0
;
initialPositions
[
2
]
=
positions
[
i
][
2
];
// Run four groups of anisotropic simulations; scaling just x, y, z, then all three.
force
->
addParticle
(
i
,
initialPositions
);
for
(
int
a
=
0
;
a
<
4
;
a
++
)
{
nb
->
addParticle
(
0
,
initialLength
/
6
,
0.1
);
// Test barostat for three different pressures.
}
for
(
int
p
=
0
;
p
<
3
;
p
++
)
{
system
.
addForce
(
force
);
// Create a system of noninteracting particles attached by harmonic springs to their initial positions.
system
.
addForce
(
nb
);
System
system
;
// Create the barostat.
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
initialLength
,
0
,
0
),
Vec3
(
0
,
initialLength
,
0
),
Vec3
(
0
,
0
,
initialLength
));
MonteCarloAnisotropicBarostat
*
barostat
=
new
MonteCarloAnisotropicBarostat
(
Vec3
(
pres3
[
p
],
pres3
[
p
],
pres3
[
p
]),
temp
,
frequency
,
(
a
==
0
||
a
==
3
),
(
a
==
1
||
a
==
3
),
(
a
==
2
||
a
==
3
));
vector
<
Vec3
>
positions
(
numParticles
);
system
.
addForce
(
barostat
);
OpenMM_SFMT
::
SFMT
sfmt
;
barostat
->
setTemperature
(
temp
);
init_gen_rand
(
0
,
sfmt
);
LangevinIntegrator
integrator
(
temp
,
0.1
,
0.01
);
// Anisotropic force constants.
Context
context
(
system
,
integrator
,
platform
);
CustomExternalForce
*
force
=
new
CustomExternalForce
(
"0.005*(x-x0)^2 + 0.01*(y-y0)^2 + 0.02*(z-z0)^2"
);
context
.
setPositions
(
positions
);
force
->
addPerParticleParameter
(
"x0"
);
// Let it equilibrate.
force
->
addPerParticleParameter
(
"y0"
);
integrator
.
step
(
equil
);
force
->
addPerParticleParameter
(
"z0"
);
// Now run it for a while and see if the volume is correct.
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
double
volume
=
0.0
;
system
.
addParticle
(
1.0
);
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
positions
[
i
]
=
Vec3
(((
i
/
16
)
%
4
+
0.5
)
*
initialLength
/
4
,
((
i
/
4
)
%
4
+
0.5
)
*
initialLength
/
4
,
(
i
%
4
+
0.5
)
*
initialLength
/
4
);
Vec3
box
[
3
];
initialPositions
[
0
]
=
positions
[
i
][
0
];
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
initialPositions
[
1
]
=
positions
[
i
][
1
];
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
initialPositions
[
2
]
=
positions
[
i
][
2
];
integrator
.
step
(
frequency
);
force
->
addParticle
(
i
,
initialPositions
);
}
}
volume
/=
steps
;
system
.
addForce
(
force
);
results
.
push_back
(
volume
);
// Create the barostat.
}
MonteCarloAnisotropicBarostat
*
barostat
=
new
MonteCarloAnisotropicBarostat
(
Vec3
(
pres3
[
p
],
pres3
[
p
],
pres3
[
p
]),
temp
,
frequency
,
(
a
==
0
||
a
==
3
),
(
a
==
1
||
a
==
3
),
(
a
==
2
||
a
==
3
));
system
.
addForce
(
barostat
);
barostat
->
setTemperature
(
temp
);
LangevinIntegrator
integrator
(
temp
,
0.1
,
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
// Let it equilibrate.
integrator
.
step
(
equil
);
// Now run it for a while and see if the volume is correct.
double
volume
=
0.0
;
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
Vec3
box
[
3
];
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
integrator
.
step
(
frequency
);
}
volume
/=
steps
;
results
[
simNum
]
=
volume
;
simNum
+=
1
;
}
}
for
(
int
p
=
0
;
p
<
3
;
p
++
)
{
// Create a system of noninteracting particles attached by harmonic springs to their initial positions.
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
initialLength
,
0
,
0
),
Vec3
(
0
,
initialLength
,
0
),
Vec3
(
0
,
0
,
initialLength
));
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
// Anisotropic force constants.
CustomExternalForce
*
force
=
new
CustomExternalForce
(
"0.005*(x-x0)^2 + 0.01*(y-y0)^2 + 0.02*(z-z0)^2"
);
force
->
addPerParticleParameter
(
"x0"
);
force
->
addPerParticleParameter
(
"y0"
);
force
->
addPerParticleParameter
(
"z0"
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
1.0
);
positions
[
i
]
=
Vec3
(((
i
/
16
)
%
4
+
0.5
)
*
initialLength
/
4
,
((
i
/
4
)
%
4
+
0.5
)
*
initialLength
/
4
,
(
i
%
4
+
0.5
)
*
initialLength
/
4
);
initialPositions
[
0
]
=
positions
[
i
][
0
];
initialPositions
[
1
]
=
positions
[
i
][
1
];
initialPositions
[
2
]
=
positions
[
i
][
2
];
force
->
addParticle
(
i
,
initialPositions
);
}
}
system
.
addForce
(
force
);
for
(
int
p
=
0
;
p
<
3
;
p
++
)
{
// Create the barostat.
// Create a system of noninteracting particles attached by harmonic springs to their initial positions.
MonteCarloBarostat
*
barostat
=
new
MonteCarloBarostat
(
pres3
[
p
],
temp
,
frequency
);
System
system
;
system
.
addForce
(
barostat
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
initialLength
,
0
,
0
),
Vec3
(
0
,
initialLength
,
0
),
Vec3
(
0
,
0
,
initialLength
));
barostat
->
setTemperature
(
temp
);
vector
<
Vec3
>
positions
(
numParticles
);
LangevinIntegrator
integrator
(
temp
,
0.1
,
0.01
);
OpenMM_SFMT
::
SFMT
sfmt
;
Context
context
(
system
,
integrator
,
platform
);
init_gen_rand
(
0
,
sfmt
);
context
.
setPositions
(
positions
);
// Anisotropic force constants.
// Let it equilibrate.
CustomExternalForce
*
force
=
new
CustomExternalForce
(
"0.005*(x-x0)^2 + 0.01*(y-y0)^2 + 0.02*(z-z0)^2"
);
integrator
.
step
(
equil
);
force
->
addPerParticleParameter
(
"x0"
);
// Now run it for a while and see if the volume is correct.
force
->
addPerParticleParameter
(
"y0"
);
double
volume
=
0.0
;
force
->
addPerParticleParameter
(
"z0"
);
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
NonbondedForce
*
nb
=
new
NonbondedForce
();
Vec3
box
[
3
];
nb
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
system
.
addParticle
(
1.0
);
integrator
.
step
(
frequency
);
positions
[
i
]
=
Vec3
(((
i
/
16
)
%
4
+
0.5
)
*
initialLength
/
4
,
((
i
/
4
)
%
4
+
0.5
)
*
initialLength
/
4
,
(
i
%
4
+
0.5
)
*
initialLength
/
4
);
initialPositions
[
0
]
=
positions
[
i
][
0
];
initialPositions
[
1
]
=
positions
[
i
][
1
];
initialPositions
[
2
]
=
positions
[
i
][
2
];
force
->
addParticle
(
i
,
initialPositions
);
nb
->
addParticle
(
0
,
initialLength
/
6
,
0.1
);
}
system
.
addForce
(
force
);
system
.
addForce
(
nb
);
// Create the barostat.
MonteCarloBarostat
*
barostat
=
new
MonteCarloBarostat
(
pres3
[
p
],
temp
,
frequency
);
system
.
addForce
(
barostat
);
barostat
->
setTemperature
(
temp
);
LangevinIntegrator
integrator
(
temp
,
0.1
,
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
// Let it equilibrate.
integrator
.
step
(
equil
);
// Now run it for a while and see if the volume is correct.
double
volume
=
0.0
;
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
Vec3
box
[
3
];
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
integrator
.
step
(
frequency
);
}
volume
/=
steps
;
results
.
push_back
(
volume
);
}
}
volume
/=
steps
;
results
[
simNum
]
=
volume
;
// Check to see if volumes decrease with increasing pressure.
simNum
+=
1
;
ASSERT_USUALLY_TRUE
(
results
[
0
]
>
results
[
1
]);
}
ASSERT_USUALLY_TRUE
(
results
[
1
]
>
results
[
2
]);
ASSERT_USUALLY_TRUE
(
results
[
3
]
>
results
[
4
]);
/*
ASSERT_USUALLY_TRUE
(
results
[
4
]
>
results
[
5
]);
for (int j = 0; j < 15; j++) {
ASSERT_USUALLY_TRUE
(
results
[
6
]
>
results
[
7
]);
printf("%.6f\n",results[j]);
ASSERT_USUALLY_TRUE
(
results
[
7
]
>
results
[
8
]);
}
*/
// Check to see if volumes decrease with increasing pressure.
ASSERT
(
results
[
0
]
>
results
[
1
]);
ASSERT
(
results
[
1
]
>
results
[
2
]);
ASSERT
(
results
[
3
]
>
results
[
4
]);
ASSERT
(
results
[
4
]
>
results
[
5
]);
ASSERT
(
results
[
6
]
>
results
[
7
]);
ASSERT
(
results
[
7
]
>
results
[
8
]);
// Check to see if incremental volume changes with increasing pressure go like kx > ky > kz.
// Check to see if incremental volume changes with increasing pressure go like kx > ky > kz.
ASSERT
((
results
[
0
]
-
results
[
1
])
>
(
results
[
3
]
-
results
[
4
]));
ASSERT
_USUALLY_TRUE
((
results
[
0
]
-
results
[
1
])
>
(
results
[
3
]
-
results
[
4
]));
ASSERT
((
results
[
1
]
-
results
[
2
])
>
(
results
[
4
]
-
results
[
5
]));
ASSERT
_USUALLY_TRUE
((
results
[
1
]
-
results
[
2
])
>
(
results
[
4
]
-
results
[
5
]));
ASSERT
((
results
[
3
]
-
results
[
4
])
>
(
results
[
6
]
-
results
[
7
]));
ASSERT
_USUALLY_TRUE
((
results
[
3
]
-
results
[
4
])
>
(
results
[
6
]
-
results
[
7
]));
ASSERT
((
results
[
4
]
-
results
[
5
])
>
(
results
[
7
]
-
results
[
8
]));
ASSERT
_USUALLY_TRUE
((
results
[
4
]
-
results
[
5
])
>
(
results
[
7
]
-
results
[
8
]));
// Check to see if the volumes are equal for isotropic and anisotropic (all axis).
// Check to see if the volumes are equal for isotropic and anisotropic (all axis).
ASSERT_USUALLY_EQUAL_TOL
(
results
[
9
],
results
[
12
],
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
results
[
9
],
results
[
12
],
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
results
[
10
],
results
[
13
],
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
results
[
10
],
results
[
13
],
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
results
[
11
],
results
[
14
],
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
results
[
11
],
results
[
14
],
3
/
std
::
sqrt
((
double
)
steps
));
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
...
...
platforms/opencl/tests/TestOpenCLMonteCarloAnisotropicBarostat.cpp
View file @
49d60231
...
@@ -6,8 +6,8 @@
...
@@ -6,8 +6,8 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2008-201
2
Stanford University and the Authors. *
* Portions copyright (c) 2008-201
3
Stanford University and the Authors. *
* Authors: Peter Eastman
*
* Authors: Peter Eastman
, Lee-Ping Wang
*
* Contributors: *
* Contributors: *
* *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* Permission is hereby granted, free of charge, to any person obtaining a *
...
@@ -51,7 +51,7 @@
...
@@ -51,7 +51,7 @@
using
namespace
OpenMM
;
using
namespace
OpenMM
;
using
namespace
std
;
using
namespace
std
;
static
OpenCLPlatform
platform
;
OpenCLPlatform
platform
;
void
testChangingBoxSize
()
{
void
testChangingBoxSize
()
{
System
system
;
System
system
;
...
@@ -191,24 +191,24 @@ void testIdealGasAxis(int axis) {
...
@@ -191,24 +191,24 @@ void testIdealGasAxis(int axis) {
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
Vec3
box
[
3
];
Vec3
box
[
3
];
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
boxX
=
box
[
0
][
0
];
boxX
=
box
[
0
][
0
];
boxY
=
box
[
1
][
1
];
boxY
=
box
[
1
][
1
];
boxZ
=
box
[
2
][
2
];
boxZ
=
box
[
2
][
2
];
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
integrator
.
step
(
frequency
);
integrator
.
step
(
frequency
);
}
}
volume
/=
steps
;
volume
/=
steps
;
double
expected
=
(
numParticles
+
1
)
*
BOLTZ
*
temp
[
i
]
/
pressureInMD
;
double
expected
=
(
numParticles
+
1
)
*
BOLTZ
*
temp
[
i
]
/
pressureInMD
;
ASSERT_USUALLY_EQUAL_TOL
(
expected
,
volume
,
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
expected
,
volume
,
3
/
std
::
sqrt
((
double
)
steps
));
if
(
!
scaleX
)
{
if
(
!
scaleX
)
{
ASSERT
(
boxX
==
initialLength
);
ASSERT
(
boxX
==
initialLength
);
}
}
if
(
!
scaleY
)
{
if
(
!
scaleY
)
{
ASSERT
(
boxY
==
0.5
*
initialLength
);
ASSERT
(
boxY
==
0.5
*
initialLength
);
}
}
if
(
!
scaleZ
)
{
if
(
!
scaleZ
)
{
ASSERT
(
boxZ
==
2
*
initialLength
);
ASSERT
(
boxZ
==
2
*
initialLength
);
}
}
}
}
}
}
...
@@ -274,155 +274,148 @@ void testRandomSeed() {
...
@@ -274,155 +274,148 @@ void testRandomSeed() {
}
}
}
}
/**
* Run a constant pressure simulation on an anisotropic Einstein crystal
* using isotropic and anisotropic barostats. There are a total of 15 simulations:
*
* 1) 3 pressures: 9.0, 10.0, 11.0 bar, for each of the following groups:
* 2) 3 groups of simulations that scale just one axis: x, y, z
* 3) 1 group of simulations that scales all three axes in the anisotropic barostat
* 4) 1 group of simulations that scales all three axes in the isotropic barostat
*
* Results that we will check:
*
* a) In each group of simulations, the volume should decrease with increasing pressure
* b) In the three simulation groups that scale just one axis, the compressibility (i.e. incremental volume change
* with increasing pressure) should go like kx > ky > kz (because the spring constant is largest in the z-direction)
* c) The anisotropic barostat should produce the same result as the isotropic barostat when all three axes are scaled
*/
void
testEinsteinCrystal
()
{
void
testEinsteinCrystal
()
{
/*
const
int
numParticles
=
64
;
const
int
frequency
=
2
;
Run a constant pressure simulation on an anisotropic Einstein crystal
const
int
equil
=
10000
;
using isotropic and anisotropic barostats. There are a total of 15 simulations:
const
int
steps
=
5000
;
const
double
pressure
=
10.0
;
1) 3 pressures: 9.0, 10.0, 11.0 bar, for each of the following groups:
const
double
pressureInMD
=
pressure
*
(
AVOGADRO
*
1e-25
);
// pressure in kJ/mol/nm^3
2) 3 groups of simulations that scale just one axis: x, y, z
const
double
temp
=
300.0
;
// Only test one temperature since we're looking at three pressures.
3) 1 group of simulations that scales all three axes in the anisotropic barostat
const
double
pres3
[]
=
{
2.0
,
8.0
,
15.0
};
4) 1 group of simulations that scales all three axes in the isotropic barostat
const
double
initialVolume
=
numParticles
*
BOLTZ
*
temp
/
pressureInMD
;
const
double
initialLength
=
std
::
pow
(
initialVolume
,
1.0
/
3.0
);
Results that we will check:
vector
<
double
>
initialPositions
(
3
);
vector
<
double
>
results
;
a) In each group of simulations, the volume should decrease with increasing pressure
// Run four groups of anisotropic simulations; scaling just x, y, z, then all three.
b) In the three simulation groups that scale just one axis, the compressibility (i.e. incremental volume change
for
(
int
a
=
0
;
a
<
4
;
a
++
)
{
with increasing pressure) should go like kx > ky > kz (because the spring constant is largest in the z-direction)
// Test barostat for three different pressures.
c) The anisotropic barostat should produce the same result as the isotropic barostat when all three axes are scaled
for
(
int
p
=
0
;
p
<
3
;
p
++
)
{
// Create a system of noninteracting particles attached by harmonic springs to their initial positions.
*/
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
initialLength
,
0
,
0
),
Vec3
(
0
,
initialLength
,
0
),
Vec3
(
0
,
0
,
initialLength
));
const
int
numParticles
=
64
;
vector
<
Vec3
>
positions
(
numParticles
);
const
int
frequency
=
10
;
OpenMM_SFMT
::
SFMT
sfmt
;
const
int
equil
=
10000
;
init_gen_rand
(
0
,
sfmt
);
const
int
steps
=
10000
;
// Anisotropic force constants.
const
double
pressure
=
10.0
;
CustomExternalForce
*
force
=
new
CustomExternalForce
(
"0.005*(x-x0)^2 + 0.01*(y-y0)^2 + 0.02*(z-z0)^2"
);
const
double
pressureInMD
=
pressure
*
(
AVOGADRO
*
1e-25
);
// pressure in kJ/mol/nm^3
force
->
addPerParticleParameter
(
"x0"
);
const
double
temp
=
300.0
;
// Only test one temperature since we're looking at three pressures.
force
->
addPerParticleParameter
(
"y0"
);
const
double
pres3
[]
=
{
9.0
,
10.0
,
11.0
};
force
->
addPerParticleParameter
(
"z0"
);
const
double
initialVolume
=
numParticles
*
BOLTZ
*
temp
/
pressureInMD
;
NonbondedForce
*
nb
=
new
NonbondedForce
();
const
double
initialLength
=
std
::
pow
(
initialVolume
,
1.0
/
3.0
);
nb
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
vector
<
double
>
initialPositions
(
3
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
// All results.
system
.
addParticle
(
1.0
);
double
results
[]
=
{
0.0
,
0.0
,
0.0
,
0.0
,
0.0
,
positions
[
i
]
=
Vec3
(((
i
/
16
)
%
4
+
0.5
)
*
initialLength
/
4
,
((
i
/
4
)
%
4
+
0.5
)
*
initialLength
/
4
,
(
i
%
4
+
0.5
)
*
initialLength
/
4
);
0.0
,
0.0
,
0.0
,
0.0
,
0.0
,
initialPositions
[
0
]
=
positions
[
i
][
0
];
0.0
,
0.0
,
0.0
,
0.0
,
0.0
};
initialPositions
[
1
]
=
positions
[
i
][
1
];
int
simNum
=
0
;
initialPositions
[
2
]
=
positions
[
i
][
2
];
// Run four groups of anisotropic simulations; scaling just x, y, z, then all three.
force
->
addParticle
(
i
,
initialPositions
);
for
(
int
a
=
0
;
a
<
4
;
a
++
)
{
nb
->
addParticle
(
0
,
initialLength
/
6
,
0.1
);
// Test barostat for three different pressures.
}
for
(
int
p
=
0
;
p
<
3
;
p
++
)
{
system
.
addForce
(
force
);
// Create a system of noninteracting particles attached by harmonic springs to their initial positions.
system
.
addForce
(
nb
);
System
system
;
// Create the barostat.
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
initialLength
,
0
,
0
),
Vec3
(
0
,
initialLength
,
0
),
Vec3
(
0
,
0
,
initialLength
));
MonteCarloAnisotropicBarostat
*
barostat
=
new
MonteCarloAnisotropicBarostat
(
Vec3
(
pres3
[
p
],
pres3
[
p
],
pres3
[
p
]),
temp
,
frequency
,
(
a
==
0
||
a
==
3
),
(
a
==
1
||
a
==
3
),
(
a
==
2
||
a
==
3
));
vector
<
Vec3
>
positions
(
numParticles
);
system
.
addForce
(
barostat
);
OpenMM_SFMT
::
SFMT
sfmt
;
barostat
->
setTemperature
(
temp
);
init_gen_rand
(
0
,
sfmt
);
LangevinIntegrator
integrator
(
temp
,
0.1
,
0.01
);
// Anisotropic force constants.
Context
context
(
system
,
integrator
,
platform
);
CustomExternalForce
*
force
=
new
CustomExternalForce
(
"0.005*(x-x0)^2 + 0.01*(y-y0)^2 + 0.02*(z-z0)^2"
);
context
.
setPositions
(
positions
);
force
->
addPerParticleParameter
(
"x0"
);
// Let it equilibrate.
force
->
addPerParticleParameter
(
"y0"
);
integrator
.
step
(
equil
);
force
->
addPerParticleParameter
(
"z0"
);
// Now run it for a while and see if the volume is correct.
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
double
volume
=
0.0
;
system
.
addParticle
(
1.0
);
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
positions
[
i
]
=
Vec3
(((
i
/
16
)
%
4
+
0.5
)
*
initialLength
/
4
,
((
i
/
4
)
%
4
+
0.5
)
*
initialLength
/
4
,
(
i
%
4
+
0.5
)
*
initialLength
/
4
);
Vec3
box
[
3
];
initialPositions
[
0
]
=
positions
[
i
][
0
];
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
initialPositions
[
1
]
=
positions
[
i
][
1
];
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
initialPositions
[
2
]
=
positions
[
i
][
2
];
integrator
.
step
(
frequency
);
force
->
addParticle
(
i
,
initialPositions
);
}
}
volume
/=
steps
;
system
.
addForce
(
force
);
results
.
push_back
(
volume
);
// Create the barostat.
}
MonteCarloAnisotropicBarostat
*
barostat
=
new
MonteCarloAnisotropicBarostat
(
Vec3
(
pres3
[
p
],
pres3
[
p
],
pres3
[
p
]),
temp
,
frequency
,
(
a
==
0
||
a
==
3
),
(
a
==
1
||
a
==
3
),
(
a
==
2
||
a
==
3
));
system
.
addForce
(
barostat
);
barostat
->
setTemperature
(
temp
);
LangevinIntegrator
integrator
(
temp
,
0.1
,
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
// Let it equilibrate.
integrator
.
step
(
equil
);
// Now run it for a while and see if the volume is correct.
double
volume
=
0.0
;
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
Vec3
box
[
3
];
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
integrator
.
step
(
frequency
);
}
volume
/=
steps
;
results
[
simNum
]
=
volume
;
simNum
+=
1
;
}
}
for
(
int
p
=
0
;
p
<
3
;
p
++
)
{
// Create a system of noninteracting particles attached by harmonic springs to their initial positions.
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
initialLength
,
0
,
0
),
Vec3
(
0
,
initialLength
,
0
),
Vec3
(
0
,
0
,
initialLength
));
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
// Anisotropic force constants.
CustomExternalForce
*
force
=
new
CustomExternalForce
(
"0.005*(x-x0)^2 + 0.01*(y-y0)^2 + 0.02*(z-z0)^2"
);
force
->
addPerParticleParameter
(
"x0"
);
force
->
addPerParticleParameter
(
"y0"
);
force
->
addPerParticleParameter
(
"z0"
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
1.0
);
positions
[
i
]
=
Vec3
(((
i
/
16
)
%
4
+
0.5
)
*
initialLength
/
4
,
((
i
/
4
)
%
4
+
0.5
)
*
initialLength
/
4
,
(
i
%
4
+
0.5
)
*
initialLength
/
4
);
initialPositions
[
0
]
=
positions
[
i
][
0
];
initialPositions
[
1
]
=
positions
[
i
][
1
];
initialPositions
[
2
]
=
positions
[
i
][
2
];
force
->
addParticle
(
i
,
initialPositions
);
}
}
system
.
addForce
(
force
);
for
(
int
p
=
0
;
p
<
3
;
p
++
)
{
// Create the barostat.
// Create a system of noninteracting particles attached by harmonic springs to their initial positions.
MonteCarloBarostat
*
barostat
=
new
MonteCarloBarostat
(
pres3
[
p
],
temp
,
frequency
);
System
system
;
system
.
addForce
(
barostat
);
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
initialLength
,
0
,
0
),
Vec3
(
0
,
initialLength
,
0
),
Vec3
(
0
,
0
,
initialLength
));
barostat
->
setTemperature
(
temp
);
vector
<
Vec3
>
positions
(
numParticles
);
LangevinIntegrator
integrator
(
temp
,
0.1
,
0.01
);
OpenMM_SFMT
::
SFMT
sfmt
;
Context
context
(
system
,
integrator
,
platform
);
init_gen_rand
(
0
,
sfmt
);
context
.
setPositions
(
positions
);
// Anisotropic force constants.
// Let it equilibrate.
CustomExternalForce
*
force
=
new
CustomExternalForce
(
"0.005*(x-x0)^2 + 0.01*(y-y0)^2 + 0.02*(z-z0)^2"
);
integrator
.
step
(
equil
);
force
->
addPerParticleParameter
(
"x0"
);
// Now run it for a while and see if the volume is correct.
force
->
addPerParticleParameter
(
"y0"
);
double
volume
=
0.0
;
force
->
addPerParticleParameter
(
"z0"
);
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
NonbondedForce
*
nb
=
new
NonbondedForce
();
Vec3
box
[
3
];
nb
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
system
.
addParticle
(
1.0
);
integrator
.
step
(
frequency
);
positions
[
i
]
=
Vec3
(((
i
/
16
)
%
4
+
0.5
)
*
initialLength
/
4
,
((
i
/
4
)
%
4
+
0.5
)
*
initialLength
/
4
,
(
i
%
4
+
0.5
)
*
initialLength
/
4
);
initialPositions
[
0
]
=
positions
[
i
][
0
];
initialPositions
[
1
]
=
positions
[
i
][
1
];
initialPositions
[
2
]
=
positions
[
i
][
2
];
force
->
addParticle
(
i
,
initialPositions
);
nb
->
addParticle
(
0
,
initialLength
/
6
,
0.1
);
}
system
.
addForce
(
force
);
system
.
addForce
(
nb
);
// Create the barostat.
MonteCarloBarostat
*
barostat
=
new
MonteCarloBarostat
(
pres3
[
p
],
temp
,
frequency
);
system
.
addForce
(
barostat
);
barostat
->
setTemperature
(
temp
);
LangevinIntegrator
integrator
(
temp
,
0.1
,
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
// Let it equilibrate.
integrator
.
step
(
equil
);
// Now run it for a while and see if the volume is correct.
double
volume
=
0.0
;
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
Vec3
box
[
3
];
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
integrator
.
step
(
frequency
);
}
volume
/=
steps
;
results
.
push_back
(
volume
);
}
}
volume
/=
steps
;
results
[
simNum
]
=
volume
;
// Check to see if volumes decrease with increasing pressure.
simNum
+=
1
;
ASSERT_USUALLY_TRUE
(
results
[
0
]
>
results
[
1
]);
}
ASSERT_USUALLY_TRUE
(
results
[
1
]
>
results
[
2
]);
ASSERT_USUALLY_TRUE
(
results
[
3
]
>
results
[
4
]);
/*
ASSERT_USUALLY_TRUE
(
results
[
4
]
>
results
[
5
]);
for (int j = 0; j < 15; j++) {
ASSERT_USUALLY_TRUE
(
results
[
6
]
>
results
[
7
]);
printf("%.6f\n",results[j]);
ASSERT_USUALLY_TRUE
(
results
[
7
]
>
results
[
8
]);
}
*/
// Check to see if volumes decrease with increasing pressure.
ASSERT
(
results
[
0
]
>
results
[
1
]);
ASSERT
(
results
[
1
]
>
results
[
2
]);
ASSERT
(
results
[
3
]
>
results
[
4
]);
ASSERT
(
results
[
4
]
>
results
[
5
]);
ASSERT
(
results
[
6
]
>
results
[
7
]);
ASSERT
(
results
[
7
]
>
results
[
8
]);
// Check to see if incremental volume changes with increasing pressure go like kx > ky > kz.
// Check to see if incremental volume changes with increasing pressure go like kx > ky > kz.
ASSERT
((
results
[
0
]
-
results
[
1
])
>
(
results
[
3
]
-
results
[
4
]));
ASSERT
_USUALLY_TRUE
((
results
[
0
]
-
results
[
1
])
>
(
results
[
3
]
-
results
[
4
]));
ASSERT
((
results
[
1
]
-
results
[
2
])
>
(
results
[
4
]
-
results
[
5
]));
ASSERT
_USUALLY_TRUE
((
results
[
1
]
-
results
[
2
])
>
(
results
[
4
]
-
results
[
5
]));
ASSERT
((
results
[
3
]
-
results
[
4
])
>
(
results
[
6
]
-
results
[
7
]));
ASSERT
_USUALLY_TRUE
((
results
[
3
]
-
results
[
4
])
>
(
results
[
6
]
-
results
[
7
]));
ASSERT
((
results
[
4
]
-
results
[
5
])
>
(
results
[
7
]
-
results
[
8
]));
ASSERT
_USUALLY_TRUE
((
results
[
4
]
-
results
[
5
])
>
(
results
[
7
]
-
results
[
8
]));
// Check to see if the volumes are equal for isotropic and anisotropic (all axis).
// Check to see if the volumes are equal for isotropic and anisotropic (all axis).
ASSERT_USUALLY_EQUAL_TOL
(
results
[
9
],
results
[
12
],
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
results
[
9
],
results
[
12
],
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
results
[
10
],
results
[
13
],
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
results
[
10
],
results
[
13
],
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
results
[
11
],
results
[
14
],
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
results
[
11
],
results
[
14
],
3
/
std
::
sqrt
((
double
)
steps
));
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
...
...
platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp
View file @
49d60231
...
@@ -6,8 +6,8 @@
...
@@ -6,8 +6,8 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2008-201
0
Stanford University and the Authors. *
* Portions copyright (c) 2008-201
3
Stanford University and the Authors. *
* Authors: Peter Eastman
*
* Authors: Peter Eastman
, Lee-Ping Wang
*
* Contributors: *
* Contributors: *
* *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* Permission is hereby granted, free of charge, to any person obtaining a *
...
@@ -34,6 +34,8 @@
...
@@ -34,6 +34,8 @@
*/
*/
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/CustomExternalForce.h"
#include "openmm/MonteCarloBarostat.h"
#include "openmm/MonteCarloAnisotropicBarostat.h"
#include "openmm/MonteCarloAnisotropicBarostat.h"
#include "openmm/Context.h"
#include "openmm/Context.h"
#include "ReferencePlatform.h"
#include "ReferencePlatform.h"
...
@@ -190,24 +192,24 @@ void testIdealGasAxis(int axis) {
...
@@ -190,24 +192,24 @@ void testIdealGasAxis(int axis) {
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
Vec3
box
[
3
];
Vec3
box
[
3
];
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
boxX
=
box
[
0
][
0
];
boxX
=
box
[
0
][
0
];
boxY
=
box
[
1
][
1
];
boxY
=
box
[
1
][
1
];
boxZ
=
box
[
2
][
2
];
boxZ
=
box
[
2
][
2
];
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
integrator
.
step
(
frequency
);
integrator
.
step
(
frequency
);
}
}
volume
/=
steps
;
volume
/=
steps
;
double
expected
=
(
numParticles
+
1
)
*
BOLTZ
*
temp
[
i
]
/
pressureInMD
;
double
expected
=
(
numParticles
+
1
)
*
BOLTZ
*
temp
[
i
]
/
pressureInMD
;
ASSERT_USUALLY_EQUAL_TOL
(
expected
,
volume
,
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
expected
,
volume
,
3
/
std
::
sqrt
((
double
)
steps
));
if
(
!
scaleX
)
{
if
(
!
scaleX
)
{
ASSERT
(
boxX
==
initialLength
);
ASSERT
(
boxX
==
initialLength
);
}
}
if
(
!
scaleY
)
{
if
(
!
scaleY
)
{
ASSERT
(
boxY
==
0.5
*
initialLength
);
ASSERT
(
boxY
==
0.5
*
initialLength
);
}
}
if
(
!
scaleZ
)
{
if
(
!
scaleZ
)
{
ASSERT
(
boxZ
==
2
*
initialLength
);
ASSERT
(
boxZ
==
2
*
initialLength
);
}
}
}
}
}
}
...
@@ -274,13 +276,159 @@ void testRandomSeed() {
...
@@ -274,13 +276,159 @@ void testRandomSeed() {
}
}
}
}
/**
* Run a constant pressure simulation on an anisotropic Einstein crystal
* using isotropic and anisotropic barostats. There are a total of 15 simulations:
*
* 1) 3 pressures: 9.0, 10.0, 11.0 bar, for each of the following groups:
* 2) 3 groups of simulations that scale just one axis: x, y, z
* 3) 1 group of simulations that scales all three axes in the anisotropic barostat
* 4) 1 group of simulations that scales all three axes in the isotropic barostat
*
* Results that we will check:
*
* a) In each group of simulations, the volume should decrease with increasing pressure
* b) In the three simulation groups that scale just one axis, the compressibility (i.e. incremental volume change
* with increasing pressure) should go like kx > ky > kz (because the spring constant is largest in the z-direction)
* c) The anisotropic barostat should produce the same result as the isotropic barostat when all three axes are scaled
*/
void
testEinsteinCrystal
()
{
const
int
numParticles
=
64
;
const
int
frequency
=
2
;
const
int
equil
=
10000
;
const
int
steps
=
5000
;
const
double
pressure
=
10.0
;
const
double
pressureInMD
=
pressure
*
(
AVOGADRO
*
1e-25
);
// pressure in kJ/mol/nm^3
const
double
temp
=
300.0
;
// Only test one temperature since we're looking at three pressures.
const
double
pres3
[]
=
{
2.0
,
8.0
,
15.0
};
const
double
initialVolume
=
numParticles
*
BOLTZ
*
temp
/
pressureInMD
;
const
double
initialLength
=
std
::
pow
(
initialVolume
,
1.0
/
3.0
);
ReferencePlatform
platform
;
vector
<
double
>
initialPositions
(
3
);
vector
<
double
>
results
;
// Run four groups of anisotropic simulations; scaling just x, y, z, then all three.
for
(
int
a
=
0
;
a
<
4
;
a
++
)
{
// Test barostat for three different pressures.
for
(
int
p
=
0
;
p
<
3
;
p
++
)
{
// Create a system of noninteracting particles attached by harmonic springs to their initial positions.
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
initialLength
,
0
,
0
),
Vec3
(
0
,
initialLength
,
0
),
Vec3
(
0
,
0
,
initialLength
));
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
// Anisotropic force constants.
CustomExternalForce
*
force
=
new
CustomExternalForce
(
"0.005*(x-x0)^2 + 0.01*(y-y0)^2 + 0.02*(z-z0)^2"
);
force
->
addPerParticleParameter
(
"x0"
);
force
->
addPerParticleParameter
(
"y0"
);
force
->
addPerParticleParameter
(
"z0"
);
NonbondedForce
*
nb
=
new
NonbondedForce
();
nb
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
1.0
);
positions
[
i
]
=
Vec3
(((
i
/
16
)
%
4
+
0.5
)
*
initialLength
/
4
,
((
i
/
4
)
%
4
+
0.5
)
*
initialLength
/
4
,
(
i
%
4
+
0.5
)
*
initialLength
/
4
);
initialPositions
[
0
]
=
positions
[
i
][
0
];
initialPositions
[
1
]
=
positions
[
i
][
1
];
initialPositions
[
2
]
=
positions
[
i
][
2
];
force
->
addParticle
(
i
,
initialPositions
);
nb
->
addParticle
(
0
,
initialLength
/
6
,
0.1
);
}
system
.
addForce
(
force
);
system
.
addForce
(
nb
);
// Create the barostat.
MonteCarloAnisotropicBarostat
*
barostat
=
new
MonteCarloAnisotropicBarostat
(
Vec3
(
pres3
[
p
],
pres3
[
p
],
pres3
[
p
]),
temp
,
frequency
,
(
a
==
0
||
a
==
3
),
(
a
==
1
||
a
==
3
),
(
a
==
2
||
a
==
3
));
system
.
addForce
(
barostat
);
barostat
->
setTemperature
(
temp
);
LangevinIntegrator
integrator
(
temp
,
0.1
,
0.01
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
// Let it equilibrate.
integrator
.
step
(
equil
);
// Now run it for a while and see if the volume is correct.
double
volume
=
0.0
;
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
Vec3
box
[
3
];
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
integrator
.
step
(
frequency
);
}
volume
/=
steps
;
results
.
push_back
(
volume
);
}
}
for
(
int
p
=
0
;
p
<
3
;
p
++
)
{
// Create a system of noninteracting particles attached by harmonic springs to their initial positions.
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
initialLength
,
0
,
0
),
Vec3
(
0
,
initialLength
,
0
),
Vec3
(
0
,
0
,
initialLength
));
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
// Anisotropic force constants.
CustomExternalForce
*
force
=
new
CustomExternalForce
(
"0.005*(x-x0)^2 + 0.01*(y-y0)^2 + 0.02*(z-z0)^2"
);
force
->
addPerParticleParameter
(
"x0"
);
force
->
addPerParticleParameter
(
"y0"
);
force
->
addPerParticleParameter
(
"z0"
);
NonbondedForce
*
nb
=
new
NonbondedForce
();
nb
->
setNonbondedMethod
(
NonbondedForce
::
CutoffPeriodic
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
1.0
);
positions
[
i
]
=
Vec3
(((
i
/
16
)
%
4
+
0.5
)
*
initialLength
/
4
,
((
i
/
4
)
%
4
+
0.5
)
*
initialLength
/
4
,
(
i
%
4
+
0.5
)
*
initialLength
/
4
);
initialPositions
[
0
]
=
positions
[
i
][
0
];
initialPositions
[
1
]
=
positions
[
i
][
1
];
initialPositions
[
2
]
=
positions
[
i
][
2
];
force
->
addParticle
(
i
,
initialPositions
);
nb
->
addParticle
(
0
,
initialLength
/
6
,
0.1
);
}
system
.
addForce
(
force
);
system
.
addForce
(
nb
);
// Create the barostat.
MonteCarloBarostat
*
barostat
=
new
MonteCarloBarostat
(
pres3
[
p
],
temp
,
frequency
);
system
.
addForce
(
barostat
);
barostat
->
setTemperature
(
temp
);
LangevinIntegrator
integrator
(
temp
,
0.1
,
0.001
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
// Let it equilibrate.
integrator
.
step
(
equil
);
// Now run it for a while and see if the volume is correct.
double
volume
=
0.0
;
for
(
int
j
=
0
;
j
<
steps
;
++
j
)
{
Vec3
box
[
3
];
context
.
getState
(
0
).
getPeriodicBoxVectors
(
box
[
0
],
box
[
1
],
box
[
2
]);
volume
+=
box
[
0
][
0
]
*
box
[
1
][
1
]
*
box
[
2
][
2
];
integrator
.
step
(
frequency
);
}
volume
/=
steps
;
results
.
push_back
(
volume
);
}
// Check to see if volumes decrease with increasing pressure.
ASSERT_USUALLY_TRUE
(
results
[
0
]
>
results
[
1
]);
ASSERT_USUALLY_TRUE
(
results
[
1
]
>
results
[
2
]);
ASSERT_USUALLY_TRUE
(
results
[
3
]
>
results
[
4
]);
ASSERT_USUALLY_TRUE
(
results
[
4
]
>
results
[
5
]);
ASSERT_USUALLY_TRUE
(
results
[
6
]
>
results
[
7
]);
ASSERT_USUALLY_TRUE
(
results
[
7
]
>
results
[
8
]);
// Check to see if incremental volume changes with increasing pressure go like kx > ky > kz.
ASSERT_USUALLY_TRUE
((
results
[
0
]
-
results
[
1
])
>
(
results
[
3
]
-
results
[
4
]));
ASSERT_USUALLY_TRUE
((
results
[
1
]
-
results
[
2
])
>
(
results
[
4
]
-
results
[
5
]));
ASSERT_USUALLY_TRUE
((
results
[
3
]
-
results
[
4
])
>
(
results
[
6
]
-
results
[
7
]));
ASSERT_USUALLY_TRUE
((
results
[
4
]
-
results
[
5
])
>
(
results
[
7
]
-
results
[
8
]));
// Check to see if the volumes are equal for isotropic and anisotropic (all axis).
ASSERT_USUALLY_EQUAL_TOL
(
results
[
9
],
results
[
12
],
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
results
[
10
],
results
[
13
],
3
/
std
::
sqrt
((
double
)
steps
));
ASSERT_USUALLY_EQUAL_TOL
(
results
[
11
],
results
[
14
],
3
/
std
::
sqrt
((
double
)
steps
));
}
int
main
()
{
int
main
()
{
try
{
try
{
testIdealGas
();
testIdealGas
();
testIdealGasAxis
(
0
);
testIdealGasAxis
(
0
);
testIdealGasAxis
(
1
);
testIdealGasAxis
(
1
);
testIdealGasAxis
(
2
);
testIdealGasAxis
(
2
);
testRandomSeed
();
testRandomSeed
();
testEinsteinCrystal
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
...
...
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