Beispiel #1
0
def prepare_forte_objects_from_psi4_wfn(options, wfn, mo_space_info):
    """
    Take a psi4 wavefunction object and prepare the ForteIntegrals, SCFInfo, and MOSpaceInfo objects

    Parameters
    ----------
    options : ForteOptions
        A Forte ForteOptions object
    wfn : psi4 Wavefunction
        A psi4 Wavefunction object
    mo_space_info : the MO space info read from options
        A Forte MOSpaceInfo object

    Returns
    -------
    tuple(ForteIntegrals, SCFInfo, MOSpaceInfo)
        a tuple containing the ForteIntegrals, SCFInfo, and MOSpaceInfo objects
    """

    # Call methods that project the orbitals (AVAS, embedding)
    mo_space_info = orbital_projection(wfn, options, mo_space_info)

    # Build Forte SCFInfo object
    scf_info = forte.SCFInfo(wfn)

    # Build a map from Forte StateInfo to the weights
    state_weights_map = forte.make_state_weights_map(options, mo_space_info)

    return (state_weights_map, mo_space_info, scf_info)
Beispiel #2
0
def prepare_ints_rdms(wfn,
                      mo_spaces,
                      rdm_level=3,
                      rdm_type=forte.RDMsType.spin_dependent):
    """
    Preparation step for DSRG: compute a CAS and its RDMs.
    :param wfn: reference wave function from psi4
    :param mo_spaces: a dictionary {mo_space: occupation}, e.g., {'ACTIVE': [0,0,0,0]}
    :param rdm_level: max RDM to be computed
    :param rdm_type: RDMs type: spin_dependent or spin_free
    :return: a tuple of (reference energy, MOSpaceInfo, ForteIntegrals, RDMs)
    """

    forte_objects = prepare_forte_objects(wfn, mo_spaces)

    ints = forte_objects['ints']
    as_ints = forte_objects['as_ints']
    scf_info = forte_objects['scf_info']
    mo_space_info = forte_objects['mo_space_info']
    state_weights_map = forte_objects['state_weights_map']

    # build a map {StateInfo: a list of weights} for multi-state computations
    state_weights_map = forte.make_state_weights_map(forte.forte_options,
                                                     mo_space_info)

    # converts {StateInfo: weights} to {StateInfo: nroots}
    state_map = forte.to_state_nroots_map(state_weights_map)

    # create an active space solver object and compute the energy
    as_solver_type = 'FCI'
    as_solver = forte.make_active_space_solver(as_solver_type, state_map,
                                               scf_info, mo_space_info,
                                               as_ints, forte.forte_options)

    state_energies_list = as_solver.compute_energy(
    )  # a map {StateInfo: a list of energies}

    # compute averaged energy --- reference energy for DSRG
    Eref = forte.compute_average_state_energy(state_energies_list,
                                              state_weights_map)

    # compute RDMs
    rdms = as_solver.compute_average_rdms(state_weights_map, rdm_level,
                                          rdm_type)

    # semicanonicalize orbitals
    semi = forte.SemiCanonical(mo_space_info, ints, forte.forte_options)
    semi.semicanonicalize(rdms, rdm_level)

    return {
        'reference_energy': Eref,
        'mo_space_info': mo_space_info,
        'ints': ints,
        'rdms': rdms
    }
