Overwriting ASE Calculator Results and Saving Results to a Trajectory File

Hello!

I’m using ASE to do Monte Carlo (MC) simulations, and I am using the ASE trajectory file format to save the trajectory, energies, forces, etc… When moves are accepted, the atomic coordinates and calculation results saves to the trajectory file as expected. However, when a move gets rejected, I restore the old coordinates of the atoms and I try to restore the calculator results with the original calculator results before the MC trial move. Unfortunately, the calculator results are not being written to the trajectory file, and only the atomic coordinates and cell information are being written. So far, the only solution I have found is to make another potential energy call if a move is rejected. If possible, I would like to avoid doing this since we already have forces and energies in this old configuration. Below is some pseudocode for what I have currently tried.

position_o = atoms.get_positions()
results_o = atoms.calc.results

# Do a MC move
# If accepted, great!

if rejected:
    atoms.set_positions(position_o)
    atoms.calc.results = results_o # Does not write to trajectory file
    energy = atoms.get_potential_energy() # Writes to trajectory file, but launches another calculation

While there is a workaround I can use to get the calculator results for a previous configuration in the analysis scripts I have, it would be nice if the old calculator results are written directly to the trajectory file. Is there an attribute I can set or a method I can call either in the Atoms or Calculator objects to do this? Any help would be much appreciated. Thanks!

I’m not sure what code you are using to write to the trajectory in the first place, so it is not clear whether we expect them to include properties.

I suggest separating the trajectory-writing Atoms from the calculation Atoms, so they are not touched by the recalculation. Something like:


def copy_with_properties(atoms: Atoms) -> Atoms:
    atoms_copy = atoms.copy()
    atoms_copy.calc = SinglePointCalculator(
        atoms_copy,
        energy=atoms.get_potential_energy(),
        forces=atoms.get_forces())
    return atoms_copy

def save_to_traj(atoms: Atoms, filename: str = 'mc.traj') -> None:
    with Trajectory(filename, mode='a') as traj:
        traj.write(atoms)

last_good_step = None
for _ in range(mc_steps):
    if _accept(atoms):  # _accept() should run atoms.get_forces() and return bool
        last_good_step = copy_with_properties(atoms)
    if last_good_step is not None:
        save_to_traj(last_good_step)
    _mc_mutate(atoms)  # Mutate atoms in place without touching calculator

Hi Adam, thank you for the suggestion I’ll try this out!

In the Materials Science Community Discourse thread titled “Overwriting ASE Calculator Results and Saving Results to a Trajectory File,” a user named potus28 describes an issue encountered during Monte Carlo (MC) simulations using the Atomic Simulation Environment (ASE). Specifically, when a trial move is rejected, restoring the previous atomic positions and calculator results does not result in the calculator data (such as energies and forces) being saved to the trajectory file. The only workaround identified involves recalculating the potential energy, which is computationally inefficient.

from ase import Atoms
from ase.calculators.singlepoint import SinglePointCalculator
from ase.io.trajectory import Trajectory

def copy_with_properties(atoms: Atoms) → Atoms:
atoms_copy = atoms.copy()
atoms_copy.calc = SinglePointCalculator(
atoms_copy,
energy=atoms.get_potential_energy(),
forces=atoms.get_forces())
return atoms_copy

def save_to_traj(atoms: Atoms, filename: str = ‘mc.traj’) → None:
with Trajectory(filename, mode=‘a’) as traj:
traj.write(atoms)

last_good_step = None
for _ in range(mc_steps):
if _accept(atoms): # _accept() should run atoms.get_forces() and return bool
last_good_step = copy_with_properties(atoms)
if last_good_step is not None:
save_to_traj(last_good_step)
_mc_mutate(atoms) # Mutate atoms in place without touching calculator
This approach ensures that the trajectory file contains both the atomic positions and the associated calculator results, even when moves are rejected, without the need for additional energy calculations.