Exemple #1
0
def test_roots_sh_legendre():
    weightf = orth.sh_legendre(5).weight_func
    verify_gauss_quad(sc.roots_sh_legendre, orth.eval_sh_legendre, weightf, 0.,
                      1., 5)
    verify_gauss_quad(sc.roots_sh_legendre,
                      orth.eval_sh_legendre,
                      weightf,
                      0.,
                      1.,
                      25,
                      atol=1e-13)
    verify_gauss_quad(sc.roots_sh_legendre,
                      orth.eval_sh_legendre,
                      weightf,
                      0.,
                      1.,
                      100,
                      atol=1e-12)

    x, w = sc.roots_sh_legendre(5, False)
    y, v, m = sc.roots_sh_legendre(5, True)
    assert_allclose(x, y, 1e-14, 1e-14)
    assert_allclose(w, v, 1e-14, 1e-14)

    muI, muI_err = integrate.quad(weightf, 0, 1)
    assert_allclose(m, muI, rtol=muI_err)

    assert_raises(ValueError, sc.roots_sh_legendre, 0)
    assert_raises(ValueError, sc.roots_sh_legendre, 3.3)
    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)
Exemple #3
0
 def scaled_quadrature_points(self):
     if self.dist_type == 'norm':
         xg, wg = sp.roots_hermitenorm(self.order) # weight function exp(-x^2/2)
         wg = wg/ np.sqrt(2*np.pi) # for standard normal distribution
     if self.dist_type == "uniform":
         xg, wg = sp.roots_sh_legendre(self.order) # weight function exp(-x^2/2)
         #wg = wg.# for standard normal distribution            
     return xg, wg
Exemple #4
0
def test_roots_sh_legendre():
    weightf = orth.sh_legendre(5).weight_func
    verify_gauss_quad(sc.roots_sh_legendre, orth.eval_sh_legendre, weightf, 0., 1., 5)
    verify_gauss_quad(sc.roots_sh_legendre, orth.eval_sh_legendre, weightf, 0., 1.,
                      25, atol=1e-13)
    verify_gauss_quad(sc.roots_sh_legendre, orth.eval_sh_legendre, weightf, 0., 1.,
                      100, atol=1e-12)

    x, w = sc.roots_sh_legendre(5, False)
    y, v, m = sc.roots_sh_legendre(5, True)
    assert_allclose(x, y, 1e-14, 1e-14)
    assert_allclose(w, v, 1e-14, 1e-14)

    muI, muI_err = integrate.quad(weightf, 0, 1)
    assert_allclose(m, muI, rtol=muI_err)

    assert_raises(ValueError, sc.roots_sh_legendre, 0)
    assert_raises(ValueError, sc.roots_sh_legendre, 3.3)
Exemple #5
0
def main_2():

    eps = 1e-15  #возьмем очень большую точность, чтобы было побольше точек в итоговой аппроксимации
    N = 1  #счетчик
    result_array = []
    error_array = []
    roots_array = []
    error = np.inf

    while error >= eps:
        roots, weights = roots_sh_legendre(N)
        matrix_of_approximation = np.empty([N, N])
        matrix_of_approximation[:] = -0.5 * weights
        numeric_solution = np.linalg.solve(
            np.eye(N) + matrix_of_approximation, g(roots))
        error = np.linalg.norm(exact_solution(roots) - numeric_solution)
        result_array.append(numeric_solution)
        roots_array.append(roots)
        error_array.append(error)
        N += 1

    x_linspace = np.linspace(min(roots_array[-1]), max(roots_array[-1]), 50)

    for i in range(len(result_array)):
        plt.figure()
        plt.title('Gaussian Quad for Fredholm Equasion')
        plt.grid()
        plt.xlabel('x')
        plt.ylabel('y')
        plt.plot(x_linspace,
                 exact_solution(x_linspace),
                 'g',
                 label='Exact solution')
        plt.plot(roots_array[i],
                 result_array[i],
                 'o',
                 label='Estimated solution using {} points'.format(i + 1))
        plt.legend()
        plt.show()

    #блок интерполяции
    plt.figure()
    plt.title('Interpolation')
    interp_func = interp1d(roots_array[8], result_array[8])
    plt.plot(x_linspace,
             interp_func(x_linspace),
             '-',
             label='Interpolation on the {} points'.format(9))
    plt.grid()
    plt.plot(x_linspace,
             exact_solution(x_linspace),
             'g',
             label='Exact solution')
    #график интерполяции с помощью scipy.interpolate.interp1d

    plt.legend()
    plt.show()
Exemple #6
0
 def intergationPoints(self,method,nbint):
     if method == 'quad':
         if self.dist_type == 'norm':
             xs,wxs = sp.roots_hermitenorm(nbint)
             wx = wxs /np.sqrt(2*np.pi)
             x = self.descaling(xs)
         if self.dist_typee == 'uniform':
             xs,wxs = sp.roots_sh_legendre(nbint)
             wx = wxs
             x = self.descaling(xs)
     if method =='MC':
         x = self.var.rvs(size = nbint)
         wx = 1./x.size
         xs = self.scaling(x)
     return x, xs,wx
Exemple #7
0
def recur_colloc(n_pts):
    """
    For non-symmetric problems produce:
        roots: Root locations
        Amat: First derivative operator
        Bmat: Second derivative 
        
    TODO: Refactor with mv_colloc_symm to avoid code duplication
    """

    n_pts_m = n_pts - 2  # number of interior collocation points
    roots = np.zeros([n_pts])
    roots[0] = 0  # left boundary root
    roots[-1] = 1  # right bounary root
    roots[1:-1] = roots_sh_legendre(n_pts_m)[0]  # interior roots

    # define 3 by n_pts matrix of polynomial derivatives at collocation points
    # row index (k) is the k + 1 derivative
    px_mat = np.zeros((3, n_pts))

    for ii in range(n_pts):
        px_mat[:, ii] = calc_px_column(roots[ii], roots)

    # Calculate derivative operators (A and B)
    Amat = np.zeros((n_pts, n_pts))
    Bmat = np.zeros((n_pts, n_pts))

    for ii in range(n_pts):
        for jj in range(n_pts):
            if ii == jj:  # Eq. 12
                Amat[ii, jj] = (1 / 2) * px_mat[1, ii] / px_mat[0, ii]
                Bmat[ii, jj] = (1 / 3) * px_mat[2, ii] / px_mat[0, ii]
            else:  # Eqs. 13, 14
                G = roots[ii] - roots[jj]
                Amat[ii, jj] = (1 / G) * px_mat[0, ii] / px_mat[0, jj]
                Bmat[ii, jj] = (1 / G) * (px_mat[1, ii] / px_mat[0, jj] -
                                          2 * Amat[ii, jj])

    return (roots, Amat, Bmat)
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