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)
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
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 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()
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
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