Input and output¶
The main input/output mechanism in Asap is the ASE Trajectories, described in the ASE Manual chapter on Trajectory files.
Trajectory objects are objects storing the temporal evolution of a simulation. A Trajectory file contains one or more Atoms objects, usually representing the time evolution of a molecular dynamics simulation.
It is important that you import the Trajectory objects from
asap3.io.trajectory
instead of directly from ASE, since you will
then get modified versions that work with ASE’s way of parallelizing
simulations.
Currently, Asap supports three kinds of Trajectory formats:
- Trajectory
This is the default ASE Trajectory format, using ASE’s own file format. Unlike the ASE version, forces are not saved in parallel simulations. Use
properties=['forces']
to cause them to be saved. Advantage: Simplicity. Disadvantage: The master node collects all information about the atoms, for very large simulations this can be a problem due to insufficient memory.- BundleTrajectory
A special Trajectory format, where data is stored in a directory rather than in a flat file. Advantage: For sufficiently large simulations, each node writes its own data for better performance and less RAM overhead on the master. Disadvantage: The output “file” is a directory, in some cases this can be a slight inconvenience. Furthermore, this format is inefficient for small simulations.
Using trajectories with simulations on a single processor¶
These simulations are all shown with the default Trajectory format. Replace Trajectory with BundleTrajectory if you wish to use that format.
Reading a configuration¶
Usually, you want to read the last (often the only) configuration from a Trajectory file in order to start your simulation. It can be done like this:
from asap3.io.trajectory import *
traj = Trajectory("inputfile.traj")
atoms = traj[-1]
traj.close()
and the atoms object can now be used to run a simulation (but remember
to associate an Asap calculator to the atoms with
set_calculator()
, the calculator is not saved in the trajectory
file).
You can also use the ASE function read()
to do the same:
atoms = read("inputfile.traj")
Writing a trajectory of a running simulation¶
Just attach the trajectory to the dynamics object, specifying how often the data should be written. This example creates a trajectory. The initial configuration is automatically written to the file when the trajectory object is created. Then, for every 100 time steps the atoms are written to the file.
# dyn is the dynamics object, e.g. VelocityVerlet
traj = Trajectory("outputfile.traj", "w", atoms)
dyn.attach(traj, interval=100)
dyn.run(nsteps) # Run the simulation.
Trajectories in parallel simulations¶
In a parallel simulation, atoms are distributed amongst the
processors, but should still be written to and read from the same
file. The Asap version of Trajectory supports this
automatically when writing. When reading, there are several ways to
do it depending on what you want to do, and a new method,
get_atoms()
has been added to Trajectory, BundleTrajectory and PickleTrajectory.
traj.get_atoms(n, cpus=None)
:Return Atoms object number n from the trajectory.
traj.get_atoms(n) is very similar to traj[n], but with the following differences:
In serial simulations traj.get_atoms(n) and traj[n] are equivalent.
In parallel simulations:
traj[n] returns all atoms on all processors
traj.get_atoms(n) returns all atoms on the master, and None on all other processors.
traj.get_atoms(n, cpus) returns a ParallelAtoms object with atoms distributed among the processors, and processor layout given by cpus (three integers or the keyword ‘auto’).
traj.get_atoms_distributed(n, cpus='auto', extra=None, verbose=True)
:Reads very large simulation in less memory intensive way.
This version of get_atoms is intended for reading huge simulations in massively parallel simulations, when there is not enough RAM to temporarily store all atoms on the master node.
This ONLY works for a BundleTrajectory written in “split mode”, i.e. written by a large parallel ASAP simulation.
Parameters:
n
: The frame number to be read. Use -1 for the last one.cpus
: The CPU layout. Three integers or the keywork ‘auto’.extra
: List of names of extra arrays to be read.verbose
: Write progress info to standard output.
Reading a configuration¶
To read the atoms from “inputfile.traj” and initialize a parallel simulation running on 2 x 2 x 3 cpus:
traj = PickleTrajectory("inputfile.traj")
atoms = traj.get_atoms(-1, cpus=[2,2,3])
del traj # release memory on master node.
Writing a trajectory of a running simulation¶
This is identical to the case of the serial simulation. Trajectory automatically detects a parallel Atoms object, and acts accordingly (if imported from asap and not directly from ase).