Skip to main content

Intrinsic Reaction Coordinate

An IRC (Intrinsic Reaction Coordinate) job follows the reaction path away from a transition-state guess in both directions. The result is an ordered trajectory of geometries from one endpoint minimum, through the TS region, to the other endpoint minimum.

Use IRC when you want to verify that a TS guess connects the expected reactant and product wells.

Your First IRC Job

import atomiverse
from atomiverse import Atoms, IRC, JobFailedError
from atomiverse.levels import GFN2_XTB

atomiverse.configure(api_key="your-api-key")

# Use a transition-state guess geometry here.
ts_guess = Atoms.from_smiles("[H][H]")

job = IRC(
atoms=ts_guess,
level_of_theory=GFN2_XTB,
)
job.submit()

try:
result = job.require_result()
except JobFailedError as exc:
print(f"Job failed: {exc.failure.error}")
else:
print(f"Trajectory frames: {len(result.trajectory)}")
print(f"Atom-only frames: {len(result.trajectory_atoms)}")
print(f"Reactant endpoint atoms: {len(result.irc_reactants)}")
print(f"Product endpoint atoms: {len(result.irc_products)}")

Input Parameters

IRC takes the same core molecular inputs as other structure-based jobs, but only requires:

  • atoms: the starting geometry (usually a TS guess)
  • level_of_theory: electronic-structure method

Optional:

  • charge (default 0)
  • multiplicity (default 1)
job = IRC(
atoms=ts_guess,
charge=0,
multiplicity=1,
level_of_theory=GFN2_XTB,
)

Result

job.require_result() returns an IRCResult.

FieldTypeDescription
trajectorylist[TrajectoryStep]Ordered IRC path with positions, energy, and forces for each frame. Energies are in Hartree and forces are in Hartree/Angstrom.

Convenience accessors:

PropertyReturns
trajectory_atomslist[Atoms]
irc_reactantsAtoms
irc_productsAtoms

The trajectory field uses the same TrajectoryStep shape as an optimization trajectory, so you can iterate over energy profiles uniformly:

result = job.require_result()

for step in result.trajectory:
print(step.energy)
print(step.forces)

Handling Failures

If path following cannot converge or the input geometry cannot be evaluated, the job transitions to FAILED with a user-facing error message. When the worker collected usable frames before stopping, the typed failure payload includes partial_trajectory, using the same TrajectoryStep shape as an optimization failure.

from atomiverse import JobFailedError

job.submit()

try:
result = job.require_result()
except JobFailedError as exc:
failure = exc.failure
print(f"IRC failed: {failure.error}")

if failure.partial_trajectory:
print(f"Partial path frames: {len(failure.partial_trajectory)}")
last = failure.partial_trajectory[-1]
print(last.energy)
else:
print(len(result.trajectory))
print(result.trajectory_atoms[0].positions)

Non-blocking Submission

from atomiverse import State

job.submit(wait=False)
job.refresh()

if job.state == State.DONE:
result = job.require_result()
print(len(result.trajectory))
elif job.state == State.FAILED:
failure = job.require_failure()
print(failure.error)
print(len(failure.partial_trajectory))