def lobatto_weight(order): ''' Lobatto weight calculator :param order: Order of legendre polynomial :return: Lobatto weights ''' x0 = lb.root(order) weight = 2.0 / (order * (order - 1) * (lg.generate(x0, order - 1))**2) return weight
def x_domain_disc(element_order, n_element, x_min=-1.0, x_max=+1.0): N = (element_order + 1) * n_element x = np.zeros(N) Dx = abs(x_max - x_min) / n_element zeta = lb.root(element_order + 1) for i in range(n_element): k = i * (element_order + 1) x[k:k + element_order + 1] = x_min + (zeta + 1.0) * (Dx / 2.0) x_min = x_min + Dx return x
def x_domain(element_order, n_element, x_min=-1.0, x_max=+1.0): N = (element_order * n_element) + 1 x = np.zeros(N) Dx = abs(x_max - x_min) / n_element zeta = lb.root(element_order + 1) for i in range(n_element): k = i * (element_order) x[k:k + element_order] = x_min + (zeta[:-1] + 1.0) * (Dx / 2.0) x_min = x_min + Dx x[N - 1] = x_max return x
def element_mass_matrix(element_order, weight, zeta): n = element_order + 1 x = lb.root(n) mass = np.zeros((n, n)) n_weight = np.size(weight) psi_combinations = np.zeros((n_weight, n)) for j in range(n_weight): for i in range(n): psi_combinations[j, i] = lagrange(x, zeta[j], i) for k in range(n_weight): temp_mass = np.zeros((n, n)) for j in range(n): for i in range(n): temp_mass[j, i] = weight[k] * psi_combinations[ k, i] * psi_combinations[k, j] mass = temp_mass + mass return mass / 2
def element_diff_matrix(element_order, weight, zeta): n = element_order + 1 x = lb.root(n) diff = np.zeros((n, n)) n_weight = np.size(weight) psi_combinations = np.zeros((n_weight, n)) psi_diff_combinations = np.zeros((n_weight, n)) for j in range(n_weight): for i in range(n): psi_combinations[j, i] = lagrange(x, zeta[j], i) psi_diff_combinations[j, i] = diff_lagrange(x, zeta[j], i) for k in range(n_weight): temp_diff = np.zeros((n, n)) for j in range(n): for i in range(n): temp_diff[j, i] = weight[k] * psi_combinations[ k, j] * psi_diff_combinations[k, i] diff = temp_diff + diff return diff
def cont_galerkin(T, n_lobatto, element_order, n_element, u=2.0, courant=1.0 / 4.0, sigma=1.0 / 8.0): X = x_domain(element_order, n_element) initial = np.e**(-1 * (X / (2 * sigma))**2) Dx = np.min(abs(X[1:element_order + 1] - X[0:element_order])) zeta = lb.root(n_lobatto) weight = ig.lobatto_weight(n_lobatto) t1 = time() edm = element_diff_matrix(element_order, weight, zeta) emm = element_mass_matrix(element_order, weight, zeta) * (2.0 / n_element) dsm = diff_stiff(n_element, edm) msm = mass_stiff(n_element, emm) R_mat = r_matrix(msm, dsm, u) R_mat[abs(R_mat) < 10**-10] = 0 dt = dt_calc(courant, u, Dx) q = rk_2nd(R_mat, initial, T, dt) t2 = time() - t1 return q, initial, X, t2
def diff_function(x): ''' :param x: function parameter :return: function value ''' y = -1 * np.pi * 0.5 * np.sin(np.pi * 0.5 * x) return y order = 15 number_of_points = 100 x0_eq = np.linspace(-1, 1, order + 1) x0_lg = lg.root(order + 1) x0_lb = lb.root(order + 1) x_eq = np.linspace(x0_eq[0], x0_eq[-1], number_of_points) x_lg = np.linspace(x0_lg[0], x0_lg[-1], number_of_points) x_lb = np.linspace(x0_lb[0], x0_lb[-1], number_of_points) y0_eq = function(x0_eq) y0_lg = function(x0_lg) y0_lb = function(x0_lb) y_eq, l_eq = ip.lagrange(x_eq, x0_eq, y0_eq) y_lg, l_lg = ip.lagrange(x_lg, x0_lg, y0_lg) y_lb, l_lb = ip.lagrange(x_lb, x0_lb, y0_lb) plt.figure(1) plt.suptitle(
q = q_temp return q n_lobatto = 9 element_order = 8 n_element = 8 u = 2.0 courant = 1.0 / 4.0 T = 1.0 sigma = 1.0 / 8.0 X = x_domain(element_order, n_element) initial = np.e**(-1 * (X / (2 * sigma))**2) Dx = np.min(X[1:] - X[:-1]) zeta = lb.root(n_lobatto) weight = ig.lobatto_weight(n_lobatto) edm = element_diff_matrix(element_order, weight, zeta) emm = element_mass_matrix(element_order, weight, zeta) * (2.0 / n_element) dsm = diff_stiff(n_element, edm) msm = mass_stiff(n_element, emm) R_mat = r_matrix(msm, dsm, u) dt = dt_calc(courant, u, Dx) q = rk_2nd(R_mat, initial, T, dt) plt.plot(X, q) plt.show()