1 """Contains the class that deals with the running of the simulation and
2 outputting the results.
4 Copyright (C) 2013, Joshua More and Michele Ceriotti
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http.//www.gnu.org/licenses/>.
20 The root class for the whole simulation. Contains references to all the top
21 level objects used in the simulation, and controls all the steps that are
22 not inherently system dependent, like the running of each time step,
23 choosing which properties to initialise, and which properties to output.
26 Simulation: Deals with running the simulation and outputting the results.
29 __all__
= ['Simulation']
32 import os
.path
, sys
, time
33 from ipi
.utils
.depend
import *
34 from ipi
.utils
.units
import *
35 from ipi
.utils
.prng
import *
36 from ipi
.utils
.io
import *
37 from ipi
.utils
.io
.io_xml
import *
38 from ipi
.utils
.messages
import verbosity
, info
39 from ipi
.utils
.softexit
import softexit
40 from ipi
.engine
.atoms
import *
41 from ipi
.engine
.cell
import *
42 from ipi
.engine
.forces
import Forces
43 from ipi
.engine
.beads
import Beads
44 from ipi
.engine
.normalmodes
import NormalModes
45 from ipi
.engine
.properties
import Properties
, Trajectories
46 from ipi
.engine
.outputs
import CheckpointOutput
48 class Simulation(dobject
):
49 """Main simulation object.
51 Contains all the references and the main dynamics loop. Also handles the
52 initialisation and output.
55 beads: A beads object giving the atom positions.
56 cell: A cell object giving the system box.
57 prng: A random number generator object.
58 flist: A list of forcefield objects giving different ways to partially
60 forces: A Forces object for calculating the total force for all the
62 ensemble: An ensemble object giving the objects necessary for producing
64 tsteps: The total number of steps.
65 ttime: The wall clock time (in seconds).
66 format: A string specifying both the format and the extension of traj
68 outputs: A list of output objects that should be printed during the run
69 nm: A helper object dealing with normal modes transformation
70 properties: A property object for dealing with property output.
71 trajs: A trajectory object for dealing with trajectory output.
72 chk: A checkpoint object for dealing with checkpoint output.
73 rollback: If set to true, the state of the simulation at the start
74 of the step will be output to a restart file rather than
75 the current state of the simulation. This is because we cannot
76 restart from half way through a step, only from the beginning of a
77 step, so this is necessary for the trajectory to be continuous.
80 step: The current simulation step.
83 def __init__(self
, beads
, cell
, forces
, ensemble
, prng
, outputs
, nm
, init
, step
=0, tsteps
=1000, ttime
=0):
84 """Initialises Simulation class.
87 beads: A beads object giving the atom positions.
88 cell: A cell object giving the system box.
89 forces: A forcefield object giving the force calculator for each
90 replica of the system.
91 ensemble: An ensemble object giving the objects necessary for
92 producing the correct ensemble.
93 prng: A random number object.
94 outputs: A list of output objects.
95 nm: A class dealing with path NM operations.
96 init: A class to deal with initializing the simulation object.
97 step: An optional integer giving the current simulation time step.
99 tsteps: An optional integer giving the total number of steps. Defaults
101 ttime: The simulation running time. Used on restart, to keep a
105 info(" # Initializing simulation object ", verbosity
.low
)
107 self
.ensemble
= ensemble
112 # initialize the configuration of the system
114 init
.init_stage1(self
)
117 self
.forces
= Forces()
118 self
.outputs
= outputs
120 dset(self
, "step", depend_value(name
="step", value
=step
))
124 self
.properties
= Properties()
125 self
.trajs
= Trajectories()
130 """Calls the bind routines for all the objects in the simulation."""
132 # binds important computation engines
133 self
.nm
.bind(self
.beads
, self
.ensemble
)
134 self
.forces
.bind(self
.beads
, self
.cell
, self
.flist
)
135 self
.ensemble
.bind(self
.beads
, self
.nm
, self
.cell
, self
.forces
, self
.prng
)
136 self
.init
.init_stage2(self
)
138 # binds output management objects
139 self
.properties
.bind(self
)
140 self
.trajs
.bind(self
)
141 for o
in self
.outputs
:
144 self
.chk
= CheckpointOutput("RESTART", 1, True, 0)
147 # registers the softexit routine
148 softexit
.register(self
.softexit
)
151 """Deals with a soft exit request.
153 Tries to ensure that a consistent restart checkpoint is
157 if self
.step
< self
.tsteps
:
159 if not self
.rollback
:
161 self
.chk
.write(store
=False)
166 """Runs the simulation.
168 Does all the simulation steps, and outputs data to the appropriate files
169 when necessary. Also deals with starting and cleaning up the threads used
170 in the communication between the driver and the PIMD code.
175 # prints inital configuration -- only if we are not restarting
178 for o
in self
.outputs
:
183 simtime
= time
.time()
191 for self
.step
in range(self
.step
,self
.tsteps
):
192 # stores the state before doing a step.
193 # this is a bit time-consuming but makes sure that we can honor soft
194 # exit requests without screwing the trajectory
196 steptime
= -time
.time()
201 for o
in self
.outputs
:
204 if os
.path
.exists("EXIT"): # soft-exit
205 self
.rollback
= False
208 steptime
+= time
.time()
210 tptime
+= self
.ensemble
.ptime
211 tqtime
+= self
.ensemble
.qtime
212 tttime
+= self
.ensemble
.ttime
215 if verbosity
.high
or (verbosity
.medium
and self
.step
%100 == 0) or (verbosity
.low
and self
.step
%1000 == 0):
216 info(" # Average timings at MD step % 7d. t/step: %10.5e [p: %10.5e q: %10.5e t: %10.5e]" %
217 ( self
.step
, ttot
/cstep
, tptime
/cstep
, tqtime
/cstep
, tttime
/cstep
) )
223 info(" # MD diagnostics: V: %10.5e Kcv: %10.5e Ecns: %10.5e" %
224 (self
.properties
["potential"], self
.properties
["kinetic_cv"], self
.properties
["conserved"] ) )
226 if (self
.ttime
> 0 and time
.time() - simtime
> self
.ttime
):
227 info(" # Wall clock time expired! Bye bye!", verbosity
.low
)
230 info(" # Simulation ran successfully for the prescribed total_step! Bye bye!", verbosity
.low
)
231 self
.rollback
= False