示例#1
0
def run_pyscf(molecule,
              run_fci=False,
              verbose=False,
              n_frozen_orbital=0,
              n_cancel_orbital=0,
              cas_irrep_nocc=None,
              cas_irrep_ncore=None):  # ZZJ CHANGE
    """
    This function runs a pyscf calculation.

    Args:
        molecule: An instance of the MolecularData or PyscfMolecularData class.
        run_scf: Optional boolean to run SCF calculation.
        run_mp2: Optional boolean to run MP2 calculation.
        run_cisd: Optional boolean to run CISD calculation.
        run_ccsd: Optional boolean to run CCSD calculation.
        run_fci: Optional boolean to FCI calculation.  ## NOTICE !!! FCI is changed to only done in the active space --- ZZJ CHANGE
        verbose: Boolean whether to print calculation results to screen.

    Returns:
        molecule: The updated PyscfMolecularData object. Note the attributes
        of the input molecule are also updated in this function.
    """
    run_scf = True  # ZZJ CHANGE scf must be run
    # Prepare pyscf molecule.
    pyscf_molecule = prepare_pyscf_molecule(molecule)
    molecule.n_orbitals = int(pyscf_molecule.nao_nr())
    molecule.n_qubits = 2 * molecule.n_orbitals
    molecule.nuclear_repulsion = float(pyscf_molecule.energy_nuc())

    # Run SCF.
    pyscf_scf = compute_scf(pyscf_molecule)
    pyscf_scf.verbose = 0
    pyscf_scf.run()
    molecule.hf_energy = float(pyscf_scf.e_tot)
    if verbose:
        print('Hartree-Fock energy for {} ({} electrons) is {}.'.format(
            molecule.name, molecule.n_electrons, molecule.hf_energy))

    # Hold pyscf data in molecule. They are required to compute density
    # matrices and other quantities.
    molecule._pyscf_data = pyscf_data = {}
    pyscf_data['mol'] = pyscf_molecule
    pyscf_data['scf'] = pyscf_scf

    # Populate fields.
    molecule.canonical_orbitals = pyscf_scf.mo_coeff.astype(float)
    molecule.orbital_energies = pyscf_scf.mo_energy.astype(float)

    # Get integrals.
    one_body_integrals, two_body_integrals = compute_integrals(
        pyscf_molecule, pyscf_scf)
    molecule.one_body_integrals = one_body_integrals
    molecule.two_body_integrals = two_body_integrals
    molecule.overlap_integrals = pyscf_scf.get_ovlp()

    # Run FCI.
    if run_fci:
        # pyscf_fci = fci.FCI(pyscf_scf)
        # pyscf_fci.verbose = 0
        # molecule.fci_energy, molecule.fci_wfn = pyscf_fci.kernel()
        # pyscf_data['fci'] = pyscf_fci
        # pyscf_data['fci_wfn'] = molecule.fci_wfn

        nelec = molecule.n_electrons - n_frozen_orbital * 2
        norb = molecule.n_orbitals - n_cancel_orbital - n_frozen_orbital
        pyscf_fci = mcscf.CASCI(pyscf_scf, norb, nelec)
        pyscf_fci.verbose = 0
        if cas_irrep_nocc != None:
            molecule.active_orbitals = mcscf.caslst_by_irrep(
                pyscf_fci, pyscf_scf.mo_coeff, cas_irrep_nocc, cas_irrep_ncore)
            mo = pyscf_fci.sort_mo_by_irrep(cas_irrep_nocc, cas_irrep_ncore)
            frozen_orbitals_0 = [
                i for i in range(molecule.active_orbitals[norb - 1] + 1)
            ]
            for i in range(len(molecule.active_orbitals)):
                molecule.active_orbitals[i] -= 1
                frozen_orbitals_0[molecule.active_orbitals[i]] = -1
            molecule.frozen_orbitals = []
            for orb in frozen_orbitals_0:
                if orb != -1:
                    molecule.frozen_orbitals.append(orb)
                if n_frozen_orbital == len(molecule.frozen_orbitals):
                    break

            pyscf_data['active_orbitals'] = molecule.active_orbitals
            pyscf_data['frozen_orbitals'] = molecule.frozen_orbitals
        else:
            mo = None
            molecule.active_orbitals = [
                i for i in range(n_frozen_orbital, n_frozen_orbital + norb)
            ]
            molecule.frozen_orbitals = [i for i in range(n_frozen_orbital)]

        fci_result = pyscf_fci.kernel(mo)
        pyscf_fci.analyze()
        molecule.fci_energy = fci_result[0]
        molecule.fci_wfn = fci_result[2]

        if verbose:
            print('FCI energy for {} ({} electrons) is {}.'.format(
                molecule.name, molecule.n_electrons, molecule.fci_energy))

    # Return updated molecule instance.
    pyscf_molecular_data = PyscfMolecularData.__new__(PyscfMolecularData)
    pyscf_molecular_data.__dict__.update(molecule.__dict__)
    pyscf_molecular_data.save()
    return pyscf_molecular_data
