Optimization calculations#

Geometry optimizations are multi-step procedures that iteratively minimize the energy of a molecule by running a sequence of singlepoint calculations at different geometries. An optimization record stores the initial and final (optimized) molecules, as well as these singlepoint calculations (trajectory)

Optimization Records#

Optimization records contain all the fields of a base record, and additionally include:

  • initial_molecule - The molecule used as the starting geometry

  • final_molecule - The optimized molecule (may be None if the record is not complete)

  • energies - A list of energies during the optimization trajectory

  • trajectory - The sequence of SinglepointRecord records representing the individual steps of the optimization trajectory

  • specification - The program, level of theory, and other options for running the optimization

The trajectory can be accessed either as a list (trajectory) or via indexing using trajectory_element(). The latter is more efficient if only one singlepoint record is needed as it will fetch only that record from the server if it does not exist locally.

Optimization Specification#

The specification for an optimization is a OptimizationSpecification. The key fields are:

  • program - The optimization program (for example, geometric). This is not necessarily the same as the program used for the singlepoint calculations.

  • qc_specification - The singlepoint QC details (method, basis, program, keywords). See Singlepoint Specification.

  • keywords - Program-specific keywords for the optimization program

  • protocols - Controls storage/return of additional information (see OptimizationProtocols)

Note

The QC singlepoint computations within an optimization always use a deferred driver. Any driver passed into the QCSpecification is overridden internally. The deferred value is a placeholder, as the true driver is controlled by the optimization program

Note

Currently the protocols field of the QC singlepoint specification is ignored. This will be fixed in the future

OptimizationSpecification objects can be created manually (for example, when adding to datasets).

Basic OptimizationSpecification with a QCSpecification
from qcportal.optimization import OptimizationSpecification
from qcportal.singlepoint import QCSpecification

# Use geometric for the optimization, psi4 for the individual gradient calculations
opt_spec = OptimizationSpecification(
    program="geometric",
    qc_specification=QCSpecification(
        program="psi4",
        method="b3lyp",
        basis="def2-svp",
        driver="deferred",
    ),
)
Pass optimization program-specific keywords
from qcportal.optimization import OptimizationSpecification
from qcportal.singlepoint import QCSpecification

opt_spec = OptimizationSpecification(
    program="geometric",
    qc_specification=QCSpecification(program="psi4", method="b3lyp", basis="def2-svp", driver="deferred"),
    keywords={
        # See your optimization program's docs (e.g., geometric) for available options
        "maxiter": 200,
    },
)
Control protocols of what is stored/returned
from qcportal.optimization import OptimizationSpecification, OptimizationProtocols
from qcportal.singlepoint import QCSpecification

opt_spec = OptimizationSpecification(
    program="geometric",
    qc_specification=QCSpecification(program="psi4", method="b3lyp", basis="def2-svp", driver="deferred"),
    protocols=OptimizationProtocols(trajectory="initial_and_final"),
)

Submitting Records#

Optimization records can be submitted using a client via the add_optimizations() method. This method takes the following information:

  • initial_molecules - A single molecule or list of molecules to optimize

  • program - The optimization program (e.g., geometric)

  • qc_specification - The QC details used for each step (see above)

  • keywords - Program-specific keywords for the optimization

  • protocols - Protocols for storing/returning data for the optimization

See Submitting computations for more information about other arguments.

Optimization Datasets#

Optimization datasets are collections of optimization records. Entries contain a single initial molecule and optional metadata.

The dataset specifications contain an OptimizationSpecification.

Client Examples#

Obtain a single optimization record by ID
r = client.get_optimizations(123)
Obtain multiple optimization records by ID
r_lst = client.get_optimizations([123, 456])
Obtain multiple optimizations by ID, ignoring missing records
r_lst = client.get_optimizations([123, 456, 789], missing_ok=True)
Include trajectory and all data for a record during initial fetch
r_lst = client.get_optimizations([123, 456], include=['**'])
Query optimizations by optimization program and QC method/basis
r_iter = client.query_optimizations(program='geometric', qc_method='b3lyp', qc_basis='def2-svp')
for r in r_iter:
    print(r.id)
Query optimizations by QC program and when the record was created, include trajectory
r_iter = client.query_optimizations(qc_program='psi4',
                                    created_after='2024-03-21 12:34:56',
                                    include=['trajectory'])
for r in r_iter:
    print(r.id, len(r.trajectory))
Add optimization records
from qcportal.singlepoint import QCSpecification

meta, ids = c.add_optimizations([mol1, mol2],
                                program='geometric',
                                qc_specification=QCSpecification(program='psi4', method='b3lyp', basis='def2-svp', driver='deferred'))
Add optimization records, set optimization keywords
from qcportal.singlepoint import QCSpecification

meta, ids = client.add_optimizations([mol1, mol2],
                                     program='geometric',
                                     qc_specification=QCSpecification(program='psi4', method='b3lyp', basis='def2-svp', driver='deferred'),
                                     keywords={'convergence_set': 'tight'})
Add optimization records, adjust protocols
from qcportal.singlepoint import QCSpecification
from qcelemental.models.procedures import OptimizationProtocols

meta, ids = client.add_optimizations([mol1, mol2],
                                     program='geometric',
                                     qc_specification=QCSpecification(program='psi4', method='b3lyp', basis='def2-svp', driver='deferred'),
                                     protocols=OptimizationProtocols(trajectory='initial_and_final'))

Dataset Examples#

See Datasets for more information and advanced usage. See the specification section for all the options in creating specifications.

Create an optimization dataset with default options
ds = client.add_dataset(
         "optimization",
         "Optimization Dataset Name",
         "An example of an optimization dataset"
)
Add a single entry to an optimization dataset
from qcportal.molecules import Molecule

h2_mol = Molecule(symbols=['h', 'h'], geometry=[0, 0, 0, 0, 0, 1.5])
ds.add_entry("hydrogen", h2_mol)
Add many entries to an optimization dataset
from qcportal.optimization import OptimizationDatasetEntry
from qcportal.molecules import Molecule

new_entries = []
for element in ['h', 'n', 'o']:
    mol = Molecule(symbols=[element], geometry=[0, 0, 0])
    ent = OptimizationDatasetEntry(name=f"{element}_atom", initial_molecule=mol)
    new_entries.append(ent)

ds.add_entries(new_entries)
Add a specification to an optimization dataset
from qcportal.optimization import OptimizationSpecification
from qcportal.singlepoint import QCSpecification

opt_spec = OptimizationSpecification(
    program="geometric",
    qc_specification=QCSpecification(program="psi4", method="b3lyp", basis="def2-svp", driver="deferred"),
)

ds.add_specification("geometric/psi4-b3lyp-def2-svp", opt_spec)

Optimization QCPortal API#