Exemplo n.º 1
0
    def Coulomb_integral_ijkq(self, i, j, k, q, spin, integrals, yukawa=False):
        name = self.Coulomb_integral_name(i, j, k, q, spin)
        if name in integrals:
            return integrals[name]

        # create the Kohn-Sham singles
        kss_ij = PairDensity(self.paw)
        kss_ij.initialize(self.paw.wfs.kpt_u[spin], i, j)
        kss_kq = PairDensity(self.paw)
        kss_kq.initialize(self.paw.wfs.kpt_u[spin], k, q)

        rhot_p = kss_ij.with_compensation_charges(self.finegrid != 0)
        phit_p = np.zeros(rhot_p.shape, rhot_p.dtype)
        if yukawa:
            self.screened_poissonsolver.solve(phit_p, rhot_p, charge=None)
        else:
            self.poisson.solve(phit_p, rhot_p, charge=None)

        if self.finegrid == 1:
            phit = self.gd.zeros()
            self.restrict(phit_p, phit)
        else:
            phit = phit_p

        rhot = kss_kq.with_compensation_charges(self.finegrid == 2)

        integrals[name] = self.Coulomb_integral_kss(kss_ij,
                                                    kss_kq,
                                                    phit,
                                                    rhot,
                                                    yukawa=yukawa)
        return integrals[name]
Exemplo n.º 2
0
def dipole_op(c, state1, state2, k=0, s=0):
    # Taken from KSSingle, maybe make this accessible in
    # KSSingle?
    wfs = c.wfs
    gd = wfs.gd

    kpt = None
    for i in wfs.kpt_u:
        if i.k == k and i.s == s:
            kpt = i

    pd = PairDensity(c)
    pd.initialize(kpt, state1, state2)

    # coarse grid contribution
    # <i|r|j> is the negative of the dipole moment (because of negative
    # e- charge)
    me = -gd.calculate_dipole_moment(pd.get())

    # augmentation contributions
    ma = np.zeros(me.shape)
    pos_av = c.get_atoms().get_positions() / Bohr
    for a, P_ni in kpt.P_ani.items():
        Ra = pos_av[a]
        Pi_i = P_ni[state1]
        Pj_i = P_ni[state2]
        Delta_pL = wfs.setups[a].Delta_pL
        ni = len(Pi_i)

        ma0 = 0
        ma1 = np.zeros(me.shape)
        for i in range(ni):
            for j in range(ni):
                pij = Pi_i[i] * Pj_i[j]
                ij = packed_index(i, j, ni)
                # L=0 term
                ma0 += Delta_pL[ij, 0] * pij
                # L=1 terms
                if wfs.setups[a].lmax >= 1:
                    # see spherical_harmonics.py for
                    # L=1:y L=2:z; L=3:x
                    ma1 += np.array([
                        Delta_pL[ij, 3], Delta_pL[ij, 1], Delta_pL[ij, 2]
                    ]) * pij
        ma += sqrt(4 * pi / 3) * ma1 + Ra * sqrt(4 * pi) * ma0
    gd.comm.sum(ma)

    me += ma

    return me * Bohr
Exemplo n.º 3
0
    def Coulomb_integral_ijkq(self, i, j, k, q, spin, integrals):
        name = self.Coulomb_integral_name(i, j, k, q, spin)
        if name in integrals:
            return integrals[name]

        # create the Kohn-Sham singles
        kss_ij = PairDensity(self.paw)
        kss_ij.initialize(self.paw.wfs.kpt_u[spin], i, j)
        kss_kq = PairDensity(self.paw)
        kss_kq.initialize(self.paw.wfs.kpt_u[spin], k, q)

        rhot_p = kss_ij.with_compensation_charges(self.finegrid is not 0)
        phit_p = np.zeros(rhot_p.shape, rhot_p.dtype)
        self.poisson.solve(phit_p, rhot_p, charge=None)

        if self.finegrid == 1:
            phit = self.gd.zeros()
            self.restrict(phit_p, phit)
        else:
            phit = phit_p

        rhot = kss_kq.with_compensation_charges(self.finegrid is 2)

        integrals[name] = self.Coulomb_integral_kss(kss_ij, kss_kq, phit, rhot)
        return integrals[name]
Exemplo n.º 4
0
def dipole_op(c, state1, state2, k=0, s=0):
    # Taken from KSSingle, maybe make this accessible in
    # KSSingle?
    wfs = c.wfs
    gd = wfs.gd

    kpt = None
    for i in wfs.kpt_u:
        if i.k == k and i.s == s:
            kpt = i
    
    pd = PairDensity(c)
    pd.initialize(kpt, state1, state2)

    # coarse grid contribution
    # <i|r|j> is the negative of the dipole moment (because of negative
    # e- charge)
    me = -gd.calculate_dipole_moment(pd.get())

    # augmentation contributions
    ma = np.zeros(me.shape)
    pos_av = c.get_atoms().get_positions() / Bohr
    for a, P_ni in kpt.P_ani.items():
        Ra = pos_av[a]
        Pi_i = P_ni[state1]
        Pj_i = P_ni[state2]
        Delta_pL = wfs.setups[a].Delta_pL
        ni = len(Pi_i)

        ma0 = 0
        ma1 = np.zeros(me.shape)
        for i in range(ni):
            for j in range(ni):
                pij = Pi_i[i]*Pj_i[j]
                ij = packed_index(i, j, ni)
                # L=0 term
                ma0 += Delta_pL[ij,0]*pij
                # L=1 terms
                if wfs.setups[a].lmax >= 1:
                    # see spherical_harmonics.py for
                    # L=1:y L=2:z; L=3:x
                    ma1 += np.array([Delta_pL[ij,3], Delta_pL[ij,1],
                                     Delta_pL[ij,2]]) * pij
        ma += sqrt(4 * pi / 3) * ma1 + Ra * sqrt(4 * pi) * ma0
    gd.comm.sum(ma)

    me += ma

    return me * Bohr
Exemplo n.º 5
0
    def __init__(self, paw):
        paw.initialize_positions()
        self.nspins = paw.wfs.nspins
        self.nbands = paw.wfs.bd.nbands
        self.restrict = paw.hamiltonian.restrict
        self.pair_density = PairDensity(paw.density, paw.atoms, finegrid=True)
        self.dv = paw.wfs.gd.dv
        self.dtype = paw.wfs.dtype
        self.setups = paw.wfs.setups

        # Allocate space for matrices
        self.nt_G = paw.wfs.gd.empty()
        self.rhot_g = paw.density.finegd.empty()
        self.vt_G = paw.wfs.gd.empty()
        self.vt_g = paw.density.finegd.empty()
        self.poisson_solve = paw.hamiltonian.poisson.solve
Exemplo n.º 6
0
    def __init__(self,
                 iidx=None,
                 jidx=None,
                 pspin=None,
                 kpt=None,
                 paw=None,
                 string=None,
                 fijscale=1):

        if string is not None:
            self.fromstring(string)
            return None

        # normal entry

        PairDensity.__init__(self, paw)
        wfs = paw.wfs
        PairDensity.initialize(self, kpt, iidx, jidx)

        self.pspin = pspin

        f = kpt.f_n
        self.fij = (f[iidx] - f[jidx]) * fijscale
        e = kpt.eps_n
        self.energy = e[jidx] - e[iidx]

        # calculate matrix elements -----------

        gd = wfs.gd
        self.gd = gd

        # length form ..........................

        # course grid contribution
        # <i|r|j> is the negative of the dipole moment (because of negative
        # e- charge)
        me = -gd.calculate_dipole_moment(self.get())

        # augmentation contributions
        ma = np.zeros(me.shape)
        pos_av = paw.atoms.get_positions() / Bohr
        for a, P_ni in kpt.P_ani.items():
            Ra = pos_av[a]
            Pi_i = P_ni[self.i]
            Pj_i = P_ni[self.j]
            Delta_pL = wfs.setups[a].Delta_pL
            ni = len(Pi_i)
            ma0 = 0
            ma1 = np.zeros(me.shape)
            for i in range(ni):
                for j in range(ni):
                    pij = Pi_i[i] * Pj_i[j]
                    ij = packed_index(i, j, ni)
                    # L=0 term
                    ma0 += Delta_pL[ij, 0] * pij
                    # L=1 terms
                    if wfs.setups[a].lmax >= 1:
                        # see spherical_harmonics.py for
                        # L=1:y L=2:z; L=3:x
                        ma1 += np.array([
                            Delta_pL[ij, 3], Delta_pL[ij, 1], Delta_pL[ij, 2]
                        ]) * pij
            ma += sqrt(4 * pi / 3) * ma1 + Ra * sqrt(4 * pi) * ma0
        gd.comm.sum(ma)

        ##        print '<KSSingle> i,j,me,ma,fac=',self.i,self.j,\
        ##            me, ma,sqrt(self.energy*self.fij)
        #        print 'l: me, ma', me, ma
        self.me = sqrt(self.energy * self.fij) * (me + ma)

        self.mur = -(me + ma)
        ##        print '<KSSingle> mur=',self.mur,-self.fij *me

        # velocity form .............................
        self.muv = np.zeros(me.shape)  # does not work XXX