示例#2
0
def run_pyscf(molecule,
              run_scf=True,
              run_mp2=False,
              run_cisd=False,
              run_ccsd=False,
              run_fci=False,
              verbose=False):
    """
    This function runs a pyscf calculation.

    Args:
        molecule: An instance of the MolecularData or PyscfMolecularData class.
        run_scf: Optional boolean to run SCF calculation.
        run_mp2: Optional boolean to run MP2 calculation.
        run_cisd: Optional boolean to run CISD calculation.
        run_ccsd: Optional boolean to run CCSD calculation.
        run_fci: Optional boolean to FCI calculation.
        verbose: Boolean whether to print calculation results to screen.

    Returns:
        molecule: The updated PyscfMolecularData object. Note the attributes
        of the input molecule are also updated in this function.
    """
    # Prepare pyscf molecule.
    pyscf_molecule = prepare_pyscf_molecule(molecule)
    molecule.n_orbitals = int(pyscf_molecule.nao_nr())
    molecule.n_qubits = 2 * molecule.n_orbitals
    molecule.nuclear_repulsion = float(pyscf_molecule.energy_nuc())

    # Run SCF.
    pyscf_scf = compute_scf(pyscf_molecule)
    pyscf_scf.verbose = 0

    # Custom properties
    pyscf_scf.chkfile = 'chkfiles/rohf.chk'
    pyscf_scf.init_guess = 'chkfile'
    #pyscf_scf.max_cycle = 1000
    pyscf_scf.max_cycle = 0  # Use chkfile
    pyscf_scf.verbose = 4

    pyscf_scf.run()
    pyscf_scf.analyze()
    molecule.hf_energy = float(pyscf_scf.e_tot)
    if verbose:
        print('Hartree-Fock energy for {} ({} electrons) is {}.'.format(
            molecule.name, molecule.n_electrons, molecule.hf_energy))

    # Hold pyscf data in molecule. They are required to compute density
    # matrices and other quantities.
    molecule._pyscf_data = pyscf_data = {}
    pyscf_data['mol'] = pyscf_molecule
    pyscf_data['scf'] = pyscf_scf

    # Populate fields.
    molecule.canonical_orbitals = pyscf_scf.mo_coeff.astype(float)
    molecule.orbital_energies = pyscf_scf.mo_energy.astype(float)

    # Get integrals.
    # Try to load integrals from file if they exist
    try:
        print("Attempting to load integrals...")
        one_body_integrals = np.load("1e-integrals.npy")
        two_body_integrals = np.load("2e-integrals.npy")
    except FileNotFoundError:
        print("Integrals not found. Recalculating...")
        one_body_integrals, two_body_integrals = compute_integrals(
            pyscf_molecule, pyscf_scf)

        np.save("1e-integrals.npy", one_body_integrals)
        np.save("2e-integrals.npy", two_body_integrals)
    print("Integrals loaded")

    molecule.one_body_integrals = one_body_integrals
    molecule.two_body_integrals = two_body_integrals
    molecule.overlap_integrals = pyscf_scf.get_ovlp()

    # Run MP2.
    if run_mp2:
        if molecule.multiplicity != 1:
            print("WARNING: RO-MP2 is not available in PySCF.")
        else:
            pyscf_mp2 = mp.MP2(pyscf_scf)
            pyscf_mp2.verbose = 0
            pyscf_mp2.run()
            # molecule.mp2_energy = pyscf_mp2.e_tot  # pyscf-1.4.4 or higher
            molecule.mp2_energy = pyscf_scf.e_tot + pyscf_mp2.e_corr
            pyscf_data['mp2'] = pyscf_mp2
            if verbose:
                print('MP2 energy for {} ({} electrons) is {}.'.format(
                    molecule.name, molecule.n_electrons, molecule.mp2_energy))

    # Run CISD.
    if run_cisd:
        pyscf_cisd = ci.CISD(pyscf_scf)
        pyscf_cisd.verbose = 0
        pyscf_cisd.run()
        molecule.cisd_energy = pyscf_cisd.e_tot
        pyscf_data['cisd'] = pyscf_cisd
        if verbose:
            print('CISD energy for {} ({} electrons) is {}.'.format(
                molecule.name, molecule.n_electrons, molecule.cisd_energy))

    # Run CCSD.
    if run_ccsd:
        pyscf_ccsd = cc.CCSD(pyscf_scf)
        pyscf_ccsd.verbose = 0
        pyscf_ccsd.run()
        molecule.ccsd_energy = pyscf_ccsd.e_tot
        pyscf_data['ccsd'] = pyscf_ccsd
        if verbose:
            print('CCSD energy for {} ({} electrons) is {}.'.format(
                molecule.name, molecule.n_electrons, molecule.ccsd_energy))

    # Run FCI.
    if run_fci:
        pyscf_fci = fci.FCI(pyscf_molecule, pyscf_scf.mo_coeff)
        pyscf_fci.verbose = 0
        molecule.fci_energy = pyscf_fci.kernel()[0]
        pyscf_data['fci'] = pyscf_fci
        if verbose:
            print('FCI energy for {} ({} electrons) is {}.'.format(
                molecule.name, molecule.n_electrons, molecule.fci_energy))

    # Return updated molecule instance.
    print("Ending pyscf...")
    pyscf_molecular_data = PyscfMolecularData.__new__(PyscfMolecularData)
    pyscf_molecular_data.__dict__.update(molecule.__dict__)
    print("Saving...")
    #pyscf_molecular_data.save()
    print("Saved")
    return pyscf_molecular_data