2 # Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
3 # (HOOMD-blue) Open Source Software License Copyright 2009-2014 The Regents of
4 # the University of Michigan All rights reserved.
6 # HOOMD-blue may contain modifications ("Contributions") provided, and to which
7 # copyright is held, by various Contributors who have granted The Regents of the
8 # University of Michigan the right to modify and/or distribute such Contributions.
10 # You may redistribute, use, and create derivate works of HOOMD-blue, in source
11 # and binary forms, provided you abide by the following conditions:
13 # * Redistributions of source code must retain the above copyright notice, this
14 # list of conditions, and the following disclaimer both in the code and
15 # prominently in any materials provided with the distribution.
17 # * Redistributions in binary form must reproduce the above copyright notice, this
18 # list of conditions, and the following disclaimer in the documentation and/or
19 # other materials provided with the distribution.
21 # * All publications and presentations based on HOOMD-blue, including any reports
22 # or published results obtained, in whole or in part, with HOOMD-blue, will
23 # acknowledge its use according to the terms posted at the time of submission on:
24 # http://codeblue.umich.edu/hoomd-blue/citations.html
26 # * Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
27 # http://codeblue.umich.edu/hoomd-blue/
29 # * Apart from the above required attributions, neither the name of the copyright
30 # holder nor the names of HOOMD-blue's contributors may be used to endorse or
31 # promote products derived from this software without specific prior written
36 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
37 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
39 # WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.
41 # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
42 # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
43 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
45 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
46 # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 # Maintainer: joaander / All Developers are free to add commands for new features
52 ## \package hoomd_script.integrate
53 # \brief Commands that integrate the equations of motion
55 # To integrate the system forward in time, an integration mode must be set. Only one integration mode can be active at
56 # a time, and the last \c integrate.mode_* command before the run() command is the one that will take effect. It is
57 # possible to set one mode, run() for a certain number of steps and then switch to another mode before the next run()
60 # The most commonly used mode is integrate.mode_standard . It specifies a standard mode where, at each time
61 # step, all of the specified forces are evaluated and used in moving the system forward to the next step.
62 # integrate.mode_standard doesn't integrate any particles by itself, one or more compatible integration methods must
63 # be specified before the run() command. Like commands that specify forces, integration methods are \b persistent and
64 # remain set until they are disabled (this differs greatly from HOOMD-blue behavior in all versions prior to 0.9.0).
65 # The benefit and reason for this change is that now multiple integration methods can be specified on different particle
66 # groups, allowing portions of the system to be fixed, integrated at a different temperature, etc...
68 # To clarify, the following series of commands will run for 1000 time steps in the NVT ensemble and then switch to
69 # NVE for another 1000 steps.
73 # integrate.mode_standard(dt=0.005)
74 # nvt = integrate.nvt(group=all, T=1.2, tau=0.5)
77 # integrate.nve(group=all)
81 # For more detailed information on the interaction of integration methods and integration modes, see
82 # integrate.mode_standard.
84 # Some integrators provide parameters that can be changed between runs.
85 # In order to access the integrator to change it, it needs to be saved
86 # in a variable. For example:
88 # integrator = integrate.nvt(group=all, T=1.2, tau=0.5)
90 # integrator.set_params(T=1.0)
93 # This code snippet runs the first 100 time steps with T=1.2 and the next 100 with T=1.0
97 from hoomd_script
import globals;
98 from hoomd_script
import compute
;
100 from hoomd_script
import util
;
101 from hoomd_script
import variant
;
102 from hoomd_script
import init
;
103 from hoomd_script
import comm
;
106 # \brief Base class for integrators
108 # An integrator in hoomd_script reflects an Integrator in c++. It is responsible
109 # for all high-level management that happens behind the scenes for hoomd_script
110 # writers. 1) The instance of the c++ integrator itself is tracked 2) All
111 # forces created so far in the simulation are updated in the cpp_integrator
112 # whenever run() is called.
115 # \brief Constructs the integrator
117 # This doesn't really do much bet set some member variables to None
119 # check if initialization has occured
120 if not init
.is_initialized():
121 globals.msg
.error("Cannot create integrator before initialization\n");
122 raise RuntimeError('Error creating integrator');
124 # by default, integrators do not support methods
125 self
.cpp_integrator
= None;
126 self
.supports_methods
= False;
128 # save ourselves in the global variable
129 globals.integrator
= self
;
131 ## \var cpp_integrator
133 # \brief Stores the C++ side Integrator managed by this class
135 ## \var supports_methods
137 # \brief True if this integrator supports integration methods
138 # \note If hoomd ever needs to support multiple TYPES of methods, we could just change this to a string naming the
139 # type that is supported and add a type string to each of the integration_methods.
142 # \brief Checks that proper initialization has completed
143 def check_initialization(self
):
144 # check that we have been initialized properly
145 if self
.cpp_integrator
is None:
146 globals.msg
.error('Bug in hoomd_script: cpp_integrator not set, please report\n');
147 raise RuntimeError();
150 # \brief Updates the integrators in the reflected c++ class
151 def update_forces(self
):
152 self
.check_initialization();
155 self
.cpp_integrator
.removeForceComputes();
156 for f
in globals.forces
:
157 if f
.cpp_force
is None:
158 globals.msg
.error('Bug in hoomd_script: cpp_force not set, please report\n');
159 raise RuntimeError('Error updating forces');
161 if f
.log
or f
.enabled
:
165 self
.cpp_integrator
.addForceCompute(f
.cpp_force
);
167 # set the constraint forces
168 for f
in globals.constraint_forces
:
169 if f
.cpp_force
is None:
170 globals.msg
.error('Bug in hoomd_script: cpp_force not set, please report\n');
171 raise RuntimeError('Error updating forces');
174 self
.cpp_integrator
.addForceConstraint(f
.cpp_force
);
178 # \brief Updates the integration methods in the reflected c++ class
179 def update_methods(self
):
180 self
.check_initialization();
182 # if we support methods, add them all to the list
183 if self
.supports_methods
:
184 self
.cpp_integrator
.removeAllIntegrationMethods();
186 if len(globals.integration_methods
) == 0:
187 globals.msg
.error('This integrator requires that one or more integration methods be specified.\n');
188 raise RuntimeError('Error initializing integrator methods');
190 for m
in globals.integration_methods
:
191 self
.cpp_integrator
.addIntegrationMethod(m
.cpp_method
);
194 if len(globals.integration_methods
) > 0:
195 globals.msg
.error("This integrator does not support the use of integration methods,\n");
196 globals.msg
.error("but some have been specified in the script. Remove them or use\n");
197 globals.msg
.error("a different integrator.\n");
198 raise RuntimeError('Error initializing integrator methods');
201 # \brief Counts the number of degrees of freedom and updates each compute.thermo specified
202 def update_thermos(self
):
203 self
.check_initialization();
205 for t
in globals.thermos
:
206 ndof
= self
.cpp_integrator
.getNDOF(t
.group
.cpp_group
);
207 t
.cpp_compute
.setNDOF(ndof
);
210 # \brief Base class for integration methods
212 # An integration_method in hoomd_script reflects an IntegrationMethod in c++. It is responsible for all high-level
213 # management that happens behind the scenes for hoomd_script writers. 1) The instance of the c++ integration method
214 # itself is tracked and added to the integrator and 2) methods are provided for disabling the integration method from
215 # being active for the next run()
217 # The design of integration_method exactly mirrors that of _force for consistency
218 class _integration_method
:
220 # \brief Constructs the integration_method
222 # Initializes the cpp_method to None.
224 # check if initialization has occured
225 if not init
.is_initialized():
226 globals.msg
.error("Cannot create an integration method before initialization\n");
227 raise RuntimeError('Error creating integration method');
229 self
.cpp_method
= None;
232 globals.integration_methods
.append(self
);
236 # \brief True if the integration method is enabled
240 # \brief Stores the C++ side IntegrationMethod managed by this class
243 # \brief Checks that proper initialization has completed
244 def check_initialization(self
):
245 # check that we have been initialized properly
246 if self
.cpp_method
is None:
247 globals.msg
.error('Bug in hoomd_script: cpp_method not set, please report\n');
248 raise RuntimeError();
250 ## Disables the integration method
257 # Executing the disable command will remove the integration method from the simulation.Any run() command executed
258 # after disabling an integration method will not apply the integration method to the particles during the
259 # simulation. A disabled integration method can be re-enabled with enable()
261 # To use this command, you must have saved the force in a variable, as
262 # shown in this example:
264 # method = integrate.some_method()
265 # # ... later in the script
269 util
.print_status_line();
270 self
.check_initialization()
272 # check if we are already disabled
274 globals.msg
.warning("Ignoring command to disable an integration method that is already disabled");
277 self
.enabled
= False;
278 globals.integration_methods
.remove(self
);
280 ## Enables the integration method
287 # See disable() for a detailed description.
289 util
.print_status_line();
290 self
.check_initialization();
292 # check if we are already disabled
294 globals.msg
.warning("Ignoring command to enable an integration method that is already enabled");
298 globals.integration_methods
.append(self
);
300 ## Enables a variety of standard integration methods
302 # integrate.mode_standard performs a standard time step integration technique to move the system forward. At each time
303 # step, all of the specified forces are evaluated and used in moving the system forward to the next step.
305 # By itself, integrate.mode_standard does nothing. You must specify one or more integration methods to apply to the
306 # system. Each integration method can be applied to only a specific group of particles enabling advanced simulation
309 # The following commands can be used to specify the integration methods used by integrate.mode_standard.
311 # - integrate.bdnvt_rigid
313 # - integrate.nve_rigid
315 # - integrate.nvt_rigid
319 # There can only be one integration mode active at a time. If there are more than one integrate.mode_* commands in
320 # a hoomd script, only the most recent before a given run() will take effect.
323 class mode_standard(_integrator
):
324 ## Specifies the standard integration mode
325 # \param dt Each time step of the simulation run() will advance the real time of the system forward by \a dt (in time units)
329 # integrate.mode_standard(dt=0.005)
330 # integrator_mode = integrate.mode_standard(dt=0.001)
332 def __init__(self
, dt
):
333 util
.print_status_line();
335 # initialize base class
336 _integrator
.__init
__(self
);
338 # initialize the reflected c++ class
339 self
.cpp_integrator
= hoomd
.IntegratorTwoStep(globals.system_definition
, dt
);
340 self
.supports_methods
= True;
342 globals.system
.setIntegrator(self
.cpp_integrator
);
344 ## Changes parameters of an existing integration mode
345 # \param dt New time step delta (if set) (in time units)
347 # To change the parameters of an existing integration mode, you must save it in a variable when it is
348 # specified, like so:
350 # integrator_mode = integrate.mode_standard(dt=5e-3)
355 # integrator_mode.set_params(dt=0.007)
357 def set_params(self
, dt
=None):
358 util
.print_status_line();
359 self
.check_initialization();
361 # change the parameters
363 self
.cpp_integrator
.setDeltaT(dt
);
365 ## NVT Integration via the Nosé-Hoover thermostat
367 # integrate.nvt performs constant volume, constant temperature simulations using the Nosé-Hoover thermostat.
369 # There are two implementations of NVT in hoomd:
370 # * The MTK equations are described in Refs. \cite Martyna1994 \cite Martyna1996.
371 # * The other mode is Equation 13 in ref. \cite Bond1999.
373 # MTK exhibits superior time stability and accuracy, it is the default. The other mode is deprecated and will be
374 # removed in a future version of HOOMD-blue. It is kept now for backwards compatibility.
376 # integrate.nvt is an integration method. It must be used in concert with an integration mode. It can be used while
377 # the following modes are active:
378 # - integrate.mode_standard
380 # integrate.nvt uses the proper number of degrees of freedom to compute the temperature of the system in both
381 # 2 and 3 dimensional systems, as long as the number of dimensions is set before the integrate.nvt command
384 class nvt(_integration_method
):
385 ## Specifies the NVT integration method
386 # \param group Group of particles on which to apply this method.
387 # \param T Temperature set point for the Nosé-Hoover thermostat. (in energy units)
388 # \param tau Coupling constant for the Nosé-Hoover thermostat. (in time units)
389 # \param mtk If *true* (default), use the time-reversible and measure-preserving Martyna-Tobias-Klein (MTK) update equations
391 # \f$ \tau \f$ is related to the Nosé mass \f$ Q \f$ by
392 # \f[ \tau = \sqrt{\frac{Q}{g k_B T_0}} \f] where \f$ g \f$ is the number of degrees of freedom,
393 # and \f$ k_B T_0 \f$ is the set point (\a T above).
395 # \a T can be a variant type, allowing for temperature ramps in simulation runs.
397 # Internally, a compute.thermo is automatically specified and associated with \a group.
402 # integrate.nvt(group=all, T=1.0, tau=0.5)
403 # integrator = integrate.nvt(group=all, tau=1.0, T=0.65)
404 # integrator = integrate.nvt(group=all, tau=1.0, T=0.65, mtk=False)
405 # typeA = group.type('A')
406 # integrator = integrate.nvt(group=typeA, tau=1.0, T=variant.linear_interp([(0, 4.0), (1e6, 1.0)]))
408 def __init__(self
, group
, T
, tau
, mtk
=True):
409 util
.print_status_line();
411 # initialize base class
412 _integration_method
.__init
__(self
);
414 # setup the variant inputs
415 T
= variant
._setup
_variant
_input
(T
);
417 # create the compute thermo
418 # as an optimization, NVT (without MTK) on the GPU uses the thermo is a way that produces incorrect values for the pressure
419 # if we are given the overall group_all, create a new group so that the invalid pressure is not passed to
421 if group
is globals.group_all
and not mtk
:
422 group_copy
= copy
.copy(group
);
423 group_copy
.name
= "__nvt_all";
424 util
._disable
_status
_lines
= True;
425 thermo
= compute
.thermo(group_copy
);
426 util
._disable
_status
_lines
= False;
428 thermo
= compute
._get
_unique
_thermo
(group
=group
);
431 suffix
= '_' + group
.name
;
433 # initialize the reflected c++ class
435 if not globals.exec_conf
.isCUDAEnabled():
436 self
.cpp_method
= hoomd
.TwoStepNVT(globals.system_definition
, group
.cpp_group
, thermo
.cpp_compute
, tau
, T
.cpp_variant
, suffix
);
438 self
.cpp_method
= hoomd
.TwoStepNVTGPU(globals.system_definition
, group
.cpp_group
, thermo
.cpp_compute
, tau
, T
.cpp_variant
, suffix
);
440 if not globals.exec_conf
.isCUDAEnabled():
441 self
.cpp_method
= hoomd
.TwoStepNVTMTK(globals.system_definition
, group
.cpp_group
, thermo
.cpp_compute
, tau
, T
.cpp_variant
, suffix
);
443 self
.cpp_method
= hoomd
.TwoStepNVTMTKGPU(globals.system_definition
, group
.cpp_group
, thermo
.cpp_compute
, tau
, T
.cpp_variant
, suffix
);
446 self
.cpp_method
.validateGroup()
448 ## Changes parameters of an existing integrator
449 # \param T New temperature (if set) (in energy units)
450 # \param tau New coupling constant (if set) (in time units)
452 # To change the parameters of an existing integrator, you must save it in a variable when it is
453 # specified, like so:
455 # integrator = integrate.nvt(group=all, tau=1.0, T=0.65)
460 # integrator.set_params(tau=0.6)
461 # integrator.set_params(tau=0.7, T=2.0)
463 def set_params(self
, T
=None, tau
=None):
464 util
.print_status_line();
465 self
.check_initialization();
467 # change the parameters
469 # setup the variant inputs
470 T
= variant
._setup
_variant
_input
(T
);
471 self
.cpp_method
.setT(T
.cpp_variant
);
473 self
.cpp_method
.setTau(tau
);
475 ## NPT Integration via MTK barostat-thermostat with triclinic unit cell
477 # integrate.npt performs constant pressure, constant temperature simulations, allowing for a fully deformable
480 # The integration method is based on the rigorous Martyna-Tobias-Klein equations of motion for NPT.
481 # For optimal stability, the update equations leave the phase-space meeasure invariant and are manifestly
484 # By default, integrate.npt performs integration in a cubic box under hydrostatic pressure by simultaneously
485 # rescaling the lengths \a Lx, \a Ly and \a Lz of the simulation box.
487 # integrate.npt can also perform more advanced integration modes. The integration mode
488 # is specified by a set of \a couplings and by specifying the box degrees of freedom that are put under
491 # \a Couplings define which diagonal elements of the pressure tensor \f$ P_{\alpha,\beta} \f$
492 # should be averaged over, so that the corresponding box lengths are rescaled by the same amount.
494 # Valid \a couplings are:<br>
495 # - \b none (all box lengths are updated independently)
496 # - \b xy (\a Lx and \a Ly are coupled)
497 # - \b xz (\a Lx and \a Lz are coupled)
498 # - \b yz (\a Ly and \a Lz are coupled)
499 # - \b xyz (\a Lx and \a Ly and \a Lz are coupled)
501 # The default coupling is \b xyz, i.e. the ratios between all box lengths stay constant.
503 # <em>Degrees of freedom</em> of the box specify which lengths and tilt factors of the box should be updated,
504 # and how particle coordinates and velocities should be rescaled.
506 # Valid keywords for degrees of freedom are:
507 # - \b x (the box length Lx is updated)
508 # - \b y (the box length Ly is updated)
509 # - \b z (the box length Lz is updated)
510 # - \b xy (the tilt factor xy is updated)
511 # - \b xz (the tilt factor xz is updated)
512 # - \b yz (the tilt factor yz is updated)
513 # - \b all (all elements are updated, equivalent to \b x, \b y, \b z, \b xy, \b xz, and \b yz together)
515 # Any of the six keywords can be combined together. By default, the \b x, \b y, and \b z degrees of freedom
518 # \note If any of the diagonal \a x, \a y, \a z degrees of freedom is not being integrated, pressure tensor components
519 # along that direction are not considered for the remaining degrees of freedom.
522 # - Specifying \b xyz copulings and \b x, \b y, and \b z degrees of freedom amounts to \a cubic symmetry (default)
523 # - Specifying \b xy couplings and \b x, \b y, and \b z degrees of freedom amounts to \a tetragonal symmetry.
524 # - Specifing no couplings and \b all degrees of freedom amounts to a fully deformable \a triclinic unit cell
526 # integrate.npt is an integration method. It must be used in concert with an integration mode. It can be used while
527 # the following modes are active:
528 # - integrate.mode_standard
530 # integrate.npt uses the proper number of degrees of freedom to compute the temperature and pressure of the system in
531 # both 2 and 3 dimensional systems, as long as the number of dimensions is set before the integrate.npt command
534 # For the MTK equations of motion, see:
536 # \cite Tuckerman2006
538 # Glaser et. al (2013), to be published
540 class npt(_integration_method
):
541 ## Specifies the NPT integrator
542 # \param group Group of particles on which to apply this method.
543 # \param T Temperature set point for the thermostat, not needed if \b nph=True (in energy units)
544 # \param P Pressure set point for the barostat (in pressure units)
545 # \param tau Coupling constant for the thermostat, not needed if \a nph=True (in time units)
546 # \param tauP Coupling constant for the barostat (in time units)
547 # \param couple Couplings of diagonal elements of the stress tensor, can be \b "none", \b "xy", \b "xz",\b "yz", or \b "xyz" (default)
548 # \param x if \b True, rescale \a Lx and x component of particle coordinates and velocities
549 # \param y if \b True, rescale \a Ly and y component of particle coordinates and velocities
550 # \param z if \b True, rescale \a Lz and z component of particle coordinates and velocities
551 # \param xy if \b True, rescale \a xy tilt factor and x and y components of particle coordinates and velocities
552 # \param xz if \b True, rescale \a xz tilt factor and x and z components of particle coordinates and velocities
553 # \param yz if \b True, rescale \a yz tilt factor and y and z components of particle coordinates and velocities
554 # \param all if \b True, rescale all lengths and tilt factors and components of particle coordinates and velocities
555 # \param nph if \b True, integrate without a thermostat, i.e. in the NPH ensemble
556 # \param rescale_all if \b True, rescale all particles, not only those in the group
558 # Both \a T and \a P can be variant types, allowing for temperature/pressure ramps in simulation runs.
560 # \f$ \tau \f$ is related to the Nosé mass \f$ Q \f$ by
561 # \f[ \tau = \sqrt{\frac{Q}{g k_B T_0}} \f] where \f$ g \f$ is the number of degrees of freedom,
562 # and \f$ k_B T_0 \f$ is the set point (\a T above).
564 # Internally, a compute.thermo is automatically specified and associated with \a group.
568 # integrate.npt(group=all, T=1.0, tau=0.5, tauP=1.0, P=2.0)
569 # integrator = integrate.npt(group=all, tau=1.0, dt=5e-3, T=0.65, tauP = 1.2, P=2.0)
570 # # orthorhombic symmetry
571 # integrator = integrate.npt(group=all, tau=1.0, dt=5e-3, T=0.65, tauP = 1.2, P=2.0, couple="none")
572 # # tetragonal symmetry
573 # integrator = integrate.npt(group=all, tau=1.0, dt=5e-3, T=0.65, tauP = 1.2, P=2.0, couple="xy")
574 # # triclinic symmetry
575 # integrator = integrate.npt(group=all, tau=1.0, dt=5e-3, T=0.65, tauP = 1.2, P=2.0, couple="none", all=True)
577 def __init__(self
, group
, P
, tauP
, couple
="xyz", x
=True, y
=True, z
=True, xy
=False, xz
=False, yz
=False, all
=False, nph
=False, T
=None, tau
=None, rescale_all
=None):
578 util
.print_status_line();
581 if (T
is None or tau
is None):
583 globals.msg
.error("integrate.npt: Need temperature T and thermostat time scale tau.\n");
584 raise RuntimeError("Error setting up NPT integration.");
590 # initialize base class
591 _integration_method
.__init
__(self
);
593 # setup the variant inputs
594 T
= variant
._setup
_variant
_input
(T
);
595 P
= variant
._setup
_variant
_input
(P
);
597 # create the compute thermo
598 thermo_group
= compute
._get
_unique
_thermo
(group
=group
);
599 thermo_all
= compute
._get
_unique
_thermo
(group
=globals.group_all
);
601 # need to know if we are running 2D simulations
602 twod
= (globals.system_definition
.getNDimensions() == 2);
604 globals.msg
.notice(2, "When running in 2D, z couplings and degrees of freedom are silently ignored.\n");
606 # initialize the reflected c++ class
608 # silently ignore any couplings that involve z
610 cpp_couple
= hoomd
.TwoStepNPTMTK
.couplingMode
.couple_none
612 cpp_couple
= hoomd
.TwoStepNPTMTK
.couplingMode
.couple_xy
614 cpp_couple
= hoomd
.TwoStepNPTMTK
.couplingMode
.couple_none
616 cpp_couple
= hoomd
.TwoStepNPTMTK
.couplingMode
.couple_none
617 elif couple
== "xyz":
618 cpp_couple
= hoomd
.TwoStepNPTMTK
.couplingMode
.couple_xy
620 globals.msg
.error("Invalid coupling mode\n");
621 raise RuntimeError("Error setting up NPT integration.");
624 cpp_couple
= hoomd
.TwoStepNPTMTK
.couplingMode
.couple_none
626 cpp_couple
= hoomd
.TwoStepNPTMTK
.couplingMode
.couple_xy
628 cpp_couple
= hoomd
.TwoStepNPTMTK
.couplingMode
.couple_xz
630 cpp_couple
= hoomd
.TwoStepNPTMTK
.couplingMode
.couple_yz
631 elif couple
== "xyz":
632 cpp_couple
= hoomd
.TwoStepNPTMTK
.couplingMode
.couple_xyz
634 globals.msg
.error("Invalid coupling mode\n");
635 raise RuntimeError("Error setting up NPT integration.");
637 # set degrees of freedom flags
638 # silently ignore z related degrees of freedom when running in 2d
641 flags |
= hoomd
.TwoStepNPTMTK
.baroFlags
.baro_x
643 flags |
= hoomd
.TwoStepNPTMTK
.baroFlags
.baro_y
644 if (z
or all
) and not twod
:
645 flags |
= hoomd
.TwoStepNPTMTK
.baroFlags
.baro_z
647 flags |
= hoomd
.TwoStepNPTMTK
.baroFlags
.baro_xy
648 if (xz
or all
) and not twod
:
649 flags |
= hoomd
.TwoStepNPTMTK
.baroFlags
.baro_xz
650 if (yz
or all
) and not twod
:
651 flags |
= hoomd
.TwoStepNPTMTK
.baroFlags
.baro_yz
653 if not globals.exec_conf
.isCUDAEnabled():
654 self
.cpp_method
= hoomd
.TwoStepNPTMTK(globals.system_definition
, group
.cpp_group
, thermo_group
.cpp_compute
, tau
, tauP
, T
.cpp_variant
, P
.cpp_variant
, cpp_couple
, flags
, nph
);
656 self
.cpp_method
= hoomd
.TwoStepNPTMTKGPU(globals.system_definition
, group
.cpp_group
, thermo_group
.cpp_compute
, tau
, tauP
, T
.cpp_variant
, P
.cpp_variant
, cpp_couple
, flags
, nph
);
658 if rescale_all
is not None:
659 self
.cpp_method
.setRescaleAll(rescale_all
)
661 self
.cpp_method
.validateGroup()
663 ## Changes parameters of an existing integrator
664 # \param T New temperature (if set) (in energy units)
665 # \param tau New coupling constant (if set) (in time units)
666 # \param P New pressure (if set) (in pressure units)
667 # \param tauP New barostat coupling constant (if set) (in time units)
668 # \param rescale_all if \b True, rescale all particles, not only those in the group
670 # To change the parameters of an existing integrator, you must save it in a variable when it is
671 # specified, like so:
673 # integrator = integrate.npt(tau=1.0, T=0.65)
678 # integrator.set_params(tau=0.6)
679 # integrator.set_params(dt=3e-3, T=2.0, P=1.0)
681 def set_params(self
, T
=None, tau
=None, P
=None, tauP
=None, rescale_all
=None):
682 util
.print_status_line();
683 self
.check_initialization();
685 # change the parameters
687 # setup the variant inputs
688 T
= variant
._setup
_variant
_input
(T
);
689 self
.cpp_method
.setT(T
.cpp_variant
);
691 self
.cpp_method
.setTau(tau
);
693 # setup the variant inputs
694 P
= variant
._setup
_variant
_input
(P
);
695 self
.cpp_method
.setP(P
.cpp_variant
);
697 self
.cpp_method
.setTauP(tauP
);
698 if rescale_all
is not None:
699 self
.cpp_method
.setRescaleAll(rescale_all
)
702 ## NPH Integration via MTK barostat-thermostat with triclinic unit cell
704 # integrate.nph performs constant pressure (NPH) simulations using a Martyna-Tobias-Klein barostat, an
705 # explicitly reversible and measure-preserving integration scheme. It allows for fully deformable simulation
706 # cells and uses the same underying integrator as integrate.npt (with \b nph=True).
708 # The available options are identical to those of integrate.npt, except that *T* cannot be specified.
709 # For further information, refer to the documentation of integrate.npt
711 # \note A time scale \b tau_p for the relaxation of the barostat is required. This is defined as the
712 # relaxation time the barostat would have at an average temperature \f$ T_0 =1 \f$, and it
713 # is related to the internally used (Andersen) Barostat mass \f$W\f$ via
714 # \f$ W=d N T_0 \tau_p^2 \f$, where \f$ d \f$ is the dimensionsality and \f$ N \f$ the number
717 # integrate.nph is an integration method. It must be used in concert with an integration mode. It can be used while
718 # the following modes are active:
719 # - integrate.mode_standard
724 ## Specifies the NPH integrator
725 # \param params Parameters used for the underlying integrate.npt (for documentation, see there)
729 # # Triclinic unit cell
730 # nph=integrate.nph(group=all, P=2.0, tau_p=1.0, couple="none", all=True)
732 # nph = integrate.nph(group=all, P=2.0, tau_p=1.0)
734 def __init__(self
, **params
):
735 util
.print_status_line();
737 # initialize base class
738 util
._disable
_status
_lines
= True;
739 npt
.__init
__(self
, nph
=True, T
=1.0, **params
);
740 util
._disable
_status
_lines
= False;
742 ## NVE Integration via Velocity-Verlet
744 # integrate.nve performs constant volume, constant energy simulations using the standard
745 # Velocity-Verlet method. For poor initial conditions that include overlapping atoms, a
746 # limit can be specified to the movement a particle is allowed to make in one time step.
747 # After a few thousand time steps with the limit set, the system should be in a safe state
748 # to continue with unconstrained integration.
750 # Another use-case for integrate.nve is to fix the velocity of a certain group of particles. This can be achieved by
751 # setting the velocity of those particles in the initial condition and setting the \a zero_force option to True
752 # for that group. A True value for \a zero_force causes integrate.nve to ignore any net force on each particle and
753 # integrate them forward in time with a constant velocity.
755 # \note With an active limit, Newton's third law is effectively \b not obeyed and the system
756 # can gain linear momentum. Activate the update.zero_momentum updater during the limited nve
757 # run to prevent this.
759 # integrate.nve is an integration method. It must be used in concert with an integration mode. It can be used while
760 # the following modes are active:
761 # - integrate.mode_standard
763 class nve(_integration_method
):
764 ## Specifies the NVE integration method
765 # \param group Group of particles on which to apply this method.
766 # \param limit (optional) Enforce that no particle moves more than a distance of \a limit in a single time step
767 # \param zero_force When set to true, particles in the \a group are integrated forward in time with constant
768 # velocity and any net force on them is ignored.
770 # Internally, a compute.thermo is automatically specified and associated with \a group.
775 # integrate.nve(group=all)
776 # integrator = integrate.nve(group=all)
777 # typeA = group.type('A')
778 # integrate.nve(group=typeA, limit=0.01)
779 # integrate.nve(group=typeA, zero_force=True)
781 def __init__(self
, group
, limit
=None, zero_force
=False):
782 util
.print_status_line();
784 # initialize base class
785 _integration_method
.__init
__(self
);
787 # create the compute thermo
788 compute
._get
_unique
_thermo
(group
=group
);
790 # initialize the reflected c++ class
791 if not globals.exec_conf
.isCUDAEnabled():
792 self
.cpp_method
= hoomd
.TwoStepNVE(globals.system_definition
, group
.cpp_group
, False);
794 self
.cpp_method
= hoomd
.TwoStepNVEGPU(globals.system_definition
, group
.cpp_group
);
797 if limit
is not None:
798 self
.cpp_method
.setLimit(limit
);
800 self
.cpp_method
.setZeroForce(zero_force
);
802 self
.cpp_method
.validateGroup()
804 ## Changes parameters of an existing integrator
805 # \param limit (if set) New limit value to set. Removes the limit if limit is False
806 # \param zero_force (if set) New value for the zero force option
808 # To change the parameters of an existing integrator, you must save it in a variable when it is
809 # specified, like so:
811 # integrator = integrate.nve(group=all)
816 # integrator.set_params(limit=0.01)
817 # integrator.set_params(limit=False)
819 def set_params(self
, limit
=None, zero_force
=None):
820 util
.print_status_line();
821 self
.check_initialization();
823 # change the parameters
824 if limit
is not None:
826 self
.cpp_method
.removeLimit();
828 self
.cpp_method
.setLimit(limit
);
830 if zero_force
is not None:
831 self
.cpp_method
.setZeroForce(zero_force
);
833 ## NVT integration via Brownian dynamics
835 # integrate.bdnvt performs constant volume, fixed average temperature simulation based on a
836 # NVE simulation with added damping and stochastic heat bath forces.
838 # The total added %force \f$ \vec{F}\f$ is
839 # \f[ \vec{F} = -\gamma \cdot \vec{v} + \vec{F}_{\mathrm{rand}} \f]
840 # where \f$ \vec{v} \f$ is the particle's velocity and \f$ \vec{F}_{\mathrm{rand}} \f$
841 # is a random force with magnitude chosen via the fluctuation-dissipation theorem
842 # to be consistent with the specified drag (\a gamma) and temperature (\a T).
844 # For poor initial conditions that include overlapping atoms, a
845 # limit can be specified to the movement a particle is allowed to make in one time step.
846 # After a few thousand time steps with the limit set, the system should be in a safe state
847 # to continue with unconstrained integration.
849 # \note With an active limit, Newton's third law is effectively \b not obeyed and the system
850 # can gain linear momentum. Activate the update.zero_momentum updater during the limited bdnvt
851 # run to prevent this.
853 # integrate.bdnvt is an integration method. It must be used in concert with an integration mode. It can be used while
854 # the following modes are active:
855 # - integrate.mode_standard
857 # integrate.bdnvt uses the proper number of degrees of freedom to compute the temperature of the system in both
858 # 2 and 3 dimensional systems, as long as the number of dimensions is set before the integrate.bdnvt command
861 class bdnvt(_integration_method
):
862 ## Specifies the BD NVT integrator
863 # \param group Group of particles on which to apply this method.
864 # \param T Temperature of the simulation (in energy units)
865 # \param seed Random seed to use for the run. Simulations that are identical, except for the seed, will follow
866 # different trajectories.
867 # \param gamma_diam If True, then then gamma for each particle will be assigned to its diameter. If False (the
868 # default), gammas are assigned per particle type via set_gamma().
869 # \param limit (optional) Enforce that no particle moves more than a distance of \a limit in a single time step
870 # \param tally (optional) If true, the energy exchange between the bd thermal reservoir and the particles is
871 # tracked. Total energy conservation can then be monitored by adding
872 # \b bdnvt_reservoir_energy_<i>groupname</i> to the logged quantities.
874 # \a T can be a variant type, allowing for temperature ramps in simulation runs.
876 # Internally, a compute.thermo is automatically specified and associated with \a group.
878 # \warning If starting from a restart binary file, the energy of the reservoir will be reset to zero.
882 # integrate.bdnvt(group=all, T=1.0, seed=5)
883 # integrator = integrate.bdnvt(group=all, T=1.0, seed=100)
884 # integrate.bdnvt(group=all, T=1.0, limit=0.01, gamma_diam=1, tally=True)
885 # typeA = group.type('A');
886 # integrate.bdnvt(group=typeA, T=variant.linear_interp([(0, 4.0), (1e6, 1.0)]))
888 def __init__(self
, group
, T
, seed
=0, gamma_diam
=False, limit
=None, tally
=False):
889 util
.print_status_line();
891 # initialize base class
892 _integration_method
.__init
__(self
);
894 # setup the variant inputs
895 T
= variant
._setup
_variant
_input
(T
);
897 # create the compute thermo
898 compute
._get
_unique
_thermo
(group
=group
);
901 suffix
= '_' + group
.name
;
903 # initialize the reflected c++ class
904 if not globals.exec_conf
.isCUDAEnabled():
905 self
.cpp_method
= hoomd
.TwoStepBDNVT(globals.system_definition
, group
.cpp_group
, T
.cpp_variant
, seed
, gamma_diam
, suffix
);
907 self
.cpp_method
= hoomd
.TwoStepBDNVTGPU(globals.system_definition
, group
.cpp_group
, T
.cpp_variant
, seed
, gamma_diam
, suffix
);
909 self
.cpp_method
.setTally(tally
);
912 if limit
is not None:
913 self
.cpp_method
.setLimit(limit
);
915 self
.cpp_method
.validateGroup()
917 ## Changes parameters of an existing integrator
918 # \param T New temperature (if set) (in energy units)
919 # \param tally (optional) If true, the energy exchange between the bd thermal reservoir and the particles is
920 # tracked. Total energy conservation can then be monitored by adding
921 # \b bdnvt_reservoir_energy_<i>groupname</i> to the logged quantities.
923 # To change the parameters of an existing integrator, you must save it in a variable when it is
924 # specified, like so:
926 # integrator = integrate.bdnvt(group=all, T=1.0)
931 # integrator.set_params(T=2.0)
932 # integrator.set_params(tally=False)
934 def set_params(self
, T
=None, tally
=None):
935 util
.print_status_line();
936 self
.check_initialization();
938 # change the parameters
940 # setup the variant inputs
941 T
= variant
._setup
_variant
_input
(T
);
942 self
.cpp_method
.setT(T
.cpp_variant
);
944 if tally
is not None:
945 self
.cpp_method
.setTally(tally
);
947 ## Sets gamma parameter for a particle type
948 # \param a Particle type
949 # \param gamma \f$ \gamma \f$ for particle type \a (in units of force/velocity)
951 # set_gamma() sets the coefficient \f$ \gamma \f$ for a single particle type, identified
954 # The gamma parameter determines how strongly a particular particle is coupled to
955 # the stochastic bath. The higher the gamma, the more strongly coupled: see
958 # If gamma is not set for any particle type, it will automatically default to 1.0.
959 # It is not an error to specify gammas for particle types that do not exist in the simulation.
960 # This can be useful in defining a single simulation script for many different types of particles
961 # even when some simulations only include a subset.
965 # bd.set_gamma('A', gamma=2.0)
968 def set_gamma(self
, a
, gamma
):
969 util
.print_status_line();
970 self
.check_initialization();
972 ntypes
= globals.system_definition
.getParticleData().getNTypes();
974 for i
in range(0,ntypes
):
975 type_list
.append(globals.system_definition
.getParticleData().getNameByType(i
));
977 # change the parameters
978 for i
in range(0,ntypes
):
979 if a
== type_list
[i
]:
980 self
.cpp_method
.setGamma(i
,gamma
);
983 ## NVE Integration for rigid bodies
985 # integrate.nve_rigid performs constant volume, constant energy simulations on rigid bodies
986 # The integration scheme is implemented from \cite Miller2002 .
988 # Reference \cite Nguyen2011 describes the rigid body implementation details in HOOMD-blue. Cite it
989 # if you utilize rigid body functionality in your work.
991 # integrate.nve_rigid \b only operates on particles that belong to rigid bodies.
993 # integrate.nve_rigid is an integration method. It must be used in concert with an integration mode. It can be used while
994 # the following modes are active:
995 # - integrate.mode_standard
997 class nve_rigid(_integration_method
):
998 ## Specifies the NVE integration method for rigid bodies
999 # \param group Group of particles on which to apply this method.
1003 # rigid = group.rigid()
1004 # integrate.nve_rigid(group=rigid)
1006 def __init__(self
, group
):
1007 util
.print_status_line();
1009 # Error out in MPI simulations
1010 if (hoomd
.is_MPI_available()):
1011 if globals.system_definition
.getParticleData().getDomainDecomposition():
1012 globals.msg
.error("integrate.nve_rigid not supported in multi-processor simulations.\n\n")
1013 raise RuntimeError("Error setting up integration method.")
1015 # initialize base class
1016 _integration_method
.__init
__(self
);
1018 # initialize the reflected c++ class
1019 if not globals.exec_conf
.isCUDAEnabled():
1020 self
.cpp_method
= hoomd
.TwoStepNVERigid(globals.system_definition
, group
.cpp_group
);
1022 self
.cpp_method
= hoomd
.TwoStepNVERigidGPU(globals.system_definition
, group
.cpp_group
);
1024 self
.cpp_method
.validateGroup()
1026 ## NVT Integration for rigid bodies
1028 # integrate.nvt_rigid performs constant volume, constant temperature simulations of the rigid bodies in the system.
1029 # The integration scheme is implemented from \cite Miller2002 and \cite Kamberaj2005 .
1031 # Reference \cite Nguyen2011 describes the rigid body implementation details in HOOMD-blue. Cite it
1032 # if you utilize rigid body functionality in your work.
1034 # integrate.nvt_rigid \b only operates on particles that belong to rigid bodies.
1036 # integrate.nvt_rigid is an integration method. It must be used in concert with an integration mode. It can be used while
1037 # the following modes are active:
1038 # - integrate.mode_standard
1039 # \MPI_NOT_SUPPORTED
1040 class nvt_rigid(_integration_method
):
1041 ## Specifies the NVT integration method for rigid bodies
1042 # \param group Group of particles on which to apply this method.
1043 # \param T Temperature set point for the thermostat (in energy units)
1044 # \param tau Time constant for the thermostat (in time units)
1046 # \a T can be a variant type, allowing for temperature ramps in simulation runs.
1050 # rigid = group.rigid()
1051 # integrate.nvt_rigid(group=all, T=1.0, tau=10.0)
1052 # integrator = integrate.nvt_rigid(group=all, tau=5.0, T=1.0)
1054 def __init__(self
, group
, T
, tau
):
1055 util
.print_status_line();
1057 # Error out in MPI simulations
1058 if (hoomd
.is_MPI_available()):
1059 if globals.system_definition
.getParticleData().getDomainDecomposition():
1060 globals.msg
.error("integrate.nvt_rigid not supported in multi-processor simulations.\n\n")
1061 raise RuntimeError("Error setting up integration method.")
1063 # initialize base class
1064 _integration_method
.__init
__(self
);
1066 # setup the variant inputs
1067 T
= variant
._setup
_variant
_input
(T
);
1069 # create the compute thermo
1070 thermo
= compute
._get
_unique
_thermo
(group
=group
);
1073 suffix
= '_' + group
.name
;
1075 # initialize the reflected c++ class
1076 if not globals.exec_conf
.isCUDAEnabled():
1077 self
.cpp_method
= hoomd
.TwoStepNVTRigid(globals.system_definition
, group
.cpp_group
, thermo
.cpp_compute
, T
.cpp_variant
, tau
, suffix
);
1079 self
.cpp_method
= hoomd
.TwoStepNVTRigidGPU(globals.system_definition
, group
.cpp_group
, thermo
.cpp_compute
, T
.cpp_variant
, tau
, suffix
);
1081 self
.cpp_method
.validateGroup()
1083 ## Changes parameters of an existing integrator
1084 # \param T New temperature (if set) (in energy units)
1085 # \param tau New coupling constant (if set) (in time units)
1087 # To change the parameters of an existing integrator, you must save it in a variable when it is
1088 # specified, like so:
1090 # integrator = integrate.nvt_rigid(group=rigid, T=0.65)
1095 # integrator.set_params(T=2.0, tau=10.0)
1097 def set_params(self
, T
=None, tau
=None):
1098 util
.print_status_line();
1099 self
.check_initialization();
1101 # change the parameters
1103 # setup the variant inputs
1104 T
= variant
._setup
_variant
_input
(T
);
1105 self
.cpp_method
.setT(T
.cpp_variant
);
1107 self
.cpp_method
.setTau(tau
);
1109 ## NVT integration via Brownian dynamics for rigid bodies
1111 # integrate.bdnvt_rigid performs constant volume, constant temperature simulation based on a
1112 # NVE simulation with added damping and stochastic heat bath forces. The NVE integration scheme
1113 # is implemented from ref \cite Miller2002.
1115 # Reference \cite Nguyen2011 describes the rigid body implementation details in HOOMD-blue. Cite it
1116 # if you utilize rigid body functionality in your work.
1118 # The total added %force \f$ \vec{F}\f$ <strong>applied to each constiuent particle</strong> is
1119 # \f[ \vec{F} = -\gamma \cdot \vec{v} + \vec{F}_{\mathrm{rand}} \f]
1120 # where \f$ \vec{v} \f$ is the particle's velocity and \f$ \vec{F}_{\mathrm{rand}} \f$
1121 # is a random force with magnitude chosen via the fluctuation-dissipation theorem
1122 # to be consistent with the specified drag (\a gamma) and temperature (\a T).
1124 # integrate.bdnvt_rigid \b only operates on particles that belong to rigid bodies.
1126 # integrate.bdnvt_rigid is an integration method. It must be used in concert with an integration mode. It can be used while
1127 # the following modes are active:
1128 # - integrate.mode_standard
1129 # \MPI_NOT_SUPPORTED
1130 class bdnvt_rigid(_integration_method
):
1131 ## Specifies the BD NVT integrator for rigid bodies
1132 # \param group Group of particles on which to apply this method.
1133 # \param T Temperature of the simulation \a T (in energy units)
1134 # \param seed Random seed to use for the run. Simulations that are identical, except for the seed, will follow
1135 # different trajectories.
1136 # \param gamma_diam If True, then then gamma for each particle will be assigned to its diameter. If False (the
1137 # default), gammas are assigned per particle type via set_gamma().
1139 # \a T can be a variant type, allowing for temperature ramps in simulation runs.
1143 # rigid = group.rigid();
1144 # integrate.bdnvt_rigid(group=rigid, T=1.0, seed=5)
1145 # integrator = integrate.bdnvt_rigid(group=all, T=1.0, seed=100)
1146 # integrate.bdnvt_rigid(group=all, T=1.0, gamma_diam=True)
1148 def __init__(self
, group
, T
, seed
=0, gamma_diam
=False):
1149 util
.print_status_line();
1151 # Error out in MPI simulations
1152 if (hoomd
.is_MPI_available()):
1153 if globals.system_definition
.getParticleData().getDomainDecomposition():
1154 globals.msg
.error("integrate.bdnvt_rigid not supported in multi-processor simulations.\n\n")
1155 raise RuntimeError("Error setting up integration method.")
1157 # initialize base class
1158 _integration_method
.__init
__(self
);
1160 # setup the variant inputs
1161 T
= variant
._setup
_variant
_input
(T
);
1163 # initialize the reflected c++ class
1164 if not globals.exec_conf
.isCUDAEnabled():
1165 self
.cpp_method
= hoomd
.TwoStepBDNVTRigid(globals.system_definition
, group
.cpp_group
, T
.cpp_variant
, seed
, gamma_diam
);
1167 self
.cpp_method
= hoomd
.TwoStepBDNVTRigidGPU(globals.system_definition
, group
.cpp_group
, T
.cpp_variant
, seed
, gamma_diam
);
1169 self
.cpp_method
.validateGroup()
1171 ## Changes parameters of an existing integrator
1172 # \param T New temperature (if set) (in energy units)
1174 # To change the parameters of an existing integrator, you must save it in a variable when it is
1175 # specified, like so:
1177 # integrator = integrate.bdnvt_rigid(group=rigid, T=1.0)
1182 # integrator.set_params(T=2.0)
1184 def set_params(self
, T
=None):
1185 util
.print_status_line();
1186 self
.check_initialization();
1188 # change the parameters
1190 # setup the variant inputs
1191 T
= variant
._setup
_variant
_input
(T
);
1192 self
.cpp_method
.setT(T
.cpp_variant
);
1194 ## Sets gamma parameter for a particle type
1195 # \param a Particle type
1196 # \param gamma \f$ \gamma \f$ for particle type (see below for examples) (in units of force/velocity)
1198 # set_gamma() sets the coefficient \f$ \gamma \f$ for a single particle type, identified
1201 # The gamma parameter determines how strongly a particular particle is coupled to
1202 # the stochastic bath. The higher the gamma, the more strongly coupled: see
1203 # integrate.bdnvt_rigid.
1205 # If gamma is not set for any particle type, it will automatically default to 1.0.
1206 # It is not an error to specify gammas for particle types that do not exist in the simulation.
1207 # This can be useful in defining a single simulation script for many different types of particles
1208 # even when some simulations only include a subset.
1212 # bd.set_gamma('A', gamma=2.0)
1215 def set_gamma(self
, a
, gamma
):
1216 util
.print_status_line();
1217 self
.check_initialization();
1219 ntypes
= globals.system_definition
.getParticleData().getNTypes();
1221 for i
in range(0,ntypes
):
1222 type_list
.append(globals.system_definition
.getParticleData().getNameByType(i
));
1224 # change the parameters
1225 for i
in range(0,ntypes
):
1226 if a
== type_list
[i
]:
1227 self
.cpp_method
.setGamma(i
,gamma
);
1229 ## NPT Integration for rigid bodies
1231 # integrate.npt_rigid performs constant pressure, constant temperature simulations of the rigid bodies in the system.
1232 # The integration scheme is implemented from \cite Miller2002 and \cite Kamberaj2005 .
1234 # Reference \cite Nguyen2011 describes the rigid body implementation details in HOOMD-blue. Cite it
1235 # if you utilize rigid body functionality in your work.
1237 # integrate.npt_rigid \b only operates on particles that belong to rigid bodies.
1239 # integrate.npt_rigid is an integration method. It must be used in concert with an integration mode. It can be used while
1240 # the following modes are active:
1241 # - integrate.mode_standard
1242 # \MPI_NOT_SUPPORTED
1243 class npt_rigid(_integration_method
):
1244 ## Specifies the NVT integration method for rigid bodies
1245 # \param group Group of particles on which to apply this method.
1246 # \param tau Time constant for the thermostat (in time units)
1247 # \param tauP Time constatnt for the barostat (in time units)
1248 # \param T Temperature set point for the thermostat (in energy units)
1249 # \param P Pressure set point for the barostat (in pressure units)
1251 # \a T (and P) can be a variant type, allowing for temperature (and pressure) ramps in simulation runs.
1255 # rigid = group.rigid()
1256 # integrate.npt_rigid(group=all, T=1.0, tau=10.0, P=1.0, tauP=1.0)
1259 def __init__(self
, group
, T
, tau
, P
, tauP
):
1260 util
.print_status_line();
1262 # Error out in MPI simulations
1263 if (hoomd
.is_MPI_available()):
1264 if globals.system_definition
.getParticleData().getDomainDecomposition():
1265 globals.msg
.error("integrate.npt_rigid not supported in multi-processor simulations.\n\n")
1266 raise RuntimeError("Error setting up integration method.")
1268 # initialize base class
1269 _integration_method
.__init
__(self
);
1271 # setup the variant inputs
1272 T
= variant
._setup
_variant
_input
(T
);
1273 P
= variant
._setup
_variant
_input
(P
);
1275 # create the compute thermo
1276 thermo_group
= compute
._get
_unique
_thermo
(group
=group
);
1277 thermo_all
= compute
._get
_unique
_thermo
(group
=globals.group_all
);
1279 # initialize the reflected c++ class
1280 if not globals.exec_conf
.isCUDAEnabled():
1281 self
.cpp_method
= hoomd
.TwoStepNPTRigid(globals.system_definition
, group
.cpp_group
, thermo_group
.cpp_compute
, thermo_all
.cpp_compute
, tau
, tauP
, T
.cpp_variant
, P
.cpp_variant
);
1283 self
.cpp_method
= hoomd
.TwoStepNPTRigidGPU(globals.system_definition
, group
.cpp_group
, thermo_group
.cpp_compute
, thermo_all
.cpp_compute
, tau
, tauP
, T
.cpp_variant
, P
.cpp_variant
);
1285 self
.cpp_method
.validateGroup()
1287 ## Changes parameters of an existing integrator
1288 # \param T New temperature (if set) (in energy units)
1289 # \param tau New coupling constant (if set) (in time units)
1290 # \param P New pressure (if set) (in pressure units)
1291 # \param tauP New coupling constant (if set) (in time units)
1293 # To change the parameters of an existing integrator, you must save it in a variable when it is
1294 # specified, like so:
1296 # integrator = integrate.npt_rigid(group=rigid, T=0.65, P=1.0)
1301 # integrator.set_params(T=2.0, tau=10.0, P=1.5)
1303 def set_params(self
, T
=None, tau
=None, P
=None, tauP
=None):
1304 util
.print_status_line();
1305 self
.check_initialization();
1307 # change the parameters
1309 # setup the variant inputs
1310 T
= variant
._setup
_variant
_input
(T
);
1311 self
.cpp_method
.setT(T
.cpp_variant
);
1313 self
.cpp_method
.setTau(tau
);
1315 # setup the variant inputs
1316 P
= variant
._setup
_variant
_input
(P
);
1317 self
.cpp_method
.setP(P
.cpp_variant
);
1318 if tauP
is not None:
1319 self
.cpp_method
.setTauP(tauP
);
1321 ## NPH Integration for rigid bodies
1323 # integrate.nph_rigid performs constant pressure, constant enthalpy simulations of the rigid bodies in the system.
1324 # The integration scheme is implemented from \cite Miller2002 and \cite Kamberaj2005 .
1326 # Reference \cite Nguyen2011 describes the rigid body implementation details in HOOMD-blue. Cite it
1327 # if you utilize rigid body functionality in your work.
1329 # integrate.nph_rigid \b only operates on particles that belong to rigid bodies.
1331 # integrate.nph_rigid is an integration method. It must be used in concert with an integration mode. It can be used while
1332 # the following modes are active:
1333 # - integrate.mode_standard
1334 # \MPI_NOT_SUPPORTED
1335 class nph_rigid(_integration_method
):
1336 ## Specifies the NPH integration method for rigid bodies
1337 # \param group Group of particles on which to apply this method.
1338 # \param tauP Time constatnt for the barostat (in time units)
1339 # \param P Pressure set point for the barostat (in pressure units)
1341 # \a P can be a variant type, allowing for pressure ramping in simulation runs.
1345 # rigid = group.rigid()
1346 # integrate.nph_rigid(group=all, P=1.0, tauP=1.0)
1349 def __init__(self
, group
, P
, tauP
):
1350 util
.print_status_line();
1352 # Error out in MPI simulations
1353 if (hoomd
.is_MPI_available()):
1354 if globals.system_definition
.getParticleData().getDomainDecomposition():
1355 globals.msg
.error("integrate.nph_rigid is not supported in multi-processor simulations.\n\n")
1356 raise RuntimeError("Error setting up integration method.")
1358 # initialize base class
1359 _integration_method
.__init
__(self
);
1361 # setup the variant inputs
1362 P
= variant
._setup
_variant
_input
(P
);
1364 # create the compute thermo
1365 thermo_group
= compute
._get
_unique
_thermo
(group
=group
);
1366 thermo_all
= compute
._get
_unique
_thermo
(group
=globals.group_all
);
1368 # initialize the reflected c++ class
1369 if not globals.exec_conf
.isCUDAEnabled():
1370 self
.cpp_method
= hoomd
.TwoStepNPHRigid(globals.system_definition
, group
.cpp_group
, thermo_group
.cpp_compute
, thermo_all
.cpp_compute
, tauP
, P
.cpp_variant
);
1372 self
.cpp_method
= hoomd
.TwoStepNPHRigidGPU(globals.system_definition
, group
.cpp_group
, thermo_group
.cpp_compute
, thermo_all
.cpp_compute
, tauP
, P
.cpp_variant
);
1374 self
.cpp_method
.validateGroup()
1376 ## Changes parameters of an existing integrator
1377 # \param P New pressure (if set) (in pressure units)
1378 # \param tauP New coupling constant (if set) (in time units)
1380 # To change the parameters of an existing integrator, you must save it in a variable when it is
1381 # specified, like so:
1383 # integrator = integrate.nph_rigid(group=rigid, P=1.0)
1388 # integrator.set_params(P=1.5, tauP=1.0)
1390 def set_params(self
, P
=None, tauP
=None):
1391 util
.print_status_line();
1392 self
.check_initialization();
1394 # change the parameters
1396 # setup the variant inputs
1397 P
= variant
._setup
_variant
_input
(P
);
1398 self
.cpp_method
.setP(P
.cpp_variant
);
1399 if tauP
is not None:
1400 self
.cpp_method
.setTauP(tauP
);
1402 ## Energy Minimizer (FIRE)
1404 # integrate.mode_minimize_fire uses the Fast Inertial Relaxation Engine (FIRE) algorithm to minimize the energy
1405 # for a group of particles while keeping all other particles fixed. This method is published in
1406 # Bitzek, et al, PRL, 2006.
1408 # At each time step,\f$\Delta t \f$, the algorithm uses the NVE Integrator to generate a x, v, and F, and then adjusts
1409 # v according to \f[ \vec{v} = (1-\alpha)\vec{v} + \alpha \hat{F}|\vec{v}| \f] where \f$ \alpha \f$ and \f$\Delta t \f$
1410 # are dynamically adaptive quantities. While a current search has been lowering the energy of system for more than
1411 # \f$N_{min}\f$ steps, \f$ \alpha \f$ is decreased by \f$ \alpha \rightarrow \alpha f_{alpha} \f$ and
1412 # \f$\Delta t \f$ is increased by \f$ \Delta t \rightarrow max(\Delta t * f_{inc}, \Delta t_{max}) \f$.
1413 # If the energy of the system increases (or stays the same), the velocity of the particles is set to 0,
1414 # \f$ \alpha \rightarrow \alpha_{start}\f$ and
1415 # \f$ \Delta t \rightarrow \Delta t * f_{dec} \f$. Convergence is determined by both the force per particle or the
1416 # change in energy per particle dropping below \a ftol and \a Etol, respectively or,
1418 # \f[ \frac{\sum |F|}{N*\sqrt{N_{dof}}} <ftol \;\; and \;\; \Delta \frac{\sum |E|}{N} < Etol \f]
1419 # where N is the number of particles the minimization is acting over (i.e. the group size). Either of the two criterion can be effectively turned off by setting the tolerance to a large number.
1421 # If the minimization is acted over a subset of all the particles in the system, the "other" particles will be kept
1422 # frozen but will still interact with the particles being moved.
1426 # fire=integrate.mode_minimize_fire( group=group.all(), dt=0.05, ftol=1e-2, Etol=1e-7)
1427 # while not(fire.has_converged()):
1428 # xml = dump.xml(filename="dump",period=1)
1432 # \note As a default setting, the algorithm will start with a \f$ \Delta t = \frac{1}{10} \Delta t_{max} \f$ and
1433 # attempts at least 10 search steps. In practice, it was found that this prevents the simulation from making too
1434 # aggressive a first step, but also from quitting before having found a good search direction. The minimum number of
1435 # attempts can be set by the user.
1437 # \warning All other integration methods must be disabled before using the FIRE energy minimizer.
1438 # \MPI_NOT_SUPPORTED
1439 class mode_minimize_fire(_integrator
):
1440 ## Specifies the FIRE energy minimizer.
1441 # \param group Particle group to be applied FIRE
1442 # \param group Group of particles on which to apply this method.
1443 # \param dt This is the maximum step size the minimizer is permitted to use. Consider the stability of the system when setting. (in time units)
1444 # \param Nmin Number of steps energy change is negative before allowing \f$ \alpha \f$ and \f$ \Delta t \f$ to adapt.
1445 # - <i>optional</i>: defaults to 5
1446 # \param finc Factor to increase \f$ \Delta t \f$ by
1447 # - <i>optional</i>: defaults to 1.1
1448 # \param fdec Factor to decrease \f$ \Delta t \f$ by
1449 # - <i>optional</i>: defaults to 0.5
1450 # \param alpha_start Initial (and maximum) \f$ \alpha \f$
1451 # - <i>optional</i>: defaults to 0.1
1452 # \param falpha Factor to decrease \f$ \alpha t \f$ by
1453 # - <i>optional</i>: defaults to 0.99
1454 # \param ftol force convergence criteria (in force units)
1455 # - <i>optional</i>: defaults to 1e-1
1456 # \param Etol energy convergence criteria (in energy units)
1457 # - <i>optional</i>: defaults to 1e-5
1458 # \param min_steps A minimum number of attempts before convergence criteria are considered
1459 # - <i>optional</i>: defaults to 10
1460 def __init__(self
, group
, dt
, Nmin
=None, finc
=None, fdec
=None, alpha_start
=None, falpha
=None, ftol
= None, Etol
= None, min_steps
=None):
1461 util
.print_status_line();
1463 # Error out in MPI simulations
1464 if (hoomd
.is_MPI_available()):
1465 if globals.system_definition
.getParticleData().getDomainDecomposition():
1466 globals.msg
.error("mode_minimize_fire is not supported in multi-processor simulations.\n\n")
1467 raise RuntimeError("Error setting up integration mode.")
1469 # initialize base class
1470 _integrator
.__init
__(self
);
1472 # initialize the reflected c++ class
1473 if not globals.exec_conf
.isCUDAEnabled():
1474 self
.cpp_integrator
= hoomd
.FIREEnergyMinimizer(globals.system_definition
, group
.cpp_group
, dt
);
1476 self
.cpp_integrator
= hoomd
.FIREEnergyMinimizerGPU(globals.system_definition
, group
.cpp_group
, dt
);
1478 self
.supports_methods
= False;
1480 globals.system
.setIntegrator(self
.cpp_integrator
);
1482 # change the set parameters if not None
1483 if not(Nmin
is None):
1484 self
.cpp_integrator
.setNmin(Nmin
);
1485 if not(finc
is None):
1486 self
.cpp_integrator
.setFinc(finc
);
1487 if not(fdec
is None):
1488 self
.cpp_integrator
.setFdec(fdec
);
1489 if not(alpha_start
is None):
1490 self
.cpp_integrator
.setAlphaStart(alpha_start
);
1491 if not(falpha
is None):
1492 self
.cpp_integrator
.setFalpha(falpha
);
1493 if not(ftol
is None):
1494 self
.cpp_integrator
.setFtol(ftol
);
1495 if not(Etol
is None):
1496 self
.cpp_integrator
.setEtol(Etol
);
1497 if not(min_steps
is None):
1498 self
.cpp_integrator
.setMinSteps(min_steps
);
1500 ## Asks if Energy Minimizer has converged
1502 def has_converged(self
):
1503 self
.check_initialization();
1504 return self
.cpp_integrator
.hasConverged()
1506 ## Energy Minimizer RIGID (FIRE)
1508 # integrate.energyminimizer_FIRE uses the Fast Inertial Relaxation Engine (FIRE) algorithm to minimize the energy
1509 # for a group of particles while keeping all other particles fixed.
1511 # For the time being, energy minimization will be handled separately for rigid and non-rigid bodies
1513 # \MPI_NOT_SUPPORTED
1514 class mode_minimize_rigid_fire(_integrator
):
1515 ## Specifies the FIRE energy minimizer.
1517 # \param group Group of particles in rigid bodies
1518 # \param dt This is the maximum timestep the minimizer is permitted to use. Consider the stability of the system when setting. (in time units)
1519 # \param Nmin Number of steps energy change is negative before allowing \f$ \alpha \f$ and \f$ \Delta t \f$ to adapt.
1520 # - <i>optional</i>: defaults to 5
1521 # \param finc Factor to increase \f$ \Delta t \f$ by
1522 # - <i>optional</i>: defaults to 1.1
1523 # \param fdec Factor to decrease \f$ \Delta t \f$ by
1524 # - <i>optional</i>: defaults to 0.5
1525 # \param alpha_start Initial (and maximum) \f$ \alpha \f$
1526 # - <i>optional</i>: defaults to 0.1
1527 # \param falpha Factor to decrease \f$ \alpha t \f$ by
1528 # - <i>optional</i>: defaults to 0.99
1529 # \param ftol force convergence criteria
1530 # - <i>optional</i>: defaults to 1e-1
1531 # \param wtol torque convergence criteria
1532 # - <i>optional</i>: defaults to 1e-1
1533 # \param Etol energy convergence criteria
1534 # - <i>optional</i>: defaults to 1e-5
1535 def __init__(self
, group
, dt
, Nmin
=None, finc
=None, fdec
=None, alpha_start
=None, falpha
=None, ftol
= None, wtol
=None, Etol
= None):
1536 util
.print_status_line();
1538 # initialize base class
1539 _integrator
.__init
__(self
);
1541 # initialize the reflected c++ class
1542 if not globals.exec_conf
.isCUDAEnabled():
1543 self
.cpp_integrator
= hoomd
.FIREEnergyMinimizerRigid(globals.system_definition
, group
.cpp_group
, dt
);
1545 self
.cpp_integrator
= hoomd
.FIREEnergyMinimizerRigidGPU(globals.system_definition
, group
.cpp_group
, dt
);
1547 self
.supports_methods
= False;
1549 globals.system
.setIntegrator(self
.cpp_integrator
);
1551 # change the set parameters if not None
1552 if not(Nmin
is None):
1553 self
.cpp_integrator
.setNmin(Nmin
);
1554 if not(finc
is None):
1555 self
.cpp_integrator
.setFinc(finc
);
1556 if not(fdec
is None):
1557 self
.cpp_integrator
.setFdec(fdec
);
1558 if not(alpha_start
is None):
1559 self
.cpp_integrator
.setAlphaStart(alpha_start
);
1560 if not(falpha
is None):
1561 self
.cpp_integrator
.setFalpha(falpha
);
1562 if not(ftol
is None):
1563 self
.cpp_integrator
.setFtol(ftol
);
1564 if not(wtol
is None):
1565 self
.cpp_integrator
.setWtol(wtol
);
1566 if not(Etol
is None):
1567 self
.cpp_integrator
.setEtol(Etol
);
1569 ## Asks if Energy Minimizer has converged
1571 def has_converged(self
):
1572 self
.check_initialization();
1573 return self
.cpp_integrator
.hasConverged()
1575 ## Applies the Berendsen thermostat.
1577 # integrate.berendsen rescales the velocities of all particles on each time step. The rescaling is performed so that
1578 # the difference in the current temperature from the set point decays exponentially \cite Berendsen1984
1580 # \frac{dT_\mathrm{cur}}{dt} = \frac{T - T_\mathrm{cur}}{\tau}
1583 # \MPI_NOT_SUPPORTED
1584 class berendsen(_integration_method
):
1585 ## Initialize the Berendsen thermostat.
1586 # \param group Group to which the Berendsen thermostat will be applied.
1587 # \param T Temperature of thermostat. (in energy units)
1588 # \param tau Time constant of thermostat. (in time units)
1590 def __init__(self
, group
, T
, tau
):
1591 util
.print_status_line();
1593 # Error out in MPI simulations
1594 if (hoomd
.is_MPI_available()):
1595 if globals.system_definition
.getParticleData().getDomainDecomposition():
1596 globals.msg
.error("integrate.berendsen is not supported in multi-processor simulations.\n\n")
1597 raise RuntimeError("Error setting up integration method.")
1599 # initialize base class
1600 _integration_method
.__init
__(self
);
1602 # setup the variant inputs
1603 T
= variant
._setup
_variant
_input
(T
);
1605 # create the compute thermo
1606 thermo
= compute
._get
_unique
_thermo
(group
= group
);
1608 # initialize the reflected c++ class
1609 if not globals.exec_conf
.isCUDAEnabled():
1610 self
.cpp_method
= hoomd
.TwoStepBerendsen(globals.system_definition
,
1616 self
.cpp_method
= hoomd
.TwoStepBerendsenGPU(globals.system_definition
,