Beispiel #1
0
    def initialize(self):
        if self.initialized:
            return
            
        cache = {}
        lmax = -1

        # Fourier transform radial functions:
        for a, spline_j in enumerate(self.spline_aj):
            self.lf_aj.append([])
            for spline in spline_j:
                l = spline.get_angular_momentum_number()
                if spline not in cache:
                    f = ft(spline)
                    f_qG = []
                    for G2_G in self.pd.G2_qG:
                        G_G = G2_G**0.5
                        f_qG.append(f.map(G_G))
                    cache[spline] = f_qG
                else:
                    f_qG = cache[spline]
                self.lf_aj[a].append((l, f_qG))
                lmax = max(lmax, l)

        # Spherical harmonics:
        for q, K_v in enumerate(self.pd.K_qv):
            G_Gv = self.pd.get_reciprocal_vectors(q=q)
            Y_LG = np.empty(((lmax + 1)**2, len(G_Gv)))
            for L in range((lmax + 1)**2):
                Y_LG[L] = Y(L, *G_Gv.T)
            self.Y_qLG.append(Y_LG)
            
        self.initialized = True
Beispiel #2
0
def Y_rotation(l, angle):
    Y_mm = np.zeros((2 * l + 1, 2 * l + 1))
    sn = sin(angle)
    cs = cos(angle)
    for m1, point in enumerate(sphere_lm[l]):
        x = point[0]
        y = cs * point[1] - sn * point[2]
        z = sn * point[1] + cs * point[2]
        for m2 in range(2 * l + 1):
            L = l**2 + m2
            Y_mm[m1, m2] = Y(L, x, y, z)
    return Y_mm
Beispiel #3
0
def Y_matrix(l, U_vv):
    """YMatrix(l, symmetry) -> matrix.

    For 2*l+1 points on the unit sphere (m1=0,...,2*l) calculate the
    value of Y_lm2 for m2=0,...,2*l.  The points are those from the
    list sphere_lm[l] rotated as described by U_vv."""

    Y_mm = np.zeros((2 * l + 1, 2 * l + 1))
    for m1, point in enumerate(sphere_lm[l]):
        x, y, z = np.dot(point, U_vv)
        for m2 in range(2 * l + 1):
            L = l**2 + m2
            Y_mm[m1, m2] = Y(L, x, y, z)
    return Y_mm
Beispiel #4
0
def run():
    from gpaw.spherical_harmonics import Y
    weight_n = np.zeros(50)
    Y_nL = np.zeros((50, 25))
    R_nv = np.zeros((50, 3))

    # We use 50 Lebedev quadrature points which will integrate
    # spherical harmonics correctly for l < 12:
    n = 0
    for v in [0, 1, 2]:
        for s in [-1, 1]:
            R_nv[n, v] = s
            n += 1
    C = 2**-0.5
    for v1 in [0, 1, 2]:
        v2 = (v1 + 1) % 3
        v3 = (v1 + 2) % 3
        for s1 in [-1, 1]:
            for s2 in [-1, 1]:
                R_nv[n, v2] = s1 * C
                R_nv[n, v3] = s2 * C
                n += 1
    C = 3**-0.5
    for s1 in [-1, 1]:
        for s2 in [-1, 1]:
            for s3 in [-1, 1]:
                R_nv[n] = (s1 * C, s2 * C, s3 * C)
                n += 1
    C1 = 0.30151134457776357
    C2 = (1.0 - 2.0 * C1**2)**0.5
    for v1 in [0, 1, 2]:
        v2 = (v1 + 1) % 3
        v3 = (v1 + 2) % 3
        for s1 in [-1, 1]:
            for s2 in [-1, 1]:
                for s3 in [-1, 1]:
                    R_nv[n, v1] = s1 * C2
                    R_nv[n, v2] = s2 * C1
                    R_nv[n, v3] = s3 * C1
                    n += 1
    assert n == 50

    weight_n[0:6] = 0.01269841269841270
    weight_n[6:18] = 0.02257495590828924
    weight_n[18:26] = 0.02109375000000000
    weight_n[26:50] = 0.02017333553791887

    n = 0
    for x, y, z in R_nv:
        Y_nL[n] = [Y(L, x, y, z) for L in range(25)]
        n += 1

    # Write all 50 points to an xyz file as 50 hydrogen atoms:
    f = open('50.xyz', 'w')
    f.write('50\n\n')
    for x, y, z in R_nv:
        print('H', 4 * x, 4 * y, 4 * z, file=f)

    #print np.dot(weights, Y_nL) * (4*pi)**.5

    print('weight_n = np.array(%s)' % weight_n.tolist())
    print('Y_nL = np.array(%s)' % Y_nL.tolist())
    print('R_nv = np.array(%s)' % R_nv.tolist())

    return weight_n, Y_nL, R_nv
