Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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