Skip to content

psi-rking/optking

Repository files navigation

About

OptKing is a molecular geometry optimization program that began as a rewrite of the previous c++ module of the same name in psi4. The translation into python and subsequent development was undertaken to support more complex tasks, and to join with interoperability efforts such as QCSchema, QCArchive and QCDB. OptKing supports the location of minima, transition states, and reaction paths on molecular potential surfaces. Current work is focused especially on expanding the available reaction path methods. Contributions are welcome! Please fork this repository and open a PR!


Build codecov license GH_release GH_commits GH_activity GH_releasedate Documentation Status Code style: black HATCH


Getting Started

Installation and Setup

Conda & Pypi

The recommended method of installation is through conda. All required dependencies and several Quantum Chemistry packages are available on conda-forge. To install OptKing

conda install optking -c conda-forge

OptKing's and its' required dependencies can also be installed from pypi.

pip install optking

From Source

The project is hosted on github. Source code can be downloaded with git or with the tarballs provided under releases.

To install OptKing and its required dependencies run the following command from the project's root directory

pip install .

Running pip install -e . instead, will install OptKing in development mode. Installing with pip will install numpy, qcengine, qcelemental, pydantic and more if not already present in the current virtual environment; however, installation of specific Quantum Chemistry programs is left to the user.

OptKing uses hatch for its build system which can be used to create conda environments. To create a conda environment with Psi4, OptKing's required dependencies, and OptKing run

Please note - do not recommend installing psi4 this way. If you need to install optking from source, please install Psi4 or your Quantum Chemistry package of choice and install optking into that environment

pip install pipx               # Recommended way to install hatch
pipx install hatch             # Install hatch and conda plugin (conda must already be installed)
pipx inject hatch hatch-conda  # Install conda plugin
hatch env create psi4          # Create conda environment with all required deps
pip install .                  # Install OptKing into conda env

For most use cases, QCEngine and your QC/MM program of choice OR Psi4 is required. If using QCEngine see MolSSI's qcengine documentation to ensure proper setup. Any QC or MM programs will need to be installed such that QCEngine can find them.

To run optking without QCEngine or Psi4, the CustomHelper class may be used though the python API. This Helper allows for the use of arbitrary packages and/or modified gradients to be used. Alternatively, an OptimizationManager or an even lower-level class could be used with custom gradients. Gradients, energies, and possibly hessians can be provided directly. To use the most basic representation of the algorithms with no reference to molecules one of the classes inheriting from OptimizationAlgorithm will be needed.

Running OptKing

Running through QCEngine

A basic driver has been implemented in QCEngine. QCEngine is built upon QCElemental which provides input validation and standardized input/output. To see the requirements for an Optimziation Input check MolSSI's qcelemental documentation. NOTE QCElemental assumes atomic units by default:

import qcengine as qcng

opt_input = {
    "initial_molecule": {
        "symbols": ["O", "O", "H", "H"],
        "geometry": [
            0.0000000000,
            0.0000000000,
            0.0000000000,
            -0.0000000000,
            -0.0000000000,
            2.7463569188,
            1.3013018774,
            -1.2902977124,
            2.9574871774,
            -1.3013018774,
            1.2902977124,
            -0.2111302586,
        ],
        "fix_com": True,
        "fix_orientation": True,
    },
    "input_specification": {
        "model": {"method": "hf", "basis": "sto-3g"},
        "driver": "gradient",
        "keywords": {"d_convergence": "1e-7"},
    },
    "keywords": {"g_convergence": "GAU_TIGHT", "program": "psi4"},
}

result = qcng.compute_procedure(opt_input, "optking")

An explicit example of creating and running an OptimizationInput. NOTE Molecule.from_data seems to be the only place Angstroms are expected:

import qcengine as qcng

from qcelemental.models import Molecule, OptimizationInput
from qcelemental.models.common_models import Model
from qcelemental.models.procedures import QCInputSpecification

# WARNING. The user MUST set fix_com and fix_orientation to True.
# optimization will almost certainly fail otherwise
molecule = Molecule.from_data(
    """
    O        0.0000000000      0.0000000000      0.0000000000
    O       -0.0000000000     -0.0000000000      1.4533095991
    H        0.6886193476     -0.6827961938      1.5650349285
    H       -0.6886193476      0.6827961938     -0.1117253294""",
    fix_com=True,
    fix_orientation=True,
)

