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