Beispiel #5
0
def two_phi_planewave_integrals(k_Gv,
                                setup=None,
                                Gstart=0,
                                Gend=None,
                                rgd=None,
                                phi_jg=None,
                                phit_jg=None,
                                l_j=None):
    """Calculate PAW-correction matrix elements with planewaves.

    ::
    
      /  _       _   ik.r     _     ~   _   ik.r ~   _
      | dr [phi (r) e    phi (r) - phi (r) e    phi (r)]
      /        1            2         1            2

                        ll    -  /     2                      ~       ~
      = 4 * pi \sum_lm  i  Y (k) | dr r  [ phi (r) phi (r) - phi (r) phi (r) j (kr)
                            lm   /            1       2         1       2     ll

           /
        * | d\Omega Y     Y     Y
          /          l1m1  l2m2  lm
          
    """

    if Gend is None:
        Gend = len(k_Gv)

    if setup is not None:
        rgd = setup.rgd
        l_j = setup.l_j
        # Obtain the phi_j and phit_j
        phi_jg = []
        phit_jg = []
        rcut2 = 2 * max(setup.rcut_j)
        gcut2 = rgd.ceil(rcut2)
        for phi_g, phit_g in zip(setup.data.phi_jg, setup.data.phit_jg):
            phi_g = phi_g.copy()
            phit_g = phit_g.copy()
            phi_g[gcut2:] = phit_g[gcut2:] = 0.
            phi_jg.append(phi_g)
            phit_jg.append(phit_g)
    else:
        assert rgd is not None
        assert phi_jg is not None
        assert l_j is not None

    ng = rgd.N
    r_g = rgd.r_g
    dr_g = rgd.dr_g

    # Construct L (l**2 + m) and j (nl) index
    L_i = []
    j_i = []
    for j, l in enumerate(l_j):
        for m in range(2 * l + 1):
            L_i.append(l**2 + m)
            j_i.append(j)
    ni = len(L_i)
    nj = len(l_j)
    lmax = max(l_j) * 2 + 1

    if setup is not None:
        assert ni == setup.ni and nj == setup.nj

    # Initialize
    npw = k_Gv.shape[0]
    R_jj = np.zeros((nj, nj))
    R_ii = np.zeros((ni, ni))
    phi_Gii = np.zeros((npw, ni, ni), dtype=complex)
    j_lg = np.zeros((lmax, ng))

    # Store (phi_j1 * phi_j2 - phit_j1 * phit_j2 ) for further use
    tmp_jjg = np.zeros((nj, nj, ng))
    for j1 in range(nj):
        for j2 in range(nj):
            tmp_jjg[j1,
                    j2] = (phi_jg[j1] * phi_jg[j2] - phit_jg[j1] * phit_jg[j2])

    # Loop over G vectors
    for iG in range(Gstart, Gend):
        kk = k_Gv[iG]
        k = np.sqrt(np.dot(kk, kk))  # calculate length of q+G

        # Calculating spherical bessel function
        for g, r in enumerate(r_g):
            j_lg[:, g] = sphj(lmax - 1, k * r)[1]

        for li in range(lmax):
            # Radial part
            for j1 in range(nj):
                for j2 in range(nj):
                    R_jj[j1, j2] = np.dot(r_g**2 * dr_g,
                                          tmp_jjg[j1, j2] * j_lg[li])

            for mi in range(2 * li + 1):
                # Angular part
                for i1 in range(ni):
                    L1 = L_i[i1]
                    j1 = j_i[i1]
                    for i2 in range(ni):
                        L2 = L_i[i2]
                        j2 = j_i[i2]
                        R_ii[i1, i2] = G_LLL[L1, L2, li**2 + mi] * R_jj[j1, j2]

                phi_Gii[iG] += R_ii * Y(li**2 + mi, kk[0] / k, kk[1] / k,
                                        kk[2] / k) * (-1j)**li

    phi_Gii *= 4 * pi

    return phi_Gii.reshape(npw, ni * ni)