model = Model(method="hf", basis="sto-3g")
input_spec = QCInputSpecification(
    driver="gradient", model=model, keywords={"d_convergence": 1e-7}  # QC program options
)

opt_input = OptimizationInput(
    initial_molecule=molecule,
    input_specification=input_spec,
    keywords={"g_convergence": "GAU_TIGHT", "program": "psi4"},  # optimizer options
)

config = qcng.get_config()  # get machine info (e.g. number of cores) can specify explicitly
opt = qcng.get_procedure("optking")
result = opt.compute(opt_input, config)

Running through Psi4

molecule hooh {
    0 1
    O        0.0000000000      0.0000000000      0.0000000000
    O       -0.0000000000     -0.0000000000      1.4533095991
    H        0.6886193476     -0.6827961938      1.5650349285
    H       -0.6886193476      0.6827961938     -0.1117253294
}

set {
    d_convergence 1e-7
    g_convergence GAU_TIGHT
}

optimize("hf/sto-3g")

The OptHelpers

For users looking to run optimizations from python, an example of QCEngine's python API has already been shown. To run optking through Psi4's python API checkout the Psi4 API docs. These two options should be sufficient for the majority of users.

If direct control over the optimizer is desired two OptHelper classes are provided to streamline performing an optimization. The molecular system, optimization coordinates, history, etc are all accessible through their respective classes and may be accessed as attributes of the OptHelper instance. EngineHelper takes an OptimizationHelper and calls qcengine.compute() to perform basic calculations with the provided input_specification CustomHelper accepts QCElemental and Psi4 molecules while requiring user provided gradients, energies, and possibly hessians. This may be useful for implementing a custom optimization driver or procedure using optking.

EngineHelper:

import qcengine as qcng

from qcelemental.models import Molecule, OptimizationInput
from qcelemental.models.common_models import Model
from qcelemental.models.procedures import QCInputSpecification


molecule = Molecule.from_data(
    """
    O        0.0000000000      0.0000000000      0.0000000000
    O       -0.0000000000     -0.0000000000      1.4533095991
    H        0.6886193476     -0.6827961938      1.5650349285
    H       -0.6886193476      0.6827961938     -0.1117253294""",
    fix_com=True,
    fix_orientation=True,
)

model = Model(method="hf", basis="sto-3g")
input_spec = QCInputSpecification(
    driver="gradient", model=model, keywords={"d_convergence": 1e-7}  # QC program options
)

opt_input = OptimizationInput(
    initial_molecule=molecule,
    input_specification=input_spec,
    keywords={"g_convergence": "GAU_TIGHT", "program": "psi4"},  # optimizer options
)

opt = optking.EngineHelper(opt_input)

for step in range(30):

    # Compute one's own energy and gradient
    opt.compute() # process input. Get ready to take a step
    opt.take_step()

    conv = opt.test_convergence()

    if conv is True:
        print("Optimization SUCCESS:")
    else:
        print("Optimization FAILURE:\n")

json_output = opt.close() # create an unvalidated OptimizationOutput like object
E = json_output["energies"][-1]

CustomHelper can take psi4 or qcelemental molecules. A simple example of a custom optimization loop is shown where the gradients are provided from a simple lennard jones potential:

h2o = psi4.geometry(
"""
 O
 H 1 1.0
 H 1 1.0 2 104.5
"""
)

psi4_options = {
    "basis": "sto-3g",
}
optking_options = {"g_convergence": "gau_verytight", "intrafrag_hess": "SIMPLE"}

psi4.set_options(psi4_options)

opt = optking.CustomHelper(h2o, optking_options)

for step in range(30):

    # Compute one's own energy and gradient
    E, gX = optking.lj_functions.calc_energy_and_gradient(opt.geom, 2.5, 0.01, True)
    # Insert these values into the 'user' computer.
    opt.E = E
    opt.gX = gX

    opt.compute() # process input. Get ready to take a step
    opt.take_step()

    conv = opt.test_convergence()

    if conv is True:
        print("Optimization SUCCESS:")
        break
else:
    print("Optimization FAILURE:\n")

json_output = opt.close() # create an unvalidated OptimizationOutput like object
E = json_output["energies"][-1]

About

optking: A molecular geometry optimization program

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages