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