Exemplo n.º 7
0
    def __init__(self, iidx=None, jidx=None, pspin=None, kpt=None,
                 paw=None, string=None, fijscale=1):
        
        if string is not None: 
            self.fromstring(string)
            return None

        # normal entry
        
        PairDensity.__init__(self, paw)
        wfs = paw.wfs
        PairDensity.initialize(self, kpt, iidx, jidx)

        self.pspin=pspin
        
        f = kpt.f_n
        self.fij = (f[iidx] - f[jidx]) * fijscale
        e = kpt.eps_n
        self.energy = e[jidx] - e[iidx]

        # calculate matrix elements -----------

        gd = wfs.gd
        self.gd = gd

        # length form ..........................

        # course grid contribution
        # <i|r|j> is the negative of the dipole moment (because of negative
        # e- charge)
        me = - gd.calculate_dipole_moment(self.get())

        # augmentation contributions
        ma = np.zeros(me.shape)
        pos_av = paw.atoms.get_positions() / Bohr
        for a, P_ni in kpt.P_ani.items():
            Ra = pos_av[a]
            Pi_i = P_ni[self.i]
            Pj_i = P_ni[self.j]
            Delta_pL = wfs.setups[a].Delta_pL
            ni=len(Pi_i)
            ma0 = 0
            ma1 = np.zeros(me.shape)
            for i in range(ni):
                for j in range(ni):
                    pij = Pi_i[i]*Pj_i[j]
                    ij = packed_index(i, j, ni)
                    # L=0 term
                    ma0 += Delta_pL[ij,0]*pij
                    # L=1 terms
                    if wfs.setups[a].lmax >= 1:
                        # see spherical_harmonics.py for
                        # L=1:y L=2:z; L=3:x
                        ma1 += np.array([Delta_pL[ij,3], Delta_pL[ij,1],
                                         Delta_pL[ij,2]]) * pij
            ma += sqrt(4 * pi / 3) * ma1 + Ra * sqrt(4 * pi) * ma0
        gd.comm.sum(ma)

        self.me = sqrt(self.energy * self.fij) * ( me + ma )

        self.mur = - ( me + ma )

        # velocity form .............................

        me = np.zeros(self.mur.shape)

        # get derivatives
        dtype = self.wfj.dtype
        dwfj_cg = gd.empty((3), dtype=dtype)
        if not hasattr(gd, 'ddr'):
            gd.ddr = [Gradient(gd, c, dtype=dtype).apply for c in range(3)]
        for c in range(3):
            gd.ddr[c](self.wfj, dwfj_cg[c], kpt.phase_cd)
            me[c] = gd.integrate(self.wfi * dwfj_cg[c])

        if 0:
            me2 = np.zeros(self.mur.shape)
            for c in range(3):
                gd.ddr[c](self.wfi, dwfj_cg[c], kpt.phase_cd)
                me2[c] = gd.integrate(self.wfj * dwfj_cg[c])
            print me, -me2, me2+me

        # augmentation contributions
        ma = np.zeros(me.shape)
        for a, P_ni in kpt.P_ani.items():
            Pi_i = P_ni[self.i]
            Pj_i = P_ni[self.j]
            nabla_iiv = paw.wfs.setups[a].nabla_iiv
            for c in range(3):
                for i1, Pi in enumerate(Pi_i):
                    for i2, Pj in enumerate(Pj_i):
                        ma[c] += Pi * Pj * nabla_iiv[i1, i2, c]
        gd.comm.sum(ma)
        
        self.muv = - (me + ma) / self.energy
##        print self.mur, self.muv, self.mur - self.muv

        # magnetic transition dipole ................

        magn = np.zeros(me.shape)
        r_cg, r2_g = coordinates(gd)

        wfi_g = self.wfi
        for ci in range(3):
            cj = (ci + 1) % 3
            ck = (ci + 2) % 3
            magn[ci] = gd.integrate(wfi_g * r_cg[cj] * dwfj_cg[ck] -
                                    wfi_g * r_cg[ck] * dwfj_cg[cj]  )
        # augmentation contributions
        ma = np.zeros(magn.shape)
        for a, P_ni in kpt.P_ani.items():
            Pi_i = P_ni[self.i]
            Pj_i = P_ni[self.j]
            rnabla_iiv = paw.wfs.setups[a].rnabla_iiv
            for c in range(3):
                for i1, Pi in enumerate(Pi_i):
                    for i2, Pj in enumerate(Pj_i):
                        ma[c] += Pi * Pj * rnabla_iiv[i1, i2, c]
        gd.comm.sum(ma)
        
        self.magn = -alpha / 2. * (magn + ma)
