### Navigation

- index
- modules
- toc
- next
- previous
- PSI4 [beta5] »
- Programming: Using the Core Libraries »

# 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

### Navigation

- index
- modules
- toc
- next
- previous
- PSI4 [beta5] »
- Programming: Using the Core Libraries »