Beispiel #3
0
def run_forte(name, **kwargs):
    r"""Function encoding sequence of PSI module and plugin calls so that
    forte can be called via :py:func:`~driver.energy`. For post-scf plugins.

    >>> energy('forte')

    """
    lowername = name.lower()
    kwargs = p4util.kwargs_lower(kwargs)

    # Compute a SCF reference, a wavefunction is return which holds the molecule used, orbitals
    # Fock matrices, and more
    ref_wfn = kwargs.get('ref_wfn', None)
    if ref_wfn is None:
        ref_wfn = psi4.driver.scf_helper(name, **kwargs)

    # Get the option object
    options = psi4.core.get_options()
    options.set_current_module('FORTE')
    forte.forte_options.update_psi_options(options)

    if ('DF' in options.get_str('INT_TYPE')):
        aux_basis = psi4.core.BasisSet.build(
            ref_wfn.molecule(), 'DF_BASIS_MP2',
            psi4.core.get_global_option('DF_BASIS_MP2'), 'RIFIT',
            psi4.core.get_global_option('BASIS'))
        ref_wfn.set_basisset('DF_BASIS_MP2', aux_basis)

    if (options.get_str('MINAO_BASIS')):
        minao_basis = psi4.core.BasisSet.build(ref_wfn.molecule(),
                                               'MINAO_BASIS',
                                               options.get_str('MINAO_BASIS'))
        ref_wfn.set_basisset('MINAO_BASIS', minao_basis)

    # Start Forte, initialize ambit
    my_proc_n_nodes = forte.startup()
    my_proc, n_nodes = my_proc_n_nodes

    # Print the banner
    forte.banner()

    # Create the MOSpaceInfo object
    mo_space_info = forte.make_mo_space_info(ref_wfn, forte.forte_options)

    # Create the AO subspace projector
    ps = forte.make_aosubspace_projector(ref_wfn, options)

    state = forte.make_state_info_from_psi_wfn(ref_wfn)
    scf_info = forte.SCFInfo(ref_wfn)
    state_weights_map = forte.make_state_weights_map(forte.forte_options,
                                                     ref_wfn)

    # Run a method
    job_type = options.get_str('JOB_TYPE')

    energy = 0.0
    if job_type != 'NONE':
        start = timeit.timeit()

        # Make an integral object
        ints = forte.make_forte_integrals(ref_wfn, options, mo_space_info)

        # Rotate orbitals before computation
        orb_type = options.get_str("ORBITAL_TYPE")
        if orb_type != 'CANONICAL':
            orb_t = forte.make_orbital_transformation(orb_type, scf_info,
                                                      forte.forte_options,
                                                      ints, mo_space_info)
            orb_t.compute_transformation()
            Ua = orb_t.get_Ua()
            Ub = orb_t.get_Ub()

            ints.rotate_orbitals(Ua, Ub)

        # Run a method
        if (job_type == 'NEWDRIVER'):
            energy = forte_driver(state_weights_map, scf_info,
                                  forte.forte_options, ints, mo_space_info)
        else:
            energy = forte.forte_old_methods(ref_wfn, options, ints,
                                             mo_space_info)

        end = timeit.timeit()
        #print('\n\n  Your calculation took ', (end - start), ' seconds');

    # Close ambit, etc.
    forte.cleanup()

    psi4.core.set_scalar_variable('CURRENT ENERGY', energy)
    return ref_wfn
