def hyper_polarizability(polobj, with_cphf=True): from pyscf.prop.nmr import rhf as rhf_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 occidx = mo_occ > 0 orbo = mo_coeff[:, occidx] orbv = mo_coeff[:, ~occidx] 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) h1 = lib.einsum('xpq,pi,qj->xij', int_r, mo_coeff.conj(), orbo) s1 = numpy.zeros_like(h1) vind = polobj.gen_vind(mf, mo_coeff, mo_occ) if with_cphf: mo1, e1 = cphf.solve(vind, mo_energy, mo_occ, h1, s1, polobj.max_cycle_cphf, polobj.conv_tol, verbose=log) else: mo1, e1 = rhf_nmr._solve_mo1_uncoupled(mo_energy, mo_occ, h1, s1) mo1 = lib.einsum('xqi,pq->xpi', mo1, mo_coeff) dm1 = lib.einsum('xpi,qi->xpq', mo1, orbo) * 2 dm1 = dm1 + dm1.transpose(0, 2, 1) vresp = mf.gen_response(hermi=1) h1ao = int_r + vresp(dm1) # *2 for double occupancy e3 = lib.einsum('xpq,ypi,zqi->xyz', h1ao, mo1, mo1) * 2 e3 -= lib.einsum('pq,xpi,yqj,zij->xyz', mf.get_ovlp(), mo1, mo1, e1) * 2 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 rhf as rhf_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 occidx = mo_occ > 0 orbo = mo_coeff[:, occidx] orbv = mo_coeff[:, ~occidx] 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) h1 = lib.einsum('xpq,pi,qj->xij', int_r, mo_coeff.conj(), orbo) s1 = numpy.zeros_like(h1) vind = polobj.gen_vind(mf, mo_coeff, mo_occ) if with_cphf: mo1 = cphf.solve(vind, mo_energy, mo_occ, h1, s1, polobj.max_cycle_cphf, polobj.conv_tol, verbose=log)[0] else: mo1 = rhf_nmr._solve_mo1_uncoupled(mo_energy, mo_occ, h1, s1)[0] e2 = numpy.einsum('xpi,ypi->xy', h1, mo1) # *-1 from the definition of dipole moment. *2 for double occupancy e2 = (e2 + e2.T) * -2 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 = 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 = rhf_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 orbo = mo_coeff[:,mo_occ>0] # for magnetic field with mol.with_common_origin(mass_center): h10 = .5 * mol.intor('int1e_cg_irxp', 3) h10 = lib.einsum('xpq,pi,qj->xij', h10, mo_coeff.conj(), orbo) # for rotation part with mol.with_common_origin(gauge_orig): h01 = -mol.intor('int1e_cg_irxp', 3) h01 = lib.einsum('xpq,pi,qj->xij', h01, mo_coeff.conj(), orbo) s10 = numpy.zeros_like(h10) mo10 = rhf_nmr._solve_mo1_uncoupled(mo_energy, mo_occ, h10, s10)[0] mag_para = numpy.einsum('xji,yji->xy', mo10.conj(), h01) mag_para = (mag_para + mag_para.conj()) * 2 # *2 for double occupancy mag_para = _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 hyper_polarizability(polobj, with_cphf=True): from pyscf.prop.nmr import rhf as rhf_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 occidx = mo_occ > 0 orbo = mo_coeff[:, occidx] orbv = mo_coeff[:,~occidx] 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) h1 = lib.einsum('xpq,pi,qj->xij', int_r, mo_coeff.conj(), orbo) s1 = numpy.zeros_like(h1) vind = polobj.gen_vind(mf, mo_coeff, mo_occ) if with_cphf: mo1, e1 = cphf.solve(vind, mo_energy, mo_occ, h1, s1, polobj.max_cycle_cphf, polobj.conv_tol, verbose=log) else: mo1, e1 = rhf_nmr._solve_mo1_uncoupled(mo_energy, mo_occ, h1, s1) mo1 = lib.einsum('xqi,pq->xpi', mo1, mo_coeff) dm1 = lib.einsum('xpi,qi->xpq', mo1, orbo) * 2 dm1 = dm1 + dm1.transpose(0,2,1) vresp = _gen_rhf_response(mf, hermi=1) h1ao = int_r + vresp(dm1) # *2 for double occupancy e3 = lib.einsum('xpq,ypi,zqi->xyz', h1ao, mo1, mo1) * 2 e3 -= lib.einsum('pq,xpi,yqj,zij->xyz', mf.get_ovlp(), mo1, mo1, e1) * 2 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 rhf as rhf_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 occidx = mo_occ > 0 orbo = mo_coeff[:, occidx] orbv = mo_coeff[:,~occidx] 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) h1 = lib.einsum('xpq,pi,qj->xij', int_r, mo_coeff.conj(), orbo) s1 = numpy.zeros_like(h1) vind = polobj.gen_vind(mf, mo_coeff, mo_occ) if with_cphf: mo1 = cphf.solve(vind, mo_energy, mo_occ, h1, s1, polobj.max_cycle_cphf, polobj.conv_tol, verbose=log)[0] else: mo1 = rhf_nmr._solve_mo1_uncoupled(mo_energy, mo_occ, h1, s1)[0] e2 = numpy.einsum('xpi,ypi->xy', h1, mo1) # *-1 from the definition of dipole moment. *2 for double occupancy e2 = (e2 + e2.T) * -2 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