def test_sparse_operator2(): """Test the SparseHamiltonian class""" import pytest import forte import forte.utils import psi4 from forte import det forte.startup() geom = """ H H 1 1.0 """ scf_energy, psi4_wfn = forte.utils.psi4_scf(geom, basis='DZ', reference='RHF') forte_objs = forte.utils.prepare_forte_objects(psi4_wfn, mo_spaces={}) as_ints = forte_objs[1] ham_op = forte.SparseHamiltonian(as_ints) ref = forte.StateVector({det("20"): 1.0}) Href1 = ham_op.compute(ref, 0.0) Href2 = ham_op.compute_on_the_fly(ref, 0.0) assert Href1[det("20")] == pytest.approx(-1.094572, abs=1e-6) assert Href2[det("20")] == pytest.approx(-1.094572, abs=1e-6) forte.cleanup() psi4.core.clean()
def test_uccsd_2(): """Test projective UCCSD on Ne using RHF/cc-pVDZ orbitals""" import forte.proc.scc as scc import forte import psi4 forte.startup() ref_energy = -128.677999887 # from Evangelista, J. Chem. Phys. 134, 224102 (2011). geom = "Ne" scf_energy, psi4_wfn = forte.utils.psi4_scf(geom, basis='cc-pVDZ', reference='RHF') forte_objs = forte.utils.prepare_forte_objects(psi4_wfn, mo_spaces={'FROZEN_DOCC': [1, 0, 0, 0, 0, 0, 0, 0]}) calc_data = scc.run_cc(forte_objs[1], forte_objs[2], forte_objs[3], cc_type='ucc', max_exc=2, e_convergence=1.0e-10) forte.cleanup() psi4.core.clean() energy = calc_data[-1][1] print(f' HF energy: {scf_energy}') print(f' UCCSD energy: {energy}') print(f' E - Eref: {energy - ref_energy}') assert energy == pytest.approx(ref_energy, 1.0e-11)
def test_duccsd(): """Test projective factorized UCCSDT on Ne using RHF/cc-pVDZ orbitals""" import pytest import forte.proc.scc as scc import forte import psi4 forte.startup() ref_energy = -128.677997285129 geom = "Ne" scf_energy, psi4_wfn = forte.utils.psi4_scf(geom, basis='cc-pVDZ', reference='RHF') forte_objs = forte.utils.prepare_forte_objects(psi4_wfn, mo_spaces={'FROZEN_DOCC': [1, 0, 0, 0, 0, 0, 0, 0]}) calc_data = scc.run_cc( forte_objs[1], forte_objs[2], forte_objs[3], cc_type='ducc', max_exc=2, e_convergence=1.0e-10 ) forte.cleanup() psi4.core.clean() energy = calc_data[-1][1] print(f' HF energy: {scf_energy}') print(f' DUCCSD energy: {energy}') print(f' E - Eref: {energy - ref_energy}') assert energy == pytest.approx(ref_energy, 1.0e-11)
def test_uccsd_3(): """Test projective UCCSD on Ne using RHF/cc-pVDZ orbitals""" import forte.proc.scc as scc import forte import psi4 import os.path forte.startup() ref_energy = -107.655681875111 psi4.set_options({'FORTE__FROZEN_DOCC': [2]}) options = forte.prepare_forte_options() forte_objects = forte.prepare_forte_objects_from_fcidump( options, os.path.dirname(__file__)) state_weights_map, mo_space_info, scf_info, fcidump = forte_objects ints = forte.make_ints_from_fcidump(fcidump, options, mo_space_info) as_ints = forte.make_active_space_ints(mo_space_info, ints, 'CORRELATED', []) calc_data = scc.run_cc(as_ints, scf_info, mo_space_info, cc_type='ucc', max_exc=2, e_convergence=1.0e-10) forte.cleanup() psi4.core.clean() energy = calc_data[-1][1] print(f' UCCSD energy: {energy}') assert energy == pytest.approx(ref_energy, 1.0e-9)
def test_ccsd(): """Test CCSD on H2 using RHF/DZ orbitals""" import pytest import forte.proc.scc as scc import forte import psi4 forte.startup() ref_energy = -1.126712715716011 # CCSD = FCI energy from psi4 geom = """ H H 1 1.0 """ scf_energy, psi4_wfn = forte.utils.psi4_scf(geom, basis='DZ', reference='RHF') forte_objs = forte.utils.prepare_forte_objects(psi4_wfn, mo_spaces={}) calc_data = scc.run_cc( forte_objs[1], forte_objs[2], forte_objs[3], cc_type='dcc', max_exc=2, e_convergence=1.0e-11, on_the_fly=True ) forte.cleanup() psi4.core.clean() energy = calc_data[-1][1] print(f' HF energy: {scf_energy}') print(f' CCSD energy: {energy}') print(f' E - Eref: {energy - ref_energy}') assert energy == pytest.approx(ref_energy, 1.0e-11)
def test_ccsdtq_3(): """Test CCSDTQ on Ne using RHF/cc-pVDZ orbitals""" import forte.proc.scc as scc import forte import psi4 forte.startup() ref_energy = -128.679014931 # from Evangelista, J. Chem. Phys. 134, 224102 (2011). geom = "Ne" scf_energy, psi4_wfn = forte.utils.psi4_scf(geom, basis='cc-pVDZ', reference='RHF') forte_objs = forte.utils.prepare_forte_objects( psi4_wfn, mo_spaces={'FROZEN_DOCC': [1, 0, 0, 0, 0, 0, 0, 0]}) calc_data = scc.run_cc(forte_objs[1], forte_objs[2], forte_objs[3], cc_type='cc', max_exc=4, e_convergence=1.0e-12) forte.cleanup() psi4.core.clean() energy = calc_data[-1][1] print(energy - ref_energy) assert energy == pytest.approx(ref_energy, 1.0e-9)
def test_uccsd_7(): """Test projective linearized unliked UCCSDT = CISDT on H4 using RHF/STO-3G orbitals""" import pytest import forte.proc.scc as scc import forte import psi4 forte.startup() ref_energy = -1.9824130356 # from CISDT geom = """ H 0.0 0.0 0.0 H 0.0 0.0 1.5 H 0.0 0.0 3.0 H 0.0 0.0 4.5 """ scf_energy, psi4_wfn = forte.utils.psi4_scf(geom, basis='sto-3g', reference='RHF') forte_objs = forte.utils.prepare_forte_objects(psi4_wfn, mo_spaces={}) calc_data = scc.run_cc( forte_objs[1], forte_objs[2], forte_objs[3], cc_type='ucc', max_exc=3, e_convergence=1.0e-10, linked=False, maxk=1 ) forte.cleanup() psi4.core.clean() energy = calc_data[-1][1] print(f' HF energy: {scf_energy}') print(f' CCSD energy: {energy}') print(f' corr. energy: {energy - scf_energy}') assert energy == pytest.approx(ref_energy, 1.0e-9)
def test_ul_uccsd_1(): """Test projective unlinked UCCSD on H4 using RHF/STO-3G orbitals""" import pytest import forte.proc.scc as scc import forte import psi4 import os.path forte.startup() ref_energy = -1.9437216535661626 # from Jonathon psi4.set_options({ 'FORTE__FCIDUMP_FILE': 'INTDUMP2', 'FORTE__FCIDUMP_DOCC': [2], 'FORTE__FROZEN_DOCC': [0], }) options = forte.prepare_forte_options() forte_objects = forte.prepare_forte_objects_from_fcidump( options, os.path.dirname(__file__)) state_weights_map, mo_space_info, scf_info, fcidump = forte_objects ints = forte.make_ints_from_fcidump(fcidump, options, mo_space_info) as_ints = forte.make_active_space_ints(mo_space_info, ints, 'CORRELATED', []) calc_data = scc.run_cc(as_ints, scf_info, mo_space_info, cc_type='ucc', max_exc=2, e_convergence=1.0e-10, linked=False, diis_start=2) forte.cleanup() psi4.core.clean() energy = calc_data[-1][2] assert energy == pytest.approx(ref_energy, 1.0e-6)
def test_ccsd_3(): """Test CCSD on H4 using RHF/DZ orbitals""" import pytest import forte.proc.scc as scc import forte import psi4 forte.startup() ref_energy = -2.225059801642 # from psi4 geom = """ H 0.0 0.0 0.0 H 0.0 0.0 1.0 H 0.0 0.0 2.0 H 0.0 0.0 3.0 """ scf_energy, psi4_wfn = forte.utils.psi4_scf(geom, basis='DZ', reference='RHF') forte_objs = forte.utils.prepare_forte_objects(psi4_wfn, mo_spaces={}) calc_data = scc.run_cc(forte_objs[1], forte_objs[2], forte_objs[3], cc_type='cc', max_exc=2, on_the_fly=True) forte.cleanup() psi4.core.clean() energy = calc_data[-1][1] print(f' HF energy: {scf_energy}') print(f' CCSD energy: {energy}') print(f' E - Eref: {energy - ref_energy}') assert energy == pytest.approx(ref_energy, 1.0e-11)
def test_uccsd_4(): """Test projective UCCSD on Ne using RHF/cc-pVDZ orbitals""" import pytest import forte.proc.scc as scc import forte import psi4 forte.startup() ref_energy = -107.655681875111 geom = """ N N 1 1.3 symmetry c1 """ scf_energy, psi4_wfn = forte.utils.psi4_scf(geom, basis='sto-3g', reference='RHF') forte_objs = forte.utils.prepare_forte_objects( psi4_wfn, mo_spaces={'frozen_docc': [2]}) calc_data = scc.run_cc(forte_objs[1], forte_objs[2], forte_objs[3], cc_type='ucc', max_exc=2, e_convergence=1.0e-10) forte.cleanup() psi4.core.clean() energy = calc_data[-1][1] print(f' HF energy: {scf_energy}') print(f' CCSD energy: {energy}') print(f' corr. energy: {energy - scf_energy}') assert energy == pytest.approx(ref_energy, 1.0e-9)
def test_ccsdtq_2(): """Test CCSDTQ on H4 using RHF/cc-pVDZ orbitals""" import pytest import forte.proc.scc as scc import forte import psi4 forte.startup() ref_energy = -2.253982496764673 # from psi4 geom = """ H 0.0 0.0 0.0 H 0.0 0.0 1.0 H 0.0 0.0 2.0 H 0.0 0.0 3.0 """ scf_energy, psi4_wfn = forte.utils.psi4_scf(geom, basis='cc-pVDZ', reference='RHF') forte_objs = forte.utils.prepare_forte_objects(psi4_wfn, mo_spaces={}) calc_data = scc.run_cc(forte_objs[1], forte_objs[2], forte_objs[3], cc_type='cc', max_exc=4, e_convergence=1.0e-12) forte.cleanup() psi4.core.clean() energy = calc_data[-1][1] print(f' HF energy: {scf_energy}') print(f' CCSDTQ energy: {energy}') print(f' E - Eref: {energy - ref_energy}') assert energy == pytest.approx(ref_energy, 1.0e-11)
def test_aci1(): import math import psi4 import forte from forte import forte_options ref_aci = -75.010199198896 rel_tol = 1e-9 abs_tol = 1e-8 h2o = psi4.geometry(""" O H 1 0.96 H 1 0.96 2 104.5 """) psi4.set_options({'basis': "sto-3g"}) E_scf, wfn = psi4.energy('scf', return_wfn=True) state = forte.StateInfo(na=5, nb=5, multiplicity=1, twice_ms=0, irrep=0) dim = psi4.core.Dimension([4, 0, 1, 2]) options = psi4.core.get_options() options.set_current_module('FORTE') forte_options.update_psi_options(options) forte.startup() forte.banner() mo_space_info = forte.make_mo_space_info(wfn, forte_options) ints = forte.make_forte_integrals(wfn, options, mo_space_info) scf_info = forte.SCFInfo(wfn) solver = forte.make_active_space_solver('ACI', state, scf_info, mo_space_info, ints, forte_options) energy = solver.compute_energy() assert math.isclose(energy, ref_aci, abs_tol=abs_tol, rel_tol=rel_tol) print("\n\nACI Energy = {}".format(energy)) forte.cleanup()
def test_ccsd2(): """Test CCSD on H2 using RHF/DZ orbitals""" import forte.proc.scc as scc import forte import psi4 forte.startup() ref_energy = -76.237730204702288 # CCSD energy from psi4 geom = """ O H 1 1.0 H 1 1.0 2 104.5 """ scf_energy, psi4_wfn = forte.utils.psi4_scf(geom, basis='cc-pVDZ', reference='RHF') forte_objs = forte.utils.prepare_forte_objects(psi4_wfn, mo_spaces={}) calc_data = scc.run_cc(forte_objs[1], forte_objs[2], forte_objs[3], cc_type='cc', max_exc=2, e_convergence=1.0e-6, r_convergence=1.0e-4, compute_threshold=1.0e-6, on_the_fly=True) forte.cleanup() psi4.core.clean() energy = calc_data[-1][1] print(f' HF energy: {scf_energy}') print(f' CCSD energy: {energy}') print(f' E - Eref: {energy - ref_energy}')
def test_aci1(): import math import psi4 import forte from forte import forte_options ref_aci = -75.010199198896 rel_tol = 1e-9 abs_tol = 1e-8 h2o = psi4.geometry(""" O H 1 0.96 H 1 0.96 2 104.5 """) psi4.set_options({'basis': "sto-3g"}) E_scf, wfn = psi4.energy('scf', return_wfn=True) state = forte.StateInfo(na=5, nb=5, multiplicity=1, twice_ms=0, irrep=0) dim = psi4.core.Dimension([4, 0, 1, 2]) options = psi4.core.get_options() options.set_current_module('FORTE') forte_options.update_psi_options(options) forte.startup() forte.banner() mo_space_info = forte.make_mo_space_info(wfn, forte_options) ints = forte.make_forte_integrals(wfn, options, mo_space_info) scf_info = forte.SCFInfo(wfn) solver = forte.make_active_space_solver('ACI',state,scf_info,mo_space_info, ints, forte_options) energy = solver.compute_energy() assert math.isclose(energy,ref_aci,abs_tol=abs_tol, rel_tol=rel_tol) print("\n\nACI Energy = {}".format(energy)) forte.cleanup()
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 test_sparse_ci2(): import math import psi4 import forte import itertools import numpy as np import pytest from forte import forte_options ref_fci = -5.623851783330647 psi4.core.clean() # need to clean the options otherwise this job will interfere forte.clean_options() h2o = psi4.geometry(""" He He 1 1.0 """) psi4.set_options({'basis': 'cc-pVDZ'}) _, wfn = psi4.energy('scf', return_wfn=True) na = wfn.nalpha() nb = wfn.nbeta() nirrep = wfn.nirrep() wfn_symmetry = 0 forte.startup() forte.banner() psi4_options = psi4.core.get_options() psi4_options.set_current_module('FORTE') forte_options.get_options_from_psi4(psi4_options) # Setup forte and prepare the active space integral class nmopi = wfn.nmopi() point_group = wfn.molecule().point_group().symbol() mo_space_info = forte.make_mo_space_info(nmopi, point_group, forte_options) ints = forte.make_ints_from_psi4(wfn, forte_options, mo_space_info) as_ints = forte.make_active_space_ints(mo_space_info, ints, 'ACTIVE', ['RESTRICTED_DOCC']) print('\n\n => Sparse FCI Test <=') print(' Number of irreps: {}'.format(nirrep)) nmo = wfn.nmo() nmopi = [wfn.nmopi()[h] for h in range(nirrep)] nmopi_str = [str(wfn.nmopi()[h]) for h in range(nirrep)] mo_sym = [] for h in range(nirrep): for i in range(nmopi[h]): mo_sym.append(h) print(' Number of orbitals per irreps: [{}]'.format(','.join(nmopi_str))) print(' Symmetry of the MOs: ', mo_sym) hf_reference = forte.Determinant() hf_reference.create_alfa_bit(0) hf_reference.create_beta_bit(0) print(' Hartree-Fock determinant: {}'.format(hf_reference.str(10))) # Compute the HF energy hf_energy = as_ints.nuclear_repulsion_energy() + as_ints.slater_rules(hf_reference, hf_reference) print(' Nuclear repulsion energy: {}'.format(as_ints.nuclear_repulsion_energy())) print(' Reference energy: {}'.format(hf_energy)) # Build a list of determinants orblist = [i for i in range(nmo)] dets = [] for astr in itertools.combinations(orblist, na): for bstr in itertools.combinations(orblist, nb): sym = 0 d = forte.Determinant() for a in astr: d.create_alfa_bit(a) sym = sym ^ mo_sym[a] for b in bstr: d.create_beta_bit(b) sym = sym ^ mo_sym[b] if (sym == wfn_symmetry): dets.append(d) print(' Determinant {} has symmetry {}'.format(d.str(nmo), sym)) print(f'\n Size of the derminant basis: {len(dets)}') energy, evals, evecs, spin = forte.diag(dets, as_ints, 1, 1, "FULL") print(energy) efci = energy[0] + as_ints.nuclear_repulsion_energy() print('\n FCI Energy: {}\n'.format(efci)) assert efci == pytest.approx(ref_fci, abs=1e-9) # Clean up forte (necessary) forte.cleanup()
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 test_sparse_ci(): import math import psi4 import forte import itertools import numpy as np import pytest from forte import forte_options ref_fci = -1.101150330132956 psi4.core.clean() h2o = psi4.geometry(""" H H 1 1.0 """) psi4.set_options({'basis': 'sto-3g'}) E_scf, wfn = psi4.energy('scf', return_wfn=True) na = wfn.nalpha() nb = wfn.nbeta() nirrep = wfn.nirrep() wfn_symmetry = 0 forte.startup() forte.banner() psi4_options = psi4.core.get_options() psi4_options.set_current_module('FORTE') forte_options.get_options_from_psi4(psi4_options) # Setup forte and prepare the active space integral class mo_space_info = forte.make_mo_space_info(wfn, forte_options) ints = forte.make_forte_integrals(wfn, forte_options, mo_space_info) as_ints = forte.make_active_space_ints(mo_space_info, ints, 'ACTIVE', ['RESTRICTED_DOCC']) as_ints.print() print('\n\n => Sparse FCI Test <=') print(' Number of irreps: {}'.format(nirrep)) nmo = wfn.nmo() nmopi = [wfn.nmopi()[h] for h in range(nirrep)] nmopi_str = [str(wfn.nmopi()[h]) for h in range(nirrep)] mo_sym = [] for h in range(nirrep): for i in range(nmopi[h]): mo_sym.append(h) print(' Number of orbitals per irreps: [{}]'.format(','.join(nmopi_str))) print(' Symmetry of the MOs: ', mo_sym) hf_reference = forte.Determinant() hf_reference.create_alfa_bit(0) hf_reference.create_beta_bit(0) print(' Hartree-Fock determinant: {}'.format(hf_reference.str(2))) # Compute the HF energy hf_energy = as_ints.nuclear_repulsion_energy() + as_ints.slater_rules( hf_reference, hf_reference) print(' Nuclear repulsion energy: {}'.format( as_ints.nuclear_repulsion_energy())) print(' Reference energy: {}'.format(hf_energy)) # Build a list of determinants orblist = [i for i in range(nmo)] dets = [] for astr in itertools.combinations(orblist, na): for bstr in itertools.combinations(orblist, nb): sym = 0 d = forte.Determinant() for a in astr: d.create_alfa_bit(a) sym = sym ^ mo_sym[a] for b in bstr: d.create_beta_bit(b) sym = sym ^ mo_sym[b] if (sym == wfn_symmetry): dets.append(d) print(' Determinant {} has symmetry {}'.format( d.str(nmo), sym)) # Build the Hamiltonian matrix using 'slater_rules' nfci = len(dets) H = np.ndarray((nfci, nfci)) for I in range(nfci): # off-diagonal terms for J in range(I + 1, nfci): HIJ = as_ints.slater_rules(dets[I], dets[J]) H[I][J] = H[J][I] = HIJ # diagonal term H[I][I] = as_ints.nuclear_repulsion_energy() + as_ints.slater_rules( dets[I], dets[I]) # Find the lowest eigenvalue efci = np.linalg.eigh(H)[0][0] print('\n FCI Energy: {}\n'.format(efci)) assert efci == pytest.approx(ref_fci, 1.0e-9) # Clean up forte (necessary) forte.cleanup()
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
def __del__(cls): forte.cleanup()
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') """ # Start Forte, initialize ambit my_proc_n_nodes = forte.startup() my_proc, n_nodes = my_proc_n_nodes # Build Forte options options = prepare_forte_options() # Print the banner forte.banner() # Prepare Forte objects: state_weights_map, mo_space_info, scf_info forte_objects = prepare_forte_objects(options, name, **kwargs) ref_wfn, state_weights_map, mo_space_info, scf_info, fcidump = forte_objects # Run a method job_type = options.get_str('JOB_TYPE') if job_type == 'NONE': psi4.core.set_scalar_variable('CURRENT ENERGY', 0.0) forte.cleanup() return ref_wfn start_pre_ints = time.time() if 'FCIDUMP' in options.get_str('INT_TYPE'): psi4.core.print_out('\n Forte will use custom integrals') # Make an integral object from the psi4 wavefunction object ints = make_ints_from_fcidump(fcidump, options, mo_space_info) else: psi4.core.print_out('\n Forte will use psi4 integrals') # Make an integral object from the psi4 wavefunction object ints = forte.make_ints_from_psi4(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 energy = 0.0 if (options.get_bool("CASSCF_REFERENCE") or job_type == "CASSCF"): if options.get_str('INT_TYPE') == 'FCIDUMP': raise Exception('Forte: the CASSCF code cannot use integrals read' ' from a FCIDUMP file') casscf = forte.make_casscf(state_weights_map, scf_info, options, mo_space_info, ints) energy = casscf.compute_energy() if (job_type == "MCSCF_TWO_STEP"): casscf = forte.make_mcscf_two_step(state_weights_map, scf_info, options, mo_space_info, ints) energy = casscf.compute_energy() if (job_type == 'NEWDRIVER'): energy = forte_driver(state_weights_map, scf_info, options, ints, mo_space_info) elif (job_type == 'MR-DSRG-PT2'): energy = mr_dsrg_pt2(job_type,forte_objects,ints,options) 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_pre_ints:12.3f} seconds\n') if 'FCIDUMP' not in options.get_str('INT_TYPE'): if options.get_bool('DUMP_ORBITALS'): dump_orbitals(ref_wfn) return ref_wfn
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 """ # Start Forte, initialize ambit my_proc_n_nodes = forte.startup() my_proc, n_nodes = my_proc_n_nodes # Get the psi4 option object optstash = p4util.OptionsState(['GLOBALS', 'DERTYPE']) psi4.core.set_global_option('DERTYPE', 'FIRST') # Build Forte options options = prepare_forte_options() # Print the banner forte.banner() # Run a method job_type = options.get_str('JOB_TYPE') if job_type not in {"CASSCF", "MCSCF_TWO_STEP"}: raise Exception('Analytic energy gradients are only implemented for job_types CASSCF and MCSCF_TWO_STEP.') # Prepare Forte objects: state_weights_map, mo_space_info, scf_info forte_objects = prepare_forte_objects(options, name, **kwargs) ref_wfn, state_weights_map, mo_space_info, scf_info, fcidump = forte_objects # Make an integral object time_pre_ints = time.time() ints = forte.make_ints_from_psi4(ref_wfn, options, mo_space_info) start = time.time() # 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) if job_type == "CASSCF": casscf = forte.make_casscf(state_weights_map, scf_info, options, mo_space_info, ints) energy = casscf.compute_energy() casscf.compute_gradient(); if job_type == "MCSCF_TWO_STEP": casscf = forte.make_mcscf_two_step(state_weights_map, scf_info, options, mo_space_info, ints) energy = casscf.compute_energy() time_pre_deriv = time.time() 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() # Close ambit, etc. forte.cleanup() # Print timings psi4.core.print_out('\n\n ==> Forte Timings <==\n') times = [('prepare integrals', start - time_pre_ints), ('run forte energy', time_pre_deriv - start), ('compute derivative integrals', end - time_pre_deriv)] max_key_size = max(len(k) for k, v in times) for key, value in times: psi4.core.print_out(f'\n Time to {key:{max_key_size}} :' f' {value:12.3f} seconds') psi4.core.print_out(f'\n {"Total":{max_key_size + 8}} :' f' {end - time_pre_ints:12.3f} seconds\n') # Dump orbitals if needed if options.get_bool('DUMP_ORBITALS'): dump_orbitals(ref_wfn) return ref_wfn