Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add orca recipes #3

Merged
merged 5 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added omdata/orca/__init__.py
Empty file.
53 changes: 53 additions & 0 deletions omdata/orca/calc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from pathlib import Path
from shutil import which

from ase.calculators.orca import ORCA, OrcaProfile
from pydantic import Field
from sella import Sella

ORCA_FUNCTIONAL = "wB97M-V"
ORCA_BASIS = "def2-TZVPD"
ORCA_SIMPLE_INPUT = [
"EnGrad",
"RIJCOSX",
"def2/J",
"NoUseSym",
"DIIS",
"NOSOSCF",
"NormalConv",
"DEFGRID2",
]
ORCA_SIMPLE_INPUT_QUACC_IGNORE = []
ORCA_BLOCKS = ["%scf Convergence Tight maxiter 500 end"]
ORCA_ASE_SIMPLE_INPUT = " ".join([ORCA_FUNCTIONAL] + [ORCA_BASIS] + ORCA_SIMPLE_INPUT)
OPT_PARAMETERS = {
"optimizer": Sella,
"store_intermediate_results": True,
"fmax": 0.01,
"max_steps": 1000,
}


def write_orca_inputs(
atoms,
output_directory,
charge=0,
mult=1,
orcasimpleinput=ORCA_ASE_SIMPLE_INPUT,
orcablocks=" ".join(ORCA_BLOCKS),
):
"""
One-off method to be used if you wanted to write inputs for an arbitrary
system. Primarily used for debugging.
"""

MyOrcaProfile = OrcaProfile([str(Field(Path(which("orca") or "orca")).default)])
calc = ORCA(
charge=charge,
mult=mult,
profile=MyOrcaProfile,
orcasimpleinput=orcasimpleinput,
orcablocks=orcablocks,
directory=output_directory,
)
calc.write_inputfiles(atoms, ["energy", "forces"])
133 changes: 133 additions & 0 deletions omdata/orca/recipes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import os
import pickle

from quacc.recipes.orca.core import ase_relax_job, static_job
from quacc.wflow_tools.customizers import strip_decorator

from omdata.orca.calc import (
OPT_PARAMETERS,
ORCA_BASIS,
ORCA_BLOCKS,
ORCA_FUNCTIONAL,
ORCA_SIMPLE_INPUT,
ORCA_SIMPLE_INPUT_QUACC_IGNORE,
)


def single_point_calculation(
atoms,
charge,
spin_multiplicity,
xc=ORCA_FUNCTIONAL,
basis=ORCA_BASIS,
orcasimpleinput=ORCA_SIMPLE_INPUT,
orcablocks=ORCA_BLOCKS,
nprocs=12,
outputdir=os.getcwd(),
):
"""
Wrapper around QUACC's static job to standardize single-point calculations.
See github.com/Quantum-Accelerators/quacc/blob/main/src/quacc/recipes/orca/core.py#L22
for more details.

Arguments
---------

atoms: Atoms
Atoms object
charge: int
Charge of system
spin_multiplicity: int
Multiplicity of the system
xc: str
Exchange-correlaction functional
basis: str
Basis set
orcasimpleinput: list
List of `orcasimpleinput` settings for the calculator
orcablocks: list
List of `orcablocks` swaps for the calculator
nprocs: int
Number of processes to parallelize across
outputdir: str
Directory to move results to upon completion
"""
from quacc import SETTINGS

SETTINGS.RESULTS_DIR = outputdir

o = strip_decorator(static_job)(
atoms,
charge=charge,
spin_multiplicity=spin_multiplicity,
xc=xc,
basis=basis,
orcasimpleinput=orcasimpleinput + ORCA_SIMPLE_INPUT_QUACC_IGNORE,
orcablocks=orcablocks,
nprocs=nprocs,
)
# TODO: how we want to handle what results to save out and where to store
# them.
with open(os.path.join(outputdir, "quacc_results.pkl"), "wb") as f:
pickle.dump(o, f)


def ase_relaxation(
atoms,
charge,
spin_multiplicity,
xc=ORCA_FUNCTIONAL,
basis=ORCA_BASIS,
orcasimpleinput=ORCA_SIMPLE_INPUT,
orcablocks=ORCA_BLOCKS,
nprocs=12,
opt_params=OPT_PARAMETERS,
outputdir=os.getcwd(),
):
"""
Wrapper around QUACC's ase_relax_job to standardize geometry optimizations.
See github.com/Quantum-Accelerators/quacc/blob/main/src/quacc/recipes/orca/core.py#L22
for more details.

Arguments
---------

atoms: Atoms
Atoms object
charge: int
Charge of system
spin_multiplicity: int
Multiplicity of the system
xc: str
Exchange-correlaction functional
basis: str
Basis set
orcasimpleinput: list
List of `orcasimpleinput` settings for the calculator
orcablocks: list
List of `orcablocks` swaps for the calculator
nprocs: int
Number of processes to parallelize across
opt_params: dict
Dictionary of optimizer parameters
outputdir: str
Directory to move results to upon completion
"""
from quacc import SETTINGS

SETTINGS.RESULTS_DIR = outputdir

o = strip_decorator(ase_relax_job)(
atoms,
charge=charge,
spin_multiplicity=spin_multiplicity,
xc=xc,
basis=basis,
orcasimpleinput=orcasimpleinput + ORCA_SIMPLE_INPUT_QUACC_IGNORE,
orcablocks=orcablocks,
opt_params=opt_params,
nprocs=nprocs,
)
# TODO: how we want to handle what results to save out and where to store them.
with open(os.path.join(outputdir, "quacc_results.pkl"), "wb") as f:
pickle.dump(o, f)
17 changes: 17 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""
Copyright (c) Facebook, Inc. and its affiliates.
This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
"""

from setuptools import find_packages, setup

setup(
name="omdata",
version="0.1.0",
description="Code for generating OMOL input configurations",
url="http://github.com/Open-Catalyst-Project/om-data",
packages=find_packages(),
mshuaibii marked this conversation as resolved.
Show resolved Hide resolved
install_requires=["ase", "quacc[sella]>=0.7.2"],
include_package_data=True,
)