Beispiel #4
0
def prepare_forte_objects(wfn,
                          mo_spaces=None,
                          active_space='ACTIVE',
                          core_spaces=['RESTRICTED_DOCC'],
                          localize=False,
                          localize_spaces=[]):
    """Take a psi4 wavefunction object and prepare the ForteIntegrals, SCFInfo, and MOSpaceInfo objects

    Parameters
    ----------
    wfn : psi4 Wavefunction
        A psi4 Wavefunction object
    mo_spaces : dict
        A dictionary with the size of each space (e.g., {'ACTIVE' : [3]})
    active_space : str
        The MO space treated as active (default: 'ACTIVE')
    core_spaces : list(str)
        The MO spaces treated as active (default: ['RESTRICTED_DOCC'])
    localize : bool
        Do localize the orbitals? (defaul: False)
    localize_spaces : list(str)
        A list of spaces to localize (default: [])
    Returns
    -------
    tuple(ForteIntegrals, ActiveSpaceIntegrals, SCFInfo, MOSpaceInfo, map(StateInfo : list)
        a tuple containing the ForteIntegrals, SCFInfo, and MOSpaceInfo objects and a map of states and weights
    """
    # fill in the options object
    psi4_options = psi4.core.get_options()
    psi4_options.set_current_module('FORTE')
    options = forte.forte_options
    options.get_options_from_psi4(psi4_options)

    if ('DF' in options.get_str('INT_TYPE')):
        aux_basis = psi4.core.BasisSet.build(
            wfn.molecule(), 'DF_BASIS_MP2',
            psi4.core.get_global_option('DF_BASIS_MP2'), 'RIFIT',
            psi4.core.get_global_option('BASIS'))
        wfn.set_basisset('DF_BASIS_MP2', aux_basis)

    if (options.get_str('MINAO_BASIS')):
        minao_basis = psi4.core.BasisSet.build(
            wfn.molecule(), 'MINAO_BASIS', psi4_options.get_str('MINAO_BASIS'))
        wfn.set_basisset('MINAO_BASIS', minao_basis)

    # Prepare base objects
    scf_info = forte.SCFInfo(wfn)

    nmopi = wfn.nmopi()
    point_group = wfn.molecule().point_group().symbol()

    if mo_spaces == None:
        mo_space_info = forte.make_mo_space_info(nmopi, point_group, options)
    else:
        mo_space_info = forte.make_mo_space_info_from_map(
            nmopi, point_group, mo_spaces, [])

    state_weights_map = forte.make_state_weights_map(options, mo_space_info)

    ints = forte.make_ints_from_psi4(wfn, options, mo_space_info)

    if localize:
        localizer = forte.Localize(forte.forte_options, ints, mo_space_info)
        localizer.set_orbital_space(localize_spaces)
        localizer.compute_transformation()
        Ua = localizer.get_Ua()
        ints.rotate_orbitals(Ua, Ua)

    # the space that defines the active orbitals. We select only the 'ACTIVE' part
    # the space(s) with non-active doubly occupied orbitals

    as_ints = forte.make_active_space_ints(mo_space_info, ints, active_space,
                                           core_spaces)

    return (ints, as_ints, scf_info, mo_space_info, state_weights_map)
Beispiel #5
0
def gradient_forte(name, **kwargs):
    r"""Function encoding sequence of PSI module and plugin calls so that
    forte can be called via :py:func:`~driver.energy`. For post-scf plugins.

    >>> gradient('forte') 
        available for : CASSCF

    """
    lowername = name.lower()
    kwargs = p4util.kwargs_lower(kwargs)

    # Compute a SCF reference, a wavefunction is return which holds the molecule used, orbitals
    # Fock matrices, and more
    ref_wfn = kwargs.get('ref_wfn', None)
    if ref_wfn is None:
        ref_wfn = psi4.driver.scf_helper(name, **kwargs)

    # Get the psi4 option object
    optstash = p4util.OptionsState(['GLOBALS', 'DERTYPE'])
    psi4_options = psi4.core.get_options()
    psi4_options.set_current_module('FORTE')

    # Get the forte option object
    options = forte.forte_options
    options.get_options_from_psi4(psi4_options)

    if ('DF' in options.get_str('INT_TYPE')):
        raise Exception('analytic gradient is not implemented for density fitting')

    if (options.get_str('MINAO_BASIS')):
        minao_basis = psi4.core.BasisSet.build(ref_wfn.molecule(), 'MINAO_BASIS',
                                               options.get_str('MINAO_BASIS'))
        ref_wfn.set_basisset('MINAO_BASIS', minao_basis)

    # Start Forte, initialize ambit
    my_proc_n_nodes = forte.startup()
    my_proc, n_nodes = my_proc_n_nodes

    # Print the banner
    forte.banner()

    # Create the MOSpaceInfo object
    mo_space_info = forte.make_mo_space_info(ref_wfn, options)

    # Call methods that project the orbitals (AVAS, embedding)
    mo_space_info = orbital_projection(ref_wfn, options, mo_space_info)

    state = forte.make_state_info_from_psi_wfn(ref_wfn)
    scf_info = forte.SCFInfo(ref_wfn)
    state_weights_map = forte.make_state_weights_map(options,ref_wfn)

    # Run a method
    job_type = options.get_str('JOB_TYPE')

    energy = 0.0

    if not job_type == 'CASSCF':
        raise Exception('analytic gradient is only implemented for CASSCF')

    start = time.time()

    # Make an integral object
    ints = forte.make_forte_integrals(ref_wfn, options, mo_space_info)

    # Rotate orbitals before computation
    orb_type = options.get_str("ORBITAL_TYPE")
    if orb_type != 'CANONICAL':
        orb_t = forte.make_orbital_transformation(orb_type, scf_info, options, ints, mo_space_info)
        orb_t.compute_transformation()
        Ua = orb_t.get_Ua()
        Ub = orb_t.get_Ub()

        ints.rotate_orbitals(Ua,Ub)

    # Run gradient computation
    energy = forte.forte_old_methods(ref_wfn, options, ints, mo_space_info)
    derivobj = psi4.core.Deriv(ref_wfn)
    derivobj.set_deriv_density_backtransformed(True)
    derivobj.set_ignore_reference(True)
    grad = derivobj.compute() #psi4.core.DerivCalcType.Correlated
    ref_wfn.set_gradient(grad)    
    optstash.restore()        

    end = time.time()
    #print('\n\n  Your calculation took ', (end - start), ' seconds');

    # Close ambit, etc.
    forte.cleanup()

    return ref_wfn
