
Adding Methods to DriverΒΆ
This is concerned at present with normal methods added first to the procedures table in driver.py that associates method names with functions to run them located in proc.py .
The function should start with a declaration, as below. methodname
is
never seen by users, so it’s good to be specific; if there’s lots of
modules that can run mp2, call methodname modulenamemethodname, perhaps.
The function must always take as arguments (name, **kwargs)
.
# energy method
def run_methodname(name, **kwargs):
# gradient method
def run_methodname_gradient(name, **kwargs):
If the function needs to test the identity of name
several times, it
can be convenient to predefine the lowercase version of the variable. The
case of all other py-side options (in kwargs) has already been handled by
energy()
, etc. in driver.py and need not be repeated here.
# include if convenient
lowername = name.lower()
# never include
kwargs = kwargs_lower(kwargs)
It’s often necessary to The function often needs to set options for the
c-side modules it calls. In order that the state of the options set by the
user remains when control is returned to the user, an
OptionsState
object is set up. See
LibOptions: globals, locals, has_changed and all that for details. All options set by the
function need to be included here, and only options set by the function
should be included. Most options should be associated with a particular
module, but a few (see below) are given without module.
# include if any options set
optstash = OptionsState(
# these and other basis options should have no associated module
['BASIS'],
['DF_BASIS_SCF'],
['DF_BASIS_MP2'],
['PUREAM'],
['FREEZE_CORE'],
# all others should have an associated module
['SCF', 'SCF_TYPE'],
['SCF', 'GUESS'],
['DFMP2', 'MP2_OS_SCALE'],
)
If options need to be set, set them anywhere here. Options should be set
locally to a module, except for those without a module in
OptionsState
.
# include if necessary as globals
psi4.set_global_option('BASIS', guessbasis)
psi4.set_global_option('DF_BASIS_SCF', guessbasisdf)
# include if necessary as locals
psi4.set_local_option('TRANSQT2', 'WFN', 'MP2')
psi4.set_local_option('CCSORT', 'WFN', 'MP2')
psi4.set_local_option('MP2', 'WFN', 'MP2')
If the regular scf module is to be run, run it through
scf_helper()
so that cast-up can be used. Also, add the
option to bypass it by pre-running scf, then running the module with this
bypass_scf
kwarg. Also, if the full two-electron integrals are
necessary for the post-scf, compute them if only the df integrals were run
previously.
# include if scf module is to be run
# Bypass routine scf if user did something special to get it to converge
if not (('bypass_scf' in kwargs) and yes.match(str(kwargs['bypass_scf']))):
scf_helper(name, **kwargs)
# include if TEI are needed beyond scf
# If the scf type is DF, then the AO integrals were never generated
if psi4.get_option('SCF', 'SCF_TYPE') == 'DF':
mints = psi4.MintsHelper()
mints.integrals()
Direct any post-scf modules to be run.
# include if further post-scf modules are needed
psi4.transqt2()
psi4.ccsort()
psi4.mp2()
If an OptionsState
object was set up, those options
need to be returned to the original user state with the following.
# include if optstash = OptionsState( was set up previously
optstash.restore()
No function should return anything. CURRENT ENERGY
will be set by
energy()
, etc.
# never include
return returnvalue