def test_basis_input(self): """Test the coboundary operator with some basis as inputs.""" p_x, p_y = 2, 2 func_space_0 = FunctionSpace(self.mesh, '0-lobatto', (p_x, p_y), is_inner=False) func_space_1 = FunctionSpace(self.mesh, '1-lobatto', (p_x, p_y), is_inner=False) func_space_2 = FunctionSpace(self.mesh, '2-lobatto', (p_x, p_y), is_inner=False) basis_0_ref = BasisForm(func_space_0) basis_1_ref = BasisForm(func_space_1) basis_0_ref.quad_grid = 'lobatto' basis_1_ref.quad_grid = 'gauss' basis_2_ref = BasisForm(func_space_2) basis_2_ref.quad_grid = 'lobatto' e_21_ref = d_21_lobatto_outer((p_x, p_y)) e_10_ref = d_10_lobatto_outer((p_x, p_y)) basis_1, e_10 = d(basis_0_ref) basis_1.quad_grid = 'gauss' basis_2, e_21 = d(basis_1_ref) basis_2.quad_grid = 'lobatto' M_1 = inner(basis_1, basis_1) M_1_ref = inner(basis_1_ref, basis_1_ref) npt.assert_array_almost_equal(M_1_ref, M_1) M_2 = inner(basis_2, basis_2) M_2_ref = inner(basis_2_ref, basis_2_ref) npt.assert_array_almost_equal(M_2_ref, M_2) npt.assert_array_equal(e_21_ref, e_21) npt.assert_array_equal(e_10_ref, e_10)
def test_func_space_input(self): """Test function space input to coboudary operator. It should return the incidence matrix. """ p_x, p_y = 3, 3 func_space = FunctionSpace(self.mesh, '1-lobatto', (p_x, p_y), is_inner=False) e_21_lobatto_ref = d_21_lobatto_outer((p_x, p_y)) e_21_lobatto = d(func_space) npt.assert_array_almost_equal(e_21_lobatto, e_21_lobatto_ref)
def test_form_input(self): p_x, p_y = 3, 3 func_space = FunctionSpace(self.mesh, '1-lobatto', (p_x, p_y), is_inner=False) form_1_cochain = np.random.rand((func_space.num_dof)) form_2_cochain_local_ref = d_21_lobatto_outer( (p_x, p_y)) @ cochain_to_local(func_space, form_1_cochain) func_space_2 = NextSpace(func_space) form_2_cochain_ref = cochain_to_global(func_space_2, form_2_cochain_local_ref) form_1 = Form(func_space, form_1_cochain) form_2 = d(form_1) npt.assert_array_almost_equal(form_2_cochain_ref, form_2.cochain)
basis_0 = BasisForm(func_space_0_ext_gauss) basis_1 = BasisForm(func_space_1_lobatto) basis_2 = BasisForm(func_space_2_lobatto) basis_0.quad_grid = 'gauss' basis_1.quad_grid = 'lobatto' basis_2.quad_grid = 'lobatto' # define forms for soultion using function space q_1 = Form(func_space_1_lobatto) # q_1.basis.quad_grid = 'lobatto' phi_0 = Form(func_space_0_ext_gauss) # phi_0.basis.quad_grid = 'gauss' E21 = d_21_lobatto_outer(p) """extended E21 with virtual volumes""" px, py = p virtual_E21 = np.zeros((px * 4, 2 * px * (px + 1))) for j in range(px): vol_id = px**2 + j edge_id = px * (px + 1) + j virtual_E21[vol_id - px**2, edge_id] = 1 virtual_E21[vol_id - px**2 + px, edge_id + px**2] = -1 for i in range(px): vol_id = px**2 + 2 * px + i edge_id = (px + 1) * i
def main(el, poly_degree): dim = 2 element_layout = (el + 1, el + 1) # print(element_layout) """define polynomial degree and inner/outer orientation""" pp = (poly_degree + 1, poly_degree + 1) # polynomial degree - primal mesh pd = (pp[0] - 1, pp[1] - 1) # polynomial degree - dual mesh orientation_inner = True outer = False # is_inner = False # orientation of primal mesh """define mesh""" bounds_domain = ((0, 1), (0, 1)) curvature = 0.0 mesh1 = CrazyMesh(dim, element_layout, bounds_domain, curvature) # gamma = (gamma1, gamma2, gamma3, gamma4) # dgamma = (dgamma1, dgamma2, dgamma3, dgamma4) # mesh1 = TransfiniteMesh(dim, element_layout, gamma, dgamma) """define function spaces used in problem""" fs_2_lobatto = FunctionSpace(mesh1, '2-lobatto', pp, outer) fs_1_lobatto = FunctionSpace(mesh1, '1-lobatto', pp, outer) fs_0_gauss = FunctionSpace(mesh1, '0-gauss', pd, inner) fs_1_lobatto.dof_map.continous_dof = True # continuous elements """define forms and quad grid""" """define (n) - source form""" f_source = Form(fs_2_lobatto) # form for source term f_source.discretize(source) f_source.basis.quad_grid = 'gauss' """define (n-1) - q form""" f_flux = Form(fs_1_lobatto) # form for flux terms f_flux.basis.quad_grid = 'lobatto' """define exact 0 - \phi form""" f_phi_exact = Form(fs_0_gauss) f_phi_exact.discretize(manufactured_solution) f_phi_exact.basis.quad_grid = 'gauss' """define unkown 0 - \phi form""" f_phi = Form(fs_0_gauss) f_phi.basis.quad_grid = 'gauss' """define anisotropic tensor as a mesh property""" # anisotropic_tensor = MeshFunction(mesh1) # anisotropic_tensor.discrete_tensor = [ # k_11(element_layout), k_12(element_layout), k_22(element_layout)] # mesh function to inject the anisotropic tensor anisotropic_tensor = MeshFunction(mesh1) anisotropic_tensor.continous_tensor = [k_11, k_12, k_22] # mesh_k = MeshFunction(crazy_mesh) # mesh_k.continous_tensor = [diffusion_11, diffusion_12, diffusion_22] """define basis functions""" basis_2 = BasisForm(fs_2_lobatto) basis_1 = BasisForm(fs_1_lobatto) basis_0 = BasisForm(fs_0_gauss) basis_2.quad_grid = 'gauss' basis_1.quad_grid = 'lobatto' basis_0.quad_grid = 'gauss' """general variables used frequently""" num_total_elements = element_layout[0] * element_layout[1] num_total_edges = fs_1_lobatto.num_dof num_total_faces = fs_2_lobatto.num_dof num_local_surfaces = fs_2_lobatto.num_local_dof dof_map_lobatto_faces = fs_2_lobatto.dof_map.dof_map """define 1-form mass matrix""" M1 = inner(basis_1, basis_1, anisotropic_tensor) M1_assembled = assemble(M1, (fs_1_lobatto, fs_1_lobatto)) """define the wedge product""" E21 = d_21_lobatto_outer(pp) W1 = basis_2.wedged(basis_0) W1_E21 = np.dot(W1, E21) W1_E21_local = np.repeat(W1_E21[:, :, np.newaxis], num_total_elements, axis=2) W1_E21_assembled = assemble(W1_E21_local, (fs_0_gauss, fs_1_lobatto)) """assemble lhs""" lhs = sparse.bmat([[M1_assembled, W1_E21_assembled.transpose()], [W1_E21_assembled, None]]).tolil() # A = np.linalg.det(lhs.todense()) # print(A) """assemble rhs""" rhs1 = np.zeros(num_total_edges)[:, np.newaxis] f_cochain_local = f_source.cochain_local[:, np.newaxis] W1_f_local = np.tensordot(W1, f_cochain_local, axes=1) rhs2 = assemble_cochain2(W1_f_local, dof_map_lobatto_faces, num_total_faces) rhs = np.vstack((rhs1, rhs2)) # print(time.time() - start_time) """implement boundary conditions""" """neuman boundary condition""" """dirichlet boundary condition""" """solve linear system of equations""" solution = sparse.linalg.spsolve(lhs.tocsc(), rhs) end_time = time.time() print("The total time taken by the program is : ", end_time - start_time) """l2 error""" """post processing / reconstruction""" eta_plot = xi_plot = xi = eta = np.linspace(-1, 1, 30) """reconstruct fluxes""" f_flux.cochain = solution[:fs_1_lobatto.num_dof] f_flux.reconstruct(xi, eta) (x_plot, y_plot), flux_x_plot, flux_y_plot = f_flux.export_to_plot() flux_x_plot, flux_y_plot = flux_y_plot, flux_x_plot """reconstruct potential""" f_phi.cochain = solution[fs_1_lobatto.num_dof:] f_phi.reconstruct(xi, eta) (x_plot, y_plot), phi_plot = f_phi.export_to_plot() phi_exact_plot = np.sin(2 * np.pi * x_plot) * np.sin(2 * np.pi * y_plot) """l2 - error in (div u -f)""" div_u_sum = np.zeros(num_total_elements) for ele_num in range(num_total_elements): l2_div_u = np.dot(E21, f_flux.cochain_local[:, ele_num] )[:, np.newaxis] - f_cochain_local[:, :, ele_num] div_u_sum[ele_num] = np.sum(l2_div_u) l2_err_div_u = np.linalg.norm(div_u_sum) l_inf_err_div_u = np.max(div_u_sum) """l2 - error in phi and flux """ l2_err_phi = f_phi.l_2_norm(phi_exact) l2_err_flux = f_flux.l_2_norm((flux_y_exact, flux_x_exact)) error = l2_err_phi, l2_err_flux, l2_err_div_u, l_inf_err_div_u print(l2_err_phi[0]) print(l2_err_flux[0]) # return error # plt.figure(1) plt.contourf(x_plot, y_plot, flux_x_plot) plt.colorbar() # # plt.figure(2) # plt.contourf(x_plot, y_plot, flux_x_exact_plot) # plt.colorbar() # print(np.max(flux_x_exact_plot), np.min(flux_x_exact_plot)) # print(np.max(flux_x_plot), np.min(flux_x_plot)) # plt.figure(3) plt.contourf(x_plot, y_plot, flux_y_plot) plt.colorbar() # # plt.figure(4) # plt.contourf(x_plot, y_plot, flux_y_exact_plot) # plt.colorbar() # print(np.max(flux_y_exact_plot), np.min(flux_y_exact_plot)) # print(np.max(flux_y_plot), np.min(flux_y_plot)) # plt.figure(5) plt.contourf(x_plot, y_plot, phi_plot) plt.colorbar() # plt.figure(6) # plt.contourf(x_plot, y_plot, phi_exact_plot) # plt.colorbar() # print(np.max(phi_exact_plot), np.min(phi_exact_plot)) # print(np.max(phi_plot), np.min(phi_plot)) plt.show()
import src.tests.path_magic from mesh import CrazyMesh from function_space import FunctionSpace from coboundaries import d_21_lobatto_outer if __name__ == '__main__': print("hello world") # mesh arguments dim = 2 elements_layout = (1, 1) bounds_domain = ((-1, 1), (-1, 1)) curvature = 0.1 # function space arguments form_type = '0-lobatto' p = (3, 3) is_inner = False numbering_rule = 'general' crazy_mesh = CrazyMesh(dim, elements_layout, bounds_domain, curvature) function_space_2_lobatto = FunctionSpace(crazy_mesh, '2-lobatto', p, is_inner) function_space_1_lobatto = FunctionSpace(crazy_mesh, '1-lobatto', p, is_inner) E_21_lobatto_outer = d_21_lobatto_outer(p)