Exemple #1
0
def make_h1_soc(hfcobj, dm0):
    '''1-electron and 2-electron spin-orbit coupling integrals.

    1-electron SOC integral is the imaginary part of [i sigma dot pV x p],
    ie [sigma dot pV x p].

    Note sigma_z is considered in the SOC integrals (the (-) sign for beta-beta
    block is included in the integral).  The factor 1/2 in the spin operator
    s=sigma/2 is not included.
    '''
# JCP, 122, 034107 Eq (2) = 1/4c^2 hso1e
    mol = hfcobj.mol
    assert(not mol.has_ecp())
    if hfcobj.so_eff_charge:
        hso1e = 0
        for ia in range(mol.natm):
            mol.set_rinv_origin(mol.atom_coord(ia))
            Z = koseki_charge(mol.atom_charge(ia))
            hso1e += -Z * mol.intor('int1e_prinvxp', 3)
    else:
        hso1e = mol.intor('int1e_pnucxp', 3)
    hso = [hso1e, -hso1e]

    if hfcobj.para_soc2e:
        hso2e = hfcobj.make_h1_soc2e(dm0)
        hso[0] += hso2e[0]
        hso[1] += hso2e[1]

    return hso
Exemple #2
0
def make_h1_soc(hfcobj, dm0):
    '''1-electron and 2-electron spin-orbit coupling integrals.

    1-electron SOC integral is the imaginary part of [i sigma dot pV x p],
    ie [sigma dot pV x p].

    Note sigma_z is considered in the SOC integrals (the (-) sign for beta-beta
    block is included in the integral).  The factor 1/2 in the spin operator
    s=sigma/2 is not included.
    '''
# JCP, 122, 034107 Eq (2) = 1/4c^2 hso1e
    mol = hfcobj.mol
    assert(not mol.has_ecp())
    if hfcobj.so_eff_charge:
        hso1e = 0
        for ia in range(mol.natm):
            mol.set_rinv_origin(mol.atom_coord(ia))
            Z = koseki_charge(mol.atom_charge(ia))
            hso1e += -Z * mol.intor('int1e_prinvxp', 3)
    else:
        hso1e = mol.intor('int1e_pnucxp', 3)
    hso = [hso1e, -hso1e]

    if hfcobj.para_soc2e:
        hso2e = hfcobj.make_h1_soc2e(dm0)
        hso[0] += hso2e[0]
        hso[1] += hso2e[1]

    return hso
Exemple #3
0
def make_h01_soc1e(obj, mo_coeff, mo_occ, qed_fac=1):
    mol = obj.mol
    assert (not mol.has_ecp())
    alpha2 = nist.ALPHA**2
    #qed_fac = (nist.G_ELECTRON - 1)
    if obj.so_eff_charge:
        hso1e = 0
        for ia in range(mol.natm):
            Z = koseki_charge(mol.atom_charge(ia))
            mol.set_rinv_origin(mol.atom_coord(ia))
            hso1e += -Z * mol.intor_asymmetric('int1e_prinvxp', 3)
    else:
        hso1e = mol.intor_asymmetric('int1e_pnucxp', 3)
    hso1e *= qed_fac * (alpha2 / 4)
    return hso1e
Exemple #4
0
def make_h01_soc1e(gobj, mo_coeff, mo_occ, qed_fac=1):
    mol = gobj.mol
    assert(not mol.has_ecp())
    alpha2 = nist.ALPHA ** 2
    #qed_fac = (nist.G_ELECTRON - 1)

# hso1e is the imaginary part of [i sigma dot pV x p]
# JCP, 122, 034107 Eq (2) = 1/4c^2 hso1e
    if gobj.so_eff_charge:
        hso1e = 0
        for ia in range(mol.natm):
            Z = koseki_charge(mol.atom_charge(ia))
            mol.set_rinv_origin(mol.atom_coord(ia))
            hso1e += -Z * mol.intor_asymmetric('int1e_prinvxp', 3)
    else:
        hso1e = mol.intor_asymmetric('int1e_pnucxp', 3)
    hso1e *= qed_fac * (alpha2/4)
    return hso1e
Exemple #5
0
def make_h01_soc1e(gobj, mo_coeff, mo_occ, qed_fac=1):
    mol = gobj.mol
    assert(not mol.has_ecp())
    alpha2 = nist.ALPHA ** 2
    #qed_fac = (nist.G_ELECTRON - 1)

# hso1e is the imaginary part of [i sigma dot pV x p]
# JCP, 122, 034107 Eq (2) = 1/4c^2 hso1e
    if gobj.so_eff_charge:
        hso1e = 0
        for ia in range(mol.natm):
            Z = koseki_charge(mol.atom_charge(ia))
            mol.set_rinv_origin(mol.atom_coord(ia))
            hso1e += -Z * mol.intor_asymmetric('int1e_prinvxp', 3)
    else:
        hso1e = mol.intor_asymmetric('int1e_pnucxp', 3)
    hso1e *= qed_fac * (alpha2/4)
    return hso1e
Exemple #6
0
def dia(gobj, dm0, gauge_orig=None):
    '''Note the side effects of set_common_origin'''

    if isinstance(dm0, numpy.ndarray) and dm0.ndim == 2:  # RHF DM
        return numpy.zeros((3, 3))
    mol = gobj.mol
    effspin = mol.spin * .5
    muB = .5  # Bohr magneton

    dma, dmb = dm0
    totdm = dma + dmb
    spindm = dma - dmb
    alpha2 = nist.ALPHA**2
    #Many choices of qed_fac, see JPC, 101, 3388
    #qed_fac = (nist.G_ELECTRON - 1)
    #qed_fac = nist.G_ELECTRON / 2
    qed_fac = 1

    assert (not mol.has_ecp())
    if gauge_orig is not None:
        mol.set_common_origin(gauge_orig)

    e11 = numpy.zeros((3, 3))
    im, mass_center = rhf_rotg.inertia_tensor(mol)
    for ia in range(mol.natm):
        Z = koseki_charge(mol.atom_charge(ia))
        R = mol.atom_coord(ia) - mass_center
        with mol.with_rinv_origin(R):
            h11 = mol.intor('int1e_drinv', comp=3) * Z  # * mol.atom_charge(ia)
            t1 = numpy.einsum('xij,ij->x', h11, spindm)
            e11 += numpy.dot(R, t1) * numpy.eye(3) - numpy.kron(R, t1).reshape(
                3, 3)

        #GIAO part of dia-magnetic constribution
        #print('kron', numpy.kron(R, t1).reshape(3,3))
        #h22 =  mol.intor('int1e_a01gp', comp=9)
        #e11 -=  Z * numpy.einsum('xij,ij->x', h22, spindm).reshape(3,3)
    gdia = e11 * alpha2 / effspin / 4.
    return gdia
Exemple #7
0
def dia(gobj, dm0, gauge_orig=None):
    '''Note the side effects of set_common_origin'''

    if isinstance(dm0, numpy.ndarray) and dm0.ndim == 2: # RHF DM
        return numpy.zeros((3,3))
    mol = gobj.mol

    dma, dmb = dm0
    spindm = dma - dmb
    effspin = mol.spin * .5
    muB = .5  # Bohr magneton
    alpha2 = nist.ALPHA ** 2
    #Many choices of qed_fac, see JPC, 101, 3388
    #qed_fac = (nist.G_ELECTRON - 1)
    #qed_fac = nist.G_ELECTRON / 2
    qed_fac = 1

# relativistic mass correction (RMC)
    rmc = -numpy.einsum('ij,ji', mol.intor('int1e_kin'), spindm)
    rmc *= qed_fac / effspin * alpha2
    logger.info(gobj, 'RMC = %s', rmc)

    assert(not mol.has_ecp())
# GC(1e)
    if gauge_orig is not None:
        mol.set_common_origin(gauge_orig)
    h11 = 0
    for ia in range(mol.natm):
        mol.set_rinv_origin(mol.atom_coord(ia))
        Z = mol.atom_charge(ia)
        if gobj.so_eff_charge or not gobj.dia_soc2e:
            Z = koseki_charge(Z)
# GC(1e) = 1/4c^2 Z/(2r_N^3) [vec{r}_N dot r sigma dot B - B dot vec{r}_N r dot sigma]
# a11part = (B dot) -1/2 frac{\vec{r}_N}{r_N^3} r (dot sigma)
        if gauge_orig is None:
            h11 += Z * mol.intor('int1e_giao_a11part', 9)
        else:
            h11 += Z * mol.intor('int1e_cg_a11part', 9)
    trh11 = h11[0] + h11[4] + h11[8]
    h11[0] -= trh11
    h11[4] -= trh11
    h11[8] -= trh11
    if gauge_orig is None:
        for ia in range(mol.natm):
            mol.set_rinv_origin(mol.atom_coord(ia))
            Z = mol.atom_charge(ia)
            if gobj.so_eff_charge or not gobj.dia_soc2e:
                Z = koseki_charge(Z)
            h11 += Z * mol.intor('int1e_a01gp', 9)
    gc1e = numpy.einsum('xij,ji->x', h11, spindm).reshape(3,3)
    if gobj.mb:  # correction of order c^{-2} from MB basis
        gc1e += numpy.einsum('ij,ji', mol.intor('int1e_nuc'), spindm) * numpy.eye(3)

    gc1e *= (alpha2/4) / effspin / muB
    if gobj.verbose >= logger.INFO:
        _write(gobj, gobj.align(gc1e)[0], 'GC(1e)')

    if gobj.dia_soc2e:
        gc2e = gobj.make_dia_gc2e(dm0, gauge_orig, qed_fac)
        if gobj.verbose >= logger.INFO:
            _write(gobj, gobj.align(gc2e)[0], 'GC(2e)')
    else:
        gc2e = 0

    gdia = gc1e + gc2e + rmc * numpy.eye(3)
    return gdia
Exemple #8
0
def dia(gobj, dm0, gauge_orig=None):
    '''Note the side effects of set_common_origin'''

    if isinstance(dm0, numpy.ndarray) and dm0.ndim == 2: # RHF DM
        return numpy.zeros((3,3))
    mol = gobj.mol

    dma, dmb = dm0
    spindm = dma - dmb
    effspin = mol.spin * .5
    muB = .5  # Bohr magneton
    alpha2 = nist.ALPHA ** 2
    #Many choices of qed_fac, see JPC, 101, 3388
    #qed_fac = (nist.G_ELECTRON - 1)
    #qed_fac = nist.G_ELECTRON / 2
    qed_fac = 1

# relativistic mass correction (RMC)
    rmc = -numpy.einsum('ij,ji', mol.intor('int1e_kin'), spindm)
    rmc *= qed_fac / effspin * alpha2
    logger.info(gobj, 'RMC = %s', rmc)

    assert(not mol.has_ecp())
# GC(1e)
    if gauge_orig is not None:
        mol.set_common_origin(gauge_orig)
    h11 = 0
    for ia in range(mol.natm):
        mol.set_rinv_origin(mol.atom_coord(ia))
        Z = mol.atom_charge(ia)
        if gobj.so_eff_charge or not gobj.dia_soc2e:
            Z = koseki_charge(Z)
# GC(1e) = 1/4c^2 Z/(2r_N^3) [vec{r}_N dot r sigma dot B - B dot vec{r}_N r dot sigma]
# a11part = (B dot) -1/2 frac{\vec{r}_N}{r_N^3} r (dot sigma)
        if gauge_orig is None:
            h11 += Z * mol.intor('int1e_giao_a11part', 9)
        else:
            h11 += Z * mol.intor('int1e_cg_a11part', 9)
    trh11 = h11[0] + h11[4] + h11[8]
    h11[0] -= trh11
    h11[4] -= trh11
    h11[8] -= trh11
    if gauge_orig is None:
        for ia in range(mol.natm):
            mol.set_rinv_origin(mol.atom_coord(ia))
            Z = mol.atom_charge(ia)
            if gobj.so_eff_charge or not gobj.dia_soc2e:
                Z = koseki_charge(Z)
            h11 += Z * mol.intor('int1e_a01gp', 9)
    gc1e = numpy.einsum('xij,ji->x', h11, spindm).reshape(3,3)
    if gobj.mb:  # correction of order c^{-2} from MB basis
        gc1e += numpy.einsum('ij,ji', mol.intor('int1e_nuc'), spindm) * numpy.eye(3)

    gc1e *= (alpha2/4) / effspin / muB
    if gobj.verbose >= logger.INFO:
        _write(gobj, gobj.align(gc1e)[0], 'GC(1e)')

    if gobj.dia_soc2e:
        gc2e = gobj.make_dia_gc2e(dm0, gauge_orig, qed_fac)
        if gobj.verbose >= logger.INFO:
            _write(gobj, gobj.align(gc2e)[0], 'GC(2e)')
    else:
        gc2e = 0

    gdia = gc1e + gc2e + rmc * numpy.eye(3)
    return gdia