예제 #1
0
파일: poly.py 프로젝트: shigh/pyfem
def gll_points(n):
    """GLL points and weights

    :param n: Number of points
    :returns: (x, w)
    :rtype: 

    """
    
    assert n>=2

    if n==2:
        x = np.array([-1.0, 1.0])
        w = np.array([ 1.0, 1.0])
        return x, w

    # See Nodal Discontinuous Galerkin Methods Appendix A for x and
    # the Mathworld page on Lobatto Quadrature for w
    x = j_roots(n-2, 1, 1)[0]
    L = eval_legendre(n-1, x)
    w1 = 2.0/(n*(n-1))
    w  = 2.0/(n*(n-1)*L*L)
    
    x = np.hstack([-1.0, x, 1.0])
    w = np.hstack([w1, w, w1])
    
    return x, w    
예제 #2
0
파일: poly.py 프로젝트: shigh/sempy
def gll_points(n):
    """GLL points and weights

    :param n: Number of points
    :returns: (x, w)
    :rtype:

    """

    assert n >= 2

    if n == 2:
        x = np.array([-1.0, 1.0])
        w = np.array([1.0, 1.0])
        return x, w

    # See Nodal Discontinuous Galerkin Methods Appendix A for x and
    # the Mathworld page on Lobatto Quadrature for w
    x = j_roots(n - 2, 1, 1)[0]
    L = eval_legendre(n - 1, x)
    w1 = 2.0 / (n * (n - 1))
    w = 2.0 / (n * (n - 1) * L * L)

    x = np.hstack([-1.0, x, 1.0])
    w = np.hstack([w1, w, w1])

    return x, w
예제 #3
0
 def _nodes_LGL(self, n):
     """ 
        Legendre-Gauss-Lobatto(LGL) points
     """
     roots, weight = special.j_roots(n - 2, 1, 1)
     nodes = np.hstack((-1, roots, 1))
     return nodes
예제 #4
0
def poisson_beta_pmf(k, k_on, k_off, k_syn, n_roots=50):
    assert (k_on > 0)
    assert (k_off > 0)

    roots, weights = special.j_roots(n_roots, alpha=k_off - 1, beta=k_on - 1)
    mus = k_syn * (roots + 1) / 2
    assert (max(mus) < 1e6)

    gs = np.sum(weights * stats.poisson.pmf(k.reshape(-1, 1), mus), axis=1)
    probabilities = 1 / special.beta(k_on, k_off) * 2**(1 - k_on - k_off) * gs
    return probabilities
예제 #5
0
    def dBP(at, alpha, bet, lam):
        at.shape = (len(at), 1)
        np.repeat(at, 50, axis=1)

        def fun(at, m):
            if (max(m) < 1e6):
                return (poisson.pmf(at, m))
            else:
                return (norm.pdf(at, loc=m, scale=sqrt(m)))

        x, w = j_roots(50, alpha=bet - 1, beta=alpha - 1)
        gs = np.sum(w * fun(at, m=lam * (1 + x) / 2), axis=1)  #m*s_i
        prob = 1 / beta_fun(alpha, bet) * 2**(-alpha - bet + 1) * gs
        return (prob)
