Analysing trajectories
The Trajectory class extends
the single-structure analysis to molecular dynamics trajectories,
applying polyhedra recipes to every frame.
Loading from XDATCAR
For VASP trajectories stored as XDATCAR files:
from polyhedral_analysis.trajectory import Trajectory
from polyhedral_analysis.polyhedra_recipe import PolyhedraRecipe
recipe = PolyhedraRecipe(
method='distance cutoff',
coordination_cutoff=3.0,
central_atoms='Ti',
vertex_atoms=['O', 'F'],
)
trajectory = Trajectory.from_xdatcar(
'XDATCAR',
recipes=[recipe],
)
If your trajectory is split across multiple XDATCAR files (e.g. from
consecutive VASP runs), use
from_xdatcars():
trajectory = Trajectory.from_xdatcars(
['XDATCAR.1', 'XDATCAR.2', 'XDATCAR.3'],
recipes=[recipe],
)
Loading from structures
You can also build a trajectory from any list of pymatgen
Structure objects:
trajectory = Trajectory.from_structures(
structures,
recipes=[recipe],
)
This works with structures from any source that pymatgen supports.
Progress bars and parallelism
For long trajectories, enable a progress bar. The correct widget is
chosen automatically for terminals and Jupyter notebooks (via
tqdm.auto):
trajectory = Trajectory.from_xdatcar(
'XDATCAR',
recipes=[recipe],
progress=True,
)
To parallelise configuration building across multiple CPU cores:
trajectory = Trajectory.from_xdatcar(
'XDATCAR',
recipes=[recipe],
ncores=4,
)
Accessing configurations
A Trajectory contains a list
of Configuration objects,
one per frame:
len(trajectory) # number of frames
trajectory.configurations[0] # first frame
trajectory.configurations[0].polyhedra # polyhedra in first frame
# Iterate over all frames
for config in trajectory.configurations:
for poly in config.polyhedra:
print(poly.best_fit_geometry)
Working with configurations
Each Configuration provides
convenience attributes and methods for querying its polyhedra and atoms.
Filtering polyhedra by label:
When you define a recipe with a label argument (see
Defining polyhedra recipes), you can retrieve matching polyhedra with
polyhedra_by_label():
config.polyhedra_by_label('Ti') # all polyhedra labelled 'Ti'
config.polyhedra_by_label(['Ti', 'Nb']) # multiple labels
The
polyhedra_labels
property lists the labels of all polyhedra:
config.polyhedra_labels # ['Ti', 'Ti', 'Ti', ...]
Accessing atoms:
The
central_atoms
and
coordination_atoms
properties return the central and vertex atoms respectively:
config.central_atoms # list of central Atom objects
config.coordination_atoms # list of vertex Atom objects
To look up a specific coordination atom by its global index:
config.coordination_atom_by_index(12) # Atom or None
Polyhedron trajectories
A PolyhedronTrajectory
tracks a single polyhedron (identified by its central atom) across all
frames of a trajectory:
from polyhedral_analysis.polyhedron_trajectory import PolyhedronTrajectory
# Track the first polyhedron across all frames
poly_traj = PolyhedronTrajectory(
polyhedra=[config.polyhedra[0] for config in trajectory.configurations],
)
The polyhedra attribute gives access to the individual
CoordinationPolyhedron
objects. You can extract time-series data for any polyhedron property
(see Geometric analysis for all available properties):
# Off-centre displacement over time
displacements = [p.off_centre_displacement for p in poly_traj.polyhedra]
# Symmetry measure over time
csm_values = [p.best_fit_geometry['symmetry_measure'] for p in poly_traj.polyhedra]
# Coordination number over time
cn_values = [p.coordination_number for p in poly_traj.polyhedra]
Combining trajectories
You can concatenate trajectories with the + operator:
combined = trajectory_1 + trajectory_2
Or extend an existing trajectory in place:
trajectory_1.extend(trajectory_2)
Exporting to lattice_mc
The
to_lattice_mc()
method exports a connectivity description for use with the
lattice_mc Monte Carlo code.
It takes a filename, a list of polyhedra labels, and a neighbour list
(typically the face-sharing neighbour list):
neighbour_list = config.face_sharing_neighbour_list(labels=['Ti'])
config.to_lattice_mc('lattice.dat', labels=['Ti'], neighbour_list=neighbour_list)