def hyper_polarizability(polobj, with_cphf=True): from pyscf.prop.nmr import uhf as uhf_nmr log = logger.new_logger(polobj) mf = polobj._scf mol = mf.mol mo_energy = mf.mo_energy mo_coeff = mf.mo_coeff mo_occ = mf.mo_occ occidxa = mo_occ[0] > 0 occidxb = mo_occ[1] > 0 mo0a, mo0b = mo_coeff orboa = mo0a[:, occidxa] orbva = mo0a[:, ~occidxa] orbob = mo0b[:, occidxb] orbvb = mo0b[:, ~occidxb] charges = mol.atom_charges() coords = mol.atom_coords() charge_center = numpy.einsum('i,ix->x', charges, coords) / charges.sum() with mol.with_common_orig(charge_center): int_r = mol.intor_symmetric('int1e_r', comp=3) h1a = lib.einsum('xpq,pi,qj->xij', int_r, mo0a.conj(), orboa) h1b = lib.einsum('xpq,pi,qj->xij', int_r, mo0b.conj(), orbob) s1a = numpy.zeros_like(h1a) s1b = numpy.zeros_like(h1b) vind = polobj.gen_vind(mf, mo_coeff, mo_occ) if with_cphf: mo1, e1 = ucphf.solve(vind, mo_energy, mo_occ, (h1a, h1b), (s1a, s1b), polobj.max_cycle_cphf, polobj.conv_tol, verbose=log) else: mo1, e1 = uhf_nmr._solve_mo1_uncoupled(mo_energy, mo_occ, (h1a, h1b), (s1a, s1b)) mo1a = lib.einsum('xqi,pq->xpi', mo1[0], mo0a) mo1b = lib.einsum('xqi,pq->xpi', mo1[1], mo0b) dm1a = lib.einsum('xpi,qi->xpq', mo1a, orboa) dm1b = lib.einsum('xpi,qi->xpq', mo1b, orbob) dm1a = dm1a + dm1a.transpose(0, 2, 1) dm1b = dm1b + dm1b.transpose(0, 2, 1) vresp = _gen_uhf_response(mf, hermi=1) h1ao = int_r + vresp(numpy.stack((dm1a, dm1b))) s0 = mf.get_ovlp() e3 = lib.einsum('xpq,ypi,zqi->xyz', h1ao[0], mo1a, mo1a) e3 += lib.einsum('xpq,ypi,zqi->xyz', h1ao[1], mo1b, mo1b) e3 -= lib.einsum('pq,xpi,yqj,zij->xyz', s0, mo1a, mo1a, e1[0]) e3 -= lib.einsum('pq,xpi,yqj,zij->xyz', s0, mo1b, mo1b, e1[1]) e3 = (e3 + e3.transpose(1, 2, 0) + e3.transpose(2, 0, 1) + e3.transpose(0, 2, 1) + e3.transpose(1, 0, 2) + e3.transpose(2, 1, 0)) e3 = -e3 log.debug('Static hyper polarizability tensor\n%s', e3) return e3
def hyper_polarizability(polobj, with_cphf=True): from pyscf.prop.nmr import uhf as uhf_nmr log = logger.new_logger(polobj) mf = polobj._scf mol = mf.mol mo_energy = mf.mo_energy mo_coeff = mf.mo_coeff mo_occ = mf.mo_occ occidxa = mo_occ[0] > 0 occidxb = mo_occ[1] > 0 mo0a, mo0b = mo_coeff orboa = mo0a[:, occidxa] orbva = mo0a[:,~occidxa] orbob = mo0b[:, occidxb] orbvb = mo0b[:,~occidxb] charges = mol.atom_charges() coords = mol.atom_coords() charge_center = numpy.einsum('i,ix->x', charges, coords) / charges.sum() with mol.with_common_orig(charge_center): int_r = mol.intor_symmetric('int1e_r', comp=3) h1a = lib.einsum('xpq,pi,qj->xij', int_r, mo0a.conj(), orboa) h1b = lib.einsum('xpq,pi,qj->xij', int_r, mo0b.conj(), orbob) s1a = numpy.zeros_like(h1a) s1b = numpy.zeros_like(h1b) vind = polobj.gen_vind(mf, mo_coeff, mo_occ) if with_cphf: mo1, e1 = ucphf.solve(vind, mo_energy, mo_occ, (h1a,h1b), (s1a,s1b), polobj.max_cycle_cphf, polobj.conv_tol, verbose=log) else: mo1, e1 = uhf_nmr._solve_mo1_uncoupled(mo_energy, mo_occ, (h1a,h1b), (s1a,s1b)) mo1a = lib.einsum('xqi,pq->xpi', mo1[0], mo0a) mo1b = lib.einsum('xqi,pq->xpi', mo1[1], mo0b) dm1a = lib.einsum('xpi,qi->xpq', mo1a, orboa) dm1b = lib.einsum('xpi,qi->xpq', mo1b, orbob) dm1a = dm1a + dm1a.transpose(0,2,1) dm1b = dm1b + dm1b.transpose(0,2,1) vresp = _gen_uhf_response(mf, hermi=1) h1ao = int_r + vresp(numpy.stack((dm1a, dm1b))) s0 = mf.get_ovlp() e3 = lib.einsum('xpq,ypi,zqi->xyz', h1ao[0], mo1a, mo1a) e3 += lib.einsum('xpq,ypi,zqi->xyz', h1ao[1], mo1b, mo1b) e3 -= lib.einsum('pq,xpi,yqj,zij->xyz', s0, mo1a, mo1a, e1[0]) e3 -= lib.einsum('pq,xpi,yqj,zij->xyz', s0, mo1b, mo1b, e1[1]) e3 = (e3 + e3.transpose(1,2,0) + e3.transpose(2,0,1) + e3.transpose(0,2,1) + e3.transpose(1,0,2) + e3.transpose(2,1,0)) e3 = -e3 log.debug('Static hyper polarizability tensor\n%s', e3) return e3
def polarizability(polobj, with_cphf=True): from pyscf.prop.nmr import uhf as uhf_nmr log = logger.new_logger(polobj) mf = polobj._scf mol = mf.mol mo_energy = mf.mo_energy mo_coeff = mf.mo_coeff mo_occ = mf.mo_occ occidxa = mo_occ[0] > 0 occidxb = mo_occ[1] > 0 mo0a, mo0b = mo_coeff orboa = mo0a[:, occidxa] orbva = mo0a[:, ~occidxa] orbob = mo0b[:, occidxb] orbvb = mo0b[:, ~occidxb] charges = mol.atom_charges() coords = mol.atom_coords() charge_center = numpy.einsum('i,ix->x', charges, coords) / charges.sum() with mol.with_common_orig(charge_center): int_r = mol.intor_symmetric('int1e_r', comp=3) h1a = lib.einsum('xpq,pi,qj->xij', int_r, mo0a.conj(), orboa) h1b = lib.einsum('xpq,pi,qj->xij', int_r, mo0b.conj(), orbob) s1a = numpy.zeros_like(h1a) s1b = numpy.zeros_like(h1b) vind = polobj.gen_vind(mf, mo_coeff, mo_occ) if with_cphf: mo1 = ucphf.solve(vind, mo_energy, mo_occ, (h1a, h1b), (s1a, s1b), polobj.max_cycle_cphf, polobj.conv_tol, verbose=log)[0] else: mo1 = uhf_nmr._solve_mo1_uncoupled(mo_energy, mo_occ, (h1a, h1b), (s1a, s1b))[0] e2 = numpy.einsum('xpi,ypi->xy', h1a, mo1[0]) e2 += numpy.einsum('xpi,ypi->xy', h1b, mo1[1]) e2 = -(e2 + e2.T) if mf.verbose >= logger.INFO: xx, yy, zz = e2.diagonal() log.note('Isotropic polarizability %.12g', (xx + yy + zz) / 3) log.note('Polarizability anisotropy %.12g', (.5 * ((xx - yy)**2 + (yy - zz)**2 + (zz - xx)**2))**.5) log.debug('Static polarizability tensor\n%s', e2) return e2
def para(magobj, gauge_orig=None, h1=None, s1=None, with_cphf=None): '''Part of rotational g-tensors from the first order wavefunctions. Unit hbar/mu_N is not included. This part may be different to the conventional para-magnetic contributions of rotational g-tensors. ''' mol = magobj.mol im, mass_center = rhf_g.inertia_tensor(mol) if gauge_orig is None: # The first order Hamiltonian for rotation part is the same to the # first order Hamiltonian for magnetic field except a factor of 2. It can # be computed using the magnetizability code. mag_para = uhf_mag.para(magobj, gauge_orig, h1, s1, with_cphf) * 2 else: mf = magobj._scf mo_energy = mf.mo_energy mo_coeff = mf.mo_coeff mo_occ = mf.mo_occ orboa = mo_coeff[0][:, mo_occ[0] > 0] orbob = mo_coeff[1][:, mo_occ[1] > 0] # for magnetic field with mol.with_common_origin(mass_center): h10 = .5 * mol.intor('int1e_cg_irxp', 3) h10a = lib.einsum('xpq,pi,qj->xij', h10, mo_coeff[0].conj(), orboa) h10b = lib.einsum('xpq,pi,qj->xij', h10, mo_coeff[1].conj(), orbob) # for rotation part with mol.with_common_origin(gauge_orig): h01 = -mol.intor('int1e_cg_irxp', 3) h01a = lib.einsum('xpq,pi,qj->xij', h01, mo_coeff[0].conj(), orboa) h01b = lib.einsum('xpq,pi,qj->xij', h01, mo_coeff[1].conj(), orbob) s10a = numpy.zeros_like(h10a) s10b = numpy.zeros_like(h10b) mo10 = uhf_nmr._solve_mo1_uncoupled(mo_energy, mo_occ, (h10a, h10b), (s10a, s10b))[0] mag_para = numpy.einsum('xji,yji->xy', mo10[0].conj(), h01a) mag_para += numpy.einsum('xji,yji->xy', mo10[1].conj(), h01b) mag_para = mag_para + mag_para.conj() mag_para = rhf_g._safe_solve(im, mag_para) # unit = hbar/mu_N, mu_N is nuclear magneton unit = -2 * nist.PROTON_MASS_AU return mag_para * unit
def para(magobj, gauge_orig=None, h1=None, s1=None, with_cphf=None): '''Part of rotational g-tensors from the first order wavefunctions. Unit hbar/mu_N is not included. This part may be different to the conventional para-magnetic contributions of rotational g-tensors. ''' mol = magobj.mol im, mass_center = rhf_g.inertia_tensor(mol) if gauge_orig is None: # The first order Hamiltonian for rotation part is the same to the # first order Hamiltonian for magnetic field except a factor of 2. It can # be computed using the magnetizability code. mag_para = uhf_mag.para(magobj, gauge_orig, h1, s1, with_cphf) * 2 else: mf = magobj._scf mo_energy = mf.mo_energy mo_coeff = mf.mo_coeff mo_occ = mf.mo_occ orboa = mo_coeff[0][:,mo_occ[0]>0] orbob = mo_coeff[1][:,mo_occ[1]>0] # for magnetic field with mol.with_common_origin(mass_center): h10 = .5 * mol.intor('int1e_cg_irxp', 3) h10a = lib.einsum('xpq,pi,qj->xij', h10, mo_coeff[0].conj(), orboa) h10b = lib.einsum('xpq,pi,qj->xij', h10, mo_coeff[1].conj(), orbob) # for rotation part with mol.with_common_origin(gauge_orig): h01 = -mol.intor('int1e_cg_irxp', 3) h01a = lib.einsum('xpq,pi,qj->xij', h01, mo_coeff[0].conj(), orboa) h01b = lib.einsum('xpq,pi,qj->xij', h01, mo_coeff[1].conj(), orbob) s10a = numpy.zeros_like(h10a) s10b = numpy.zeros_like(h10b) mo10 = uhf_nmr._solve_mo1_uncoupled(mo_energy, mo_occ, (h10a,h10b), (s10a,s10b))[0] mag_para = numpy.einsum('xji,yji->xy', mo10[0].conj(), h01a) mag_para+= numpy.einsum('xji,yji->xy', mo10[1].conj(), h01b) mag_para = mag_para + mag_para.conj() mag_para = rhf_g._safe_solve(im, mag_para) # unit = hbar/mu_N, mu_N is nuclear magneton unit = -2 * nist.PROTON_MASS_AU return mag_para * unit
def polarizability(polobj, with_cphf=True): from pyscf.prop.nmr import uhf as uhf_nmr log = logger.new_logger(polobj) mf = polobj._scf mol = mf.mol mo_energy = mf.mo_energy mo_coeff = mf.mo_coeff mo_occ = mf.mo_occ occidxa = mo_occ[0] > 0 occidxb = mo_occ[1] > 0 mo0a, mo0b = mo_coeff orboa = mo0a[:, occidxa] orbva = mo0a[:,~occidxa] orbob = mo0b[:, occidxb] orbvb = mo0b[:,~occidxb] charges = mol.atom_charges() coords = mol.atom_coords() charge_center = numpy.einsum('i,ix->x', charges, coords) / charges.sum() with mol.with_common_orig(charge_center): int_r = mol.intor_symmetric('int1e_r', comp=3) h1a = lib.einsum('xpq,pi,qj->xij', int_r, mo0a.conj(), orboa) h1b = lib.einsum('xpq,pi,qj->xij', int_r, mo0b.conj(), orbob) s1a = numpy.zeros_like(h1a) s1b = numpy.zeros_like(h1b) vind = polobj.gen_vind(mf, mo_coeff, mo_occ) if with_cphf: mo1 = ucphf.solve(vind, mo_energy, mo_occ, (h1a,h1b), (s1a,s1b), polobj.max_cycle_cphf, polobj.conv_tol, verbose=log)[0] else: mo1 = uhf_nmr._solve_mo1_uncoupled(mo_energy, mo_occ, (h1a,h1b), (s1a,s1b))[0] e2 = numpy.einsum('xpi,ypi->xy', h1a, mo1[0]) e2+= numpy.einsum('xpi,ypi->xy', h1b, mo1[1]) e2 = -(e2 + e2.T) if mf.verbose >= logger.INFO: xx, yy, zz = e2.diagonal() log.note('Isotropic polarizability %.12g', (xx+yy+zz)/3) log.note('Polarizability anisotropy %.12g', (.5 * ((xx-yy)**2 + (yy-zz)**2 + (zz-xx)**2))**.5) log.debug('Static polarizability tensor\n%s', e2) return e2