예제 #1
0
파일: orb_scf.py 프로젝트: hebrewsnabla/mrh
def mc1step_gen_g_hop(mc, mo, u, casdm1, casdm2, eris):
    ''' Wrapper to mc1step.gen_g_hop for minimizing the PDFT energy
        instead of the CASSCF energy by varying orbitals '''
    ncore, ncas, nelecas = mc.ncore, mc.ncas, mc.nelecas
    nocc = ncore + ncas
    nao, nmo = mo.shape
    casdm1s = casdm1 * 0.5
    casdm1s = np.stack([casdm1s, casdm1s], axis=0)
    veff1, veff2 = mc.get_pdft_veff(mo=mo,
                                    casdm1s=casdm1s,
                                    casdm2=casdm2,
                                    incl_coul=True)
    veff2.eot_h_op = EotOrbitalHessianOperator(mc,
                                               mo_coeff=mo,
                                               casdm1=casdm1,
                                               casdm2=casdm2,
                                               do_cumulant=True)

    def get_hcore(mol=None):
        return mc._scf.get_hcore(mol) + veff1

    with lib.temporary_env(mc, get_hcore=get_hcore):
        g_orb, _, h_op, h_diag = mc1step.gen_g_hop(mc, mo, u, casdm1, casdm2,
                                                   veff2)
    gorb_update = get_gorb_update(mc, mo)
    return g_orb, gorb_update, h_op, h_diag
예제 #2
0
 def __init__(self, mc):
     oneRDMs = mc.make_rdm1s ()
     casdm1s = mc.fcisolver.make_rdm1s (mc.ci, mc.ncas, mc.nelecas)
     casdm1, casdm2 = mc.fcisolver.make_rdm12 (mc.ci, mc.ncas, mc.nelecas)
     twoCDM = get_2CDM_from_2RDM (casdm2, casdm1s)
     ao2amo = mc.mo_coeff[:,mc.ncore:][:,:mc.ncas]
     self.calculator = HessianCalculator (mc._scf, oneRDMs, twoCDM, ao2amo)
     self.cas = mc
     self.cas_mo = mc.mo_coeff
     self.ncore, self.ncas, self.nelecas = mc.ncore, mc.ncas, mc.nelecas
     self.nocc = self.ncore + self.ncas
     self.nmo = self.cas_mo.shape[1]
     self.hop, self.hdiag = gen_g_hop (mc, self.cas_mo, 1, casdm1, casdm2, mc.ao2mo (self.cas_mo))[2:]
예제 #3
0
    def gen_g_hop(self, mo, u, casdm1, casdm2, eris):
        casdm1 = _symmetrize(casdm1, self.orbsym[self.ncore : self.ncore + self.ncas], self.mol.groupname)
        g_orb, gorb_op, h_op, h_diag = mc1step.gen_g_hop(self, mo, u, casdm1, casdm2, eris)
        g_orb = _symmetrize(self.unpack_uniq_var(g_orb), self.orbsym, self.mol.groupname)
        h_diag = _symmetrize(self.unpack_uniq_var(h_diag), self.orbsym, self.mol.groupname)

        def sym_h_op(x):
            hx = h_op(x)
            hx = _symmetrize(self.unpack_uniq_var(hx), self.orbsym, self.mol.groupname)
            return self.pack_uniq_var(hx)

        def sym_gorb_op(x):
            g = gorb_op(x)
            g = _symmetrize(self.unpack_uniq_var(g), self.orbsym, self.mol.groupname)
            return self.pack_uniq_var(g)

        return self.pack_uniq_var(g_orb), sym_gorb_op, sym_h_op, self.pack_uniq_var(h_diag)