Beispiel #6
0
def run_forte(name, **kwargs):
    r"""Function encoding sequence of PSI module and plugin calls so that
    forte can be called via :py:func:`~driver.energy`. For post-scf plugins.

    >>> energy('forte')

    """
    lowername = name.lower()
    kwargs = p4util.kwargs_lower(kwargs)

    # Compute a SCF reference, a wavefunction is return which holds the molecule used, orbitals
    # Fock matrices, and more
    ref_wfn = kwargs.get('ref_wfn', None)
    if ref_wfn is None:
        ref_wfn = psi4.driver.scf_helper(name, **kwargs)

    # Get the option object
    psi4_options = psi4.core.get_options()
    psi4_options.set_current_module('FORTE')

    # Get the forte option object
    options = forte.forte_options
    options.get_options_from_psi4(psi4_options)

    if ('DF' in options.get_str('INT_TYPE')):
        aux_basis = psi4.core.BasisSet.build(ref_wfn.molecule(), 'DF_BASIS_MP2',
                                         options.get_str('DF_BASIS_MP2'),
                                         'RIFIT', options.get_str('BASIS'))
        ref_wfn.set_basisset('DF_BASIS_MP2', aux_basis)

    if (options.get_str('MINAO_BASIS')):
        minao_basis = psi4.core.BasisSet.build(ref_wfn.molecule(), 'MINAO_BASIS',
                                               options.get_str('MINAO_BASIS'))
        ref_wfn.set_basisset('MINAO_BASIS', minao_basis)

    # Start Forte, initialize ambit
    my_proc_n_nodes = forte.startup()
    my_proc, n_nodes = my_proc_n_nodes

    # Print the banner
    forte.banner()

    # Create the MOSpaceInfo object
    mo_space_info = forte.make_mo_space_info(ref_wfn, options)

    # Call methods that project the orbitals (AVAS, embedding)
    mo_space_info = orbital_projection(ref_wfn, options, mo_space_info)

    # Averaging spin multiplets if doing spin-adapted computation
    if options.get_str('CORRELATION_SOLVER') == 'SA-MRDSRG':
        options_dict = options.dict()
        options_dict['SPIN_AVG_DENSITY']['value'] = True
        options.set_dict(options_dict)

    state = forte.make_state_info_from_psi_wfn(ref_wfn)
    scf_info = forte.SCFInfo(ref_wfn)
    state_weights_map = forte.make_state_weights_map(options,ref_wfn)

    # Run a method
    job_type = options.get_str('JOB_TYPE')

    energy = 0.0

    if job_type == 'NONE':
        forte.cleanup()
        return ref_wfn

    start_pre_ints = time.time()

    # Make an integral object
    ints = forte.make_forte_integrals(ref_wfn, options, mo_space_info)

    start = time.time()

    # Rotate orbitals before computation (e.g. localization, MP2 natural orbitals, etc.)
    orb_type = options.get_str("ORBITAL_TYPE")
    if orb_type != 'CANONICAL':
        orb_t = forte.make_orbital_transformation(orb_type, scf_info, options, ints, mo_space_info)
        orb_t.compute_transformation()
        Ua = orb_t.get_Ua()
        Ub = orb_t.get_Ub()
        ints.rotate_orbitals(Ua,Ub)

    # Run a method
    if (job_type == 'NEWDRIVER'):
        energy = forte_driver(state_weights_map, scf_info, options, ints, mo_space_info)
    else:
        energy = forte.forte_old_methods(ref_wfn, options, ints, mo_space_info)

    end = time.time()

    # Close ambit, etc.
    forte.cleanup()

    psi4.core.set_scalar_variable('CURRENT ENERGY', energy)

    psi4.core.print_out(f'\n\n  Time to prepare integrals: {start - start_pre_ints:12.3f} seconds')
    psi4.core.print_out(f'\n  Time to run job          : {end - start:12.3f} seconds')
    psi4.core.print_out(f'\n  Total                    : {end - start:12.3f} seconds')
    return ref_wfn