Exemplo n.º 8
0
    def __init__(self,
                 iidx=None,
                 jidx=None,
                 pspin=None,
                 kpt=None,
                 paw=None,
                 string=None,
                 fijscale=1,
                 dtype=float):

        if string is not None:
            self.fromstring(string, dtype)
            return None

        # normal entry

        PairDensity.__init__(self, paw)
        PairDensity.initialize(self, kpt, iidx, jidx)

        self.pspin = pspin

        self.energy = 0.0
        self.fij = 0.0

        self.me = np.zeros((3), dtype=dtype)
        self.mur = np.zeros((3), dtype=dtype)
        self.muv = np.zeros((3), dtype=dtype)
        self.magn = np.zeros((3), dtype=dtype)

        self.kpt_comm = paw.wfs.kd.comm

        # leave empty if not my kpt
        if kpt is None:
            return

        wfs = paw.wfs
        gd = wfs.gd

        self.energy = kpt.eps_n[jidx] - kpt.eps_n[iidx]
        self.fij = (kpt.f_n[iidx] - kpt.f_n[jidx]) * fijscale

        # calculate matrix elements -----------

        # length form ..........................

        # course grid contribution
        # <i|r|j> is the negative of the dipole moment (because of negative
        # e- charge)
        me = -gd.calculate_dipole_moment(self.get())

        # augmentation contributions
        ma = np.zeros(me.shape, dtype=dtype)
        pos_av = paw.atoms.get_positions() / Bohr
        for a, P_ni in kpt.P_ani.items():
            Ra = pos_av[a]
            Pi_i = P_ni[self.i].conj()
            Pj_i = P_ni[self.j]
            Delta_pL = wfs.setups[a].Delta_pL
            ni = len(Pi_i)
            ma0 = 0
            ma1 = np.zeros(me.shape, dtype=me.dtype)
            for i in range(ni):
                for j in range(ni):
                    pij = Pi_i[i] * Pj_i[j]
                    ij = packed_index(i, j, ni)
                    # L=0 term
                    ma0 += Delta_pL[ij, 0] * pij
                    # L=1 terms
                    if wfs.setups[a].lmax >= 1:
                        # see spherical_harmonics.py for
                        # L=1:y L=2:z; L=3:x
                        ma1 += np.array([
                            Delta_pL[ij, 3], Delta_pL[ij, 1], Delta_pL[ij, 2]
                        ]) * pij
            ma += sqrt(4 * pi / 3) * ma1 + Ra * sqrt(4 * pi) * ma0
        gd.comm.sum(ma)

        self.me = sqrt(self.energy * self.fij) * (me + ma)
        self.mur = -(me + ma)

        # velocity form .............................

        if self.lcao:
            # XXX Velocity form not supported in LCAO
            return

        me = np.zeros(self.mur.shape, dtype=dtype)

        # get derivatives
        dtype = self.wfj.dtype
        dwfj_cg = gd.empty((3), dtype=dtype)
        if not hasattr(gd, 'ddr'):
            gd.ddr = [Gradient(gd, c, dtype=dtype).apply for c in range(3)]
        for c in range(3):
            gd.ddr[c](self.wfj, dwfj_cg[c], kpt.phase_cd)
            me[c] = gd.integrate(self.wfi.conj() * dwfj_cg[c])

        if 0:
            me2 = np.zeros(self.mur.shape)
            for c in range(3):
                gd.ddr[c](self.wfi, dwfj_cg[c], kpt.phase_cd)
                me2[c] = gd.integrate(self.wfj * dwfj_cg[c])
            print(me, -me2, me2 + me)

        # augmentation contributions
        ma = np.zeros(me.shape, dtype=me.dtype)
        for a, P_ni in kpt.P_ani.items():
            Pi_i = P_ni[self.i].conj()
            Pj_i = P_ni[self.j]
            nabla_iiv = paw.wfs.setups[a].nabla_iiv
            for c in range(3):
                for i1, Pi in enumerate(Pi_i):
                    for i2, Pj in enumerate(Pj_i):
                        ma[c] += Pi * Pj * nabla_iiv[i1, i2, c]
        gd.comm.sum(ma)

        self.muv = -(me + ma) / self.energy

        # magnetic transition dipole ................

        r_cg, r2_g = coordinates(gd)
        magn = np.zeros(me.shape, dtype=dtype)

        wfi_g = self.wfi.conj()
        for ci in range(3):
            cj = (ci + 1) % 3
            ck = (ci + 2) % 3
            magn[ci] = gd.integrate(wfi_g * r_cg[cj] * dwfj_cg[ck] -
                                    wfi_g * r_cg[ck] * dwfj_cg[cj])
        # augmentation contributions
        ma = np.zeros(magn.shape, dtype=magn.dtype)
        for a, P_ni in kpt.P_ani.items():
            Pi_i = P_ni[self.i].conj()
            Pj_i = P_ni[self.j]
            rnabla_iiv = paw.wfs.setups[a].rnabla_iiv
            for c in range(3):
                for i1, Pi in enumerate(Pi_i):
                    for i2, Pj in enumerate(Pj_i):
                        ma[c] += Pi * Pj * rnabla_iiv[i1, i2, c]
        gd.comm.sum(ma)

        self.magn = -alpha / 2. * (magn + ma)