Esempio n. 1
0
def gauss_to_string(l, m, numeric=False):
    """Return string representation of the generalized gaussian::
    
                       _____                           2  
         m            /  1       l!         l+3/2  -a r   l  m
        g (x,y,z) =  / ----- --------- (4 a)      e      r  Y (x,y,z)
         l         \/  4 pi  (2l + 1)!                       l
         
       numeric=True/False indicates whether the normalization constant should 
       be written as a number or an algebraic expression.
    """
    norm, xyzs = Y_collect(l, m)

    ng = Q(2**(2 * l + 3) * factorial(l), 2 * factorial(2 * l + 1))
    norm.multiply(ng)

    string = to_string(l, xyzs)
    string = (' * ' + string) * (string != '1')
    if numeric:
        snorm = repr(eval(repr(norm.norm)))
    else:
        snorm = repr(norm.norm)
    string = 'sqrt(a**%s*%s)/pi' % (2 * l + 3, snorm) + string
    string += ' * exp(-a*r2)'

    return string
Esempio n. 2
0
def legendre(l, m):
    """Determine z dependence of spherical harmonic.
       Returns vector, where the p'th element is the coefficient of
       z^p r^(l-|m|-p).
    """
    # Check if requested has already been calculated
    if (l, m) in Y_lp[0]:
        return Y_lp[0][(l, m)]

    m = abs(m)
    assert l >= 0 and 0 <= m <= l
    result = np.zeros(l - m + 1, 'O')
    if l == m == 0:
        """Use that
             0
            P (z) = 1
             0
        """
        result[0] = Q(1)
    elif l == m:
        """Use the recursion relation
            m              m-1
           P (z) = (2m-1) P   (z)
            m              m-1
        """
        result[:] += (2 * m - 1) * legendre(l - 1, m - 1)
    elif l == m + 1:
        """Use the recursion relation
            l-1              l-1
           P  (z) = (2l-1)z P   (z)
            l                l-1
            
        """
        result[1:] += (2 * l - 1) * legendre(l - 1, l - 1)
    else:
        """Use the recursion relation
            m     2l-1    m       l+m-1  2  m
           P (z)= ---- z P  (z) - ----- r  P  (z)
            l      l-m    l-1      l-m      l-2
        """
        result[1:] += np.multiply(legendre(l - 1, m), Q(2 * l - 1, l - m))
        result[:(l - 2) - m + 1] -= np.multiply(legendre(l - 2, m),
                                                Q(l + m - 1, l - m))
    # Store result in global dictionary
    Y_lp[0][(l, m)] = result
    return result
Esempio n. 3
0
def gauss_potential_to_string(l, m, numeric=False):
    """Return string representation of the potential of  a generalized
       gaussian.

       The potential is determined by::

          m        m ^    _           m ^
         v [g (r) Y (r) ](r) = v (r) Y (r)
          l  l     l         l     l  l

       where::
               4 pi /  -l-1 /r    l+2         l /oo   1-l      \ 
       v (r) = ---- | r     | dx x   g (r) + r  | dx x   g (r) |
        l      2l+1 \       /0        l         /r        l    /
    """
    v_l = [
        [Q(4, 1), 1],
        [Q(4, 3), 1, 2],
        [Q(4, 15), 3, 6, 4],
        [Q(4, 105), 15, 30, 20, 8],
        [Q(4, 945), 105, 210, 140, 56, 16],
        [Q(4, 10395), 945, 1890, 1260, 504, 144, 32],
    ]

    norm, xyzs = Y_collect(l, m)
    norm.multiply(v_l[l][0])

    string = txt_sqrt(norm.norm, numeric) + '*' + (l != 0) * '('
    if numeric:
        string += repr(v_l[l][1] * sqrt(pi))
    else:
        string += str(v_l[l][1]) + '*sqrt(pi)'
    string += '*erf(sqrt(a)*r)'

    if len(v_l[l]) > 2:
        string += '-('
        for n, coeff in enumerate(v_l[l][2:]):
            if n == 0:
                string += str(coeff)
            else:
                string += '+' + str(coeff) + '*(sqrt(a)*r)**%d' % (2 * n)
        string += ')*sqrt(a)*r*exp(-a*r2)'

    if l == 0:
        string += '/r'
    elif l == 1:
        string += ')/r/r2*' + to_string(l, xyzs)
    else:
        string += ')/r/r2**%d*' % l + to_string(l, xyzs)

    return string
Esempio n. 4
0
def simplify(xyzs):
    """Rescale coefficients to smallest integer value"""
    norm = Q(1)
    numxyz = np.array(xyzs.values())

    # up-scale all 'xyz' coefficients to integers
    for xyz in numxyz:
        numxyz *= xyz.denom
        norm /= xyz.denom

    # determine least common divisor for 'xyz' coefficients
    dmax = 1
    num_max = max(abs(np.floor(numxyz)))
    for d in range(2, num_max + 1):
        test = numxyz / d
        if np.alltrue(test == np.floor(test)): dmax = d

    # Update simplified dictionary
    norm *= dmax
    for i, xyz in enumerate(xyzs):
        xyzs[xyz] = numxyz[i] / dmax

    return norm
Esempio n. 5
0
 def __init__(self, l, m):
     m = abs(m)
     if m == 0:
         self.norm = Q(2 * l + 1, 4)
     else:
         self.norm = Q((2 * l + 1) * factorial(l - m), 2 * factorial(l + m))