Beispiel #7
0
def run_forte(name, **kwargs):
    r"""Function encoding sequence of PSI module and plugin calls so that
    forte can be called via :py:func:`~driver.energy`. For post-scf plugins.

    >>> energy('forte')

    """
    lowername = name.lower()
    kwargs = p4util.kwargs_lower(kwargs)

    # Compute a SCF reference, a wavefunction is return which holds the molecule used, orbitals
    # Fock matrices, and more
    ref_wfn = kwargs.get('ref_wfn', None)
    if ref_wfn is None:
        ref_wfn = psi4.driver.scf_helper(name, **kwargs)

    # Get the option object
    options = psi4.core.get_options()
    options.set_current_module('FORTE')
    forte.forte_options.update_psi_options(options)

    if ('DF' in options.get_str('INT_TYPE')):
        aux_basis = psi4.core.BasisSet.build(ref_wfn.molecule(), 'DF_BASIS_MP2',
                                         psi4.core.get_global_option('DF_BASIS_MP2'),
                                         'RIFIT', psi4.core.get_global_option('BASIS'))
        ref_wfn.set_basisset('DF_BASIS_MP2', aux_basis)

    if (options.get_str('MINAO_BASIS')):
        minao_basis = psi4.core.BasisSet.build(ref_wfn.molecule(), 'MINAO_BASIS',
                                               options.get_str('MINAO_BASIS'))
        ref_wfn.set_basisset('MINAO_BASIS', minao_basis)

    # Start Forte, initialize ambit
    my_proc_n_nodes = forte.startup()
    my_proc, n_nodes = my_proc_n_nodes

    # Print the banner
    forte.banner()

    # Create the MOSpaceInfo object
    mo_space_info = forte.make_mo_space_info(ref_wfn, forte.forte_options)

    # Call methods that project the orbitals (AVAS, embedding)
    orbital_projection(ref_wfn, options)

    state = forte.make_state_info_from_psi_wfn(ref_wfn)
    scf_info = forte.SCFInfo(ref_wfn)
    state_weights_map = forte.make_state_weights_map(forte.forte_options,ref_wfn)

    # Run a method
    job_type = options.get_str('JOB_TYPE')

    energy = 0.0

    if job_type == 'NONE':
        forte.cleanup()
        return ref_wfn

    start = timeit.timeit()

    # Make an integral object
    ints = forte.make_forte_integrals(ref_wfn, options, mo_space_info)

    # Rotate orbitals before computation
    orb_type = options.get_str("ORBITAL_TYPE")
    if orb_type != 'CANONICAL':
        orb_t = forte.make_orbital_transformation(orb_type, scf_info, forte.forte_options, ints, mo_space_info)
        orb_t.compute_transformation()
        Ua = orb_t.get_Ua()
        Ub = orb_t.get_Ub()

        ints.rotate_orbitals(Ua,Ub)

    # Run a method
    if (job_type == 'NEWDRIVER'):
        energy = forte_driver(state_weights_map, scf_info, forte.forte_options, ints, mo_space_info)
    else:
        energy = forte.forte_old_methods(ref_wfn, options, ints, mo_space_info)

    end = timeit.timeit()
    #print('\n\n  Your calculation took ', (end - start), ' seconds');

    # Close ambit, etc.
    forte.cleanup()

    psi4.core.set_scalar_variable('CURRENT ENERGY', energy)
    return ref_wfn