Optimize a structure
Run an ASE geometry optimization and save the relaxed coordinates, trajectory and convergence report.
The shared Python runtime (`compute/runtime`). Uses an inexpensive local EMT model.
Run an ASE geometry optimization inside a job and save the relaxed coordinates, trajectory, and convergence report together under results/.
Note: This tutorial uses an inexpensive copper dimer with ASE's built-in
EMTcalculator so it runs in seconds on any laptop. For real molecular chemistry, swapEMT()for a qualified ML potential or quantum chemistry calculator.
1. Install the scientific runtime
Sync the shared Python 3.13 environment (compute/runtime), which includes ASE, NumPy, and SciPy:
2. Inspect the optimization script
Look at compute/jobs/examples/optimize_structure.py:
What this script records under results/:
relaxed.extxyz— Final atomic coordinates and calculator energy/forces.optimization.traj&optimizer.log— Full BFGS step history and force progression.summary.json— Structured convergence report (converged,steps,energy_ev,max_force_ev_per_angstrom).- Explicit convergence check — If
optimizer.run(fmax=0.05, steps=100)does not converge within 100 steps, the script still writes the diagnostic files toresults/before raisingRuntimeError.
3. Run the optimization locally
Pass the shared runtime's Python interpreter to ct-cli run:
Open results/summary.json inside the printed attempt directory:
4. Turn it into a reusable Program
When you are ready to run optimizations across many structures on remote workers:
- Accept typed inputs: Wrap the function in a reusable Program that takes the input
.xyzfilename,charge,multiplicity, andfmax. - Keep large arrays in files: Return the small summary dict as your Pydantic output model and keep
.trajand.extxyzfiles inresults/. - Separate minimum optimization from TS search: Relaxing to a local minimum does not verify a transition state—use Search and verify a transition state for saddle-point searches and IRC checks, or Create an algorithm benchmark to compare calculators across a dataset.