Update MTK documentation
[hoomd-blue.git] / python-module / hoomd_script / variant.py
blob3a6a323b6110f54fdcc311bee14657c46f310339
1 # -- start license --
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
32 # permission.
34 # Disclaimer
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.
48 # -- end license --
50 # Maintainer: joaander / All Developers are free to add commands for new features
52 import hoomd;
53 from hoomd_script import globals;
54 import sys;
55 from hoomd_script import init;
57 ## \package hoomd_script.variant
58 # \brief Commands for specifying values that vary over time
60 # This package contains various commands for creating quantities that can vary
61 # smoothly over the course of a simulation. For example, the temperature in
62 # update.nvt can be set to a variant.linear_interp in order to slowly heat
63 # or cool the system over a long simulation.
65 ## \internal
66 # \brief Base class for variant type
68 # _variant should not be used directly in code, it only serves as a base class
69 # for the other variant types.
70 class _variant:
71 ## Does common initialization for all variants
73 def __init__(self):
74 # check if initialization has occurred
75 if not init.is_initialized():
76 globals.msg.error("Cannot create a variant before initialization\n");
77 raise RuntimeError('Error creating variant');
79 self.cpp_variant = None;
81 ## \internal
82 # \brief A constant "variant"
84 # This is just a placeholder for a constant value. It does not need to be documented
85 # as all hoomd_script commands that take in variants should use _setup_variant_input()
86 # which will allow a simple constant number to be passed in and automatically converted
87 # to variant.constant for use in setting up whatever code uses the variant.
88 class _constant(_variant):
89 ## Specify a %constant %variant
91 # \param val Value of the variant
93 def __init__(self, val):
94 # initialize the base class
95 _variant.__init__(self);
97 # create the c++ mirror class
98 self.cpp_variant = hoomd.VariantConst(val);
99 self.cpp_variant.setOffset(globals.system.getCurrentTimeStep());
101 ## Linearly interpolated variant
103 # variant.linear_interp creates a time-varying quantity where the value at each time step
104 # is determined by linear interpolation between a given set of points.
106 # At time steps before the
107 # initial point, the value is identical to the value at the first given point. At time steps
108 # after the final point, the value is identical to the value at the last given point. All points
109 # between are determined by linear interpolation.
111 # By default, a time step for a given point is referenced to the current time step of the simulation.
112 # For example,
113 # \code
114 # init.create_random(N=1000, phi_p=0.2)
115 # ...
116 # run(1000)
117 # variant.linear_interp(...)
118 # run(1000)
119 # \endcode
120 # A value specified at time 0 in the shown linear_interp is set at the actual \b absolute time step
121 # 1000. To say it another way, time for validate.linear_interp starts counting from 0 right
122 # at the time of creation. The point where 0 is defined can be changed by setting the \z zero parameter in the
123 # command that specifies the linear_interp.
125 # See __init__() for the syntax which the set values can be specified.
126 class linear_interp(_variant):
127 ## Specify a linearly interpolated %variant
129 # \param points Set points in the linear interpolation (see below)
130 # \param zero Specify absolute time step number location for 0 in \a points. Use 'now' to indicate the current step.
132 # \a points is a list of (time, set value) tuples. For example, to specify
133 # a series of points that goes from 10 at time step 0 to 20 at time step 100 and then
134 # back down to 5 at time step 200:
135 # \code
136 # points = [(0, 10), (100, 20), (200, 5)]
137 # \endcode
138 # Any number of points can be specified in any order. However, listing them
139 # monotonically increasing in time will result in a much more human readable set
140 # of values.
142 # \b Examples:
143 # \code
144 # L = variant.linear_interp(points = [(0, 10), (100, 20), (200, 5)])
145 # V = variant.linear_interp(points = [(0, 10), (1e6, 20)], zero=80000)
146 # integrate.nvt(group=all, tau = 0.5,
147 # T = variant.linear_interp(points = [(0, 1.0), (1e5, 2.0)])
148 # \endcode
149 def __init__(self, points, zero='now'):
150 # initialize the base class
151 _variant.__init__(self);
153 # create the c++ mirror class
154 self.cpp_variant = hoomd.VariantLinear();
155 if zero == 'now':
156 self.cpp_variant.setOffset(globals.system.getCurrentTimeStep());
157 else:
158 # validate zero
159 if zero < 0:
160 globals.msg.error("Cannot create a linear_interp variant with a negative zero\n");
161 raise RuntimeError('Error creating variant');
162 if zero > globals.system.getCurrentTimeStep():
163 globals.msg.error("Cannot create a linear_interp variant with a zero in the future\n");
164 raise RuntimeError('Error creating variant');
166 self.cpp_variant.setOffset(zero);
168 # set the points
169 if len(points) == 0:
170 globals.msg.error("Cannot create a linear_interp variant with 0 points\n");
171 raise RuntimeError('Error creating variant');
173 for (t, v) in points:
174 if t < 0:
175 globals.msg.error("Negative times are not allowed in variant.linear_interp\n");
176 raise RuntimeError('Error creating variant');
178 self.cpp_variant.setPoint(int(t), v);
181 ## \internal
182 # \brief Internal helper function to aid in setting up variants
184 # For backwards compatibility and convenience, anything that takes in a Variant should
185 # also automatically take in a constant number. This method will take the values passed
186 # in by the user and turn it into a variant._constant if it is a number. Otherwise,
187 # it will return the variant unchanged.
188 def _setup_variant_input(v):
189 if isinstance(v, _variant):
190 return v;
191 else:
192 try:
193 return _constant(float(v));
194 except ValueError:
195 globals.msg.error("Value must either be a scalar value or a the result of a variant command\n");
196 raise RuntimeError('Error creating variant');