Geometry Optimization¶
Take the strain out of a freshly built structure: LBFGS relaxes it to a
local force-field minimum and reports why it stopped.
When you need it¶
A freshly built or packed structure is rarely at a force-field minimum: bond lengths, angles, and close contacts carry excess energy. Before a production simulation — or to compare energies meaningfully — you minimize the geometry so the forces drop below a tolerance.
LBFGS moves atoms downhill on a set of potentials until the maximum force
falls under fmax. The minimizer is the native limited-memory quasi-Newton
implementation, re-exported as molpy.LBFGS / molpy.optimize.LBFGS; it
drives the Potentials a force field compiles for your frame.
Minimizing a structure¶
import molpy as mp
from molpy.conformer import Conformer
mol, _ = Conformer(seed=42).generate(mp.io.read_smiles("CCO"))
forcefield = mp.io.read_xml_forcefield(mp.data.get_forcefield_path("oplsaa.xml"))
frame = mp.typifier.OPLSAATypifier().typify(mol).to_frame()
potentials = forcefield.to_potentials(frame) # bonded + pair terms for this frame
opt = mp.LBFGS(potentials, fmax=0.05, max_steps=200)
frame, report = opt.run(frame) # a new frame with the relaxed coordinates
print(report.converged, report.final_energy, report.final_fmax, report.n_steps)
run never mutates its input: it returns the relaxed frame and an
OptReport. Keep the returned frame; the one you passed in is unchanged.
Parameters¶
LBFGS(potentials, *, fmax=0.05, max_steps=500, max_step=0.2, memory=8):
| Parameter | Effect |
|---|---|
fmax |
Convergence threshold on the largest force component (kcal/mol/Å). The run stops when every force is below it. |
max_steps |
Hard cap on iterations — a safety net if fmax is never reached. |
max_step |
Largest atomic displacement per step (Å). Smaller = more stable but slower; raise it only if convergence is sluggish and stable. |
memory |
Number of past steps the L-BFGS Hessian approximation keeps. More memory = better curvature estimate, more storage. |
run also accepts a bare (N, 3) coordinate array (or a (B, N, 3) batch)
when you already hold coordinates outside a frame; it returns arrays of the
same shape.
Reading the result¶
OptReport carries converged, final_energy, final_fmax and n_steps.
Always check converged: a run that hit max_steps (converged = False)
has not reached the minimum — loosen fmax, raise max_steps, or inspect
the structure.
Pitfalls¶
- Not converged ≠ minimized. A
Falseconvergedmeans you stopped at the step cap. - Units are the native units: energies in kcal/mol, forces in kcal/mol/Å, lengths in Å. A threshold that is too tight for a coarse force field never converges; too loose leaves residual strain.
- The potentials are compiled for one topology. Relaxing a frame whose bonds
or types changed needs
to_potentialsagain. - Optimization needs a typified frame with a force field — run a typifier
first, otherwise
to_potentialshas nothing to compile.
See also¶
- Force Field — building the
ForceFieldyou optimize against. - 3D Conformer Generation — the graph-embedding step that precedes force-field relaxation.
- Engine — running full dynamics after minimization.