Beispiel #6
0
 phit_i = num.empty((s.ni, 59), num.Float)
 x = num.empty(59, num.Float)
 x[29:] = r
 x[29::-1] = -r
 x *= paw.a0
 i = 0
 nj = len(phi_j)
 for j in range(nj):
     f = phi_j[j]
     ft = phit_j[j]
     l = f.get_angular_momentum_number()
     f = num.array([f(R) for R in r]) * r**l
     ft = num.array([ft(R) for R in r]) * r**l
     for m in range(2 * l + 1):
         L = l**2 + m
         phi_i[i + m, 29:] = f * Y(L, 1, 0, 0)
         phi_i[i + m, 29::-1] = f * Y(L, -1, 0, 0)
         phit_i[i + m, 29:] = ft * Y(L, 1, 0, 0)
         phit_i[i + m, 29::-1] = ft * Y(L, -1, 0, 0)
     i += 2 * l + 1
 assert i == s.ni
 P_i = n.P_uni[0, N]
 X = n.spos_c[0] * a - c
 p.plot(X + x,
        num.dot(P_i, phit_i),
        C + '-',
        lw=1,
        label=r'$\tilde{\psi}^%s$' % s.symbol)
 p.plot(X + x,
        num.dot(P_i, phi_i),
        C + '-',
Beispiel #7
0
def two_phi_nabla_planewave_integrals(k_Gv, setup=None, Gstart=0, Gend=None,
                                      rgd=None, phi_jg=None,
                                      phit_jg=None, l_j=None):
    """Calculate PAW-correction matrix elements with planewaves and gradient.

    ::
    
      /  _       _   ik.r d       _     ~   _   ik.r d   ~   _
      | dr [phi (r) e     -- phi (r) - phi (r) e     -- phi (r)]
      /        1          dx    2         1          dx    2

    and similar for y and z."""

    if Gend is None:
        Gend = len(k_Gv)
        
    if setup is not None:
        rgd = setup.rgd
        l_j = setup.l_j
        # Obtain the phi_j and phit_j
        phi_jg = []
        phit_jg = []
        rcut2 = 2 * max(setup.rcut_j)
        gcut2 = rgd.ceil(rcut2)
        for phi_g, phit_g in zip(setup.data.phi_jg, setup.data.phit_jg):
            phi_g = phi_g.copy()
            phit_g = phit_g.copy()
            phi_g[gcut2:] = phit_g[gcut2:] = 0.
            phi_jg.append(phi_g)
            phit_jg.append(phit_g)
    else:
        assert rgd is not None
        assert phi_jg is not None
        assert l_j is not None

    ng = rgd.N
    r_g = rgd.r_g
    dr_g = rgd.dr_g

    # Construct L (l**2 + m) and j (nl) index
    L_i = []
    j_i = []
    for j, l in enumerate(l_j):
        for m in range(2 * l + 1):
            L_i.append(l**2 + m)
            j_i.append(j)
    ni = len(L_i)
    nj = len(l_j)
    lmax = max(l_j) * 2 + 1
    
    ljdef = 3
    l2max = max(l_j) * (max(l_j) > ljdef) + ljdef * (max(l_j) <= ljdef)
    G_LLL = gaunt(l2max)
    Y_LLv = nabla(2 * l2max)

    if setup is not None:
        assert ni == setup.ni and nj == setup.nj

    # Initialize
    npw = k_Gv.shape[0]
    R1_jj = np.zeros((nj, nj))
    R2_jj = np.zeros((nj, nj))
    R_vii = np.zeros((3, ni, ni))
    phi_vGii = np.zeros((3, npw, ni, ni), dtype=complex)
    j_lg = np.zeros((lmax, ng))
    
    # Store (phi_j1 * dphidr_j2 - phit_j1 * dphitdr_j2) for further use
    tmp_jjg = np.zeros((nj, nj, ng))
    tmpder_jjg = np.zeros((nj, nj, ng))
    for j1 in range(nj):
        for j2 in range(nj):
            dphidr_g = np.empty_like(phi_jg[j2])
            rgd.derivative(phi_jg[j2], dphidr_g)
            dphitdr_g = np.empty_like(phit_jg[j2])
            rgd.derivative(phit_jg[j2], dphitdr_g)

            tmpder_jjg[j1, j2] = (phi_jg[j1] * dphidr_g -
                                  phit_jg[j1] * dphitdr_g)
            tmp_jjg[j1, j2] = (phi_jg[j1] * phi_jg[j2] -
                               phit_jg[j1] * phit_jg[j2])

    # Loop over G vectors
    for iG in range(Gstart, Gend):
        kk = k_Gv[iG]
        k = np.sqrt(np.dot(kk, kk))  # calculate length of q+G

        # Calculating spherical bessel function
        for g, r in enumerate(r_g):
            j_lg[:, g] = sphj(lmax - 1, k * r)[1]

        for li in range(lmax):
            # Radial part
            for j1 in range(nj):
                for j2 in range(nj):
                    R1_jj[j1, j2] = np.dot(r_g**2 * dr_g,
                                           tmpder_jjg[j1, j2] * j_lg[li])
                    R2_jj[j1, j2] = np.dot(r_g * dr_g,
                                           tmp_jjg[j1, j2] * j_lg[li])

            for mi in range(2 * li + 1):
                if k == 0:
                    Ytmp = Y(li**2 + mi, 1.0, 0, 0)
                else:
                    # Note the spherical bessel gives
                    # zero when k == 0 for li != 0
                    Ytmp = Y(li**2 + mi, kk[0] / k, kk[1] / k, kk[2] / k)

                for v in range(3):
                    Lv = 1 + (v + 2) % 3
                    # Angular part
                    for i1 in range(ni):
                        L1 = L_i[i1]
                        j1 = j_i[i1]
                        for i2 in range(ni):
                            L2 = L_i[i2]
                            j2 = j_i[i2]
                            l2 = l_j[j2]

                            R_vii[v, i1, i2] = ((4 * pi / 3)**0.5 *
                                                np.dot(G_LLL[L1, L2],
                                                       G_LLL[Lv, li**2 + mi])
                                                * (R1_jj[j1, j2] - l2 *
                                                   R2_jj[j1, j2]))

                            R_vii[v, i1, i2] += (R2_jj[j1, j2] *
                                                 np.dot(G_LLL[L1, li**2 + mi],
                                                        Y_LLv[:, L2, v]))

                phi_vGii[:, iG] += (R_vii * Ytmp * (-1j)**li)

    phi_vGii *= 4 * pi

    return phi_vGii.reshape(3, npw, ni * ni)