コード例 #1
0
def run(r, xc, ot_name, chkfile):
    r /= 2
    mol = gto.M(atom=f'H  0 0 {r}; H 0 0 -{r}',
                basis='cc-pvtz',
                symmetry=False,
                verbose=0)
    mf = scf.RHF(mol)
    mf.kernel()
    mc = mcdcft.CASSCF(mf, xc, 2, 2, ot_name=ot_name, grids_level=6)
    mc.fcisolver = csf_solver(mol, smult=1)
    mc.chkfile = chkfile
    mc.kernel()
    mc.dump_mcdcft_chk(chkfile)
    return mc.e_tot
コード例 #2
0
ファイル: test_grad_h2co.py プロジェクト: hebrewsnabla/mrh
def get_mc_ref(mol, ri=False, sa2=False):
    mf = scf.RHF(mol)
    if ri: mf = mf.density_fit(auxbasis=df.aug_etb(mol))
    mc = mcpdft.CASSCF(mf.run(), 'tPBE', 6, 6, grids_level=6)
    if sa2:
        fcisolvers = [csf_solver(mol, smult=((2 * i) + 1)) for i in (0, 1)]
        if mol.symmetry:
            fcisolvers[0].wfnsym = 'A1'
            fcisolvers[1].wfnsym = 'A2'
        mc = mc.state_average_mix_(fcisolvers, [0.5, 0.5])
        ref = np.load('h2co_sa2_tpbe66_631g_grad_num.npy').reshape(2, 2, 4,
                                                                   3)[int(ri)]
    else:
        ref = np.load('h2co_tpbe66_631g_grad_num.npy')[int(ri)]
    return mc.run(), ref
コード例 #3
0
ファイル: lasci_ominus1.py プロジェクト: hebrewsnabla/mrh
def get_init_guess (fci, norb, nelec, norb_f, h1, h2, nelec_f=None, smult_f=None):
    if nelec_f is None:
        nelec_f = _guess_nelec_f (fci, norb, nelec, norb_f, h1, h2)
    if smult_f is None:
        smult_f = [abs(n[0]-n[1])+1 for n in nelec_f]
    h2 = ao2mo.restore (1, h2, norb)
    i = 0
    ci0_f = []
    for no, ne, s in zip (norb_f, nelec_f, smult_f):
        j = i + no
        h1_i = h1[i:j,i:j]
        h2_i = h2[i:j,i:j,i:j,i:j]
        i = j
        csf = csf_solver (fci.mol, smult=s)
        hdiag = csf.make_hdiag_csf (h1_i, h2_i, no, ne)
        ci = csf.get_init_guess (no, ne, 1, hdiag)[0]
        ci = np.squeeze (fockspace.hilbert2fock (ci, no, ne))
        ci0_f.append (ci)
    return ci0_f
コード例 #4
0
    print("eta = {:.2f} degrees".format(out_of_plane_angle(carts, 0, 2, 3, 1)))


# Energy calculation at initial geometry
h2co_casscf66_631g_xyz = '''C  0.534004  0.000000  0.000000
O -0.676110  0.000000  0.000000
H  1.102430  0.000000  0.920125
H  1.102430  0.000000 -0.920125'''
mol = gto.M(atom=h2co_casscf66_631g_xyz,
            basis='6-31g',
            symmetry=False,
            verbose=logger.INFO,
            output='h2co_sa2_tpbe66_631g_opt0.log')
mf = scf.RHF(mol).run()
mc = mcpdft.CASSCF(mf, 'tPBE', 6, 6, grids_level=9)
mc.fcisolver = csf_solver(mol, smult=1)
mc.state_average_([0.5, 0.5])
mc.kernel()

# Geometry optimization (my_call is optional; it just prints the geometry in internal coordinates every iteration)
print("Initial geometry: ")
h2co_geom_analysis(mol.atom_coords() * BOHR)
print("Initial energy: {:.8e}".format(mc.e_states[0]))


def my_call(env):
    carts = env['mol'].atom_coords() * BOHR
    h2co_geom_analysis(carts)


