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)
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 }
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
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)
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
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
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