def gen_vind(mf, mo_coeff, mo_occ): '''Induced potential''' vresp = _gen_uhf_response(mf, with_j=False, hermi=0) occidxa = mo_occ[0] > 0 occidxb = mo_occ[1] > 0 orboa = mo_coeff[0][:, occidxa] orbva = mo_coeff[0][:, ~occidxa] orbob = mo_coeff[1][:, occidxb] orbvb = mo_coeff[1][:, ~occidxb] nocca = orboa.shape[1] noccb = orbob.shape[1] nvira = orbva.shape[1] nvirb = orbvb.shape[1] nova = nocca * nvira novb = noccb * nvirb mo_va_oa = numpy.asarray(numpy.hstack((orbva, orboa)), order='F') mo_vb_ob = numpy.asarray(numpy.hstack((orbvb, orbob)), order='F') def vind(mo1): mo1a = mo1.reshape(-1, nova + novb)[:, :nova].reshape(-1, nvira, nocca) mo1b = mo1.reshape(-1, nova + novb)[:, nova:].reshape(-1, nvirb, noccb) nset = mo1a.shape[0] dm1a = _dm1_mo2ao(mo1a, orbva, orboa) dm1b = _dm1_mo2ao(mo1b, orbvb, orbob) dm1 = numpy.vstack( [dm1a - dm1a.transpose(0, 2, 1), dm1b - dm1b.transpose(0, 2, 1)]) v1 = vresp(dm1) v1a = _ao2mo.nr_e2(v1[:nset], mo_va_oa, (0, nvira, nvira, nvira + nocca)) v1b = _ao2mo.nr_e2(v1[nset:], mo_vb_ob, (0, nvirb, nvirb, nvirb + noccb)) v1mo = numpy.hstack((v1a.reshape(nset, -1), v1b.reshape(nset, -1))) return v1mo.ravel() return vind
def gen_vind(self, mo1): '''Induced potential''' vresp = _gen_uhf_response(self._scf, hermi=2) mo_coeff = self._scf.mo_coeff mo_occ = self._scf.mo_occ occidxa = mo_occ[0] > 0 occidxb = mo_occ[1] > 0 orboa = mo_coeff[0][:, occidxa] orbob = mo_coeff[1][:, occidxb] nocca = orboa.shape[1] noccb = orbob.shape[1] nao, nmo = mo_coeff[0].shape nvira = nmo - nocca def vind(mo1): #direct_scf_bak, self._scf.direct_scf = self._scf.direct_scf, False mo1a = mo1.reshape(3, -1)[:, :nocca * nmo].reshape(3, nmo, nocca) mo1b = mo1.reshape(3, -1)[:, nocca * nmo:].reshape(3, nmo, noccb) dm1a = [ reduce(numpy.dot, (mo_coeff[0], x, orboa.T.conj())) for x in mo1a ] dm1b = [ reduce(numpy.dot, (mo_coeff[1], x, orbob.T.conj())) for x in mo1b ] dm1 = numpy.asarray( ([d1 - d1.conj().T for d1 in dm1a], [d1 - d1.conj().T for d1 in dm1b])) v1ao = vresp(dm1) v1a = [ reduce(numpy.dot, (mo_coeff[0].T.conj(), x, orboa)) for x in v1ao[0] ] v1b = [ reduce(numpy.dot, (mo_coeff[1].T.conj(), x, orbob)) for x in v1ao[1] ] v1mo = numpy.hstack((numpy.asarray(v1a).reshape(3, -1), numpy.asarray(v1b).reshape(3, -1))) #self._scf.direct_scf = direct_scf_bak return v1mo.ravel() return vind
def _gen_hop_uhf_external(mf, with_symmetry=True, verbose=None): mol = mf.mol mo_coeff = mf.mo_coeff mo_energy = mf.mo_energy mo_occ = mf.mo_occ occidxa = numpy.where(mo_occ[0]>0)[0] occidxb = numpy.where(mo_occ[1]>0)[0] viridxa = numpy.where(mo_occ[0]==0)[0] viridxb = numpy.where(mo_occ[1]==0)[0] nocca = len(occidxa) noccb = len(occidxb) nvira = len(viridxa) nvirb = len(viridxb) orboa = mo_coeff[0][:,occidxa] orbob = mo_coeff[1][:,occidxb] orbva = mo_coeff[0][:,viridxa] orbvb = mo_coeff[1][:,viridxb] if with_symmetry and mol.symmetry: orbsyma, orbsymb = uhf_symm.get_orbsym(mol, mo_coeff) sym_forbida = orbsyma[viridxa].reshape(-1,1) != orbsyma[occidxa] sym_forbidb = orbsymb[viridxb].reshape(-1,1) != orbsymb[occidxb] sym_forbid1 = numpy.hstack((sym_forbida.ravel(), sym_forbidb.ravel())) h1e = mf.get_hcore() dm0 = mf.make_rdm1(mo_coeff, mo_occ) fock_ao = h1e + mf.get_veff(mol, dm0) focka = reduce(numpy.dot, (mo_coeff[0].T, fock_ao[0], mo_coeff[0])) fockb = reduce(numpy.dot, (mo_coeff[1].T, fock_ao[1], mo_coeff[1])) fooa = focka[occidxa[:,None],occidxa] fvva = focka[viridxa[:,None],viridxa] foob = fockb[occidxb[:,None],occidxb] fvvb = fockb[viridxb[:,None],viridxb] h_diaga =(focka[viridxa,viridxa].reshape(-1,1) - focka[occidxa,occidxa]) h_diagb =(fockb[viridxb,viridxb].reshape(-1,1) - fockb[occidxb,occidxb]) hdiag1 = numpy.hstack((h_diaga.reshape(-1), h_diagb.reshape(-1))) if with_symmetry and mol.symmetry: hdiag1[sym_forbid1] = 0 mem_now = lib.current_memory()[0] max_memory = max(2000, mf.max_memory*.8-mem_now) vrespz = _gen_uhf_response(mf, with_j=False, hermi=2) def hop_real2complex(x1): if with_symmetry and mol.symmetry: x1 = x1.copy() x1[sym_forbid1] = 0 x1a = x1[:nvira*nocca].reshape(nvira,nocca) x1b = x1[nvira*nocca:].reshape(nvirb,noccb) x2a = numpy.einsum('pr,rq->pq', fvva, x1a) x2a-= numpy.einsum('sq,ps->pq', fooa, x1a) x2b = numpy.einsum('pr,rq->pq', fvvb, x1b) x2b-= numpy.einsum('qs,ps->pq', foob, x1b) d1a = reduce(numpy.dot, (orbva, x1a, orboa.T.conj())) d1b = reduce(numpy.dot, (orbvb, x1b, orbob.T.conj())) dm1 = numpy.array((d1a-d1a.T.conj(), d1b-d1b.T.conj())) v1 = vrespz(dm1) x2a += reduce(numpy.dot, (orbva.T.conj(), v1[0], orboa)) x2b += reduce(numpy.dot, (orbvb.T.conj(), v1[1], orbob)) x2 = numpy.hstack((x2a.ravel(), x2b.ravel())) if with_symmetry and mol.symmetry: x2[sym_forbid1] = 0 return x2 if with_symmetry and mol.symmetry: orbsyma, orbsymb = uhf_symm.get_orbsym(mol, mo_coeff) sym_forbidab = orbsyma[viridxa].reshape(-1,1) != orbsymb[occidxb] sym_forbidba = orbsymb[viridxb].reshape(-1,1) != orbsyma[occidxa] sym_forbid2 = numpy.hstack((sym_forbidab.ravel(), sym_forbidba.ravel())) hdiagab = fvva.diagonal().reshape(-1,1) - foob.diagonal() hdiagba = fvvb.diagonal().reshape(-1,1) - fooa.diagonal() hdiag2 = numpy.hstack((hdiagab.ravel(), hdiagba.ravel())) if with_symmetry and mol.symmetry: hdiag2[sym_forbid2] = 0 vresp1 = _gen_uhf_response(mf, with_j=False, hermi=0) # Spin flip GHF solution is not considered def hop_uhf2ghf(x1): if with_symmetry and mol.symmetry: x1 = x1.copy() x1[sym_forbid2] = 0 x1ab = x1[:nvira*noccb].reshape(nvira,noccb) x1ba = x1[nvira*noccb:].reshape(nvirb,nocca) x2ab = numpy.einsum('pr,rq->pq', fvva, x1ab) x2ab-= numpy.einsum('sq,ps->pq', foob, x1ab) x2ba = numpy.einsum('pr,rq->pq', fvvb, x1ba) x2ba-= numpy.einsum('qs,ps->pq', fooa, x1ba) d1ab = reduce(numpy.dot, (orbva, x1ab, orbob.T.conj())) d1ba = reduce(numpy.dot, (orbvb, x1ba, orboa.T.conj())) dm1 = numpy.array((d1ab+d1ba.T.conj(), d1ba+d1ab.T.conj())) v1 = vresp1(dm1) x2ab += reduce(numpy.dot, (orbva.T.conj(), v1[0], orbob)) x2ba += reduce(numpy.dot, (orbvb.T.conj(), v1[1], orboa)) x2 = numpy.hstack((x2ab.ravel(), x2ba.ravel())) if with_symmetry and mol.symmetry: x2[sym_forbid2] = 0 return x2 return hop_real2complex, hdiag1, hop_uhf2ghf, hdiag2
def solve_mo1_fc(sscobj, h1): cput1 = (time.clock(), time.time()) log = logger.Logger(sscobj.stdout, sscobj.verbose) mol = sscobj.mol mo_energy = sscobj._scf.mo_energy mo_coeff = sscobj._scf.mo_coeff mo_occ = sscobj._scf.mo_occ h1aa, h1ab, h1ba, h1bb = h1 nset = len(h1aa) eai_aa = 1. / lib.direct_sum('a-i->ai', mo_energy[0][mo_occ[0]==0], mo_energy[0][mo_occ[0]>0]) eai_ab = 1. / lib.direct_sum('a-i->ai', mo_energy[0][mo_occ[0]==0], mo_energy[1][mo_occ[1]>0]) eai_ba = 1. / lib.direct_sum('a-i->ai', mo_energy[1][mo_occ[1]==0], mo_energy[0][mo_occ[0]>0]) eai_bb = 1. / lib.direct_sum('a-i->ai', mo_energy[1][mo_occ[1]==0], mo_energy[1][mo_occ[1]>0]) mo1_fc = (numpy.asarray(h1aa) * -eai_aa, numpy.asarray(h1ab) * -eai_ab, numpy.asarray(h1ba) * -eai_ba, numpy.asarray(h1bb) * -eai_bb) h1aa = h1ab = h1ba = h1bb = None if not sscobj.cphf: return mo1_fc orboa = mo_coeff[0][:,mo_occ[0]> 0] orbva = mo_coeff[0][:,mo_occ[0]==0] orbob = mo_coeff[1][:,mo_occ[1]> 0] orbvb = mo_coeff[1][:,mo_occ[1]==0] nocca = orboa.shape[1] nvira = orbva.shape[1] noccb = orbob.shape[1] nvirb = orbvb.shape[1] p1 = nvira * nocca p2 = p1 + nvira * noccb p3 = p2 + nvirb * nocca def _split_mo1(mo1): mo1 = mo1.reshape(nset,-1) mo1aa = mo1[:, :p1].reshape(nset,nvira,nocca) mo1ab = mo1[:,p1:p2].reshape(nset,nvira,noccb) mo1ba = mo1[:,p2:p3].reshape(nset,nvirb,nocca) mo1bb = mo1[:,p3: ].reshape(nset,nvirb,noccb) return mo1aa, mo1ab, mo1ba, mo1bb mo1_fc = numpy.hstack((mo1_fc[0].reshape(nset,-1), mo1_fc[1].reshape(nset,-1), mo1_fc[2].reshape(nset,-1), mo1_fc[3].reshape(nset,-1))) vresp = _gen_uhf_response(mf, with_j=False, hermi=1) mo_va_oa = numpy.asarray(numpy.hstack((orbva,orboa)), order='F') mo_va_ob = numpy.asarray(numpy.hstack((orbva,orbob)), order='F') mo_vb_oa = numpy.asarray(numpy.hstack((orbvb,orboa)), order='F') mo_vb_ob = numpy.asarray(numpy.hstack((orbvb,orbob)), order='F') def vind(mo1): mo1aa, mo1ab, mo1ba, mo1bb = _split_mo1(mo1) dm1aa = _dm1_mo2ao(mo1aa, orbva, orboa) dm1ab = _dm1_mo2ao(mo1ab, orbva, orbob) dm1ba = _dm1_mo2ao(mo1ba, orbvb, orboa) dm1bb = _dm1_mo2ao(mo1bb, orbvb, orbob) dm1 = numpy.vstack([dm1aa+dm1aa.transpose(0,2,1), dm1ab+dm1ba.transpose(0,2,1), dm1ba+dm1ab.transpose(0,2,1), dm1bb+dm1bb.transpose(0,2,1)]) v1 = vresp(dm1) v1aa = _ao2mo.nr_e2(v1[ :nset ], mo_va_oa, (0,nvira,nvira,nvira+nocca)) v1ab = _ao2mo.nr_e2(v1[nset*1:nset*2], mo_va_ob, (0,nvira,nvira,nvira+noccb)) v1ba = _ao2mo.nr_e2(v1[nset*2:nset*3], mo_vb_oa, (0,nvirb,nvirb,nvirb+nocca)) v1bb = _ao2mo.nr_e2(v1[nset*3: ], mo_vb_ob, (0,nvirb,nvirb,nvirb+noccb)) v1aa = v1aa.reshape(nset,nvira,nocca) v1ab = v1ab.reshape(nset,nvira,noccb) v1ba = v1ba.reshape(nset,nvirb,nocca) v1bb = v1bb.reshape(nset,nvirb,noccb) v1aa *= eai_aa v1ab *= eai_ab v1ba *= eai_ba v1bb *= eai_bb v1mo = numpy.hstack((v1aa.reshape(nset,-1), v1ab.reshape(nset,-1), v1ba.reshape(nset,-1), v1bb.reshape(nset,-1))) return v1mo.ravel() mo1 = lib.krylov(vind, mo1_fc.ravel(), tol=1e-9, max_cycle=20, verbose=log) log.timer('solving FC CPHF eqn', *cput1) mo1_fc = _split_mo1(mo1) return mo1_fc
def get_vind(self, mf): ''' [ A B][X] [-B -A][Y] ''' wfnsym = self.wfnsym singlet = self.singlet mol = mf.mol mo_coeff = mf.mo_coeff assert (mo_coeff[0].dtype == numpy.double) mo_energy = mf.mo_energy mo_occ = mf.mo_occ nao, nmo = mo_coeff[0].shape occidxa = numpy.where(mo_occ[0] > 0)[0] occidxb = numpy.where(mo_occ[1] > 0)[0] viridxa = numpy.where(mo_occ[0] == 0)[0] viridxb = numpy.where(mo_occ[1] == 0)[0] nocca = len(occidxa) noccb = len(occidxb) nvira = len(viridxa) nvirb = len(viridxb) orboa = mo_coeff[0][:, occidxa] orbob = mo_coeff[1][:, occidxb] orbva = mo_coeff[0][:, viridxa] orbvb = mo_coeff[1][:, viridxb] if wfnsym is not None and mol.symmetry: orbsyma, orbsymb = uhf_symm.get_orbsym(mol, mo_coeff) sym_forbida = (orbsyma[viridxa].reshape(-1, 1) ^ orbsyma[occidxa]) != wfnsym sym_forbidb = (orbsymb[viridxb].reshape(-1, 1) ^ orbsymb[occidxb]) != wfnsym sym_forbid = numpy.hstack( (sym_forbida.ravel(), sym_forbidb.ravel())) e_ai_a = mo_energy[0][viridxa].reshape(-1, 1) - mo_energy[0][occidxa] e_ai_b = mo_energy[1][viridxb].reshape(-1, 1) - mo_energy[1][occidxb] e_ai = hdiag = numpy.hstack((e_ai_a.reshape(-1), e_ai_b.reshape(-1))) if wfnsym is not None and mol.symmetry: hdiag[sym_forbid] = 0 hdiag = numpy.hstack((hdiag.ravel(), hdiag.ravel())) mo_a = numpy.asarray(numpy.hstack((orboa, orbva)), order='F') mo_b = numpy.asarray(numpy.hstack((orbob, orbvb)), order='F') mem_now = lib.current_memory()[0] max_memory = max(2000, self.max_memory * .8 - mem_now) vresp = _gen_uhf_response(mf, hermi=0, max_memory=max_memory) def vind(xys): nz = len(xys) if wfnsym is not None and mol.symmetry: # shape(nz,2,-1): 2 ~ X,Y xys = numpy.copy(zs).reshape(nz, 2, -1) xys[:, :, :, sym_forbid] = 0 dms = numpy.empty((2, nz, nao, nao)) # 2 ~ alpha,beta for i in range(nz): x, y = xys[i].reshape(2, -1) xa = x[:nocca * nvira].reshape(nvira, nocca) xb = x[nocca * nvira:].reshape(nvirb, noccb) ya = y[:nocca * nvira].reshape(nvira, nocca) yb = y[nocca * nvira:].reshape(nvirb, noccb) dmx = reduce(numpy.dot, (orbva, xa, orboa.T)) dmy = reduce(numpy.dot, (orboa, ya.T, orbva.T)) dms[0, i] = dmx + dmy # AX + BY dmx = reduce(numpy.dot, (orbvb, xb, orbob.T)) dmy = reduce(numpy.dot, (orbob, yb.T, orbvb.T)) dms[1, i] = dmx + dmy # AX + BY v1ao = vresp(dms) v1avo = _ao2mo.nr_e2(v1ao[0], mo_a, (nocca, nmo, 0, nocca)) v1bvo = _ao2mo.nr_e2(v1ao[1], mo_b, (noccb, nmo, 0, noccb)) v1aov = _ao2mo.nr_e2(v1ao[0], mo_a, (0, nocca, nocca, nmo)) v1bov = _ao2mo.nr_e2(v1ao[1], mo_b, (0, noccb, noccb, nmo)) hx = numpy.empty((nz, 2, nvira * nocca + nvirb * noccb), dtype=v1avo.dtype) for i in range(nz): x, y = xys[i].reshape(2, -1) hx[i, 0, :nvira * nocca] = v1avo[i].ravel() hx[i, 0, nvira * nocca:] = v1bvo[i].ravel() hx[i, 0] += e_ai * x # AX hx[i, 1, :nvira * nocca] = -v1aov[i].reshape(nocca, nvira).T.ravel() hx[i, 1, nvira * nocca:] = -v1bov[i].reshape(noccb, nvirb).T.ravel() hx[i, 1] -= e_ai * y #-AY if wfnsym is not None and mol.symmetry: hx[:, :, sym_forbid] = 0 return hx.reshape(nz, -1) return vind, hdiag
def gen_tda_hop(mf, fock_ao=None, wfnsym=None, max_memory=2000): '''(A+B)x Kwargs: wfnsym : int Point group symmetry for excited CIS wavefunction. ''' mol = mf.mol mo_coeff = mf.mo_coeff assert (mo_coeff[0].dtype == numpy.double) mo_energy = mf.mo_energy mo_occ = mf.mo_occ nao, nmo = mo_coeff[0].shape occidxa = numpy.where(mo_occ[0] > 0)[0] occidxb = numpy.where(mo_occ[1] > 0)[0] viridxa = numpy.where(mo_occ[0] == 0)[0] viridxb = numpy.where(mo_occ[1] == 0)[0] nocca = len(occidxa) noccb = len(occidxb) nvira = len(viridxa) nvirb = len(viridxb) orboa = mo_coeff[0][:, occidxa] orbob = mo_coeff[1][:, occidxb] orbva = mo_coeff[0][:, viridxa] orbvb = mo_coeff[1][:, viridxb] if wfnsym is not None and mol.symmetry: orbsyma, orbsymb = uhf_symm.get_orbsym(mol, mo_coeff) sym_forbida = (orbsyma[viridxa].reshape(-1, 1) ^ orbsyma[occidxa]) != wfnsym sym_forbidb = (orbsymb[viridxb].reshape(-1, 1) ^ orbsymb[occidxb]) != wfnsym sym_forbid = numpy.hstack((sym_forbida.ravel(), sym_forbidb.ravel())) e_ai_a = mo_energy[0][viridxa].reshape(-1, 1) - mo_energy[0][occidxa] e_ai_b = mo_energy[1][viridxb].reshape(-1, 1) - mo_energy[1][occidxb] e_ai = hdiag = numpy.hstack((e_ai_a.reshape(-1), e_ai_b.reshape(-1))) if wfnsym is not None and mol.symmetry: hdiag[sym_forbid] = 0 mo_a = numpy.asarray(numpy.hstack((orboa, orbva)), order='F') mo_b = numpy.asarray(numpy.hstack((orbob, orbvb)), order='F') mem_now = lib.current_memory()[0] max_memory = max(2000, max_memory * .8 - mem_now) vresp = _gen_uhf_response(mf, hermi=0, max_memory=max_memory) def vind(zs): nz = len(zs) if wfnsym is not None and mol.symmetry: zs = numpy.copy(zs) zs[:, sym_forbid] = 0 dmvo = numpy.empty((2, nz, nao, nao)) for i, z in enumerate(zs): za = z[:nocca * nvira].reshape(nvira, nocca) zb = z[nocca * nvira:].reshape(nvirb, noccb) dmvo[0, i] = reduce(numpy.dot, (orbva, za, orboa.T)) dmvo[1, i] = reduce(numpy.dot, (orbvb, zb, orbob.T)) v1ao = vresp(dmvo) v1a = _ao2mo.nr_e2(v1ao[0], mo_a, (nocca, nmo, 0, nocca)).reshape(-1, nvira, nocca) v1b = _ao2mo.nr_e2(v1ao[1], mo_b, (noccb, nmo, 0, noccb)).reshape(-1, nvirb, noccb) for i, z in enumerate(zs): za = z[:nocca * nvira].reshape(nvira, nocca) zb = z[nocca * nvira:].reshape(nvirb, noccb) v1a[i] += numpy.einsum('ai,ai->ai', e_ai_a, za) v1b[i] += numpy.einsum('ai,ai->ai', e_ai_b, zb) hx = numpy.hstack((v1a.reshape(nz, -1), v1b.reshape(nz, -1))) if wfnsym is not None and mol.symmetry: hx[:, sym_forbid] = 0 return hx return vind, hdiag