def calc_solver_matrix(nr, nz, ne):
    '''
    nr: number of radial points
    nz: number of axial points
    ne: number of axial segments
    '''
    solver_data = {'nc': nr, 'mc': nz}

    def dspoly(ia, nd, nc, x):
        q = np.ones((nd, nc))
        y = np.zeros(2 * nc)
        c = np.zeros((nd, nc))
        d = np.zeros((nd, nc))
        f = np.zeros(nd)

        loopq = [2 * (i + 1) - 3 for i in range(1, nc)]
        loopc = [2 * (i + 1) - 4 for i in range(1, nc)]
        cfac = np.array([2 * i for i in range(1, nc)])
        loopd = loopq[:-1]  #[2*(i+1)-5 for i in range(2,nc)]
        dfac = np.array([(2 * i - 2) * (2 * i - 4 + ia)
                         for i in range(3, nc + 1)])

        for j in range(nd):
            y = np.array([x[j]**n for n in range(1, 2 * nc + 1)])
            q[j, 1:] = np.array([y[i] for i in loopq])
            c[j, 1:] = cfac * np.array([y[i] for i in loopc])  #2. * y[0]
            d[j][1] = 2. * ia
            d[j, 2:] = dfac * np.array([y[i] for i in loopd])
            f[j] = 1. / float(2. * (j + 1) - 2. + ia)

        return q, f, c, d

    def dupoly(nd, nc, x):
        q = np.ones((nd, nc))
        y = np.zeros(2 * nc)
        c = np.zeros((nd, nc))
        d = np.zeros((nd, nc))

        for j in range(nd):
            y[0] = 1.
            for i in range(1, nc):
                y[i] = y[i - 1] * (2. * x[j] - 1.)
            q[j, :] = np.array([y[i] for i in range(nc)])
            c[j][1] = 2.
            for i in range(2, nc):
                c[j][i] = 2. * i * y[i - 1]
                d[j][i] = 4. * i * (i - 1.) * y[i - 2]

        return q, c, d

    def build_colloc(n_pts):
        '''
        levih method
        '''
        n_pts_m = n_pts - 2  #number of interior points

        roots = np.zeros([n_pts])
        roots[-1] = 1  #right boundary
        roots[1:-1] = special.roots_sh_legendre(n_pts_m)[0]

        Qmat = np.zeros([n_pts, n_pts])
        Cmat = np.zeros([n_pts, n_pts])
        Dmat = np.zeros([n_pts, n_pts])

        for i in range(n_pts):
            for j in range(n_pts):
                Qmat[i, j] = roots[i]**j
            for j in range(1, n_pts):
                Cmat[i, j] = (j) * roots[i]**[j - 1]
            for j in range(2, n_pts):
                Dmat[i, j] = (j) * (j - 1) * roots[i]**[j - 2]

        Qinv = np.linalg.inv(Qmat)
        Amat = np.dot(Cmat, Qinv)
        Bmat = np.dot(Dmat, Qinv)

        return (roots, Amat, Bmat)

    def advect_operator(ne, nz):
        nz_n = ne * nz - (ne - 1)  #total number of axial points
        f = ne  #Element width adjustment to derivatives

        roots, A, _ = build_colloc(nz)  # construct first derivative operator

        ### Calculation location of overall gridpoints
        Xvals = np.zeros(ne * nz)
        for k in range(ne):
            Xvals[k * nz:(k + 1) * nz] = (roots / f + k / f)  #/f

        to_delete = [nz * (k + 1) for k in range(ne - 1)]
        Xvals = np.delete(Xvals, to_delete)

        Q = A[-1, -1] - A[0, 0]

        #adjusted element advection operator
        Z = np.zeros([nz, nz])
        Z[:, :] = f * A

        #construct overall advection operator
        Adv_Op = np.zeros([nz_n, nz_n])

        #fill in blocks for element interiors
        for k in range(ne):
            ii = k * (nz - 1)
            iii = (k + 1) * nz - k
            Adv_Op[ii:iii, ii:iii] = Z[:, :]

        #fill in continuation points where elements meet
        for k in range(ne - 1):
            idx = k * nz - k
            ii = (k + 1) * nz - (k + 1)
            iii = (k + 2) * nz - (k + 1)

            Adv_Op[ii, :] = 0  # zero out continuation

            CC1 = Z[-1, :-1] - Z[-1, -1] / Q * A[-1, :-1]
            CC2 = Z[-1, -1] / Q * A[0, 1:]

            Adv_Op[ii, idx:ii] = CC1
            Adv_Op[ii, ii + 1:iii] = CC2

        Adv_Op[0, :] = 0  # Constant inlet boundary

        return Adv_Op, Xvals

    ngeor = 3  # spherical
    alfar = 1.
    betar = 0.5

    #   radial matrices
    rr = betar * (special.j_roots(nr - 1, alfar, betar)[0] + alfar)
    rr = np.append(rr, [1])  #[0],rr)
    r = np.sqrt(rr)
    q, f, c, d = dspoly(ngeor, nr, nr, r)
    qi2 = np.linalg.inv(q)
    wr = f.dot(qi2)  #.dot(f)
    br = d.dot(qi2)

    #    axial
    if ne == 1:
        z = special.roots_sh_legendre(nz - 2)[0]
        z = np.append(np.append([0], z), [1])
        q, c, d = dupoly(nz, nz, z)
        qi = np.linalg.inv(q)
        az = c.dot(qi)
    elif ne > 1:
        az, _ = advect_operator(ne, nz)
        solver_data['mc'] = ne * nz - (ne - 1)