conv_params = {
コード例 #5
0
from mrh.my_pyscf.df.grad import dfsacasscf as casscf_grad
from mrh.my_pyscf.grad import numeric as numeric_grad
from mrh.my_pyscf.fci import csf_solver

h2co_casscf66_631g_xyz = '''C  0.534004  0.000000  0.000000
O -0.676110  0.000000  0.000000
H  1.102430  0.000000  0.920125
H  1.102430  0.000000 -0.920125'''
mol = gto.M(atom=h2co_casscf66_631g_xyz,
            basis='6-31g',
            symmetry=False,
            verbose=lib.logger.INFO,
            output='h2co_sa2_casscf66_631g_grad.log')
mf_conv = scf.RHF(mol).run()
mc_conv = mcscf.CASSCF(mf_conv, 6, 6)
mc_conv.fcisolver = csf_solver(mol, smult=1)
mc_conv = mc_conv.state_average_([0.5, 0.5])
mc_conv.conv_tol = 1e-10
mc_conv.kernel()

mf = scf.RHF(mol).density_fit(auxbasis=df.aug_etb(mol)).run()
mc = mcscf.CASSCF(mf, 6, 6)
mc.fcisolver = csf_solver(mol, smult=1)
mc = mc.state_average_([0.5, 0.5])
mc.conv_tol = 1e-10
mc.kernel()

numgrad_conv = numeric_grad.Gradients(mc_conv).run()
print("First state")
de_conv = mc_conv.nuc_grad_method().kernel(state=0)
print("Conventional ERI analytic:\n", de_conv)
コード例 #6
0
from mrh.my_pyscf.fci import csf_solver
import unittest

Natom = scf.RHF(
    gto.M(atom='N 0 0 0',
          basis='cc-pvtz',
          spin=3,
          symmetry='Dooh',
          output='/dev/null')).run()
Beatom = scf.RHF(
    gto.M(atom='Be 0 0 0',
          basis='cc-pvtz',
          spin=2,
          symmetry=False,
          output='/dev/null')).run()
Natom_hs = mcscf.CASSCF(Natom, 4, (4, 1)).set(fcisolver=csf_solver(Natom.mol,
                                                                   smult=4),
                                              conv_tol=1e-10).run()
Natom_ls = mcscf.CASSCF(Natom, 4, (3, 2)).set(fcisolver=csf_solver(Natom.mol,
                                                                   smult=2),
                                              conv_tol=1e-10).run()
Beatom_ls = mcscf.CASSCF(Beatom, 4,
                         (1, 1)).set(fcisolver=csf_solver(Beatom.mol, smult=1),
                                     conv_tol=1e-10).run()
Beatom_hs = mcscf.CASSCF(Beatom, 4,
                         (2, 0)).set(fcisolver=csf_solver(Beatom.mol, smult=3),
                                     conv_tol=1e-10).run()


def get_gap(gs, es, fnal):
    e0 = mcpdft.CASSCF(gs._scf, fnal, gs.ncas, gs.nelecas,
                       grids_level=9).set(fcisolver=gs.fcisolver,
コード例 #7
0
conv_params = {
    'convergence_energy': 1e-6,  # Eh
    'convergence_grms': 5.0e-5,  # Eh/Bohr
    'convergence_gmax': 7.5e-5,  # Eh/Bohr
    'convergence_drms': 1.0e-4,  # Angstrom
    'convergence_dmax': 1.5e-4,  # Angstrom
}

h2co_casscf66_631g_xyz = '''C  0.534004  0.000000  0.000000
O -0.676110  0.000000  0.000000
H  1.102430  0.000000  0.920125
H  1.102430  0.000000 -0.920125'''
mol = gto.M (atom = h2co_casscf66_631g_xyz, basis = '6-31g', symmetry = True, verbose = lib.logger.INFO, output = 'h2co_sa2_tpbe66_631g_symm_opt.log')
mf_conv = scf.RHF (mol).run ()
mc_conv = mcpdft.CASSCF (mf_conv, 'tPBE', 6, 6, grids_level=6)
fcisolvers = [csf_solver (mol, smult=1) for i in (0,1)]
fcisolvers[0].wfnsym = 'A1'
fcisolvers[1].wfnsym = 'A2'
mc_conv = mc_conv.state_average_mix_(fcisolvers, [0.5,0.5])
mc_conv.conv_tol = 1e-10
mc_conv.kernel ()

mf = scf.RHF (mol).density_fit (auxbasis = df.aug_etb (mol)).run ()
mc_df = mcpdft.CASSCF (mf, 'tPBE', 6, 6, grids_level=6)
fcisolvers = [csf_solver (mol, smult=1) for i in (0,1)]
fcisolvers[0].wfnsym = 'A1'
fcisolvers[1].wfnsym = 'A2'
mc_df = mc_df.state_average_mix_(fcisolvers, [0.5,0.5])
mc_df.conv_tol = 1e-10
mc_df.kernel ()
コード例 #8
0
import numpy as np
from pyscf import gto, scf, mcscf, lib
from mrh.my_pyscf.fci import csf_solver
from mrh.exploratory.unitary_cc import uccsd_sym0
from mrh.exploratory.unitary_cc import uccsd_sym1
import unittest, math

mol = gto.M (atom = 'H 0 0 0; H 1.5 0 0', basis='6-31g', verbose=0, output='/dev/null')
rhf = scf.RHF (mol).run ()
uhf = scf.UHF (mol)
dm_a, dm_b = uhf.get_init_guess ()
dm_b[:2,:2] = 0.0
uhf.kernel ((dm_a, dm_b))
fci = mcscf.CASSCF (rhf, 4, 2).set (fcisolver = csf_solver (mol, smult=1)).run ()

def tearDownModule():
    global mol, rhf, uhf, fci
    mol.stdout.close ()
    del mol, rhf, uhf, fci

class KnownValues(unittest.TestCase):

    def test_sym0_uccs (self):
        np.random.seed (1) 
        x0 = (1 - 2*np.random.rand (28))*math.pi/2
        uccs = uccsd_sym0.UCCS (mol).run (x=x0)
        self.assertAlmostEqual (uhf.e_tot, uccs.e_tot, 6)

    def test_sym0_uccsd (self):
        uccsd = uccsd_sym0.UCCSD (mol).run ()
        self.assertAlmostEqual (uccsd.e_tot, fci.e_tot, 6)
コード例 #9
0
from mrh.my_pyscf.tools import molden as molden
from mrh.my_pyscf.fci import csf_solver
from mrh.my_pyscf.mcscf.lasscf_o0 import LASSCF
from mrh.exploratory.citools.lasci_ominus1 import FCISolver as lasci
from mrh.exploratory.unitary_cc.lasuccsd import FCISolver as lasucc
from mrh.exploratory.citools import fockspace

norb = 8
nelec = 8
norb_f = (4,4)
nelec_f = ((2,2),(2,2))
mol = structure (0.0, 0.0, output='c4h6_equil_631g.log', verbose=logger.DEBUG)
mf = scf.RHF (mol).run ()

# CASSCF (for orbital initialization)
mc = mcscf.CASSCF (mf, norb, nelec).set (fcisolver = csf_solver (mol, smult=1))
mo_coeff = mc.sort_mo ([11,12,14,15,16,17,21,24])
mc.kernel (mo_coeff)
mo_coeff = mc.mo_coeff.copy ()

# LASSCF (for comparison)
las = LASSCF (mf, norb_f, nelec_f, spin_sub=(1,1)).set (mo_coeff=mo_coeff)
mo_loc = las.localize_init_guess ([[0,1,2,3,4],[5,6,7,8,9]])
ncore, ncas, nmo = las.ncore, las.ncas, mo_coeff.shape[1]
e_las = las.kernel (mo_loc)[0]
#mo_loc = las.localize_init_guess ([[0,1,2,3,4],[5,6,7,8,9]],
#    freeze_cas_spaces=True)
mo_loc = las.mo_coeff.copy ()
molden.from_lasscf (las, 'c4h6_equil_lasscf88_631g.molden')

# CASCI (for comparison)
コード例 #10
0
    # code in this block will only execute if you run this python script as the
    # input directly: "python cmspdft3.py".

    from pyscf import scf
    from mrh.my_pyscf.tools import molden  # My version is better for MC-SCF
    from mrh.my_pyscf.fci import csf_solver
    xyz = '''O  0.00000000   0.08111156   0.00000000
             H  0.78620605   0.66349738   0.00000000
             H -0.78620605   0.66349738   0.00000000'''
    mol = gto.M(atom=xyz,
                basis='sto-3g',
                symmetry=False,
                output='cmspdft3.log',
                verbose=lib.logger.DEBUG)
    mf = scf.RHF(mol).run()
    mc = mcpdft.CASSCF(mf, 'tPBE', 4, 4).set(fcisolver=csf_solver(mol, 1))
    mc = mc.state_average([
        1.0 / 3,
    ] * 3).run()
    molden.from_sa_mcscf(mc, 'h2o_sapdft_sa.molden', cas_natorb=True)
    # ^ molden file with state-averaged NOs
    for i in range(3):
        fname = 'h2o_sapdft_ref{}.molden'.format(i)
        # ^ molden file with ith reference state NOs
        molden.from_sa_mcscf(mc, fname, state=i, cas_natorb=True)

    conv, E_int, ci_int = kernel(mc, 3)
    print("The iteration did{} converge".format((' not', '')[int(conv)]))
    print("The intermediate-state energies are", E_int)
    print(("Molden files with intermediate-state NOs are in "
           "h2o_sapdft_int?.molden"))
コード例 #11
0
ファイル: pyscf_casscf.py プロジェクト: hebrewsnabla/mrh
def solve (frag, guess_1RDM, chempot_imp):

    # Augment OEI with the chemical potential
    OEI = frag.impham_OEI_C - chempot_imp

    # Do I need to get the full RHF solution?
    guess_orbs_av = len (frag.imp_cache) == 2 or frag.norbs_as > 0 

    # Get the RHF solution
    mol = gto.Mole()
    abs_2MS = int (round (2 * abs (frag.target_MS)))
    abs_2S = int (round (2 * abs (frag.target_S)))
    sign_MS = int (np.sign (frag.target_MS)) or 1
    mol.spin = abs_2MS
    mol.verbose = 0 
    if frag.mol_stdout is None:
        mol.output = frag.mol_output
        mol.verbose = 0 if frag.mol_output is None else lib.logger.DEBUG
    mol.atom.append(('H', (0, 0, 0)))
    mol.nelectron = frag.nelec_imp
    if frag.enforce_symmetry:
        mol.groupname  = frag.symmetry
        mol.symm_orb   = get_subspace_symmetry_blocks (frag.loc2imp, frag.loc2symm)
        mol.irrep_name = frag.ir_names
        mol.irrep_id   = frag.ir_ids
    mol.max_memory = frag.ints.max_memory
    mol.build ()
    if frag.mol_stdout is None:
        frag.mol_stdout = mol.stdout
    else:
        mol.stdout = frag.mol_stdout
        mol.verbose = 0 if frag.mol_output is None else lib.logger.DEBUG
    if frag.enforce_symmetry: mol.symmetry = True
    #mol.incore_anyway = True
    mf = scf.RHF(mol)
    mf.get_hcore = lambda *args: OEI
    mf.get_ovlp = lambda *args: np.eye(frag.norbs_imp)
    mf.energy_nuc = lambda *args: frag.impham_CONST
    if frag.impham_CDERI is not None:
        mf = mf.density_fit ()
        mf.with_df._cderi = frag.impham_CDERI
    else:
        mf._eri = ao2mo.restore(8, frag.impham_TEI, frag.norbs_imp)
    mf = fix_my_RHF_for_nonsinglet_env (mf, frag.impham_OEI_S)
    mf.__dict__.update (frag.mf_attr)
    if guess_orbs_av: mf.max_cycle = 2
    mf.scf (guess_1RDM)
    if (not mf.converged) and (not guess_orbs_av):
        if np.any (np.abs (frag.impham_OEI_S) > 1e-8) and mol.spin != 0:
            raise NotImplementedError('Gradient and Hessian fixes for nonsinglet environment of Newton-descent ROHF algorithm')
        print ("CASSCF RHF-step not converged on fixed-point iteration; initiating newton solver")
        mf = mf.newton ()
        mf.kernel ()

    # Instability check and repeat
    if not guess_orbs_av:
        for i in range (frag.num_mf_stab_checks):
            if np.any (np.abs (frag.impham_OEI_S) > 1e-8) and mol.spin != 0:
                raise NotImplementedError('ROHF stability-check fixes for nonsinglet environment')
            mf.mo_coeff = mf.stability ()[0]
            guess_1RDM = mf.make_rdm1 ()
            mf = scf.RHF(mol)
            mf.get_hcore = lambda *args: OEI
            mf.get_ovlp = lambda *args: np.eye(frag.norbs_imp)
            mf._eri = ao2mo.restore(8, frag.impham_TEI, frag.norbs_imp)
            mf = fix_my_RHF_for_nonsinglet_env (mf, frag.impham_OEI_S)
            mf.scf (guess_1RDM)
            if not mf.converged:
                mf = mf.newton ()
                mf.kernel ()

    E_RHF = mf.e_tot
    print ("CASSCF RHF-step energy: {}".format (E_RHF))

    # Get the CASSCF solution
    CASe = frag.active_space[0]
    CASorb = frag.active_space[1] 
    checkCAS =  (CASe <= frag.nelec_imp) and (CASorb <= frag.norbs_imp)
    if (checkCAS == False):
        CASe = frag.nelec_imp
        CASorb = frag.norbs_imp
    if (abs_2MS > abs_2S):
        CASe = ((CASe + sign_MS * abs_2S) // 2, (CASe - sign_MS * abs_2S) // 2)
    else:
        CASe = ((CASe + sign_MS * abs_2MS) // 2, (CASe - sign_MS * abs_2MS) // 2)
    if frag.impham_CDERI is not None:
        mc = mcscf.DFCASSCF(mf, CASorb, CASe)
    else:
        mc = mcscf.CASSCF(mf, CASorb, CASe)
    smult = abs_2S + 1 if frag.target_S is not None else (frag.nelec_imp % 2) + 1
    mc.fcisolver = csf_solver (mf.mol, smult, symm=frag.enforce_symmetry)
    if frag.enforce_symmetry: mc.fcisolver.wfnsym = frag.wfnsym
    mc.max_cycle_macro = 50 if frag.imp_maxiter is None else frag.imp_maxiter
    mc.conv_tol = min (1e-9, frag.conv_tol_grad**2)  
    mc.ah_start_tol = mc.conv_tol / 10
    mc.ah_conv_tol = mc.conv_tol / 10
    mc.__dict__.update (frag.corr_attr)
    mc = fix_my_CASSCF_for_nonsinglet_env (mc, frag.impham_OEI_S)
    norbs_amo = mc.ncas
    norbs_cmo = mc.ncore
    norbs_imo = frag.norbs_imp - norbs_amo
    nelec_amo = sum (mc.nelecas)
    norbs_occ = norbs_amo + norbs_cmo
    #mc.natorb = True

    # Guess orbitals
    ci0 = None
    dm_imp = frag.get_oneRDM_imp ()
    fock_imp = mf.get_fock (dm=dm_imp)
    if len (frag.imp_cache) == 2:
        imp2mo, ci0 = frag.imp_cache
        print ("Taking molecular orbitals and ci vector from cache")
    elif frag.norbs_as > 0:
        nelec_imp_guess = int (round (np.trace (frag.oneRDMas_loc)))
        norbs_cmo_guess = (frag.nelec_imp - nelec_imp_guess) // 2
        print ("Projecting stored amos (frag.loc2amo; spanning {} electrons) onto the impurity basis and filling the remainder with default guess".format (nelec_imp_guess))
        imp2mo, my_occ = project_amo_manually (frag.loc2imp, frag.loc2amo, fock_imp, norbs_cmo_guess, dm=frag.oneRDMas_loc)
    elif frag.loc2amo_guess is not None:
        print ("Projecting stored amos (frag.loc2amo_guess) onto the impurity basis (no amo dm available)")
        imp2mo, my_occ = project_amo_manually (frag.loc2imp, frag.loc2amo_guess, fock_imp, norbs_cmo, dm=None)
        frag.loc2amo_guess = None
    else:
        dm_imp = np.asarray (mf.make_rdm1 ())
        while dm_imp.ndim > 2:
            dm_imp = dm_imp.sum (0)
        imp2mo = mf.mo_coeff
        fock_imp = mf.get_fock (dm=dm_imp)
        fock_mo = represent_operator_in_basis (fock_imp, imp2mo)
        _, evecs = matrix_eigen_control_options (fock_mo, sort_vecs=1)
        imp2mo = imp2mo @ evecs
        my_occ = ((dm_imp @ imp2mo) * imp2mo).sum (0)
        print ("No stored amos; using mean-field canonical MOs as initial guess")
    # Guess orbital processing
    if callable (frag.cas_guess_callback):
        mo = reduce (np.dot, (frag.ints.ao2loc, frag.loc2imp, imp2mo))
        mo = frag.cas_guess_callback (frag.ints.mol, mc, mo)
        imp2mo = reduce (np.dot, (frag.imp2loc, frag.ints.ao2loc.conjugate ().T, frag.ints.ao_ovlp, mo))
        frag.cas_guess_callback = None

    # Guess CI vector
    if len (frag.imp_cache) != 2 and frag.ci_as is not None:
        loc2amo_guess = np.dot (frag.loc2imp, imp2mo[:,norbs_cmo:norbs_occ])
        metric = np.arange (CASorb) + 1
        gOc = np.dot (loc2amo_guess.conjugate ().T, (frag.ci_as_orb * metric[None,:]))
        umat_g, svals, umat_c = matrix_svd_control_options (gOc, sort_vecs=1, only_nonzero_vals=True)
        if (svals.size == norbs_amo):
            print ("Loading ci guess despite shifted impurity orbitals; singular value error sum: {}".format (np.sum (svals - metric)))
            imp2mo[:,norbs_cmo:norbs_occ] = np.dot (imp2mo[:,norbs_cmo:norbs_occ], umat_g)
            ci0 = transform_ci_for_orbital_rotation (frag.ci_as, CASorb, CASe, umat_c)
        else:
            print ("Discarding stored ci guess because orbitals are too different (missing {} nonzero svals)".format (norbs_amo-svals.size))

    # Symmetry align if possible
    imp2unac = frag.align_imporbs_symm (np.append (imp2mo[:,:norbs_cmo], imp2mo[:,norbs_occ:], axis=1), sorting_metric=fock_imp,
        sort_vecs=1, orbital_type='guess unactive', mol=mol)[0]
    imp2mo[:,:norbs_cmo] = imp2unac[:,:norbs_cmo]
    imp2mo[:,norbs_occ:] = imp2unac[:,norbs_cmo:]
    #imp2mo[:,:norbs_cmo] = frag.align_imporbs_symm (imp2mo[:,:norbs_cmo], sorting_metric=fock_imp, sort_vecs=1, orbital_type='guess inactive', mol=mol)[0]
    imp2mo[:,norbs_cmo:norbs_occ], umat = frag.align_imporbs_symm (imp2mo[:,norbs_cmo:norbs_occ], sorting_metric=fock_imp,
        sort_vecs=1, orbital_type='guess active', mol=mol)
    #imp2mo[:,norbs_occ:] = frag.align_imporbs_symm (imp2mo[:,norbs_occ:], sorting_metric=fock_imp, sort_vecs=1, orbital_type='guess external', mol=mol)[0]
    if frag.enforce_symmetry:
        imp2mo = cleanup_subspace_symmetry (imp2mo, mol.symm_orb)
        err_symm = measure_subspace_blockbreaking (imp2mo, mol.symm_orb)
        err_orth = measure_basis_nonorthonormality (imp2mo)
        print ("Initial symmetry error after cleanup = {}".format (err_symm))
        print ("Initial orthonormality error after cleanup = {}".format (err_orth))
    if ci0 is not None: ci0 = transform_ci_for_orbital_rotation (ci0, CASorb, CASe, umat)
        

    # Guess orbital printing
    if frag.mfmo_printed == False and frag.ints.mol.verbose:
        ao2mfmo = reduce (np.dot, [frag.ints.ao2loc, frag.loc2imp, imp2mo])
        print ("Writing {} {} orbital molden".format (frag.frag_name, 'CAS guess'))
        molden.from_mo (frag.ints.mol, frag.filehead + frag.frag_name + '_mfmorb.molden', ao2mfmo, occ=my_occ)
        frag.mfmo_printed = True
    elif len (frag.active_orb_list) > 0: # This is done AFTER everything else so that the _mfmorb.molden always has consistent ordering
        print('Applying caslst: {}'.format (frag.active_orb_list))
        imp2mo = mc.sort_mo(frag.active_orb_list, mo_coeff=imp2mo)
        frag.active_orb_list = []
    if len (frag.frozen_orb_list) > 0:
        mc.frozen = copy.copy (frag.frozen_orb_list)
        print ("Applying frozen-orbital list (this macroiteration only): {}".format (frag.frozen_orb_list))
        frag.frozen_orb_list = []

    if frag.enforce_symmetry: imp2mo = lib.tag_array (imp2mo, orbsym=label_orb_symm (mol, mol.irrep_id, mol.symm_orb, imp2mo, s=mf.get_ovlp (), check=False))

    t_start = time.time()
    E_CASSCF = mc.kernel(imp2mo, ci0)[0]
    if (not mc.converged) and np.all (np.abs (frag.impham_OEI_S) < 1e-8):
        mc = mc.newton ()
        E_CASSCF = mc.kernel(mc.mo_coeff, mc.ci)[0]
    if not mc.converged:
        print ('Assuming ci vector is poisoned; discarding...')
        imp2mo = mc.mo_coeff.copy ()
        mc = mcscf.CASSCF(mf, CASorb, CASe)
        smult = abs_2S + 1 if frag.target_S is not None else (frag.nelec_imp % 2) + 1
        mc.fcisolver = csf_solver (mf.mol, smult)
        E_CASSCF = mc.kernel(imp2mo)[0]
        if not mc.converged:
            if np.any (np.abs (frag.impham_OEI_S) > 1e-8):
                raise NotImplementedError('Gradient and Hessian fixes for nonsinglet environment of Newton-descent CASSCF algorithm')
            mc = mc.newton ()
            E_CASSCF = mc.kernel(mc.mo_coeff, mc.ci)[0]
    assert (mc.converged)

    '''
    mc.conv_tol = 1e-12
    mc.ah_start_tol = 1e-10
    mc.ah_conv_tol = 1e-12
    E_CASSCF = mc.kernel(mc.mo_coeff, mc.ci)[0]
    if not mc.converged:
        mc = mc.newton ()
        E_CASSCF = mc.kernel(mc.mo_coeff, mc.ci)[0]
    #assert (mc.converged)
    '''
    
    # Get twoRDM + oneRDM. cs: MC-SCF core, as: MC-SCF active space
    # I'm going to need to keep some representation of the active-space orbitals

    # Symmetry align if possible
    oneRDM_amo, twoRDM_amo = mc.fcisolver.make_rdm12 (mc.ci, mc.ncas, mc.nelecas)
    fock_imp = mc.get_fock ()
    mc.mo_coeff[:,:norbs_cmo] = frag.align_imporbs_symm (mc.mo_coeff[:,:norbs_cmo], sorting_metric=fock_imp, sort_vecs=1, orbital_type='optimized inactive', mol=mol)[0]
    mc.mo_coeff[:,norbs_cmo:norbs_occ], umat = frag.align_imporbs_symm (mc.mo_coeff[:,norbs_cmo:norbs_occ],
        sorting_metric=oneRDM_amo, sort_vecs=-1, orbital_type='optimized active', mol=mol)
    mc.mo_coeff[:,norbs_occ:] = frag.align_imporbs_symm (mc.mo_coeff[:,norbs_occ:], sorting_metric=fock_imp, sort_vecs=1, orbital_type='optimized external', mol=mol)[0]
    if frag.enforce_symmetry:
        amo2imp = mc.mo_coeff[:,norbs_cmo:norbs_occ].conjugate ().T
        mc.mo_coeff = cleanup_subspace_symmetry (mc.mo_coeff, mol.symm_orb)
        umat = umat @ (amo2imp @ mc.mo_coeff[:,norbs_cmo:norbs_occ])
        err_symm = measure_subspace_blockbreaking (mc.mo_coeff, mol.symm_orb)
        err_orth = measure_basis_nonorthonormality (mc.mo_coeff)
        print ("Final symmetry error after cleanup = {}".format (err_symm))
        print ("Final orthonormality error after cleanup = {}".format (err_orth))
    mc.ci = transform_ci_for_orbital_rotation (mc.ci, CASorb, CASe, umat)

    # Cache stuff
    imp2mo = mc.mo_coeff #mc.cas_natorb()[0]
    loc2mo = np.dot (frag.loc2imp, imp2mo)
    imp2amo = imp2mo[:,norbs_cmo:norbs_occ]
    loc2amo = loc2mo[:,norbs_cmo:norbs_occ]
    frag.imp_cache = [mc.mo_coeff, mc.ci]
    frag.ci_as = mc.ci
    frag.ci_as_orb = loc2amo.copy ()
    t_end = time.time()

    # oneRDM
    oneRDM_imp = mc.make_rdm1 ()

    # twoCDM
    oneRDM_amo, twoRDM_amo = mc.fcisolver.make_rdm12 (mc.ci, mc.ncas, mc.nelecas)
    oneRDMs_amo = np.stack (mc.fcisolver.make_rdm1s (mc.ci, mc.ncas, mc.nelecas), axis=0)
    oneSDM_amo = oneRDMs_amo[0] - oneRDMs_amo[1] if frag.target_MS >= 0 else oneRDMs_amo[1] - oneRDMs_amo[0]
    oneSDM_imp = represent_operator_in_basis (oneSDM_amo, imp2amo.conjugate ().T)
    print ("Norm of spin density: {}".format (linalg.norm (oneSDM_amo)))
    # Note that I do _not_ do the *real* cumulant decomposition; I do one assuming oneSDM_amo = 0.
    # This is fine as long as I keep it consistent, since it is only in the orbital gradients for this impurity that
    # the spin density matters. But it has to stay consistent!
    twoCDM_amo = get_2CDM_from_2RDM (twoRDM_amo, oneRDM_amo)
    twoCDM_imp = represent_operator_in_basis (twoCDM_amo, imp2amo.conjugate ().T)
    print('Impurity CASSCF energy (incl chempot): {}; spin multiplicity: {}; time to solve: {}'.format (E_CASSCF, spin_square (mc)[1], t_end - t_start))

    # Active-space RDM data
    frag.oneRDMas_loc  = symmetrize_tensor (represent_operator_in_basis (oneRDM_amo, loc2amo.conjugate ().T))
    frag.oneSDMas_loc  = symmetrize_tensor (represent_operator_in_basis (oneSDM_amo, loc2amo.conjugate ().T))
    frag.twoCDMimp_amo = twoCDM_amo
    frag.loc2mo  = loc2mo
    frag.loc2amo = loc2amo
    frag.E2_cum  = np.tensordot (ao2mo.restore (1, mc.get_h2eff (), mc.ncas), twoCDM_amo, axes=4) / 2
    frag.E2_cum += (mf.get_k (dm=oneSDM_imp) * oneSDM_imp).sum () / 4
    # The second line compensates for my incorrect cumulant decomposition. Anything to avoid changing the checkpoint files...

    # General impurity data
    frag.oneRDM_loc = frag.oneRDMfroz_loc + symmetrize_tensor (represent_operator_in_basis (oneRDM_imp, frag.imp2loc))
    frag.oneSDM_loc = frag.oneSDMfroz_loc + frag.oneSDMas_loc
    frag.twoCDM_imp = None # Experiment: this tensor is huge. Do I actually need to keep it? In principle, of course not.
    frag.E_imp      = E_CASSCF + np.einsum ('ab,ab->', chempot_imp, oneRDM_imp)

    return None
コード例 #12
0
from mrh.exploratory.unitary_cc.lasuccsd import FCISolver as lasucc
from mrh.exploratory.citools import fockspace

norb = 8
nelec = 8
norb_f = (4, 4)
nelec_f = ((2, 2), (2, 2))
mol = structure(3.0,
                3.0,
                output='c4h6_stretched_631g.log',
                verbose=logger.DEBUG)
mf = scf.RHF(mol).run()

# CASSCF (for orbital initialization)
mc = mcscf.CASSCF(mf, norb,
                  nelec).set(fcisolver=csf_solver(mol, smult=1)).run()
mo_coeff = mc.mo_coeff.copy()

# LASSCF (for comparison)
las = LASSCF(mf, norb_f, nelec_f, spin_sub=(1, 1)).set(mo_coeff=mo_coeff)
mo_loc = las.localize_init_guess([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])
ncore, ncas, nmo = las.ncore, las.ncas, mo_coeff.shape[1]
e_las = las.kernel(mo_loc)[0]
mo_loc = las.localize_init_guess([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]],
                                 freeze_cas_spaces=True)
molden.from_lasscf(las, 'c4h6_stretched_lasscf88_631g.molden')

# CASCI (for comparison)
mc = mcscf.CASCI(mf, 8, 8).set(mo_coeff=mo_loc,
                               fcisolver=csf_solver(mol, smult=1)).run()
e_cas = mc.e_tot
コード例 #13
0
import unittest
from pyscf import gto, scf, mcscf, lib
from mrh.my_pyscf.fci import csf_solver
from mrh.my_pyscf.mcscf.addons import state_average_n_mix

mol = gto.M(atom='O 0 0 0; H 1.145 0 0',
            basis='6-31g',
            symmetry=True,
            charge=-1,
            spin=0,
            verbose=0,
            output='/dev/null')
mf = scf.RHF(mol).set(conv_tol=1e-10).run()
mc = mcscf.CASSCF(mf, 8, 8).set(conv_tol=1e-10).run()

anion = csf_solver(mol, smult=1)
anion.wfnsym = 'A1'

rad1 = csf_solver(mol, smult=2)
rad1.spin = 1
rad1.charge = 1
rad1.wfnsym = 'E1x'

rad2 = csf_solver(mol, smult=2)
rad2.spin = 1
rad2.charge = 1
rad2.wfnsym = 'E1y'

mc = state_average_n_mix(mc, [anion, rad1, rad2], [
    1.0 / 3.0,
] * 3)
コード例 #14
0
ファイル: test_me2n2_sa.py プロジェクト: Dayou-Zhang/mrh
import numpy as np
from pyscf import lib, gto, scf, dft, fci, mcscf, df
from pyscf.mcscf import newton_casscf
from pyscf.mcscf.addons import state_average_mix
from me2n2_struct import structure as struct
from mrh.my_pyscf.mcscf.lasscf_testing import LASSCF
from mrh.my_pyscf.fci import csf_solver

r_nn = 3.0
mol = struct(3.0, '6-31g')
mol.output = 'test_me2n2_sa.log'
mol.verbose = lib.logger.DEBUG
mol.build()
mf = scf.RHF(mol).run()
mc = state_average_mix(mcscf.CASSCF(
    mf, 4, 4), [csf_solver(mol, smult=m2 + 1).set(spin=m2) for m2 in (0, 2)],
                       [0.5, 0.5]).run()
mf_df = mf.density_fit(auxbasis=df.aug_etb(mol)).run()
mc_df = state_average_mix(mcscf.CASSCF(
    mf_df, 4,
    4), [csf_solver(mol, smult=m2 + 1).set(spin=m2) for m2 in (0, 2)],
                          [0.5, 0.5]).run()


def tearDownModule():
    global mol, mf, mf_df, mc, mc_df
    mol.stdout.close()
    del mol, mf, mf_df, mc, mc_df


class KnownValues(unittest.TestCase):
コード例 #15
0
def solve(frag, guess_1RDM, chempot_imp):

    # Augment OEI with the chemical potential
    OEI = frag.impham_OEI - chempot_imp

    # Do I need to get the full RHF solution?
    guess_orbs_av = len(frag.imp_cache) == 2 or frag.norbs_as > 0

    # Get the RHF solution
    mol = gto.Mole()
    mol.spin = int(round(2 * frag.target_MS))
    mol.verbose = 0 if frag.mol_output is None else lib.logger.DEBUG
    mol.output = frag.mol_output
    mol.atom.append(('H', (0, 0, 0)))
    mol.nelectron = frag.nelec_imp
    mol.build()
    #mol.incore_anyway = True
    mf = scf.RHF(mol)
    mf.get_hcore = lambda *args: OEI
    mf.get_ovlp = lambda *args: np.eye(frag.norbs_imp)
    mf.energy_nuc = lambda *args: frag.impham_CONST
    if frag.impham_CDERI is not None:
        mf = mf.density_fit()
        mf.with_df._cderi = frag.impham_CDERI
    else:
        mf._eri = ao2mo.restore(8, frag.impham_TEI, frag.norbs_imp)
    mf.__dict__.update(frag.mf_attr)
    if guess_orbs_av: mf.max_cycle = 2
    mf.scf(guess_1RDM)
    if (not mf.converged) and (not guess_orbs_av):
        print(
            "CASSCF RHF-step not converged on fixed-point iteration; initiating newton solver"
        )
        mf = mf.newton()
        mf.kernel()

    # Instability check and repeat
    if not guess_orbs_av:
        for i in range(frag.num_mf_stab_checks):
            mf.mo_coeff = mf.stability()[0]
            guess_1RDM = mf.make_rdm1()
            mf = scf.RHF(mol)
            mf.get_hcore = lambda *args: OEI
            mf.get_ovlp = lambda *args: np.eye(frag.norbs_imp)
            mf._eri = ao2mo.restore(8, frag.impham_TEI, frag.norbs_imp)
            mf.scf(guess_1RDM)
            if not mf.converged:
                mf = mf.newton()
                mf.kernel()

    print("CASSCF RHF-step energy: {}".format(mf.e_tot))
    #print(mf.mo_occ)
    '''    
    idx = mf.mo_energy.argsort()
    mf.mo_energy = mf.mo_energy[idx]
    mf.mo_coeff = mf.mo_coeff[:,idx]'''

    # Get the CASSCF solution
    CASe = frag.active_space[0]
    CASorb = frag.active_space[1]
    checkCAS = (CASe <= frag.nelec_imp) and (CASorb <= frag.norbs_imp)
    if (checkCAS == False):
        CASe = frag.nelec_imp
        CASorb = frag.norbs_imp
    if (frag.target_MS > frag.target_S):
        CASe = ((CASe // 2) + frag.target_S, (CASe // 2) - frag.target_S)
    else:
        CASe = ((CASe // 2) + frag.target_MS, (CASe // 2) - frag.target_MS)
    if frag.impham_CDERI is not None:
        mc = mcscf.DFCASSCF(mf, CASorb, CASe)
    else:
        mc = mcscf.CASSCF(mf, CASorb, CASe)
    norbs_amo = mc.ncas
    norbs_cmo = mc.ncore
    norbs_imo = frag.norbs_imp - norbs_amo
    nelec_amo = sum(mc.nelecas)
    norbs_occ = norbs_amo + norbs_cmo
    #mc.natorb = True

    # Guess orbitals
    ci0 = None
    if len(frag.imp_cache) == 2:
        imp2mo, ci0 = frag.imp_cache
        print("Taking molecular orbitals and ci vector from cache")
    elif frag.norbs_as > 0:
        nelec_imp_guess = int(round(np.trace(frag.oneRDMas_loc)))
        norbs_cmo_guess = (frag.nelec_imp - nelec_imp_guess) // 2
        print(
            "Projecting stored amos (frag.loc2amo; spanning {} electrons) onto the impurity basis and filling the remainder with default guess"
            .format(nelec_imp_guess))
        imp2mo, my_occ = project_amo_manually(
            frag.loc2imp,
            frag.loc2amo,
            mf.get_fock(dm=frag.get_oneRDM_imp()),
            norbs_cmo_guess,
            dm=frag.oneRDMas_loc)
    elif frag.loc2amo_guess is not None:
        print(
            "Projecting stored amos (frag.loc2amo_guess) onto the impurity basis (no dm available)"
        )
        imp2mo, my_occ = project_amo_manually(
            frag.loc2imp,
            frag.loc2amo_guess,
            mf.get_fock(dm=frag.get_oneRDM_imp()),
            norbs_cmo,
            dm=None)
        frag.loc2amo_guess = None
    else:
        imp2mo = mc.mo_coeff
        my_occ = mf.mo_occ
        print(
            "No stored amos; using mean-field canonical MOs as initial guess")

    # Guess orbital processing
    if callable(frag.cas_guess_callback):
        mo = reduce(np.dot, (frag.ints.ao2loc, frag.loc2imp, imp2mo))
        mo = frag.cas_guess_callback(frag.ints.mol, mc, mo)
        imp2mo = reduce(np.dot, (frag.imp2loc, frag.ints.ao2loc.conjugate().T,
                                 frag.ints.ao_ovlp, mo))
        frag.cas_guess_callback = None
    elif len(frag.active_orb_list) > 0:
        print('Applying caslst: {}'.format(frag.active_orb_list))
        imp2mo = mc.sort_mo(frag.active_orb_list, mo_coeff=imp2mo)
        frag.active_orb_list = []
    if len(frag.frozen_orb_list) > 0:
        mc.frozen = copy.copy(frag.frozen_orb_list)
        print("Applying frozen-orbital list (this macroiteration only): {}".
              format(frag.frozen_orb_list))
        frag.frozen_orb_list = []

    # Guess orbital printing
    if frag.mfmo_printed == False:
        ao2mfmo = reduce(np.dot, [frag.ints.ao2loc, frag.loc2imp, imp2mo])
        molden.from_mo(frag.ints.mol,
                       frag.filehead + frag.frag_name + '_mfmorb.molden',
                       ao2mfmo,
                       occ=my_occ)
        frag.mfmo_printed = True

    # Guess CI vector
    if len(frag.imp_cache) != 2 and frag.ci_as is not None:
        loc2amo_guess = np.dot(frag.loc2imp, imp2mo[:, norbs_cmo:norbs_occ])
        gOc = np.dot(loc2amo_guess.conjugate().T, frag.ci_as_orb)
        umat_g, svals, umat_c = matrix_svd_control_options(
            gOc, sort_vecs=-1, only_nonzero_vals=True)
        if (svals.size == norbs_amo):
            print(
                "Loading ci guess despite shifted impurity orbitals; singular value sum: {}"
                .format(np.sum(svals)))
            imp2mo[:, norbs_cmo:norbs_occ] = np.dot(
                imp2mo[:, norbs_cmo:norbs_occ], umat_g)
            ci0 = transform_ci_for_orbital_rotation(frag.ci_as, CASorb, CASe,
                                                    umat_c)
        else:
            print(
                "Discarding stored ci guess because orbitals are too different (missing {} nonzero svals)"
                .format(norbs_amo - svals.size))

    t_start = time.time()
    smult = 2 * frag.target_S + 1 if frag.target_S is not None else (
        frag.nelec_imp % 2) + 1
    mc.fcisolver = csf_solver(mf.mol, smult)
    mc.max_cycle_macro = 50 if frag.imp_maxiter is None else frag.imp_maxiter
    mc.ah_start_tol = 1e-10
    mc.ah_conv_tol = 1e-10
    mc.conv_tol = 1e-9
    mc.__dict__.update(frag.corr_attr)
    E_CASSCF = mc.kernel(imp2mo, ci0)[0]
    if not mc.converged:
        mc = mc.newton()
        E_CASSCF = mc.kernel(mc.mo_coeff, mc.ci)[0]
    if not mc.converged:
        print('Assuming ci vector is poisoned; discarding...')
        imp2mo = mc.mo_coeff.copy()
        mc = mcscf.CASSCF(mf, CASorb, CASe)
        smult = 2 * frag.target_S + 1 if frag.target_S is not None else (
            frag.nelec_imp % 2) + 1
        mc.fcisolver = csf_solver(mf.mol, smult)
        E_CASSCF = mc.kernel(imp2mo)[0]
        if not mc.converged:
            mc = mc.newton()
            E_CASSCF = mc.kernel(mc.mo_coeff, mc.ci)[0]
    assert (mc.converged)
    '''
    mc.conv_tol = 1e-12
    mc.ah_start_tol = 1e-10
    mc.ah_conv_tol = 1e-12
    E_CASSCF = mc.kernel(mc.mo_coeff, mc.ci)[0]
    if not mc.converged:
        mc = mc.newton ()
        E_CASSCF = mc.kernel(mc.mo_coeff, mc.ci)[0]
    #assert (mc.converged)
    '''

    # Get twoRDM + oneRDM. cs: MC-SCF core, as: MC-SCF active space
    # I'm going to need to keep some representation of the active-space orbitals
    imp2mo = mc.mo_coeff  #mc.cas_natorb()[0]
    loc2mo = np.dot(frag.loc2imp, imp2mo)
    imp2amo = imp2mo[:, norbs_cmo:norbs_occ]
    loc2amo = loc2mo[:, norbs_cmo:norbs_occ]
    frag.imp_cache = [mc.mo_coeff, mc.ci]
    frag.ci_as = mc.ci
    frag.ci_as_orb = loc2amo.copy()
    t_end = time.time()
    print(
        'Impurity CASSCF energy (incl chempot): {}; spin multiplicity: {}; time to solve: {}'
        .format(E_CASSCF,
                spin_square(mc)[1], t_end - t_start))

    # oneRDM
    oneRDM_imp = mc.make_rdm1()

    # twoCDM
    oneRDM_amo, twoRDM_amo = mc.fcisolver.make_rdm12(mc.ci, mc.ncas,
                                                     mc.nelecas)
    # Note that I do _not_ do the *real* cumulant decomposition; I do one assuming oneRDMs_amo_alpha = oneRDMs_amo_beta
    # This is fine as long as I keep it consistent, since it is only in the orbital gradients for this impurity that
    # the spin density matters. But it has to stay consistent!
    twoCDM_amo = get_2CDM_from_2RDM(twoRDM_amo, oneRDM_amo)
    twoCDM_imp = represent_operator_in_basis(twoCDM_amo, imp2amo.conjugate().T)

    # General impurity data
    frag.oneRDM_loc = symmetrize_tensor(
        frag.oneRDMfroz_loc +
        represent_operator_in_basis(oneRDM_imp, frag.imp2loc))
    frag.twoCDM_imp = None  # Experiment: this tensor is huge. Do I actually need to keep it? In principle, of course not.
    frag.E_imp = E_CASSCF + np.einsum('ab,ab->', chempot_imp, oneRDM_imp)

    # Active-space RDM data
    frag.oneRDMas_loc = symmetrize_tensor(
        represent_operator_in_basis(oneRDM_amo,
                                    loc2amo.conjugate().T))
    frag.twoCDMimp_amo = twoCDM_amo
    frag.loc2mo = loc2mo
    frag.loc2amo = loc2amo
    frag.E2_cum = 0.5 * np.tensordot(
        ao2mo.restore(1, mc.get_h2eff(), mc.ncas), twoCDM_amo, axes=4)

    return None