Esempio n. 1
0
def nat_orbs_rdm_rhf(rdm1: np.ndarray,
                     mo: np.ndarray,
                     mol: gto.mole.Mole = None,
                     disable_sym: bool = False,
                     mo_a: bool = False) -> Tuple[np.ndarray, list]:
    r"""Natural orbitals from rdm1 and mos both should be RHF.

        Args:
            rdm1 (array):               1-particle reduced density matrix in MO basis.
                                        2-dimension (RHF)!
            mo (array):                 Molecular orbital coefficients.
            mol (object):               Optional in case of symmetry.
            disable_sym (bool):         Avoid symmetric diagonialization even if mol has
                                        symmetry.
            mo_a (bool):                Select alpha orbitals if UHF MOs were passed.

        Returns:
            occ (np.ndarray):           Natural orbital occupations.
            no (np.ndarray):            Natural orbitals.

        raises:
            ValueError: wrong sum of occupation.

    """
    rdm1, mo = asserts(rdm1, mo, mol=mol, mo_a=mo_a, type='RHF')

    if mol is not None:
        if (mol.symmetry is True
                or mol.symmetry == 1) and disable_sym is False:
            do_sym = True
        else:
            do_sym = False
    else:
        do_sym = False

    if do_sym is True:
        orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mo)
        eigval, eigvec = symm.eigh(rdm1, orbsym)
    else:
        eigval, eigvec = eigh(rdm1)

    occ = np.flip(eigval)
    no = np.dot(mo, np.fliplr(eigvec))

    if not nat_orbs_test(occ, mol=mol):
        raise ValueError(
            'Sum of occupation does not match number of electrons')

    return no, occ
Esempio n. 2
0
dm = mf.make_rdm1()
ncas, nelecas, mo = dmet_cas.dmet_cas(mf, dm, aolst, threshold=0.1)

mc = mcscf.CASSCF(mf, ncas, nelecas)
mc.max_cycle_macro = 250
mc.max_cycle_micro = 7
mc.chkfile = name + '.chk'
mc.fcisolver = fci.direct_spin0_symm.FCI()
mc.fix_spin_(shift=.5, ss=0)
#mc.__dict__.update(scf.chkfile.load(name+'.chk', 'mcscf'))
#mo = lib.chkfile.load(name+'.chk', 'mcscf/mo_coeff')
mc.kernel(mo)

nmo = mc.ncore + mc.ncas
rdm1, rdm2 = mc.fcisolver.make_rdm12(mc.ci, mc.ncas, mc.nelecas)
rdm1, rdm2 = mcscf.addons._make_rdm12_on_mo(rdm1, rdm2, mc.ncore, mc.ncas, nmo)

orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb,
                             mc.mo_coeff[:, :nmo])
natocc, natorb = symm.eigh(-rdm1, orbsym)
for i, k in enumerate(numpy.argmax(abs(natorb), axis=0)):
    if natorb[k, i] < 0:
        natorb[:, i] *= -1
natorb = numpy.dot(mc.mo_coeff[:, :nmo], natorb)
natocc = -natocc

with open(name + '.wfn', 'w') as f2:
    wfn_format.write_mo(f2, mol, natorb, mo_occ=natocc)
    wfn_format.write_coeff(f2, mol, mc.mo_coeff[:, :nmo])
    wfn_format.write_ci(f2, mc.ci, mc.ncas, mc.nelecas, ncore=mc.ncore)
mol = gto.M(atom='C 0 0 0; C 0 0 1.24253', basis='cc-pvdz', symmetry=1,
            symmetry_subgroup='D2h')

# run HF and store HF results in mf
mf = scf.RHF(mol).run()

# run MP2 and store MP2 results in mp2
mp2 = mp.MP2(mf).run()

rdm1 = numpy.diag(mf.mo_occ)  # The HF 1-particle density matrix in MO representation
rdm1 += mp2.make_rdm1()  # Add the correlation part

natocc, natorb = numpy.linalg.eigh(rdm1)
# Note natorb is in MO basis representation
natorb = numpy.dot(mf.mo_coeff, natorb)
try:
    natorb_sym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, natorb)
    print(natorb_sym)
except ValueError:
    print('The diagonalization for rdm1 breaks the symmetry of the degenerated natural orbitals.')

print('\nIn eigenvalue sovler symm.eigh, we diagonalize the density matrix with the MO symmetry '
      'information.  The eigenvectors are all symmetry adapted.')
orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mf.mo_coeff)
natocc, natorb = symm.eigh(rdm1, orbsym)
natorb = numpy.dot(mf.mo_coeff, natorb)
natorb_sym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, natorb)
print(natorb_sym)