#save data to export object
    solver_data['wr'] = wr
    solver_data['az'] = az
    solver_data['br'] = br

    return solver_data
예제 #7
0
def getZIntegrator(state, var="vortZ", nNs=40):
    """
    compute integrator 
    Input: 
    - var: variable to integrate vortZ, uS, or uPhi
    """

    nL = state.specRes.L
    nM = state.specRes.M
    nN = state.specRes.N
    E = state.parameters.E

    nNmax, nLmax, nMmax, nNs = nN, nL, nM, nNs

    N_z = nNmax + nLmax // 2  # function of Nmax and Lmax

    # Jacobi polynomial roots and weights
    # Legendre alpha=0, beta=0
    alpha = 0
    beta = 0
    roots, w = j_roots(N_z, alpha, beta)

    d = 10. * np.sqrt(E)
    ekmanR = 1. - d

    grid_s = np.linspace(0, ekmanR, nNs + 1)

    grid_s = 0.5 * (grid_s[0:-1] + grid_s[1:])
    grid_z = np.zeros((nNs, N_z))
    grid_cost = np.zeros_like(grid_z)
    grid_sint = np.zeros_like(grid_z)
    grid_r = np.zeros_like(grid_z)

    # Generating (s,z) grids
    for id_s, s in enumerate(grid_s):
        # Quadrature points
        #z_local = roots * sqrt(1.0 - s * s) * (1.0 - d)  # from -1 to 1
        z_local = roots * np.sqrt(
            (1.0 - d) * (1.0 - d) - s * s)  # from -1 to 1
        grid_cost[id_s, :] = sz2ct(s, z_local)  # from -1 to 1
        grid_sint[id_s, :] = sz2st(s, z_local)
        grid_r[id_s, :] = sz2r(s, z_local)
        grid_z[id_s, :] = z_local

    #vortz_tor = np.zeros((nNs, nNmax, nLmax * (nLmax + 1) // 2), dtype=complex)
    vortz_tor = np.zeros(
        (nNs, nNmax, nMmax * (nMmax + 1) // 2 + nMmax * (nLmax - nMmax)),
        dtype=complex)
    vortz_pol = np.zeros_like(vortz_tor)
    #ur_pol = np.zeros_like(vortz_tor)
    uphi_tor = np.zeros_like(vortz_tor)
    uphi_pol = np.zeros_like(vortz_tor)
    #uth_tor = np.zeros_like(vortz_tor)
    #uth_pol = np.zeros_like(vortz_tor)
    us_tor = np.zeros_like(vortz_tor)
    us_pol = np.zeros_like(vortz_tor)

    tr0 = time.time()

    for id_s in range(0, nNs):
        #print('id_s=', id_s)
        print('id_s: ', id_s, end=" ")  # ' timestep: ', timestep)
        t0 = time.time()
        for n in range(0, nNmax):  # debug
            # print('n=', n)
            ind = 0
            for l in range(0, nLmax):
                #for m in range(0, min(l, Mmax) + 1):
                for m in range(0, min(l, nMmax - 1) + 1):
                    # pdb.set_trace()
                    # Leo: compute on the fly instead of using memory
                    r_local = grid_r[id_s, :]
                    cos_local = grid_cost[id_s, :]
                    sin_local = grid_sint[id_s, :]

                    # polynomials for reconstruction
                    plm_w1 = W(n, l, r_local)
                    plm_lapw1 = laplacianW(n, l, r_local)
                    plm_diffw1 = diffW(n, l, r_local)

                    plm_leg = legSchmidtM(l, m, cos_local)
                    plm_diffLeg = diffLegM(l, m, cos_local)

                    if var == "vortZ":
                        # computing contributions from toroidal and poloidal vorticity onto Z
                        vort_z = 1j * m * plm_lapw1 * plm_leg  # times P
                        vortz_tor[id_s, n, ind] = sum(
                            w * vort_z) * np.sqrt(1 - grid_s[id_s]**2) * (1.0 -
                                                                          d)

                        vort_z = l * (l + 1.0) * plm_w1 * plm_leg * cos_local / r_local \
                                                 - plm_diffw1 * plm_diffLeg / r_local  # times P
                        vortz_pol[id_s, n, ind] = sum(
                            w * vort_z) * np.sqrt(1 - grid_s[id_s]**2) * (1.0 -
                                                                          d)

                        #sum(w*vort_z)*sqrt(1-grid_s[id_s]**2)*(1.0-d)

                    elif var == "uPhi":
                        #uth_tor[id_s, n, ind, :] = 1j * m * plm_w1 * plm_leg / sin_local
                        u_phi = -plm_w1 * plm_diffLeg / sin_local  # -\partial_\theta T
                        uphi_tor[id_s, n, ind] = sum(
                            w * u_phi) * np.sqrt(1 - grid_s[id_s]**2) * (1.0 -
                                                                         d)

                        #ur_pol[id_s, n, ind, :] = l * (l + 1.0) * plm_w1 * plm_leg / r_local  # 1/r * L2(P)
                        #uth_pol[id_s, n, ind, :] = plm_diffw1 * plm_diffLeg / (r_local * sin_local)  # ???

                        # 1/(r sin(theta)) \partial_r * r * \partial_\phi P
                        u_phi = 1j * m * plm_diffw1 * plm_leg / (r_local *
                                                                 sin_local)
                        uphi_pol[id_s, n, ind] = sum(
                            w * u_phi) * np.sqrt(1 - grid_s[id_s]**2) * (1.0 -
                                                                         d)

                    elif var == "uS":
                        # u_s = u_r * sin(theta) + u_theta * cos(theta)
                        u_s = l * (
                            l + 1.0
                        ) * plm_w1 * plm_leg * sin_local / r_local + plm_diffw1 * plm_diffLeg * cos_local / (
                            r_local * sin_local)
                        us_pol[id_s, n, ind] = sum(
                            w * u_s) * np.sqrt(1 - grid_s[id_s]**2) * (1.0 - d)

                        u_s = 1j * m * plm_w1 * plm_leg * cos_local / sin_local
                        us_tor[id_s, n, ind] = sum(
                            w * u_s) * np.sqrt(1 - grid_s[id_s]**2) * (1.0 - d)

                        # u_z = u_r * cos(theta) - u_theta * sin(theta)
                        #uz_pol[id_s, n, ind, :] = l * (
                        #            l + 1.0) * plm_w1 * plm_leg * cos_local / r_local - plm_diffw1 * plm_diffLeg / r_local
                        #uz_tor[id_s, n, ind, :] = 1j * m * plm_w1 * plm_leg
                        # h = u_z * vort_z

                    ind = ind + 1

            #Make sure dimensions idx[l,m] agree
            #assert(ind == vortz_tor.shape[2]), "size of integrator and ind=idx[l,m] don't agree"
            #assert(ind == vortz_pol.shape[2]), "size of integrator and ind=idx[l,m] don't agree"
            #assert(ind == us_tor.shape[2]), "size of integrator and ind=idx[l,m] don't agree"
            #assert(ind == us_pol.shape[2]), "size of integrator and ind=idx[l,m] don't agree"
            #assert(ind == uphi_tor.shape[2]), "size of integrator and ind=idx[l,m] don't agree"
            #assert(ind == uphi_pol.shape[2]), "size of integrator and ind=idx[l,m] don't agree"

        t1 = time.time()
        print("time: ", t1 - t0)

    tr1 = time.time()
    print("Total time:", tr1 - tr0)

    #resolution
    res = (nNmax, nLmax, nMmax, nNs)

    if var == "vortZ":
        return Integrator(grid_s, vortz_tor, vortz_pol, res, var)
    elif var == "uPhi":
        return Integrator(grid_s, uphi_tor, uphi_pol, res, var)
    elif var == "uS":
        return Integrator(grid_s, us_tor, us_pol, res, var)
    else:
        print("output variable must be defined omegaZ, uPhi, or uS")
예제 #8
0
def computeUniformVorticity(state, rmax):
    """
    function to compute uniform vorticity from a state file from 0 to rmax
    Input: 
    - state: input state to compute uniform vorticity
    - rmax : maximum radius to compute vorticity
    """
    #rot.projectWf(dataT, E, nN, nL, nM, "rotation")
    #Projection of spectral coefficients onto the T10, T11 modes
    #Computing Wf with n=0,1,2,... nN-1
    #dataT: Toroidal data
    #E: Ekman number
    #nN: number of radial modes
    #nL: number of spherical harmonic order
    #nM: number of azimuthal wave number
    #scale: 'rotation' or 'viscous' timescale
    dataT = state.fields.velocity_tor
    nN = state.specRes.N
    nL = state.specRes.L
    nM = state.specRes.M
    E = state.parameters.E

    #2*nX + 1 = 2*NN+l + 3
    l = 1
    nX = (nN + l // 2 + 1)

    #Jacobi polynomial roots and weights
    #Legendre alpha=0, beta=0
    alpha = 0
    beta = 0
    roots, w = j_roots(nX, alpha, beta)

    #ekmanR=1.0
    #ekmanR=1.-10.*np.sqrt(E)
    ekmanR = rmax

    #x = [-a,b]
    #z = [0,1]
    grid_r = (roots + 1.) / (2.) * ekmanR
    poly = np.empty((nX, nN), dtype='float64', order='F')
    quicc_pybind.wnl(poly, l, grid_r)

    #index table
    idx = idxlm(nL, nM)

    Y11R = 0
    Y11I = 0
    Y10 = 0

    #compute integral
    for n in range(0, nN):
        #print('nN', nN, 'n', n, 'dataT.shape:', dataT.shape)
        #breakpoint()
        #print("idx:",idx[1,1])
        fi_wi = -2 * grid_r**3 * poly[:, n] * w
        #print(grid_r**3*poly[:, n]*w)
        #print(fi_wi.sum()*ekmanR/2)
        Y11R = Y11R + dataT[idx[1, 1], n].real * fi_wi.sum() * (
            ekmanR / 2.) * 5. / (ekmanR**5)
        #print(dataT[idx[1,1], n,0])
        fi_wi = 2 * grid_r**3 * poly[:, n] * w
        Y11I = Y11I + dataT[idx[1, 1], n].imag * fi_wi.sum() * (
            ekmanR / 2.) * 5. / (ekmanR**5)
        #print(dataT[idx[1,1], n, 1])
        #print(grid_r**3*poly[:, n]*w)
        fi_wi = grid_r**3 * poly[:, n] * w
        #print(fi_wi.sum()*ekmanR/2)
        #print(dataT[idx[1,0], n, 0])
        Y10 = Y10 + dataT[idx[1, 0], n].real * fi_wi.sum() * (
            ekmanR / 2.) * 5. / (ekmanR**5)
        #print("projectWf(n=",n,")", Y11R, Y11I, Y10)

    omegaF = np.zeros(3)
    omegaF[0] = Y11R
    omegaF[1] = Y11I
    omegaF[2] = Y10

    return omegaF