예제 #4
0
    def __init__(self, mc, ot=None, mo_coeff=None, ncore=None, ncas=None,
            casdm1=None, casdm2=None, max_memory=None, do_cumulant=True,
            incl_d2rho=False):
        if ot is None: ot = mc.otfnal
        if mo_coeff is None: mo_coeff = mc.mo_coeff
        if ncore is None: ncore = mc.ncore
        if ncas is None: ncas = mc.ncas
        if max_memory is None: max_memory = mc.max_memory
        if (casdm1 is None) or (casdm2 is None):
            dm1, dm2 = mc.fcisolver.make_rdm12 (mc.ci, ncas, mc.nelecas)
            if casdm1 is None: casdm1 = dm1
            if casdm2 is None: casdm2 = dm2

        self.ot = ot
        self.verbose, self.stdout = ot.verbose, ot.stdout
        self.log = lib.logger.new_logger (self, self.verbose)
        self.ni, self.xctype = ni, xctype = ot._numint, ot.xctype
        self.rho_deriv, self.Pi_deriv = ot.dens_deriv, ot.Pi_deriv
        deriv = ot.dens_deriv
        self.nderiv_rho = (1,4,10)[int (ot.dens_deriv)]
        self.nderiv_Pi = (1,4)[int (ot.Pi_deriv)]
        self.nderiv_ao = (deriv+1)*(deriv+2)*(deriv+3)//6
        self.mo_coeff = mo_coeff
        self.nao, self.nmo = nao, nmo = mo_coeff.shape
        self.ncore = ncore
        self.ncas = ncas
        self.nocc = nocc = ncore + ncas
        self.casdm2 = casdm2
        self.casdm1s = casdm1s = np.stack ([casdm1, casdm1], axis=0)/2
        self.cascm2 = cascm2 = get_2CDM_from_2RDM (casdm2, casdm1)
        self.max_memory = max_memory        
        self.do_cumulant = do_cumulant
        self.incl_d2rho = incl_d2rho

        self._col_mask = None
        self._row_mask = None

        dm1 = 2 * np.eye (nocc, dtype=casdm1.dtype)
        dm1[ncore:,ncore:] = casdm1
        occ_coeff = mo_coeff[:,:nocc]
        no_occ, uno = linalg.eigh (dm1)
        no_coeff = occ_coeff @ uno
        dm1 = occ_coeff @ dm1 @ occ_coeff.conj ().T
        self.dm1 = dm1 = lib.tag_array (dm1, mo_coeff=no_coeff, mo_occ=no_occ)

        self.make_rho = ni._gen_rho_evaluator (ot.mol, dm1, 1)[0]
        self.pack_uniq_var = mc.pack_uniq_var
        self.unpack_uniq_var = mc.unpack_uniq_var        

        self.shls_slice = (0, ot.mol.nbas)
        self.ao_loc = ot.mol.ao_loc_nr()

        if incl_d2rho: # Include d^2rho/dk^2 type derivatives
            # Also include a full E_OT value and gradient recalculator
            # for debugging purposes
            self.veff1, self.veff2 = mc.get_pdft_veff (mo=mo_coeff,
                casdm1s=casdm1s, casdm2=casdm2, incl_coul=False)
            get_hcore = lambda * args: self.veff1
            with lib.temporary_env (mc, get_hcore=get_hcore):
                g_orb, _, h_op, h_diag = mc1step.gen_g_hop (mc, mo_coeff,
                    np.eye (nmo), casdm1, casdm2, self.veff2)
            # dressed gen_g_hop objects
            from mrh.my_pyscf.mcpdft.orb_scf import get_gorb_update
            gorb_update_u = get_gorb_update (mc, mo_coeff, ncore=ncore,
                ncas=ncas, eot_only=True)
            def delta_gorb (x):
                u = mc.update_rotate_matrix (x)
                g1 = gorb_update_u (u, mc.ci)
                return g1 - g_orb
            jk_null = np.zeros ((ncas,nmo)), np.zeros ((ncore,nmo-ncore))
            update_jk = lambda * args: jk_null
            def d2rho_h_op (x):
                with lib.temporary_env (mc, update_jk_in_ah=update_jk):
                    return h_op (x)
            self.g_orb = g_orb
            self.delta_gorb = delta_gorb
            self.d2rho_h_op = d2rho_h_op
            self.h_diag = h_diag
            # on-top energy and calculator
            mo_cas = mo_coeff[:,ncore:nocc]
            dm1s = np.dot (mo_cas, casdm1s).transpose (1,0,2)
            dm1s = np.dot (dm1s, mo_cas.conj ().T)
            mo_core = mo_coeff[:,:ncore]
            dm1s += (mo_core @ mo_core.conj ().T)[None,:,:]
            dm_list = (dm1s, (casdm1s, (cascm2, None, None)))
            e_ot = mc.energy_dft (ot=ot, mo_coeff=mo_coeff, dm_list=dm_list)
            def delta_eot (x):
                u = mc.update_rotate_matrix (x)
                mo1 = mo_coeff @ u
                mo_cas = mo1[:,ncore:nocc]
                dm1s = np.dot (mo_cas, casdm1s).transpose (1,0,2)
                dm1s = np.dot (dm1s, mo_cas.conj ().T)
                mo_core = mo1[:,:ncore]
                dm1s += (mo_core @ mo_core.conj ().T)[None,:,:]
                dm_list = (dm1s, (casdm1s, (cascm2, None, None)))
                e1 = mc.energy_dft (ot=ot, mo_coeff=mo1, dm_list=dm_list)
                return e1 - e_ot
            self.e_ot = e_ot
            self.delta_eot = delta_eot

        if self.verbose > lib.logger.INFO:
            # TODO: require higher verbosity
            from mrh.my_pyscf.mcpdft.pdft_veff import lazy_kernel
            v1, v2 = lazy_kernel (ot, dm1s, cascm2, mo_coeff[:,ncore:nocc])
            self._v1 = mo_coeff.conj ().T @ v1 @ mo_coeff
            self._v2 = ao2mo.full (v2, mo_coeff)