Beispiel #1
0
    def hess_wuyang(self, x, P_ref, dim, Ne_frag, Ne_env, impJK_sub,
                    bathJK_sub):

        size = dim * (dim + 1) // 2
        umat = tools.vec2mat(x, dim)

        ops = self.ops
        subKin = ops["subKin"]
        subVnuc1 = ops["subVnuc1"]
        subVnuc2 = ops["subVnuc2"]
        subVnuc_bound1 = ops["subVnuc_bound1"]
        subVnuc_bound2 = ops["subVnuc_bound2"]
        subCoreJK = ops["subCoreJK"]
        subTEI = ops["subTEI"]

        subOEI1 = subKin + subVnuc1 + subVnuc_bound1 + impJK_sub + umat
        subOEI2 = subKin + subVnuc2 + subVnuc_bound2 + subCoreJK + bathJK_sub + umat

        FRAG_energy, FRAG_1RDM, mo_coeff_frag, mo_energy_frag, mo_occ_frag = qcwrap.pyscf_rhf.scf_oei(
            subOEI1, dim, Ne_frag, self.smear_sigma)
        hess_frag = oep_hess(mo_coeff_frag, mo_energy_frag, size, dim,
                             self.Ne_frag // 2, mo_occ_frag, self.smear_sigma)

        ENV_energy, ENV_1RDM, mo_coeff_env, mo_energy_env, mo_occ_env = qcwrap.pyscf_rhf.scf_oei(
            subOEI2, dim, Ne_env, self.smear_sigma)
        hess_env = oep_hess(mo_coeff_env, mo_energy_env, size, dim,
                            self.Ne_env // 2, mo_occ_env, self.smear_sigma)

        hess = hess_frag + hess_env
        return hess
Beispiel #2
0
    def oep_calc_diffP(self, x, dim, Ne_frag, Ne_env, P_ref, ops):

        umat = tools.vec2mat(x, dim)
        #print "|umat| = ", np.linalg.norm(umat)
        if (self.params.oep_print >= 3):
            #print "sum(diag(umat)) = ", np.sum(np.diag(umat))
            tools.MatPrint(umat, 'umat')

        FRAG_1RDM = np.zeros([dim, dim], dtype=float)
        ENV_1RDM = np.zeros([dim, dim], dtype=float)
        FRAG_energy = 0.0
        ENV_energy = 0.0
        frag_mo = np.zeros([dim, dim], dtype=float)
        env_mo = np.zeros([dim, dim], dtype=float)

        subKin = ops["subKin"]
        subVnuc1 = ops["subVnuc1"]
        subVnuc2 = ops["subVnuc2"]
        subVnuc_bound1 = ops["subVnuc_bound1"]
        subVnuc_bound2 = ops["subVnuc_bound2"]
        subCoreJK = ops["subCoreJK"]
        subTEI = ops["subTEI"]

        subOEI1 = subKin + subVnuc1 + subVnuc_bound1 + umat
        subOEI2 = subKin + subVnuc2 + subVnuc_bound2 + subCoreJK + umat

        if (Ne_frag > 0):
            frag_coredm_guess, mo_coeff = tools.fock2onedm(
                subOEI1, Ne_frag // 2)
            FRAG_energy, FRAG_1RDM, frag_mo = qcwrap.pyscf_rhf.scf(
                subOEI1,
                subTEI,
                dim,
                Ne_frag,
                frag_coredm_guess,
                mf_method=self.mf_method)

        if (Ne_env > 0):
            env_coredm_guess, mo_coeff = tools.fock2onedm(subOEI2, Ne_env // 2)
            ENV_energy, ENV_1RDM, env_mo = qcwrap.pyscf_rhf.scf(
                subOEI2,
                subTEI,
                dim,
                Ne_env,
                env_coredm_guess,
                mf_method=self.mf_method)

        self.frag_mo = frag_mo
        self.env_mo = env_mo
        self.P_imp = FRAG_1RDM
        self.P_bath = ENV_1RDM

        diffP = FRAG_1RDM + ENV_1RDM - P_ref
        grad = tools.mat2vec(diffP, dim)

        #print "2-norm (grad),       max(grad):"
        #print np.linalg.norm(grad), ", ", np.amax(np.absolute(grad))

        return grad
Beispiel #3
0
    def opt_umat_homo_diff(self, umat, gtol=1e-6):

        ops = self.ops
        Ne_frag = self.Ne_frag
        Ne_env = self.Ne_env
        dim = self.dim

        subTEI = ops["subTEI"]
        subOEI1 = ops["subKin"] + ops["subVnuc1"] + ops["subVnuc_bound1"] + umat
        subOEI2 = ops["subKin"] + ops["subVnuc2"] + ops[
            "subVnuc_bound2"] + ops["subCoreJK"] + umat

        coredm = self.core1PDM_ao
        ao2sub = self.ao2sub[:, :dim]

        #frag_coredm_guess = tools.fock2onedm(subOEI1, Ne_frag//2)[0]
        frag_coredm_guess = self.P_imp
        mf_frag = qcwrap.qc_scf(Ne_frag,dim,self.mf_method,mol=self.mol,oei=subOEI1,tei=subTEI,\
                                dm0=frag_coredm_guess,coredm=0.0,ao2sub=ao2sub, smear_sigma = 0.0)
        mf_frag.runscf()

        #env_coredm_guess = tools.fock2onedm(subOEI2, Ne_env//2)[0]
        env_coredm_guess = self.P_bath
        mf_env = qcwrap.qc_scf(Ne_env,dim,self.mf_method,mol=self.mol,oei=subOEI2,tei=subTEI,\
                               dm0=env_coredm_guess,coredm=coredm,ao2sub=ao2sub, smear_sigma = 0.0)
        mf_env.runscf()

        print(np.linalg.norm(mf_frag.rdm1 - self.P_imp))
        print(np.linalg.norm(mf_env.rdm1 - self.P_bath))

        diffP = mf_frag.rdm1 + mf_env.rdm1 - self.P_ref
        print("|P_frag + P_env - P_ref| = ", np.linalg.norm(diffP))
        print("max element of (P_frag + P_env - P_ref) = ",
              np.amax(np.absolute(diffP)))
        self.P_imp = mf_frag.rdm1
        self.P_bath = mf_env.rdm1

        #build null space
        vint = self.build_null_space(mf_frag, mf_env, Ne_frag, Ne_env, dim)
        if vint is None:
            return umat

        #minimize |ehomo_A-ehomo_B|^2
        x0 = tools.mat2vec(umat, dim)
        n = vint.shape[-1]
        c = np.zeros((n))
        res = self.minimize_ehomo_2(c, x0, vint, gtol)
        c = res.x
        #print '|c| = ', np.linalg.norm(c)
        for i in range(n):
            x0 += c[i] * vint[:, i]

        umat = tools.vec2mat(x0, dim)
        #xmat = xmat - np.eye( xmat.shape[ 0 ] ) * np.average( np.diag( xmat ) )

        #tools.MatPrint(umat,'umat')
        #print '|umat| = ', np.linalg.norm(umat)

        return umat
Beispiel #4
0
    def cost_hess_wuyang(self,
                         x,
                         P_ref,
                         dim,
                         Ne_frag,
                         Ne_env,
                         impJK_sub,
                         bathJK_sub,
                         calc_hess=False):

        size = dim * (dim + 1) // 2
        umat = tools.vec2mat(x, dim)

        print("|umat| = ", np.linalg.norm(umat))
        #if(self.params.oep_print >= 3):
        #    print "sum(diag(umat)) = ", np.sum(np.diag(umat))
        #    tools.MatPrint(umat, 'umat')

        FRAG_1RDM = np.zeros([dim, dim], dtype=float)
        ENV_1RDM = np.zeros([dim, dim], dtype=float)
        FRAG_energy = 0.0
        ENV_energy = 0.0

        ops = self.ops
        subKin = ops["subKin"]
        subVnuc1 = ops["subVnuc1"]
        subVnuc2 = ops["subVnuc2"]
        subVnuc_bound1 = ops["subVnuc_bound1"]
        subVnuc_bound2 = ops["subVnuc_bound2"]
        subCoreJK = ops["subCoreJK"]
        subTEI = ops["subTEI"]

        if (impJK_sub is not None):
            subOEI1 = subKin + subVnuc1 + subVnuc_bound1 + impJK_sub + umat
            subOEI2 = subKin + subVnuc2 + subVnuc_bound2 + subCoreJK + bathJK_sub + umat
            FRAG_energy, FRAG_1RDM, frag_mo_coeff, frag_mo_energy, frag_mo_occ = \
                qcwrap.pyscf_rhf.scf_oei( subOEI1, dim, Ne_frag, self.smear_sigma)
            if (Ne_env > 0):
                ENV_energy, ENV_1RDM, env_mo_coeff, env_mo_energy, env_mo_occ =\
                    qcwrap.pyscf_rhf.scf_oei( subOEI2, dim, Ne_env, self.smear_sigma)

            if (calc_hess):
                hess_frag = oep_hess(frag_mo_coeff, frag_mo_energy, size, dim,
                                     Ne_frag // 2, frag_mo_occ,
                                     self.smear_sigma)
                hess_env = oep_hess(env_mo_coeff, env_mo_energy, size, dim,
                                    Ne_env // 2, env_mo_occ, self.smear_sigma)
                hess = hess_frag + hess_env
        else:
            raise Exception("NYI")

        diffP = FRAG_1RDM + ENV_1RDM - P_ref
        energy = FRAG_energy + ENV_energy - np.trace(np.dot(P_ref, umat))

        grad = tools.mat2vec(diffP, dim)
        #grad = tools.mat2vec_hchain(diffP, dim)
        grad = -1.0 * grad

        print("2-norm (grad),       max(grad):")
        print(np.linalg.norm(grad), ", ", np.amax(np.absolute(grad)))

        f = -energy
        print('-W = ', f)

        #test
        #f = np.linalg.norm(grad)

        if (calc_hess):
            return (f, grad, hess)
        else:
            return (f, grad)
Beispiel #5
0
    def cost_ehomo_2(self, c, x0, vint):

        x = x0.copy()

        n = len(c)
        for i in range(n):
            x += c[i] * vint[:, i]

        ops = self.ops
        Ne_frag = self.Ne_frag
        Ne_env = self.Ne_env
        dim = self.dim

        umat = tools.vec2mat(x, dim)
        subTEI = ops["subTEI"]
        subOEI1 = ops["subKin"] + ops["subVnuc1"] + ops["subVnuc_bound1"] + umat
        subOEI2 = ops["subKin"] + ops["subVnuc2"] + ops[
            "subVnuc_bound2"] + ops["subCoreJK"] + umat

        coredm = self.core1PDM_ao
        ao2sub = self.ao2sub[:, :dim]

        frag_coredm_guess = self.P_imp
        mf_frag = qcwrap.qc_scf(Ne_frag,dim,self.mf_method,mol=self.mol,oei=subOEI1,tei=subTEI,\
                                dm0=frag_coredm_guess,coredm=0.0,ao2sub=ao2sub, smear_sigma = 0.0)
        mf_frag.runscf()

        env_coredm_guess = self.P_bath
        mf_env = qcwrap.qc_scf(Ne_env,dim,self.mf_method,mol=self.mol,oei=subOEI2,tei=subTEI,\
                               dm0=env_coredm_guess,coredm=coredm,ao2sub=ao2sub, smear_sigma = 0.0)
        mf_env.runscf()

        diffP = mf_frag.rdm1 + mf_env.rdm1 - self.P_ref
        #print "|P_frag + P_env - P_ref| = ", np.linalg.norm(diffP)
        #print "max element of (P_frag + P_env - P_ref) = ", np.amax(np.absolute(diffP) )

        ehomo_A = mf_frag.mo_energy[Ne_frag // 2 - 1]
        ehomo_B = mf_env.mo_energy[Ne_env // 2 - 1]
        delta_ehomo = ehomo_A - ehomo_B
        #print 'ehomo_A=',ehomo_A,'  ehomo_B=',ehomo_B, '  delta_ehomo=', delta_ehomo

        elumo_A = mf_frag.mo_energy[Ne_frag // 2]
        elumo_B = mf_env.mo_energy[Ne_env // 2]
        delta_elumo = elumo_A - elumo_B
        #print 'elumo_A=',elumo_A,'  elumo_B=',elumo_B, '  delta_elumo=', delta_elumo

        #objective function
        f = delta_ehomo * delta_ehomo + delta_elumo * delta_elumo  #+ (elumo_A-ehomo_A-0.3)**2

        homo_A = mf_frag.mo_coeff[:, Ne_frag // 2 - 1]
        homo_B = mf_env.mo_coeff[:, Ne_env // 2 - 1]
        lumo_A = mf_frag.mo_coeff[:, Ne_frag // 2]
        lumo_B = mf_env.mo_coeff[:, Ne_env // 2]
        #gradient
        g = np.zeros((n))
        for i in range(n):
            tmp = tools.vec2mat(vint[:, i], dim)
            EA = np.dot(homo_A, np.dot(tmp, homo_A))
            EB = np.dot(homo_B, np.dot(tmp, homo_B))
            g[i] = 2.0 * delta_ehomo * (EA - EB)

            EA = np.dot(lumo_A, np.dot(tmp, lumo_A))
            EB = np.dot(lumo_B, np.dot(tmp, lumo_B))
            g[i] += 2.0 * delta_elumo * (EA - EB)

            #EB=np.dot(homo_A,np.dot(tmp,homo_A))
            #g[i] += 2.0*(elumo_A-ehomo_A-0.3)*(EA-EB)

        return (f, g)