Ejemplo n.º 1
0
    def test_integral_moment_first(self):
        lmax = 5 #XXX use meshgrid above l=5

        # Test first-order moments of the spherical harmonics
        for l1,m1 in lmiter(lmax, comm=world):
            s1_L = Y(l1, m1, theta_L, phi_L)
            for l2,m2 in lmiter(lmax):
                s2_L = Y(l2, m2, theta_L, phi_L)

                # Note that weights times surface area make up for sin(theta)
                v_ex = 4 * np.pi * np.vdot(s1_L, np.cos(phi_L) \
                    * np.sin(theta_L) * s2_L * weight_L)
                v_ey = 4 * np.pi * np.vdot(s1_L, np.sin(phi_L) \
                    * np.sin(theta_L) * s2_L * weight_L)
                v_ez = 4 * np.pi * np.vdot(s1_L, np.cos(theta_L) \
                    * s2_L * weight_L)

                v0_ex = intYY_ex(l1, m1, l2, m2)
                v0_ey = intYY_ey(l1, m1, l2, m2)
                v0_ez = intYY_ez(l1, m1, l2, m2)

                self.assertAlmostEqual(v_ex, v0_ex, 12, '%s != %s (l1=%2d, ' \
                    'm1=%2d, l2=%2d, m2=%2d)' % (v_ex,v0_ex,l1,m1,l2,m2))
                self.assertAlmostEqual(v_ey, v0_ey, 12, '%s != %s (l1=%2d, ' \
                    'm1=%2d, l2=%2d, m2=%2d)' % (v_ey,v0_ey,l1,m1,l2,m2))
                self.assertAlmostEqual(v_ez, v0_ez, 12, '%s != %s (l1=%2d, ' \
                    'm1=%2d, l2=%2d, m2=%2d)' % (v_ez,v0_ez,l1,m1,l2,m2))
Ejemplo n.º 2
0
def bilinear_concentric_force(r_g, dr_g, f_g, ft_g, l1, l2, alpha, rfilt=None):
    """Calculate corrections for concentric functions and potentials::

        _        /     _   _a  __    _   _a    ~   _   _a  __  ~ _   _a   _
        F      = | f  (r - R ) \/_ V(r - R ) - f  (r - R ) \/_ V(r - R ) dr
         m1,m2   /  L1,L2        r               L1,L2       r

    where f(r) and ft(r) are bilinear product of two localized functions which
    are radial splines times real spherical harmonics (l1,m1) or (l2,m2) and::

          _       1       _ -1              ~ _    erf(alpha*r)  _ -1
        V(r) = --------- |r|        ^       V(r) = ------------ |r|
               4 pi eps0                            4 pi eps0

    Note that alpha (and rfilt) should conform with the cutoff radius.
    """
    work_g = erf(alpha*r_g) - 2*alpha/np.pi**0.5 \
        * r_g * np.exp(-alpha**2 * r_g**2)

    if rfilt is None:
        M = - np.vdot(f_g - ft_g * work_g, dr_g)
    else:
        M = - np.vdot((f_g - ft_g * work_g)[r_g>=rfilt], dr_g[r_g>=rfilt])

        # Replace 1/r -> (3-r^2/rfilt^2)/(2*rfilt) for r < rfilt
        work_g = (r_g/rfilt) * erf(alpha*r_g) - alpha*rfilt/np.pi**0.5 \
            * (3-(r_g/rfilt)**2) * np.exp(-alpha**2 * r_g**2)
        M += - np.vdot((f_g * (r_g/rfilt) - ft_g * work_g)[r_g<rfilt], \
            ((r_g/rfilt)**2 * dr_g)[r_g<rfilt])

    F_mmv = np.empty((2*l1+1, 2*l2+1, 3), dtype=float)
    for m1 in range(2*l1+1):
        for m2 in range(2*l2+1):
            F_mmv[m1,m2,0] = M * intYY_ex(l1, m1-l1, l2, m2-l2)
            F_mmv[m1,m2,1] = M * intYY_ey(l1, m1-l1, l2, m2-l2)
            F_mmv[m1,m2,2] = M * intYY_ez(l1, m1-l1, l2, m2-l2)
    return F_mmv