def make_fc(sscobj, nuc_pair=None): '''Only Fermi-contact''' if nuc_pair is None: nuc_pair = sscobj.nuc_pair mol = sscobj.mol mo_coeff = sscobj._scf.mo_coeff mo_occ = sscobj._scf.mo_occ atm1dic, atm2dic = _uniq_atoms(nuc_pair) h1 = make_h1_fc(mol, mo_coeff, mo_occ, sorted(atm2dic.keys())) mo1aa, mo1ab, mo1ba, mo1bb = solve_mo1_fc(sscobj, h1) h1 = None h1aa, h1ab, h1ba, h1bb = make_h1_fc(mol, mo_coeff, mo_occ, sorted(atm1dic.keys())) para = [] for i,j in nuc_pair: at1 = atm1dic[i] at2 = atm2dic[j] # If GHF orbitals are considered, spin matrices of FC+SD part can be # explicitly considered as below. However, it is inconsistent to RHF # results for closed shell systems. To make UHF and RHF code # consistent, only z-component is considered. # [See Eq. (19) of JCP 113, 3530 (2000); DOI:10.1063/1.1286806] if ZZ_ONLY: ez = numpy.einsum('ij,ij', h1aa[at1], mo1aa[at2]) * 2 # *2 for +c.c. ez += numpy.einsum('ij,ij', h1bb[at1], mo1bb[at2]) * 2 para.append(ez * numpy.eye(3)) else: ez = numpy.einsum('ij,ij', h1aa[at1], mo1aa[at2]) * 2 # *2 for +c.c. ez += numpy.einsum('ij,ij', h1bb[at1], mo1bb[at2]) * 2 ex = numpy.einsum('ij,ij', h1ab[at1], mo1ab[at2]) * 2 ex += numpy.einsum('ij,ij', h1ba[at1], mo1ba[at2]) * 2 ey = ex para.append((ex + ey + ez) / 3 * numpy.eye(3)) return numpy.asarray(para) * nist.ALPHA**4
def make_fc(sscobj, nuc_pair=None): '''Only Fermi-contact''' if nuc_pair is None: nuc_pair = sscobj.nuc_pair mol = sscobj.mol mo_coeff = sscobj._scf.mo_coeff mo_occ = sscobj._scf.mo_occ atm1dic, atm2dic = _uniq_atoms(nuc_pair) h1 = make_h1_fc(mol, mo_coeff, mo_occ, sorted(atm2dic.keys())) mo1aa, mo1ab, mo1ba, mo1bb = solve_mo1_fc(sscobj, h1) h1 = None h1aa, h1ab, h1ba, h1bb = make_h1_fc(mol, mo_coeff, mo_occ, sorted(atm1dic.keys())) para = [] for i,j in nuc_pair: at1 = atm1dic[i] at2 = atm2dic[j] # If GHF orbitals are considered, spin matrices of FC+SD part can be # explicitly considered as below. However, it is inconsistent to RHF # results for closed shell systems. To make UHF and RHF code # consistent, only z-component is considered. # (See Eq. (19) of JCP, 113, 3530) if ZZ_ONLY: ez = numpy.einsum('ij,ij', h1aa[at1], mo1aa[at2]) * 2 # *2 for +c.c. ez += numpy.einsum('ij,ij', h1bb[at1], mo1bb[at2]) * 2 para.append(ez * numpy.eye(3)) else: ez = numpy.einsum('ij,ij', h1aa[at1], mo1aa[at2]) * 2 # *2 for +c.c. ez += numpy.einsum('ij,ij', h1bb[at1], mo1bb[at2]) * 2 ex = numpy.einsum('ij,ij', h1ab[at1], mo1ab[at2]) * 2 ex += numpy.einsum('ij,ij', h1ba[at1], mo1ba[at2]) * 2 ey = ex para.append((ex + ey + ez) / 3 * numpy.eye(3)) return numpy.asarray(para) * nist.ALPHA**4
def make_pso(sscobj, mol, mo1, mo_coeff, mo_occ, nuc_pair=None): if nuc_pair is None: nuc_pair = sscobj.nuc_pair atm1dic, atm2dic = _uniq_atoms(nuc_pair) h1a, h1b = make_h1_pso(mol, mo_coeff, mo_occ, sorted(atm1dic.keys())) mo1a, mo1b = mo1 nvira, nocca = h1a[0].shape nvirb, noccb = h1b[0].shape mo1a = mo1a.reshape(len(atm2dic), 3, nvira, nocca) mo1b = mo1b.reshape(len(atm2dic), 3, nvirb, noccb) h1a = numpy.asarray(h1a).reshape(len(atm1dic), 3, nvira, nocca) h1b = numpy.asarray(h1b).reshape(len(atm1dic), 3, nvirb, noccb) para = [] for i, j in nuc_pair: # PSO = -Tr(Im[h1_ov], Im[mo1_vo]) + cc = 2 * Tr(Im[h1_vo], Im[mo1_vo]) e = numpy.einsum('xij,yij->xy', h1a[atm1dic[i]], mo1a[atm2dic[j]]) * 2 e += numpy.einsum('xij,yij->xy', h1b[atm1dic[i]], mo1b[atm2dic[j]]) * 2 para.append(e) return numpy.asarray(para) * nist.ALPHA**4
def make_pso(sscobj, mol, mo1, mo_coeff, mo_occ, nuc_pair=None): if nuc_pair is None: nuc_pair = sscobj.nuc_pair atm1dic, atm2dic = _uniq_atoms(nuc_pair) h1a, h1b = make_h1_pso(mol, mo_coeff, mo_occ, sorted(atm1dic.keys())) mo1a, mo1b = mo1 nvira, nocca = h1a[0].shape nvirb, noccb = h1b[0].shape mo1a = mo1a.reshape(len(atm2dic),3,nvira,nocca) mo1b = mo1b.reshape(len(atm2dic),3,nvirb,noccb) h1a = numpy.asarray(h1a).reshape(len(atm1dic),3,nvira,nocca) h1b = numpy.asarray(h1b).reshape(len(atm1dic),3,nvirb,noccb) para = [] for i,j in nuc_pair: # PSO = -Tr(Im[h1_ov], Im[mo1_vo]) + cc = 2 * Tr(Im[h1_vo], Im[mo1_vo]) e = numpy.einsum('xij,yij->xy', h1a[atm1dic[i]], mo1a[atm2dic[j]]) * 2 e+= numpy.einsum('xij,yij->xy', h1b[atm1dic[i]], mo1b[atm2dic[j]]) * 2 para.append(e) return numpy.asarray(para) * nist.ALPHA**4
def make_fcsd(sscobj, nuc_pair=None): '''FC + SD contributions to 2nd order energy''' if nuc_pair is None: nuc_pair = sscobj.nuc_pair mol = sscobj.mol mo_coeff = sscobj._scf.mo_coeff mo_occ = sscobj._scf.mo_occ atm1dic, atm2dic = _uniq_atoms(nuc_pair) h1 = make_h1_fcsd(mol, mo_coeff, mo_occ, sorted(atm2dic.keys())) mo1aa, mo1ab, mo1ba, mo1bb = solve_mo1_fc(sscobj, h1) h1 = None h1aa, h1ab, h1ba, h1bb = make_h1_fcsd(mol, mo_coeff, mo_occ, sorted(atm1dic.keys())) mo1aa = mo1aa.reshape(h1aa.shape) mo1ab = mo1ab.reshape(h1ab.shape) mo1ba = mo1ba.reshape(h1ba.shape) mo1bb = mo1bb.reshape(h1bb.shape) para = [] for i, j in nuc_pair: at1 = atm1dic[i] at2 = atm2dic[j] # If GHF orbitals are considered, spin matrices of FC+SD part can be # explicitly considered as below. However, it is inconsistent to RHF # results for closed shell systems. To make UHF and RHF code # consistent, only z-component is considered. if ZZ_ONLY: e = numpy.einsum('xwij,ywij->xy', h1aa[at1], mo1aa[at2]) e += numpy.einsum('xwij,ywij->xy', h1bb[at1], mo1bb[at2]) else: # x contributions e = numpy.einsum('xij,yij->xy', h1ab[at1, 0], mo1ab[at2, 0]) e += numpy.einsum('xij,yij->xy', h1ba[at1, 0], mo1ba[at2, 0]) # y contributions e += numpy.einsum('xij,yij->xy', h1ab[at1, 1], mo1ab[at2, 1]) e += numpy.einsum('xij,yij->xy', h1ba[at1, 1], mo1ba[at2, 1]) # z contribution e += numpy.einsum('xij,yij->xy', h1aa[at1, 2], mo1aa[at2, 2]) e += numpy.einsum('xij,yij->xy', h1bb[at1, 2], mo1bb[at2, 2]) para.append(e * 2) # *2 for +c.c. return numpy.asarray(para) * nist.ALPHA**4
def make_fcsd(sscobj, nuc_pair=None): '''FC + SD contributions to 2nd order energy''' if nuc_pair is None: nuc_pair = sscobj.nuc_pair mol = sscobj.mol mo_coeff = sscobj._scf.mo_coeff mo_occ = sscobj._scf.mo_occ atm1dic, atm2dic = _uniq_atoms(nuc_pair) h1 = make_h1_fcsd(mol, mo_coeff, mo_occ, sorted(atm2dic.keys())) mo1aa, mo1ab, mo1ba, mo1bb = solve_mo1_fc(sscobj, h1) h1 = None h1aa, h1ab, h1ba, h1bb = make_h1_fcsd(mol, mo_coeff, mo_occ, sorted(atm1dic.keys())) nocca = numpy.count_nonzero(mo_occ[0] > 0) nvira = numpy.count_nonzero(mo_occ[0] == 0) noccb = numpy.count_nonzero(mo_occ[1] > 0) nvirb = numpy.count_nonzero(mo_occ[1] == 0) mo1aa = numpy.asarray(mo1aa).reshape(-1, 3, 3, nvira, nocca) mo1ab = numpy.asarray(mo1ab).reshape(-1, 3, 3, nvira, noccb) mo1ba = numpy.asarray(mo1ba).reshape(-1, 3, 3, nvirb, nocca) mo1bb = numpy.asarray(mo1bb).reshape(-1, 3, 3, nvirb, noccb) h1aa = numpy.asarray(h1aa).reshape(-1, 3, 3, nvira, nocca) h1ab = numpy.asarray(h1ab).reshape(-1, 3, 3, nvira, noccb) h1ba = numpy.asarray(h1ba).reshape(-1, 3, 3, nvirb, nocca) h1bb = numpy.asarray(h1bb).reshape(-1, 3, 3, nvirb, noccb) para = [] for i, j in nuc_pair: at1 = atm1dic[i] at2 = atm2dic[j] # x contributions e = numpy.einsum('xij,yij->xy', h1ab[at1, 0], mo1ab[at2, 0]) e += numpy.einsum('xij,yij->xy', h1ba[at1, 0], mo1ba[at2, 0]) # y contributions e += numpy.einsum('xij,yij->xy', h1ab[at1, 1], mo1ab[at2, 1]) e += numpy.einsum('xij,yij->xy', h1ba[at1, 1], mo1ba[at2, 1]) # z contribution e += numpy.einsum('xij,yij->xy', h1aa[at1, 2], mo1aa[at2, 2]) e += numpy.einsum('xij,yij->xy', h1bb[at1, 2], mo1bb[at2, 2]) para.append(e * 2) # *2 for +c.c. return numpy.asarray(para) * nist.ALPHA**4
def make_fcsd(sscobj, nuc_pair=None): '''FC + SD contributions to 2nd order energy''' if nuc_pair is None: nuc_pair = sscobj.nuc_pair mol = sscobj.mol mo_coeff = sscobj._scf.mo_coeff mo_occ = sscobj._scf.mo_occ atm1dic, atm2dic = _uniq_atoms(nuc_pair) h1 = make_h1_fcsd(mol, mo_coeff, mo_occ, sorted(atm2dic.keys())) mo1aa, mo1ab, mo1ba, mo1bb = solve_mo1_fc(sscobj, h1) h1 = None h1aa, h1ab, h1ba, h1bb = make_h1_fcsd(mol, mo_coeff, mo_occ, sorted(atm1dic.keys())) mo1aa = mo1aa.reshape(h1aa.shape) mo1ab = mo1ab.reshape(h1ab.shape) mo1ba = mo1ba.reshape(h1ba.shape) mo1bb = mo1bb.reshape(h1bb.shape) para = [] for i,j in nuc_pair: at1 = atm1dic[i] at2 = atm2dic[j] # If GHF orbitals are considered, spin matrices of FC+SD part can be # explicitly considered as below. However, it is inconsistent to RHF # results for closed shell systems. To make UHF and RHF code # consistent, only z-component is considered. if ZZ_ONLY: e = numpy.einsum('xwij,ywij->xy', h1aa[at1], mo1aa[at2]) e+= numpy.einsum('xwij,ywij->xy', h1bb[at1], mo1bb[at2]) else: # x contributions e = numpy.einsum('xij,yij->xy', h1ab[at1,0], mo1ab[at2,0]) e+= numpy.einsum('xij,yij->xy', h1ba[at1,0], mo1ba[at2,0]) # y contributions e+= numpy.einsum('xij,yij->xy', h1ab[at1,1], mo1ab[at2,1]) e+= numpy.einsum('xij,yij->xy', h1ba[at1,1], mo1ba[at2,1]) # z contribution e+= numpy.einsum('xij,yij->xy', h1aa[at1,2], mo1aa[at2,2]) e+= numpy.einsum('xij,yij->xy', h1bb[at1,2], mo1bb[at2,2]) para.append(e*2) # *2 for +c.c. return numpy.asarray(para) * nist.ALPHA**4
def make_fc(sscobj, nuc_pair=None): '''Only Fermi-contact''' if nuc_pair is None: nuc_pair = sscobj.nuc_pair mol = sscobj.mol mo_coeff = sscobj._scf.mo_coeff mo_occ = sscobj._scf.mo_occ atm1dic, atm2dic = _uniq_atoms(nuc_pair) h1 = make_h1_fc(mol, mo_coeff, mo_occ, sorted(atm2dic.keys())) mo1aa, mo1ab, mo1ba, mo1bb = solve_mo1_fc(sscobj, h1) h1 = None h1aa, h1ab, h1ba, h1bb = make_h1_fc(mol, mo_coeff, mo_occ, sorted(atm1dic.keys())) para = [] for i,j in nuc_pair: at1 = atm1dic[i] at2 = atm2dic[j] ez = numpy.einsum('ij,ij', h1aa[at1], mo1aa[at2]) * 2 # *2 for +c.c. ez += numpy.einsum('ij,ij', h1bb[at1], mo1bb[at2]) * 2 ex = numpy.einsum('ij,ij', h1ab[at1], mo1ab[at2]) * 2 ex += numpy.einsum('ij,ij', h1ba[at1], mo1ba[at2]) * 2 ey = ex para.append(numpy.diag([ex,ey,ez])) return numpy.asarray(para) * lib.param.ALPHA**4