Coding with Theory
Objects#
AaronTools.theory.Theory()
keeps much of the code for
writing quantum chemistry input files similar across different software packages.
Here, we will cover the basics of creating and using a Theory.
Creation#
Several objects or variables must be passed to Theory to make it usable. Each of the necessary objects are found in the AaronTools.theory package. We’ll briefly cover each of these.
Method Class#
AaronTools.theory.Method()
is used to keep method keywords
the same across different formats.
As an example:
from AaronTools.theory import Method
pbe0 = Method("PBE0")
When used with a Gaussian input file, this Method
will use the
Gaussian keyword for PBE0 (PBE1PBE).
Method also takes a is_semiempirical
argument:
rm1 = Method("RM1", is_semiempirical=True)
For Gaussian and ORCA input files, using a semi-empirical method will cause basis set information to be omitted.
SAPTMethod#
AaronTools.theory.SAPTMethod()
is a subclass of Method
that is specific for SAPT jobs. When used to make a Psi4 input file,
the molecule will be split into monomers, which are specified by the
components attribute of the Geometry instance.
sapt0 = SAPTMethod("sapt0")
Basis Sets
The AaronTools.theory.BasisSet()
object is a collection of
AaronTools.theory.Basis()
and AaronTools.theory.ECP()
objects.
from AaronTools.theory import Basis, ECP, BasisSet
from AaronTools.finders import AnyTransitionMetal, AnyNonTransitionMetal
basis = BasisSet(
[
Basis("cc-pVTZ", AnyNonTransitionMetal()),
Basis("cc-pVTZ", AnyNonTransitionMetal(), aux_type='C'),
Basis("cc-pVTZ-PP", AnyTransitionMetal()),
Basis("cc-pVTZ-PP", AnyTransitionMetal(), aux_type='C')
],
[ECP("SK-MCDHF-RSC")]
)
The second argument given to each Basis
determines which
elements that basis applies to. By default, a Basis applies to all elements.
An ECP
applies to any transition metal.
These elements will be overridden if another argument is supplied when
creating an ECP
or Basis
(i.e. list of elements or
AaronTools.finders.Finders()
).
The aux_type
keyword is used for ORCA and Psi4 input files to specify
auxiliary basis sets.
A list of elements or an appropriate Finder
that use that basis set can
be given to a Basis
or ECP
.
Empirical Dispersion#
:py:meth`AaronTools.theory.emp_dispersion.EmpiricalDispersion` keeps specifying dispersion corrections consistent across different formats.
from AaronTools.theory import EmpiricalDispersion
disp = EmpiricalDispersion("Grimme D2")
The following are equivalent:
disp = EmpiricalDispersion("Grimme D2")
disp = EmpiricalDispersion("GD2")
disp = EmpiricalDispersion("D2")
disp = EmpiricalDispersion("-D2")
Some dispersion methods are not available in all QM software programs.
Check the get_gaussian
, get_orca
, etc. methods of the
EmpiricalDispersion
class (or the respective manuals) for
acceptable dispersion methods.
Integration Grid#
As with other objects in the AaronTools.theory
package, the
AaronTools.theory.IntegrationGrid()
object is a way to
specify grids in a similar manner across different file formats.
It’s important to note that different programs use different types of grids. This, combined with varied grid pruning algorithms, mean that grids will usually have to be approximated if you use a keyword from one program to make an input file for a different program.
from AaronTools.theory import IntegrationGrid
grid = IntegrationGrid("SuperFineGrid")
Gaussian, ORCA, and Psi4 all have different ways of specifying integration grids.
Gaussian and ORCA have grid keywords.
When using an ORCA grid keyword to write a Gaussian input file,
IntegrationGrid
will try to approximate the ORCA grid’s density.
Psi4 specifies grid density by supplying a number of radial and angular points.
Gaussian allows a similar specification.
These can be specified as a string of the format "(radial, angular)"
.
As an example,
grid = IntegrationGrid("(99, 590)")
This grid can be used with Gaussian and Psi4, and should give similar results
(down to grid pruning and other algorithmic differences).
If you’re going to write and ORCA input file with this grid,
the number of radial points is set indirectly with the IntAcc
option.
IntAcc
will be set for the number of radial points in the 2nd row
of the periodic table.
Job Types#
There are six job types in the theory package:
A single JobType
can be given to a Theory.
If multiple JobType
instances are given as list,
the job-related information will appear in the order it appears
in the list. For example:
jobs = [FrequencyJob(), OptimizationJob()]
A Psi4 input file that uses this list will specify frequency before optimize, but many programs are not sensitive to the order these jobs will appear in the input file.
Other Options#
charge - overall charge
multiplicity - multiplicity
processors - allocated cores
memory - allocated RAM
When writing an input file, additional keywords can be passed to
AaronTools.geometry.Geometry.write()
that specify any other options.
The keywords for the dictionary are listed in Theory parameters.
Examples#
Below are examples of writing roughly equivalent input files for Gaussian, ORCA, and Psi4.
from AaronTools.geometry import Geometry
from AaronTools.theory import *
geom = Geometry('tnt.xyz')
fun = Method("B3LYP")
basis_set = BasisSet([Basis("def2-SVP")])
int_grid = IntegrationGrid("(99, 590)")
disp = EmpiricalDispersion("D2")
jobs = [OptimizationJob(), FrequencyJob()]
b3lyp_def2svp = Theory(
method=fun,
basis=basis_set,
grid=int_grid,
empirical_dispersion=disp,
job_type=jobs,
)
geom.write(
outfile="tnt_freq.com",
theory=b3lyp_def2svp,
GAUSSIAN_ROUTE={'freq':['HPModes', 'NoRaman']}
)
geom.write(
outfile="tnt_freq.inp",
theory=b3lyp_def2svp
)
geom.write(
outfile="tnt_freq.in",
theory=b3lyp_def2svp
)
Note that Method
, BasisSet
, IntegrationGrid
,
and EmpiricalDispersion
objects can be created automatically
when creating a Theory
object just by passing strings:
b3lyp_def2svp = Theory(
method="B3LYP",
basis="def2-SVP",
grid="(99, 590)",
empirical_dispersion="D2",
job_type=jobs,
)