21.1. Quick Guide

The geometry optimization module provides an interface between PyBEST and the geomeTRIC optimizer. PyBEST evaluates the electronic energy and analytic nuclear gradient, while geomeTRIC updates the molecular geometry.

The current version of PyBEST supports geometry optimization for

  • restricted Hartree–Fock wave functions,

  • restricted orbital-optimized pCCD wave functions.

The corresponding classes are

  • RHFGeometryOptimizer,

  • ROOpCCDGeometryOptimizer.

If you use this module, please cite [behjou2026a].

21.1.1. Supported features

The geometry optimization module currently supports

  • analytic RHF nuclear gradients,

  • analytic ROOpCCD nuclear gradients,

  • dense one- and two-electron integrals,

  • non-relativistic molecular Hamiltonians,

  • unconstrained geometry optimizations,

  • constrained geometry optimizations through geomeTRIC,

  • transition-state searches through geomeTRIC.

21.1.2. Current limitations

The following features are currently not supported:

  • Cholesky-decomposed electron-repulsion integrals,

  • DKH Hamiltonians,

  • X2C Hamiltonians,

  • frozen-core ROOpCCD geometry optimizations.

21.1.3. How to: geometry optimization

Similar to the previous modules, we assume the following names for PyBEST objects

lf:

A LinalgFactory instance.

occ_model:

An occupation model containing the molecular basis and occupations.

For an RHF geometry optimization, initialize the optimizer as follows:

from pybest.geometry import RHFGeometryOptimizer

optimizer = RHFGeometryOptimizer(
    lf,
    occ_model,
    maxiter=100,
)

result = optimizer()

The optimized Cartesian coordinates are stored in the returned IOData container,

result.coordinates

For an ROOpCCD geometry optimization, use

from pybest.geometry import ROOpCCDGeometryOptimizer

optimizer = ROOpCCDGeometryOptimizer(
    lf,
    occ_model,
    maxiter=100,
)

result = optimizer()

21.1.4. Wave-function keyword arguments

Wave-function-specific options can be forwarded through nested dictionaries. For RHF calculations, use hf_kwargs:

result = optimizer(
    hf_kwargs={
        "threshold": 1.0e-10,
        "maxiter": 128,
    }
)

For ROOpCCD calculations, use hf_kwargs for the initial RHF calculation and pccd_kwargs for the ROOpCCD calculation:

result = optimizer(
    hf_kwargs={
        "threshold": 1.0e-10,
    },
    pccd_kwargs={
        "threshold": 1.0e-10,
        "localize": True,
    },
)