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_basis_inner(self): """Test inner product with basis functions.""" p_x, p_y = 2, 2 func_space_0 = FunctionSpace(self.mesh, '0-lobatto', (p_x, p_y)) func_space_1 = FunctionSpace(self.mesh, '1-lobatto', (p_x, p_y)) basis_0 = BasisForm(func_space_0) basis_1 = BasisForm(func_space_1) basis_1.quad_grid = 'lobatto' basis_0.quad_grid = 'lobatto' M_1 = inner(basis_1, basis_1) e_10 = d(func_space_0) inner_prod_ref = np.tensordot(e_10, M_1, axes=((0), (0))) # inner_prod = inner(d(basis_0), basis_1) npt.assert_array_almost_equal(inner_prod_ref, inner_prod) # inner_prod_1_ref = np.rollaxis( np.tensordot(M_1, e_10, axes=((0), (0))), 2) inner_prod_1 = inner(basis_1, d(basis_0)) npt.assert_array_almost_equal(inner_prod_1_ref, inner_prod_1) # inner_prod_2_ref = np.tensordot(e_10, np.tensordot(e_10, M_1, axes=((0), (0))), axes=((0), (1))) inner_prod_2 = inner(d(basis_0), d(basis_0)) # npt.assert_array_almost_equal(inner_prod_2_ref, inner_prod_2)
def test_assemble_incidence_matrices(self): p_dual = (self.p[0] - 1, self.p[1] - 1) func_space_lob_0 = FunctionSpace(self.mesh, '0-lobatto', self.p) func_space_extgauss_0 = FunctionSpace(self.mesh, '0-ext_gauss', p_dual) func_space_lob_1 = NextSpace(func_space_lob_0) func_space_extgauss_1 = FunctionSpace(self.mesh, '1-ext_gauss', p_dual) func_space_lob_2 = FunctionSpace(self.mesh, '2-lobatto', self.p) func_space_extgauss_2 = FunctionSpace(self.mesh, '2-ext_gauss', p_dual) e10_lob = d(func_space_lob_0) e21_lob = d(func_space_lob_1) e10_ext = d(func_space_extgauss_0) # e21_ext = d(func_space_extgauss_1) # e10_lob_assembled_ref = assemble_slow( self.mesh, e10_lob, func_space_lob_1.dof_map.dof_map, func_space_lob_0.dof_map.dof_map, mode='replace') e21_lob_assembled_ref = assemble_slow( self.mesh, e21_lob, func_space_lob_2.dof_map.dof_map, func_space_lob_1.dof_map.dof_map, mode='replace') e10_ext_assembled_ref = assemble_slow( self.mesh, e10_ext, func_space_extgauss_1.dof_map.dof_map, func_space_extgauss_0.dof_map.dof_map, mode='replace') # e21_ext_assembled_ref = assemble_slow( # self.mesh, e21_ext, func_space_extgauss_2.dof_map.dof_map, # func_space_extgauss_1.dof_map.dof_map, mode='replace') e10_lob_assembled = assemble(e10_lob, (func_space_lob_1, func_space_lob_0)).toarray() e21_lob_assembled = assemble(e21_lob, (func_space_lob_2, func_space_lob_1)).toarray() e10_ext_assembled = assemble(e10_ext, (func_space_extgauss_1, func_space_extgauss_0)).toarray() # e21_ext_assembled = assemble(e21_ext, func_space_extgauss_2, # func_space_extgauss_1).toarray() npt.assert_array_almost_equal(e10_lob_assembled_ref, e10_lob_assembled) npt.assert_array_almost_equal(e21_lob_assembled_ref, e21_lob_assembled) npt.assert_array_almost_equal(e10_ext_assembled_ref, e10_ext_assembled) # npt.assert_array_almost_equal(e21_ext_assembled_ref, e21_ext_assembled) e10_internal = d(func_space_extgauss_0)[:func_space_extgauss_1.num_internal_local_dof] e10_internal_assembled_ref = assemble_slow( self.mesh, e10_internal, func_space_extgauss_1.dof_map.dof_map_internal, func_space_extgauss_0.dof_map.dof_map) e10_internal_assembled = assemble( e10_internal, (func_space_extgauss_1, func_space_extgauss_0)).toarray() npt.assert_array_almost_equal(e10_internal_assembled_ref, e10_internal_assembled)
def test_visulization_lobato_e10_inner(self): def pfun(x, y): return np.sin(np.pi * x) * np.sin(np.pi * y) p = (20, 20) n = (2, 2) mesh = CrazyMesh(2, n, ((-1, 1), (-1, 1)), 0.2) xi = eta = np.linspace(-1, 1, 100) func_space = FunctionSpace(mesh, '0-lobatto', p) form_0 = Form(func_space) form_0.discretize(pfun) form_0.reconstruct(xi, eta) (x, y), data = form_0.export_to_plot() plt.contourf(x, y, data) plt.title('reduced lobatto 0-form') plt.colorbar() plt.show() form_1 = d(form_0) form_1.reconstruct(xi, eta) (x, y), data_dx, data_dy = form_1.export_to_plot() plt.contourf(x, y, data_dx) plt.title('lobatto 1-form dx') plt.colorbar() # plt.show() plt.contourf(x, y, data_dy) plt.title('lobatto 1-form dy') plt.colorbar() # plt.show() print(np.min(data_dy))
def test_visulalization_extended_gauss_e10_inner(self): def pfun(x, y): return np.sin(np.pi * x) * np.sin(np.pi * y) p = (10, 10) n = (20, 20) mesh = CrazyMesh(2, n, ((-1, 1), (-1, 1)), 0.3) func_space_extGau = FunctionSpace(mesh, '0-ext_gauss', p) form_0_extG = Form(func_space_extGau) form_0_extG.discretize(self.pfun) xi = eta = np.linspace(-1, 1, 10) form_0_extG.reconstruct(xi, eta) (x, y), data = form_0_extG.export_to_plot() plt.contourf(x, y, data) plt.title('reduced extended_gauss 0-form') plt.colorbar() plt.show() form_1 = d(form_0_extG) form_1.reconstruct(xi, eta) (x, y), data_dx, data_dy = form_1.export_to_plot() ufun_x, ufun_y = self.ufun() plt.contourf(x, y, data_dx) plt.title('extended_gauss 1-form dx') plt.colorbar() plt.show() # plt.contourf(x, y, data_dy) plt.title('extended_gauss 1-form dy') plt.colorbar() plt.show() print(np.min(data_dy))
def multiple_element(): mesh = CrazyMesh(2, (5, 7), ((-1, 1), (-1, 1)), curvature=0.3) p = 10, 10 func_space_vort = FunctionSpace(mesh, '0-ext_gauss', (p[0] - 1, p[1] - 1), is_inner=False) func_space_outer_vel = FunctionSpace( mesh, '1-total_ext_gauss', (p[0], p[1]), is_inner=False) # func_space_outer_vel = FunctionSpace( # mesh, '1-gauss', (p[0], p[1]), is_inner=False) func_space_inner_vel = FunctionSpace(mesh, '1-lobatto', p, is_inner=True) func_space_inner_vel.dof_map.continous_dof = True func_space_source = FunctionSpace(mesh, '2-lobatto', p, is_inner=True) basis_vort = BasisForm(func_space_vort) basis_vel_in = BasisForm(func_space_inner_vel) basis_vel_in.quad_grid = 'lobatto' basis_vel_out = BasisForm(func_space_outer_vel) basis_vel_out.quad_grid = 'lobatto' basis_2 = BasisForm(func_space_source) psi = Form(func_space_vort) u_in = Form(func_space_inner_vel) source = Form(func_space_source) source.discretize(ffun) M_1 = inner(basis_vel_in, basis_vel_in) E_21_in = d(func_space_inner_vel) W_02 = basis_2.wedged(basis_vort) W_02_E21 = np.transpose(W_02 @ E_21_in) M_1 = assemble(M_1, (func_space_inner_vel, func_space_inner_vel)) print(np.shape(M_1)) W_02_E21 = assemble(W_02_E21, (func_space_inner_vel, func_space_vort)) print(np.shape(W_02_E21)) W_02 = assemble(W_02, (func_space_source, func_space_vort)) lhs = spr.bmat([[M_1, W_02_E21], [W_02_E21.transpose(), None]]) print(np.shape(lhs)) rhs = np.zeros(np.shape(lhs)[0]) rhs[-func_space_source.num_dof:] = W_02 @ source.cochain solution = spr.linalg.spsolve(lhs.tocsc(), rhs) u_in.cochain = solution[:func_space_inner_vel.num_dof] cochian_psi = np.zeros(func_space_vort.num_dof) cochian_psi[:func_space_vort.num_internal_dof] = solution[-func_space_vort.num_internal_dof:] psi.cochain = cochian_psi xi = eta = np.linspace(-1, 1, 40) u_in.reconstruct(xi, eta) (x, y), u_x, u_y = u_in.export_to_plot() plt.contourf(x, y, u_x) plt.colorbar() plt.title("u_x inner") plt.show() psi.reconstruct(xi, eta) (x, y), psi_value = psi.export_to_plot() plt.contourf(x, y, psi_value) plt.title("psi outer" ) plt.colorbar() plt.show()
def test_multiple_elements(self): """Test the anysotropic case in multiple element.""" p = (6, 6) is_inner = False crazy_mesh = CrazyMesh(2, (8, 5), ((-1, 1), (-1, 1)), curvature=0.1) func_space_2_lobatto = FunctionSpace(crazy_mesh, '2-lobatto', p, is_inner) func_space_1_lobatto = FunctionSpace(crazy_mesh, '1-lobatto', p, is_inner) func_space_1_lobatto.dof_map.continous_dof = True def diffusion_11(x, y): return 4 * np.ones(np.shape(x)) def diffusion_12(x, y): return 3 * np.ones(np.shape(x)) def diffusion_22(x, y): return 5 * np.ones(np.shape(x)) def source(x, y): return -36 * np.pi ** 2 * np.sin(2 * np.pi * x) * np.sin(2 * np.pi * y) + 24 * np.pi ** 2 * np.cos(2 * np.pi * x) * np.cos(2 * np.pi * y) # mesh function to inject the anisotropic tensor mesh_k = MeshFunction(crazy_mesh) mesh_k.continous_tensor = [diffusion_11, diffusion_12, diffusion_22] # definition of the basis functions basis_1 = BasisForm(func_space_1_lobatto) basis_1.quad_grid = 'gauss' basis_2 = BasisForm(func_space_2_lobatto) basis_2.quad_grid = 'gauss' # solution form phi_2 = Form(func_space_2_lobatto) phi_2.basis.quad_grid = 'gauss' form_source = Form(func_space_2_lobatto) form_source.discretize(source, ('gauss', 30)) # find inner product M_1k = inner(basis_1, basis_1, mesh_k) N_2 = inner(d(basis_1), basis_2) M_2 = inner(basis_2, basis_2) # assemble M_1k = assemble(M_1k, func_space_1_lobatto) N_2 = assemble(N_2, (func_space_1_lobatto, func_space_2_lobatto)) M_2 = assemble(M_2, func_space_2_lobatto) lhs = sparse.bmat([[M_1k, N_2], [N_2.transpose(), None]]).tocsc() rhs_source = (form_source.cochain @ M_2)[:, np.newaxis] rhs_zeros = np.zeros(lhs.shape[0] - np.size(rhs_source))[:, np.newaxis] rhs = np.vstack((rhs_zeros, rhs_source)) solution = sparse.linalg.spsolve(lhs, rhs) phi_2.cochain = solution[-func_space_2_lobatto.num_dof:] # sample the solution xi = eta = np.linspace(-1, 1, 200) phi_2.reconstruct(xi, eta) (x, y), data = phi_2.export_to_plot() plt.contourf(x, y, data) plt.show() print("max value {0} \nmin value {1}" .format(np.max(data), np.min(data))) npt.assert_array_almost_equal(self.solution(x, y), data, decimal=2)
def test_single_element(self): """Test the anysotropic case in a single element.""" dim = 2 elements_layout = (1, 1) bounds_domain = ((-1, 1), (-1, 1)) curvature = 0.1 p = (20, 20) is_inner = False crazy_mesh = CrazyMesh(dim, elements_layout, bounds_domain, curvature) func_space_2_lobatto = FunctionSpace(crazy_mesh, '2-lobatto', p, is_inner) func_space_1_lobatto = FunctionSpace(crazy_mesh, '1-lobatto', p, is_inner) def diffusion_11(x, y): return 4 * np.ones(np.shape(x)) def diffusion_12(x, y): return 3 * np.ones(np.shape(x)) def diffusion_22(x, y): return 5 * np.ones(np.shape(x)) mesh_k = MeshFunction(crazy_mesh) mesh_k.continous_tensor = [diffusion_11, diffusion_12, diffusion_22] basis_1 = BasisForm(func_space_1_lobatto) basis_1.quad_grid = 'gauss' basis_2 = BasisForm(func_space_2_lobatto) basis_2.quad_grid = 'gauss' phi_2 = Form(func_space_2_lobatto) phi_2.basis.quad_grid = 'gauss' M_1k = inner(basis_1, basis_1, mesh_k) N_2 = inner(basis_2, d(basis_1)) def source(x, y): return -36 * np.pi ** 2 * np.sin(2 * np.pi * x) * np.sin(2 * np.pi * y) + 24 * np.pi ** 2 * np.cos(2 * np.pi * x) * np.cos(2 * np.pi * y) form_source = Form(func_space_2_lobatto) form_source.discretize(source) M_2 = inner(basis_2, basis_2) lhs = np.vstack((np.hstack((M_1k[:, :, 0], N_2[:, :, 0])), np.hstack( (np.transpose(N_2[:, :, 0]), np.zeros((np.shape(N_2)[1], np.shape(N_2)[1])))))) rhs = np.zeros((np.shape(lhs)[0], 1)) rhs[-np.shape(M_2)[0]:] = form_source.cochain @ M_2 phi_2.cochain = np.linalg.solve(lhs, rhs)[-phi_2.basis.num_basis:].flatten() xi = eta = np.linspace(-1, 1, 200) phi_2.reconstruct(xi, eta) (x, y), data = phi_2.export_to_plot() print("max value {0} \nmin value {1}" .format(np.max(data), np.min(data))) npt.assert_array_almost_equal(self.solution(x, y), data, decimal=2)
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)
def test_coboundary_lobatto_e10_inner(self): """Test of the coundary 0->1 for lobatto form inner oriented.""" p = (20, 20) n = (6, 6) mesh = CrazyMesh(2, n, ((-1, 1), (-1, 1)), 0.1) xi = eta = np.linspace(-1, 1, 100) func_space = FunctionSpace(mesh, '0-lobatto', p) form_0 = Form(func_space) form_0.discretize(self.pfun) form_1 = d(form_0) form_1.reconstruct(xi, eta) (x, y), data_dx, data_dy = form_1.export_to_plot() ufun_x, ufun_y = self.ufun() npt.assert_array_almost_equal(ufun_x(x, y), data_dx) npt.assert_array_almost_equal(ufun_y(x, y), data_dy)
def test_coboundary_extended_gauss_e10_inner(self): def pfun(x, y): return np.sin(np.pi * x) * np.sin(np.pi * y) p = (10, 10) n = (20, 20) mesh = CrazyMesh(2, n, ((-1, 1), (-1, 1)), 0.3) func_space_extGau = FunctionSpace(mesh, '0-ext_gauss', p) form_0_extG = Form(func_space_extGau) form_0_extG.discretize(self.pfun) xi = eta = np.linspace(-1, 1, 10) form_0_extG.reconstruct(xi, eta) form_1 = d(form_0_extG) form_1.reconstruct(xi, eta) (x, y), data_dx, data_dy = form_1.export_to_plot() ufun_x, ufun_y = self.ufun() npt.assert_array_almost_equal(ufun_x(x, y), data_dx) npt.assert_array_almost_equal(ufun_y(x, y), data_dy) print(np.min(data_dy))
def solver(p, n, c): px = py = p nx = ny = n print("\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^") print("Start div grad solver @ p=", px) print(" @ n=", nx) print(" @ c=", c) mesh = CrazyMesh(2, (nx, ny), ((0, 1), (0, 1)), c) xi = eta = np.linspace(-1, 1, np.ceil(500 / (nx * ny)) + 1) # %% function spaces func_space_eg0 = FunctionSpace(mesh, '0-ext_gauss', (px, py)) p0 = Form(func_space_eg0) p0_exact = Form(func_space_eg0) p0_exact.discretize(pfun) #p0_exact.reconstruct(xi, eta) #(x, y), data = p0_exact.export_to_plot() #plt.contourf(x, y, data) #plt.title('exact extended gauss 0-form, p0') #plt.colorbar() #plt.show() func_space_eg1 = FunctionSpace(mesh, '1-ext_gauss', (px, py)) ui = Form(func_space_eg1) func_space_gl1 = FunctionSpace(mesh, '1-lobatto', (px + 1, py + 1), is_inner=False) uo = Form(func_space_gl1) func_space_gl2 = FunctionSpace(mesh, '2-lobatto', (px + 1, py + 1), is_inner=False) f2 = Form(func_space_gl2) f2.discretize(ffun, ('gauss', px + 5)) # f2.reconstruct(xi, eta) # (x, y), data = f2.export_to_plot() # plt.contourf(x, y, data) # plt.title('exact lobatto 2-form, f2') # plt.colorbar() # plt.show() # %% E10 = d(func_space_eg0)[0:ui.basis.num_basis] # E10 = d(func_space_eg0) H = hodge(func_space_gl1) E21 = d(func_space_gl1) # print(np.shape(uo.function_space.dof_map.dof_map)) # print(np.shape(ui.function_space.dof_map.dof_map_internal)) # E10_assembled = assemble_(mesh, E10, ui.function_space.dof_map.dof_map_internal, # p0.function_space.dof_map.dof_map, mode='replace') E10_assembled = assemble(E10, (ui.function_space, p0.function_space)) # H_assembled = assemble_(mesh, H, uo.function_space.dof_map.dof_map, # ui.function_space.dof_map.dof_map_internal) # E21_assembled = assemble_(mesh, E21, f2.function_space.dof_map.dof_map, # uo.function_space.dof_map.dof_map, mode='replace') E21_assembled = assemble(E21, (f2.function_space, uo.function_space)) #print(E21_assembled) # E10_assembled = assemble(E10, ui.function_space, p0.function_space) H_assembled = -assemble(H, ui.function_space, uo.function_space) # E21_assembled = assemble(E21, f2.function_space, uo.function_space) # %% test the assembled matrices # ui_cochian_internal = E10_assembled.dot(p0_exact.cochain) # ui.cochain = np.concatenate((ui_cochian_internal, np.zeros( # ui.function_space.num_dof - ui.basis.num_basis * ui.mesh.num_elements)), axis=0) # ui.reconstruct(xi, eta) # (x, y), data_dx, data_dy = ui.export_to_plot() ## plt.contourf(x, y, data_dx) ## plt.title('exact extended_gauss 1-form dx') ## plt.colorbar() ## plt.show() # # plt.contourf(x, y, data_dy) # plt.title('exact extended_gauss 1-form dy') # plt.colorbar() # plt.show() # # uo.cochain = H_assembled.dot( ui_cochian_internal) # uo.reconstruct(xi, eta) # (x, y), data_dx, data_dy = uo.export_to_plot() # plt.contourf(x, y, data_dx) # plt.title('exact lobbat 1-form dx') # plt.colorbar() # plt.show() # plt.contourf(x, y, data_dy) # plt.title('exact lobbat 1-form dy') # plt.colorbar() # plt.show() # %% # system: # | H E10 | | uo | | 0 | # | | | | | | # | | * | | = | | # | | | | | | # | E21 0 | | p | | f | ui_num_dof_internal = ui.basis.num_basis * ui.mesh.num_elements # LHS1 = np.hstack((np.eye(ui_num_dof_internal), # np.zeros((ui_num_dof_internal, uo.function_space.num_dof)), # -E10_assembled)) # # LHS2 = np.hstack((-H_assembled, # np.eye(uo.function_space.num_dof), # np.zeros((uo.function_space.num_dof, p0.function_space.num_dof)))) # # LHS3 = np.hstack((np.zeros((f2.function_space.num_dof, ui_num_dof_internal)), # E21_assembled, # np.zeros((f2.function_space.num_dof, p0.function_space.num_dof)))) LHS1 = sparse.hstack((H_assembled, E10_assembled)) LHS2 = sparse.hstack( (E21_assembled, sparse.csc_matrix( (f2.function_space.num_dof, p0.function_space.num_dof)))) RHS1 = np.zeros(shape=(uo.function_space.num_dof, 1)) RHS2 = f2.cochain.reshape((f2.function_space.num_dof, 1)) # %% def dof_map_crazy_lobatto_edges(mesh, p): nx, ny = mesh.n_x, mesh.n_y global_numbering = np.zeros((nx * ny, 2 * p * (p + 1)), dtype=np.int32) local_numbering = np.array([int(i) for i in range(2 * p * (p + 1))]) for i in range(nx): for j in range(ny): s = j + i * ny global_numbering[s, :] = local_numbering + 2 * p * (p + 1) * s interface_edge_pair = np.zeros( (((nx - 1) * ny + nx * (ny - 1)) * p, 2), dtype=np.int32) n = 0 for i in range(nx - 1): for j in range(ny): s1 = j + i * ny s2 = j + (i + 1) * ny for m in range(p): interface_edge_pair[n, 0] = global_numbering[s1, p * (p + 1) + p**2 + m] interface_edge_pair[n, 1] = global_numbering[s2, p * (p + 1) + m] n += 1 for i in range(nx): for j in range(ny - 1): s1 = j + i * ny s2 = j + 1 + i * ny for m in range(p): interface_edge_pair[n, 0] = global_numbering[s1, (m + 1) * (p + 1) - 1] interface_edge_pair[n, 1] = global_numbering[s2, m * (p + 1)] n += 1 return interface_edge_pair interface_edge_pair = dof_map_crazy_lobatto_edges(mesh, px + 1) LItFuo = sparse.lil_matrix( (np.shape(interface_edge_pair)[0], uo.function_space.num_dof + p0.function_space.num_dof)) RItFuo = np.zeros(shape=(np.shape(interface_edge_pair)[0], 1)) for i in range(np.shape(interface_edge_pair)[0]): LItFuo[i, interface_edge_pair[i, 0]] = 1 LItFuo[i, interface_edge_pair[i, 1]] = -1 # %% def CrazyMesh_2d_extended_gauss0_general_boundary_nodes( mesh, p, gathering_matrix): p += 1 nx = mesh.n_x ny = mesh.n_y Left = np.zeros(shape=(ny * p), dtype=np.int16) Right = np.zeros(shape=(ny * p), dtype=np.int16) Bottom = np.zeros(shape=(nx * p), dtype=np.int16) Top = np.zeros(shape=(nx * p), dtype=np.int16) for J in range(ny): eleidLeft = J Left[J * p:J * p + p] = gathering_matrix[eleidLeft, p**2:p**2 + p] eleidRight = (nx - 1) * ny + J Right[J * p:J * p + p] = gathering_matrix[eleidRight, p**2 + p:p**2 + 2 * p] for I in range(nx): eleidBottom = I * ny Bottom[I * p:I * p + p] = gathering_matrix[eleidBottom, p**2 + 2 * p:p**2 + 3 * p] eleidTop = I * ny + ny - 1 Top[I * p:I * p + p] = gathering_matrix[eleidTop, p**2 + 3 * p:p**2 + 4 * p] return Left, Right, Bottom, Top Left, Right, Bottom, Top = CrazyMesh_2d_extended_gauss0_general_boundary_nodes( mesh, px, p0.function_space.dof_map.dof_map) Boundarypoint = np.hstack((Left, Right, Bottom, Top)) # LBCphi = np.zeros(shape=(np.size(Boundarypoint), ui_num_dof_internal + # uo.function_space.num_dof + p0.function_space.num_dof)) LBCphi = sparse.lil_matrix( (np.size(Boundarypoint), uo.function_space.num_dof + p0.function_space.num_dof)) RBCphi = np.zeros(shape=(np.size(Boundarypoint), 1)) for i in range(np.size(Boundarypoint)): LBCphi[i, uo.function_space.num_dof + Boundarypoint[i]] = 1 RBCphi[i] = p0_exact.cochain[Boundarypoint[i]] # %% LHS and RHS and solve it LHS = sparse.vstack((LHS1, LHS2, LItFuo, LBCphi)) RHS = np.vstack((RHS1, RHS2, RItFuo, RBCphi)) print("----------------------------------------------------") print("LHS shape:", np.shape(LHS)) # LHS = sparse.csr_matrix(LHS) print("------ solve the square sparse system:......") Res = sparse.linalg.spsolve(LHS, RHS) # Res = sparse.linalg.lsqr(LHS,RHS, atol=1e-20, btol=1e-20)[0] # print("++++++ solve the singular square full system:......") # Res = np.linalg.solve(LHS, RHS) # %% split into pieces uo.cochain = Res[:uo.function_space.num_dof].reshape( uo.function_space.num_dof) p0.cochain = Res[-p0.function_space.num_dof:].reshape( p0.function_space.num_dof) # %% view the result p0.reconstruct(xi, eta) (x, y), data = p0.export_to_plot() plt.contourf(x, y, data) plt.title('solution extended gauss 0-form, p0') plt.colorbar() plt.show() # # uo.reconstruct(xi, eta) # (x, y), data_dx, data_dy = uo.export_to_plot() # plt.contourf(x, y, data_dx) # plt.title('lobatto 1-form dx') # plt.colorbar() # plt.show() # # plt.contourf(x, y, data_dy) # plt.title('lobatto 1-form dy') # plt.colorbar() # plt.show() #f2.reconstruct(xi, eta) #(x, y), data = f2.export_to_plot() #plt.contourf(x, y, data) #plt.title('exact lobatto 2-form, f2') #plt.colorbar() #plt.show() # %% L2_error L2_error_p0 = p0.l_2_norm(pfun, ('gauss', px + 5))[0] L2_error_uo = uo.l_2_norm((uo_dx, uo_dy), ('lobatto', px + 5))[0] print("------ L2_error_p0 =", L2_error_p0) print("------ L2_error_uo =", L2_error_uo) return L2_error_p0, L2_error_uo print("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n")
def solver(p, n, c): print("\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^") print("Start curl curl solver @ p=", p) print(" @ n=", n) print(" @ c=", c) px = py = p nx = n ny = n mesh = CrazyMesh(2, (nx, ny), ((-1, 1), (-1, 1)), c) xi = eta = np.linspace(-1, 1, np.ceil(500 / (nx * ny)) + 1) # %% exact p(0) func_space_gl0 = FunctionSpace(mesh, '0-lobatto', (px + 1, py + 1), is_inner=False) p0_exact = Form(func_space_gl0) p0_exact.discretize(pfun) p0_exact.reconstruct(xi, eta) (x, y), data = p0_exact.export_to_plot() plt.contourf(x, y, data) plt.title('exact lobatto 0-form, p0') plt.colorbar() plt.show() # %% p(0) func_space_gl0 = FunctionSpace(mesh, '0-lobatto', (px + 1, py + 1), is_inner=False) p0 = Form(func_space_gl0) # %% func_space_gl1 = FunctionSpace(mesh, '1-lobatto', (px + 1, py + 1), is_inner=False) uo = Form(func_space_gl1) # %% func_space_eg1 = FunctionSpace(mesh, '1-ext_gauss', (px, py)) ui = Form(func_space_eg1) # %% func_space_eg2 = FunctionSpace(mesh, '2-ext_gauss', (px, py)) f2 = Form(func_space_eg2) f2_exact = Form(func_space_eg2) f2_exact.discretize(ffun) # f2_exact.reconstruct(xi, eta) # (x, y), data = f2_exact.export_to_plot() # plt.contourf(x, y, data) # plt.title('exact extended-gauss 2-form, f2') # plt.colorbar() # plt.show() # %% E10 = d(func_space_gl0) # E10_assembled = assemble(mesh, E10, uo.function_space.dof_map.dof_map,p0.function_space.dof_map.dof_map, mode='replace') E10_assembled = assemble(E10, (uo.function_space, p0.function_space)) H = hodge(func_space_gl1) # H_assembled = assemble(mesh, H , ui.function_space.dof_map.dof_map_internal, uo.function_space.dof_map.dof_map) H_assembled = assemble(H, (ui.function_space, uo.function_space)) #H_assembled = np.linalg.inv(H_assembled) E21 = d(func_space_eg1) # E21_assembled = assemble(mesh, E21, f2.function_space.dof_map.dof_map, ui.function_space.dof_map.dof_map, mode = 'replace') E21_assembled = assemble(E21, (f2.function_space, ui.function_space)) # %% # uo.cochain = E10_assembled.dot(p0_exact.cochain) # uo.reconstruct(xi, eta) # (x, y), data_dx, data_dy = uo.export_to_plot() # plt.contourf(x, y, data_dx) # plt.title('exact lobatto 1-form dx') # plt.colorbar() # plt.show() # print('uo_dx max:', np.max(data_dx)) # print('uo_dx min:', np.min(data_dx)) # # plt.contourf(x, y, data_dy) # plt.title('exact lobatto 1-form dy') # plt.colorbar() # plt.show() # print('uo_dy max:', np.max(data_dy)) # print('uo_dy min:', np.min(data_dy)) # # ui_internal_cochain = H_assembled.dot(uo.cochain) # ui.cochain = np.concatenate((ui_internal_cochain, np.zeros( # ui.function_space.num_dof - ui.basis.num_basis * ui.mesh.num_elements)), axis=0) # ui.reconstruct(xi, eta) # (x, y), data_dx, data_dy = ui.export_to_plot() # plt.contourf(x, y, data_dx) # plt.title('ext_gauss 1-form dx') # plt.colorbar() # plt.show() # print('ui_dx max:', np.max(data_dx)) # print('ui_dy min:', np.min(data_dx)) # # plt.contourf(x, y, data_dy) # plt.title('ext_gauss 1-form dy') # plt.colorbar() # plt.show() # print('ui_dy max:', np.max(data_dy)) # print('ui_dy min:', np.min(data_dy)) # def UBC(mesh, s, p, position): # def pullbackedfun_dx(xi, eta): # x, y = mesh.mapping(xi, eta, s) # return ui_dx(x, y) # # def pullbackedfun_dy(xi, eta): # x, y = mesh.mapping(xi, eta, s) # return ui_dy(x, y) # # def fun2bint_dxi(xi, eta): # return pullbackedfun_dx(xi, eta) * mesh.dx_dxi(xi, eta, s) + pullbackedfun_dy(xi, eta) * mesh.dy_dxi(xi, eta, s) # # def fun2bint_deta(xi, eta): # return pullbackedfun_dx(xi, eta) * mesh.dx_deta(xi, eta, s) + pullbackedfun_dy(xi, eta) * mesh.dy_deta(xi, eta, s) # # UBC_s = np.zeros(shape = (p+1)) # extended_gauss_nodes, _ = extended_gauss_quad(p-1) # if position == 'Left': # for i in range(p+1): # # print("hello, Left world") # def fun2bint_deta_BC(eta): # return fun2bint_deta(-1, eta) # UBC_s[i] = quad(fun2bint_deta_BC, extended_gauss_nodes[i], extended_gauss_nodes[i+1] )[0] # elif position == 'Right': # for i in range(p+1): # # print("hello, Right world") # def fun2bint_deta_BC(eta): # return fun2bint_deta(+1, eta) # UBC_s[i] = quad(fun2bint_deta_BC, extended_gauss_nodes[i], extended_gauss_nodes[i+1] )[0] # elif position == 'Bottom': # for i in range(p+1): # # print("hello, Bottom world") # def fun2bint_dxi_BC(xi): # return fun2bint_dxi(xi, -1) # UBC_s[i] = quad(fun2bint_dxi_BC, extended_gauss_nodes[i], extended_gauss_nodes[i+1] )[0] # elif position == 'Top': # for i in range(p+1): # # print("hello, Top world") # def fun2bint_dxi_BC(xi): # return fun2bint_dxi(xi, +1) # UBC_s[i] = quad(fun2bint_dxi_BC, extended_gauss_nodes[i], extended_gauss_nodes[i+1] )[0] # return UBC_s # # def extended_gauss1_general_boundary_edges(mesh, p, gathering_matrix): # p+=1 # nx = mesh.n_x # ny = mesh.n_y # # Left = np.zeros( shape = (ny*(p+1)), dtype=np.int32 ) # Right = np.zeros( shape = (ny*(p+1)), dtype=np.int32 ) # Bottom = np.zeros( shape = (nx*(p+1)), dtype=np.int32 ) # Top = np.zeros( shape = (nx*(p+1)), dtype=np.int32 ) # # M = 2 * p * (p+1) # N = p+1 # # UBC_L = UBC_R = UBC_B = UBC_T = 0 # # for J in range(ny): # eleidLeft = J # Left[ J*N : J*N + N ] = gathering_matrix[ eleidLeft , M +2*N : M +3*N ] # UBC_s=UBC(mesh, eleidLeft, p, "Left") # if UBC_L is 0: # UBC_L= UBC_s # else: # UBC_L = np.hstack((UBC_L, UBC_s)) # # eleidRight = (nx-1)*ny + J # Right[ J*N : J*N + N ] = gathering_matrix[ eleidRight, M +3*N : M +4*N ] # UBC_s=UBC(mesh, eleidRight, p, "Right") # if UBC_R is 0: # UBC_R= UBC_s # else: # UBC_R = np.hstack((UBC_R, UBC_s)) # # for I in range(nx): # eleidBottom = I*ny # Bottom[ I*N : I*N + N ] = gathering_matrix[ eleidBottom, M : M + N ] # UBC_s=UBC(mesh, eleidBottom, p, "Bottom") # if UBC_B is 0: # UBC_B= UBC_s # else: # UBC_B = np.hstack((UBC_B, UBC_s)) # # eleidTop = I*ny + ny -1 # Top[ I*N : I*N + N ] = gathering_matrix[ eleidTop , M + N : M + 2*N ] # UBC_s=UBC(mesh, eleidTop, p, "Top") # if UBC_T is 0: # UBC_T= UBC_s # else: # UBC_T = np.hstack((UBC_T, UBC_s)) # # return np.vstack((Left, UBC_L)), np.vstack((Right, UBC_R)), np.vstack((Bottom, UBC_B)), np.vstack((Top, UBC_T)) # # Left, Right, Bottom, Top = extended_gauss1_general_boundary_edges(mesh, px, ui.function_space.dof_map.dof_map) # Boundaryedgs = np.hstack( (Left, Right, Bottom, Top) ) # for i in range(np.shape(Boundaryedgs)[1]): # ui.cochain[int(Boundaryedgs[0, i])] =Boundaryedgs[1, i] # # f2.cochain = E21_assembled.dot(ui.cochain) # f2.reconstruct(xi, eta) # (x, y), data = f2.export_to_plot() # plt.contourf(x, y, data) # plt.title('exact extended-gauss 2-form, f2') # plt.colorbar() # plt.show() # %% # system: # | I -H 0 | | ui | | 0 | # | | | | | | # | 0 I -E10 | * | uo | = | 0 | # | | | | | | # | E21 0 0 | | p | | f | ui_num_dof_internal = ui.basis.num_basis * ui.mesh.num_elements ui_num_dof_external = ui.function_space.num_dof - ui_num_dof_internal # LHS1 = np.hstack(( np.eye(ui_num_dof_internal) , # np.zeros((ui_num_dof_internal, ui_num_dof_external)), # -H_assembled , # np.zeros((ui_num_dof_internal, p0.function_space.num_dof)) )) LHS1 = sparse.hstack( (sparse.eye(ui_num_dof_internal), sparse.csc_matrix( (ui_num_dof_internal, ui_num_dof_external)), -H_assembled, sparse.csc_matrix((ui_num_dof_internal, p0.function_space.num_dof)))) # LHS2 = np.hstack(( np.zeros((uo.function_space.num_dof, ui.function_space.num_dof )) , # np.eye(uo.function_space.num_dof) , # -E10_assembled )) LHS2 = sparse.hstack( (sparse.csc_matrix( (uo.function_space.num_dof, ui.function_space.num_dof)), sparse.eye(uo.function_space.num_dof), -E10_assembled)) # LHS3 = np.hstack(( E21_assembled , # np.zeros((f2.function_space.num_dof, uo.function_space.num_dof )) , # np.zeros((f2.function_space.num_dof, f2.function_space.num_dof )) )) LHS3 = sparse.hstack( (E21_assembled, sparse.csc_matrix( (f2.function_space.num_dof, uo.function_space.num_dof)), sparse.csc_matrix( (f2.function_space.num_dof, f2.function_space.num_dof)))) RHS1 = np.zeros((ui_num_dof_internal, 1)) RHS2 = np.zeros((uo.function_space.num_dof, 1)) RHS3 = f2_exact.cochain.reshape((f2_exact.function_space.num_dof, 1)) # %% boundary edges # def UBC(mesh, s, p, position): # def pullbackedfun_dx(xi, eta): # x, y = mesh.mapping(xi, eta, s) # return ufun_u(x, y) # # def pullbackedfun_dy(xi, eta): # x, y = mesh.mapping(xi, eta, s) # return ufun_v(x, y) # # def fun2bint_dxi(xi, eta): # return pullbackedfun_dx(xi, eta) * mesh.dx_dxi(xi, eta, s) + pullbackedfun_dy(xi, eta) * mesh.dy_dxi(xi, eta, s) # # def fun2bint_deta(xi, eta): # return pullbackedfun_dx(xi, eta) * mesh.dx_deta(xi, eta, s) + pullbackedfun_dy(xi, eta) * mesh.dy_deta(xi, eta, s) # # UBC_s = np.zeros(shape = (p+1)) # extended_gauss_nodes, _ = extended_gauss_quad(p-1) # if position == 'Left': # for i in range(p+1): # # print("hello, Left world") # def fun2bint_deta_BC(eta): # return fun2bint_deta(-1, eta) # UBC_s[i] = quad(fun2bint_deta_BC, extended_gauss_nodes[i], extended_gauss_nodes[i+1] )[0] # elif position == 'Right': # for i in range(p+1): # # print("hello, Right world") # def fun2bint_deta_BC(eta): # return fun2bint_deta(+1, eta) # UBC_s[i] = quad(fun2bint_deta_BC, extended_gauss_nodes[i], extended_gauss_nodes[i+1] )[0] # elif position == 'Bottom': # for i in range(p+1): # # print("hello, Bottom world") # def fun2bint_dxi_BC(xi): # return fun2bint_dxi(xi, -1) # UBC_s[i] = quad(fun2bint_dxi_BC, extended_gauss_nodes[i], extended_gauss_nodes[i+1] )[0] # elif position == 'Top': # for i in range(p+1): # # print("hello, Top world") # def fun2bint_dxi_BC(xi): # return fun2bint_dxi(xi, +1) # UBC_s[i] = quad(fun2bint_dxi_BC, extended_gauss_nodes[i], extended_gauss_nodes[i+1] )[0] # return UBC_s # # def extended_gauss1_general_boundary_edges(mesh, p, gathering_matrix): # p+=1 # nx = mesh.n_x # ny = mesh.n_y # # Left = np.zeros( shape = (ny*(p+1)), dtype=np.int32 ) # Right = np.zeros( shape = (ny*(p+1)), dtype=np.int32 ) # Bottom = np.zeros( shape = (nx*(p+1)), dtype=np.int32 ) # Top = np.zeros( shape = (nx*(p+1)), dtype=np.int32 ) # # M = 2 * p * (p+1) # N = p+1 # # UBC_L = UBC_R = UBC_B = UBC_T = 0 # # for J in range(ny): # eleidLeft = J # Left[ J*N : J*N + N ] = gathering_matrix[ eleidLeft , M +2*N : M +3*N ] # UBC_s=UBC(mesh, eleidLeft, p, "Left") # if UBC_L is 0: # UBC_L= UBC_s # else: # UBC_L = np.hstack((UBC_L, UBC_s)) # # eleidRight = (nx-1)*ny + J # Right[ J*N : J*N + N ] = gathering_matrix[ eleidRight, M +3*N : M +4*N ] # UBC_s=UBC(mesh, eleidRight, p, "Right") # if UBC_R is 0: # UBC_R= UBC_s # else: # UBC_R = np.hstack((UBC_R, UBC_s)) # # for I in range(nx): # eleidBottom = I*ny # Bottom[ I*N : I*N + N ] = gathering_matrix[ eleidBottom, M : M + N ] # UBC_s=UBC(mesh, eleidBottom, p, "Bottom") # if UBC_B is 0: # UBC_B= UBC_s # else: # UBC_B = np.hstack((UBC_B, UBC_s)) # # eleidTop = I*ny + ny -1 # Top[ I*N : I*N + N ] = gathering_matrix[ eleidTop , M + N : M + 2*N ] # UBC_s=UBC(mesh, eleidTop, p, "Top") # if UBC_T is 0: # UBC_T= UBC_s # else: # UBC_T = np.hstack((UBC_T, UBC_s)) # # return np.vstack((Left, UBC_L)), np.vstack((Right, UBC_R)), np.vstack((Bottom, UBC_B)), np.vstack((Top, UBC_T)) # # Left, Right, Bottom, Top = extended_gauss1_general_boundary_edges(mesh, px, ui.function_space.dof_map.dof_map) # Boundaryedgs = np.hstack( (Left, Right, Bottom, Top) ) # ## LBC = np.zeros( shape = ( np.shape(Boundaryedgs)[1], ui.function_space.num_dof+ uo.function_space.num_dof + p0.function_space.num_dof ) ) # LBC = sparse.lil_matrix( ( np.shape(Boundaryedgs)[1], ui.function_space.num_dof+ uo.function_space.num_dof + p0.function_space.num_dof ) ) # # RBC = np.zeros( shape = ( np.shape(Boundaryedgs)[1], 1) ) # for i in range(np.shape(Boundaryedgs)[1]): # if i == 0 : # LBC[0, ui.function_space.num_dof+ uo.function_space.num_dof] = 1 # RBC[0] = p0_exact.cochain[0] # else: # LBC[i, int(Boundaryedgs[0, i])] =1 # RBC[i] = Boundaryedgs[1, i] # %% def PBC(p, nx, ny, gathering_matrix, gathering_matrix_edge): p += 1 Left = np.zeros(shape=(ny * (p + 1), 4), dtype=np.int32) Right = np.zeros(shape=(ny * (p + 1), 4), dtype=np.int32) Bottom = np.zeros(shape=(nx * (p + 1), 4), dtype=np.int32) Top = np.zeros(shape=(nx * (p + 1), 4), dtype=np.int32) N = p + 1 P = 2 * p * (p + 1) Q = (p + 1) for J in range(ny): eleidLeft = J Left[J * N:J * N + N, 0] = gathering_matrix[eleidLeft, :N] if eleidLeft == 0: # left-bottom corner element Left[0, 0] = -1 # left - bottom corner point Left[0, 1] = gathering_matrix_edge[0, P + 2 * Q] Left[0, 2] = gathering_matrix_edge[0, P] if eleidLeft == ny - 1: # left-top corner element Left[-1, 0] = -3 # left _- top corner point Left[-1, 1] = gathering_matrix_edge[eleidLeft, P + Q] Left[-1, 2] = gathering_matrix_edge[eleidLeft, P + 3 * Q - 1] if eleidLeft >= 0 and eleidLeft < ny - 1: Left[J * N + N - 1, 0] = -2 # left Left[J * N + N - 1, 1] = gathering_matrix_edge[eleidLeft, P + 3 * Q - 1] Left[J * N + N - 1, 2] = gathering_matrix_edge[eleidLeft, P + Q] Left[J * N + N - 1, 3] = gathering_matrix_edge[eleidLeft + 1, P + 2 * Q] eleidRight = (nx - 1) * ny + J Right[J * N:J * N + N, 0] = gathering_matrix[eleidRight, -N:] if eleidRight == nx * ny - ny: # right bottom element Right[0, 0] = -4 Right[0, 1] = gathering_matrix_edge[eleidRight, P + Q - 1] Right[0, 2] = gathering_matrix_edge[eleidRight, P + 3 * Q] if eleidRight == nx * ny - 1: # right top element Right[-1, 0] = -5 Right[-1, 1] = gathering_matrix_edge[eleidRight, P + 2 * Q - 1] Right[-1, 2] = gathering_matrix_edge[eleidRight, -1] if eleidRight >= nx * ny - ny and eleidRight < nx * ny - 1: # right elements Right[J * N + N - 1, 0] = -6 Right[J * N + N - 1, 1] = gathering_matrix_edge[eleidRight, -1] Right[J * N + N - 1, 2] = gathering_matrix_edge[eleidRight, P + 2 * Q - 1] Right[J * N + N - 1, 3] = gathering_matrix_edge[eleidRight + 1, P + 3 * Q] for I in range(nx): eleidBottom = I * ny Bottom[I * N:I * N + N, 0] = gathering_matrix[eleidBottom, 0:N**2:N] if eleidBottom >= 0 and eleidBottom < nx * ny - ny: # bottom elements Bottom[I * N + N - 1, 0] = -7 Bottom[I * N + N - 1, 1] = gathering_matrix_edge[eleidBottom, P + Q - 1] Bottom[I * N + N - 1, 2] = gathering_matrix_edge[eleidBottom, P + 3 * Q] Bottom[I * N + N - 1, 3] = gathering_matrix_edge[eleidBottom + ny, P] eleidTop = I * ny + ny - 1 Top[I * N:I * N + N, 0] = gathering_matrix[eleidTop, N - 1:N**2:N] if eleidTop >= 0 and eleidTop < nx * ny - 1: # bottom elements Top[I * N + N - 1, 0] = -8 Top[I * N + N - 1, 1] = gathering_matrix_edge[eleidTop, P + 2 * Q - 1] Top[I * N + N - 1, 2] = gathering_matrix_edge[eleidTop, -1] Top[I * N + N - 1, 3] = gathering_matrix_edge[eleidTop + ny, P + Q] return Left, Right, Bottom, Top Left, Right, Bottom, Top = PBC(p, nx, ny, p0_exact.function_space.dof_map.dof_map, ui.function_space.dof_map.dof_map) Boundarypoints = np.vstack((Left, Right, Bottom, Top)) LBC = sparse.lil_matrix( (np.shape(Boundarypoints)[0], ui.function_space.num_dof + uo.function_space.num_dof + p0.function_space.num_dof)) RBC = np.zeros(shape=(np.shape(Boundarypoints)[0], 1)) for i in range(np.shape(Boundarypoints)[0]): if Boundarypoints[i, 0] == -1: LBC[i, Boundarypoints[i, 1]] = +1 LBC[i, Boundarypoints[i, 2]] = +1 RBC[i] = 0 elif Boundarypoints[i, 0] == -2: LBC[i, Boundarypoints[i, 1]] = -2 LBC[i, Boundarypoints[i, 2]] = +1 LBC[i, Boundarypoints[i, 3]] = +1 RBC[i] = 0 elif Boundarypoints[i, 0] == -3: LBC[i, Boundarypoints[i, 1]] = +1 LBC[i, Boundarypoints[i, 2]] = -1 RBC[i] = 0 elif Boundarypoints[i, 0] == -4: LBC[i, Boundarypoints[i, 1]] = +1 LBC[i, Boundarypoints[i, 2]] = -1 RBC[i] = 0 elif Boundarypoints[i, 0] == -5: LBC[i, Boundarypoints[i, 1]] = +1 LBC[i, Boundarypoints[i, 2]] = +1 RBC[i] = 0 elif Boundarypoints[i, 0] == -6: LBC[i, Boundarypoints[i, 1]] = +1 LBC[i, Boundarypoints[i, 2]] = +1 LBC[i, Boundarypoints[i, 3]] = -2 RBC[i] = 0 elif Boundarypoints[i, 0] == -7: LBC[i, Boundarypoints[i, 1]] = -2 LBC[i, Boundarypoints[i, 2]] = +1 LBC[i, Boundarypoints[i, 3]] = +1 RBC[i] = 0 elif Boundarypoints[i, 0] == -8: LBC[i, Boundarypoints[i, 1]] = +1 LBC[i, Boundarypoints[i, 2]] = +1 LBC[i, Boundarypoints[i, 3]] = -2 RBC[i] = 0 else: LBC[i, ui.function_space.num_dof + uo.function_space.num_dof + int(Boundarypoints[i, 0])] = 1 RBC[i] = p0_exact.cochain[Boundarypoints[i, 0]] # %% def dof_map_crazy_lobatto_point_pair(mesh, p, global_numbering, global_numbering_edges): nx, ny = mesh.n_x, mesh.n_y N = p + 1 interface_point_pair = np.zeros( (((nx - 1) * ny + nx * (ny - 1)) * N, 4), dtype=np.int32) n = 0 P = 2 * p * (p + 1) Q = (p + 1) for i in range(nx - 1): for j in range(ny): s1 = j + i * ny s2 = j + (i + 1) * ny # print(s1, s2) for m in range(N): interface_point_pair[n, 0] = global_numbering[s1, N * p + m] interface_point_pair[n, 1] = global_numbering[s2, m] if j < ny - 1 and m == N - 1: s3 = s2 + 1 interface_point_pair[n, 0] = global_numbering_edges[s1, P + 2 * Q - 1] interface_point_pair[n, 1] = global_numbering_edges[s1, -1] interface_point_pair[n, 2] = global_numbering_edges[s2, P + Q] interface_point_pair[n, 3] = global_numbering_edges[s3, P + 2 * Q] n += 1 for i in range(nx): for j in range(ny - 1): s1 = j + i * ny s2 = j + 1 + i * ny # print(s1, s2) for m in range(N): interface_point_pair[n, 0] = global_numbering[s1, (m + 1) * N - 1] interface_point_pair[n, 1] = global_numbering[s2, m * N] n += 1 return interface_point_pair interface_point_pair = dof_map_crazy_lobatto_point_pair( mesh, px + 1, p0.function_space.dof_map.dof_map, ui.function_space.dof_map.dof_map) # Lintface = np.zeros( shape = ( np.shape( interface_point_pair )[0], ui.function_space.num_dof+ uo.function_space.num_dof + p0.function_space.num_dof ) ) Lintface = sparse.lil_matrix( (np.shape(interface_point_pair)[0], ui.function_space.num_dof + uo.function_space.num_dof + p0.function_space.num_dof)) #Rintface = np.zeros( shape = ( np.shape( interface_point_pair )[0]-(nx-1)*(ny-1), 1) ) Rintface = np.zeros(shape=(np.shape(interface_point_pair)[0], 1)) for i in range(np.shape(interface_point_pair)[0]): if interface_point_pair[i, 2] != 0 and interface_point_pair[i, 3] != 0: Lintface[i, interface_point_pair[i, 0]] = 1 Lintface[i, interface_point_pair[i, 1]] = 1 Lintface[i, interface_point_pair[i, 2]] = -1 Lintface[i, interface_point_pair[i, 3]] = -1 else: Lintface[i, ui.function_space.num_dof + uo.function_space.num_dof + interface_point_pair[i, 0]] = 1 Lintface[i, ui.function_space.num_dof + uo.function_space.num_dof + interface_point_pair[i, 1]] = -1 # Lintface = sparse.csr_matrix(Lintface) # %% #Lintface=Lintface[~np.all(Lintface == 0, axis=1)] LHS = sparse.vstack((LHS1, LHS2, LHS3, Lintface, LBC)) RHS = np.vstack((RHS1, RHS2, RHS3, Rintface, RBC)) #rrefLHS = np.array(Matrix(LHS).rref()[0]).astype(None) #print(rrefLHS) print("----------------------------------------------------") print("LHS shape:", np.shape(LHS)) print("------ solve the square sparse system:......") LHS = sparse.csr_matrix(LHS) Res = sparse.linalg.spsolve(LHS, RHS) # # print("------ solve the singular square sparse system:......") # solution = sparse.linalg.lsqr(LHS,RHS, atol=1e-20, btol=1e-20) # Res = solution[0].reshape((np.size(solution[0]),1)) # residual = np.sum(np.abs(LHS.dot(Res) - RHS)) # print("------ least square solution error =",residual) # print("++++++ solve the singular square full system:......") # solution= np.linalg.lstsq(LHS,RHS) # %% eigen values and eigen vector # w, v = sp.linalg.eig(LHS.todense()) # %% ui.cochain = Res[0:ui.function_space.num_dof].reshape( ui.function_space.num_dof) uo.cochain = Res[ui.function_space. num_dof:-p0.function_space.num_dof].reshape( uo.function_space.num_dof) p0.cochain = Res[-p0.function_space.num_dof:].reshape( p0.function_space.num_dof) # %% view the result p0.reconstruct(xi, eta) (x, y), data = p0.export_to_plot() plt.contourf(x, y, data) plt.title('solution lobatto 0-form, p0') plt.colorbar() plt.show() print('p0 max:', np.max(data)) print('p0 min:', np.min(data)) uo.reconstruct(xi, eta) (x, y), data_dx, data_dy = uo.export_to_plot() plt.contourf(x, y, data_dx) plt.title('solution lobatto 1-form dx') plt.colorbar() plt.show() print('uo max:', np.max(data_dx)) print('uo min:', np.min(data_dx)) plt.contourf(x, y, data_dy) plt.title('solution lobatto 1-form dy') plt.colorbar() plt.show() print('uo max:', np.max(data_dy)) print('uo min:', np.min(data_dy)) # # ui.reconstruct(xi, eta) (x, y), data_dx, data_dy = ui.export_to_plot() plt.contourf(x, y, data_dx) plt.title('solution extended_gauss 1-form dx') plt.colorbar() plt.show() print('ui max:', np.max(data_dx)) print('ui min:', np.min(data_dx)) plt.contourf(x, y, data_dy) plt.title('solution extended_gauss 1-form dy') plt.colorbar() plt.show() print('ui max:', np.max(data_dy)) print('ui min:', np.min(data_dy)) f2_exact.reconstruct(xi, eta) (x, y), data = f2_exact.export_to_plot() plt.contourf(x, y, data) plt.title('exact extended-gauss 2-form, f2') plt.colorbar() plt.show() # %% error L2_error_p0 = p0.l_2_norm(pfun, ('gauss', 10))[0] print("------ L2_error_psi0 =", L2_error_p0) L2_error_ui = ui.l_2_norm((ui_dx, ui_dy), ('gauss', 5))[0] print("------ L2_error_ui =", L2_error_ui) print("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n") # %% return return L2_error_p0, L2_error_ui
def solver(p,n,c): # %% define px = py = p nx = n ny = n mesh = CrazyMesh(2, (nx, ny), ((-1, 1), (-1, 1)), c) xi = eta = np.linspace(-1, 1, np.ceil(1000 / (nx * ny)) + 1) # %% exact p(0) func_space_gl0 = FunctionSpace(mesh, '0-lobatto', (px + 1, py + 1), is_inner=False) # p0_exact = Form(func_space_gl0) # p0_exact.discretize(pfun) # p0_exact.reconstruct(xi, eta) # (x, y), data = p0_exact.export_to_plot() # plt.contourf(x, y, data) # plt.title('exact lobatto 0-form, p0') # plt.colorbar() # plt.show() # %% p(0) func_space_gl0 = FunctionSpace(mesh, '0-lobatto', (px + 1, py + 1), is_inner=False) p0 = Form(func_space_gl0) # %% func_space_gl1 = FunctionSpace(mesh, '1-lobatto', (px + 1, py + 1), is_inner=False) uo = Form(func_space_gl1) # %% func_space_eg1 = FunctionSpace(mesh, '1-ext_gauss', (px, py)) ui = Form(func_space_eg1) # %% func_space_eg2 = FunctionSpace(mesh, '2-ext_gauss', (px, py)) f2 = Form(func_space_eg2) f2_exact = Form(func_space_eg2) f2_exact.discretize(ffun) # f2_exact.reconstruct(xi, eta) # (x, y), data = f2_exact.export_to_plot() # plt.contourf(x, y, data) # plt.title('exact extended-gauss 2-form, f2') # plt.colorbar() # plt.show() # %% E10 = d(func_space_gl0) E10_assembled = assemble(mesh, E10, uo.function_space.dof_map.dof_map, p0.function_space.dof_map.dof_map, mode='replace') H = hodge(func_space_gl1) H_assembled = assemble(mesh, H , ui.function_space.dof_map.dof_map_internal, uo.function_space.dof_map.dof_map) #H_assembled = np.linalg.inv(H_assembled) E21 = d(func_space_eg1) E21_assembled = assemble(mesh, E21, f2.function_space.dof_map.dof_map, ui.function_space.dof_map.dof_map, mode = 'replace') # %% #uo.cochain = E10_assembled.dot(p0_exact.cochain) #uo.reconstruct(xi, eta) #(x, y), data_dx, data_dy = uo.export_to_plot() #plt.contourf(x, y, data_dx) #plt.title('test lobatto outer 1-form dx') #plt.colorbar() #plt.show() # #plt.contourf(x, y, data_dy) #plt.title('test lobatto outer 1-form dy') #plt.colorbar() #plt.show() # #cochain_internal = H_assembled.dot(uo.cochain) #ui.cochain = np.concatenate((cochain_internal, np.zeros(ui.function_space.num_dof - ui.basis.num_basis * ui.mesh.num_elements )), axis=0) #ui.reconstruct(xi, eta) #(x, y), data_dx, data_dy = ui.export_to_plot() #plt.contourf(x, y, data_dx) #plt.title('test extended gauss inner 1-form dx') #plt.colorbar() #plt.show() # #plt.contourf(x, y, data_dy) #plt.title('test extended gauss inner 1-form dy') #plt.colorbar() #plt.show() # %% # system: # | I H*E10 | | ui | | 0 | # | | | | = | | # | E21 0 | | p | | f | ui_num_dof_internal = ui.basis.num_basis * ui.mesh.num_elements ui_num_dof_external = ui.function_space.num_dof - ui_num_dof_internal LHS1 = np.hstack(( np.eye(ui_num_dof_internal) , np.zeros((ui_num_dof_internal, ui_num_dof_external)), -H_assembled.dot(E10_assembled) )) LHS3 = np.hstack(( E21_assembled , np.zeros((f2.function_space.num_dof, p0.function_space.num_dof )) )) RHS1 = np.zeros((ui_num_dof_internal, 1 )) RHS3 = f2_exact.cochain.reshape( (f2_exact.function_space.num_dof,1) ) LHS3[-1,:] = 0 LHS3[-1,-1] = 1 RHS3[-1,0] = 0 # %% boundary edges def UBC(mesh, s, p, position): def pullbackedfun_dx(xi, eta): x, y = mesh.mapping(xi, eta, s) return ufun_u(x, y) def pullbackedfun_dy(xi, eta): x, y = mesh.mapping(xi, eta, s) return ufun_v(x, y) def fun2bint_dxi(xi, eta): return pullbackedfun_dx(xi, eta) * mesh.dx_dxi(xi, eta, s) + pullbackedfun_dy(xi, eta) * mesh.dy_dxi(xi, eta, s) def fun2bint_deta(xi, eta): return pullbackedfun_dx(xi, eta) * mesh.dx_deta(xi, eta, s) + pullbackedfun_dy(xi, eta) * mesh.dy_deta(xi, eta, s) UBC_s = np.zeros(shape = (p+1)) extended_gauss_nodes, _ = extended_gauss_quad(p-1) if position == 'Left': for i in range(p+1): # print("hello, Left world") def fun2bint_deta_BC(eta): return fun2bint_deta(-1, eta) UBC_s[i] = quad(fun2bint_deta_BC, extended_gauss_nodes[i], extended_gauss_nodes[i+1] )[0] elif position == 'Right': for i in range(p+1): # print("hello, Right world") def fun2bint_deta_BC(eta): return fun2bint_deta(+1, eta) UBC_s[i] = quad(fun2bint_deta_BC, extended_gauss_nodes[i], extended_gauss_nodes[i+1] )[0] elif position == 'Bottom': for i in range(p+1): # print("hello, Bottom world") def fun2bint_dxi_BC(xi): return fun2bint_dxi(xi, -1) UBC_s[i] = quad(fun2bint_dxi_BC, extended_gauss_nodes[i], extended_gauss_nodes[i+1] )[0] elif position == 'Top': for i in range(p+1): # print("hello, Top world") def fun2bint_dxi_BC(xi): return fun2bint_dxi(xi, +1) UBC_s[i] = quad(fun2bint_dxi_BC, extended_gauss_nodes[i], extended_gauss_nodes[i+1] )[0] return UBC_s def extended_gauss1_general_boundary_edges(mesh, p, gathering_matrix): p+=1 nx = mesh.n_x ny = mesh.n_y Left = np.zeros( shape = (ny*(p+1)), dtype=np.int32 ) Right = np.zeros( shape = (ny*(p+1)), dtype=np.int32 ) Bottom = np.zeros( shape = (nx*(p+1)), dtype=np.int32 ) Top = np.zeros( shape = (nx*(p+1)), dtype=np.int32 ) M = 2 * p * (p+1) N = p+1 UBC_L = UBC_R = UBC_B = UBC_T = 0 for J in range(ny): eleidLeft = J Left[ J*N : J*N + N ] = gathering_matrix[ eleidLeft , M +2*N : M +3*N ] UBC_s=UBC(mesh, eleidLeft, p, "Left") if UBC_L is 0: UBC_L= UBC_s else: UBC_L = np.hstack((UBC_L, UBC_s)) eleidRight = (nx-1)*ny + J Right[ J*N : J*N + N ] = gathering_matrix[ eleidRight, M +3*N : M +4*N ] UBC_s=UBC(mesh, eleidRight, p, "Right") if UBC_R is 0: UBC_R= UBC_s else: UBC_R = np.hstack((UBC_R, UBC_s)) for I in range(nx): eleidBottom = I*ny Bottom[ I*N : I*N + N ] = gathering_matrix[ eleidBottom, M : M + N ] UBC_s=UBC(mesh, eleidBottom, p, "Bottom") if UBC_B is 0: UBC_B= UBC_s else: UBC_B = np.hstack((UBC_B, UBC_s)) eleidTop = I*ny + ny -1 Top[ I*N : I*N + N ] = gathering_matrix[ eleidTop , M + N : M + 2*N ] UBC_s=UBC(mesh, eleidTop, p, "Top") if UBC_T is 0: UBC_T= UBC_s else: UBC_T = np.hstack((UBC_T, UBC_s)) return np.vstack((Left, UBC_L)), np.vstack((Right, UBC_R)), np.vstack((Bottom, UBC_B)), np.vstack((Top, UBC_T)) Left, Right, Bottom, Top = extended_gauss1_general_boundary_edges(mesh, px, ui.function_space.dof_map.dof_map) Boundaryedgs = np.hstack( (Left, Right, Bottom, Top) ) LBC = np.zeros( shape = ( np.shape(Boundaryedgs)[1], ui.function_space.num_dof + p0.function_space.num_dof ) ) RBC = np.zeros( shape = ( np.shape(Boundaryedgs)[1], 1) ) for i in range(np.shape(Boundaryedgs)[1]): LBC[i, int(Boundaryedgs[0, i])] =1 RBC[i] = Boundaryedgs[1, i] #ui.cochain = np.concatenate((cochain_internal, Bottom[1,:], Top[1,:], Left[1,:], Right[1,:])) #f2.cochain = E21_assembled.dot(ui.cochain) #f2.discretize(ffun) #f2.reconstruct(xi, eta) #(x, y), data = f2.export_to_plot() #plt.contourf(x, y, data) #plt.title('test extended-gauss 2-form, f2') #plt.colorbar() #plt.show() #size_Left = np.size( Left ) /2 # %% def dof_map_crazy_lobatto_point_pair(mesh, p, global_numbering): nx, ny = mesh.n_x, mesh.n_y N = p+1 interface_point_pair = np.zeros( ( ( (nx - 1) * ny + nx * (ny - 1) ) * N, 2 ), dtype=np.int32 ) n = 0 for i in range(nx - 1): for j in range(ny): s1 = j + i * ny s2 = j + (i + 1) * ny # print(s1, s2) for m in range(N): interface_point_pair[n, 0] = global_numbering[s1, N * p + m] interface_point_pair[n, 1] = global_numbering[s2, m] # if j < ny-1 and m == N-1: # interface_point_pair[n, 0] = interface_point_pair[n, 1] = 0 n += 1 for i in range(nx): for j in range(ny - 1): s1 = j + i * ny s2 = j + 1 + i * ny # print(s1, s2) for m in range(N): interface_point_pair[n, 0] = global_numbering[s1, (m+1)*N -1] interface_point_pair[n, 1] = global_numbering[s2, m*N] n += 1 return interface_point_pair interface_point_pair = dof_map_crazy_lobatto_point_pair(mesh, px+1, p0.function_space.dof_map.dof_map) Lintface = np.zeros( shape = ( np.shape( interface_point_pair )[0], ui.function_space.num_dof + p0.function_space.num_dof ) ) #Rintface = np.zeros( shape = ( np.shape( interface_point_pair )[0]-(nx-1)*(ny-1), 1) ) Rintface = np.zeros( shape = ( np.shape( interface_point_pair )[0], 1) ) for i in range( np.shape( interface_point_pair )[0] ): if interface_point_pair[i, 0] == interface_point_pair[i, 1] == 0: pass else: Lintface[i, ui.function_space.num_dof + interface_point_pair[i, 0]] = 1 Lintface[i, ui.function_space.num_dof + interface_point_pair[i, 1]] = -1 # %% #Lintface=Lintface[~np.all(Lintface == 0, axis=1)] LHS = np.vstack( (LHS1, LHS3, Lintface, LBC) ) RHS = np.vstack( (RHS1, RHS3, Rintface, RBC) ) #rrefLHS = np.array(Matrix(LHS).rref()[0]).astype(None) #print(rrefLHS) # solution= np.linalg.lstsq(LHS,RHS) sLHS = sparse.csr_matrix(LHS) solution = sparse.linalg.lsqr(sLHS,RHS) Res = solution[0].reshape((np.size(solution[0]),1)) residual = np.sum(np.abs(LHS.dot(Res) - RHS)) print("residual=",residual) # %% ui.cochain = Res[0:ui.function_space.num_dof].reshape(ui.function_space.num_dof) p0.cochain = Res[-p0.function_space.num_dof:].reshape(p0.function_space.num_dof) # %% view the result p0.reconstruct(xi, eta) (x, y), data = p0.export_to_plot() plt.contourf(x, y, data) plt.title('solution lobatto 0-form, p0') plt.colorbar() plt.show() print('p0 max:', np.max(data)) print('p0 min:', np.min(data)) # # ui.reconstruct(xi, eta) (x, y), data_dx, data_dy = ui.export_to_plot() plt.contourf(x, y, data_dx) plt.title('solution extended_gauss 1-form dx') plt.colorbar() plt.show() print('ui max:', np.max(data_dx)) print('ui min:', np.min(data_dx)) plt.contourf(x, y, data_dy) plt.title('solution extended_gauss 1-form dy') plt.colorbar() plt.show() print('ui max:', np.max(data_dy)) print('ui min:', np.min(data_dy)) L2_error_p0 = p0.l_2_norm(pfun, ('gauss', 40))[0] print(L2_error_p0) L2_error_ui = ui.l_2_norm((ufun_u, ufun_v), ('lobatto', 40))[0] print(L2_error_ui) return L2_error_p0, L2_error_ui
def single_element(): mesh = CrazyMesh(2, (1, 1), ((-1, 1), (-1, 1)), curvature=0.1) p = 20, 20 func_space_vort = FunctionSpace(mesh, '0-ext_gauss', (p[0] - 1, p[1] - 1), is_inner=False) func_space_outer_vel = FunctionSpace( mesh, '1-ext_gauss', (p[0] - 2, p[1] - 2), is_inner=False) func_space_inner_vel = FunctionSpace(mesh, '1-lobatto', p, is_inner=True) func_space_source = FunctionSpace(mesh, '2-lobatto', p, is_inner=True) basis_vort = BasisForm(func_space_vort) basis_vel_in = BasisForm(func_space_inner_vel) basis_vel_out = BasisForm(func_space_outer_vel) basis_2 = BasisForm(func_space_source) psi = Form(func_space_vort) u_in = Form(func_space_inner_vel) source = Form(func_space_source) source.discretize(ffun) M_1 = inner(basis_vel_in, basis_vel_in) W_11 = basis_vel_out.wedged(basis_vel_in) E_10_ext = d(func_space_vort) E_21_in = d(func_space_inner_vel) W_02 = basis_vort.wedged(basis_2) print("shapes : \n \ M_1 : {0} \n \ W_11 : {1} \n \ E_10 : {2} \n \ E_21_in : {3} \n \ W_02 : {4} \n" .format(np.shape(M_1), np.shape(W_11), np.shape(E_10_ext), np.shape(E_21_in), np.shape(W_02))) # one element # print(func_space_inner_vel.num_dof, func_space_vort.num_dof) lhs_0 = np.hstack((M_1[:, :, 0], np.transpose(W_02 @ E_21_in))) col_size_0 = np.shape(lhs_0)[1] eW = W_02 @ E_21_in col_zeros = col_size_0 - np.shape(eW)[1] lhs_1 = np.hstack((eW, np.zeros( (func_space_source.num_dof, col_zeros)))) lhs = np.vstack((lhs_0, lhs_1)) rhs_source = (source.cochain @ W_02)[:, np.newaxis] rhs_zeros = np.zeros((np.shape(lhs)[0] - func_space_source.num_dof, 1)) rhs = np.vstack((rhs_zeros, rhs_source)) print(np.shape(lhs)) solution = np.linalg.solve(lhs, rhs).flatten() print(np.shape(solution)) print(func_space_vort.num_dof) u_in.cochain = solution[:func_space_inner_vel.num_dof] psi_zeros = np.zeros((func_space_vort.num_dof - func_space_vort.num_internal_local_dof)) psi.cochain = np.append(solution[func_space_inner_vel.num_dof:], np.zeros((func_space_vort.num_dof - func_space_vort.num_internal_local_dof))) xi = eta = np.linspace(-1, 1, 40) u_in.reconstruct(xi, eta) (x, y), u_x, u_y = u_in.export_to_plot() plt.contourf(x, y, u_x) plt.colorbar() plt.title("u_x inner") plt.show() psi.reconstruct(xi, eta) (x, y), psi_value = psi.export_to_plot() plt.contourf(x, y, psi_value) plt.title("psi outer" ) plt.colorbar() plt.show()
# # solution = sparse.linalg.spsolve(lhs, rhs) # # phi_2.cochain = solution[-func_space_2_lobatto.num_dof:] # # # # # sample the solution # # xi = eta = np.linspace(-1, 1, 200) # # phi_2.reconstruct(xi, eta) # # (x, y), data = phi_2.export_to_plot() # # plt.contourf(x, y, data) # # plt.show() # # # # solve for unknowns M_1k = inner(basis_1, basis_1, anisotropic_tensor) N_2 = inner(basis_2, d(basis_1)) M_2 = inner(basis_2, basis_2) # assemble inner products M_1k = assemble(M_1k, func_space_1_lobatto) N_2 = assemble(N_2, (func_space_2_lobatto, func_space_1_lobatto)) M_2 = assemble(M_2, func_space_2_lobatto) lhs = sparse.bmat([[M_1k, N_2.transpose()], [N_2, None]]).tolil() rhs_source = (form_source.cochain @ M_2)[:, np.newaxis] rhs_zeros = np.zeros(lhs.shape[0] - np.size(rhs_source))[:, np.newaxis] rhs = np.vstack((rhs_zeros, rhs_source)) # print(func_space_1_lobatto.dof_map.dof_map_boundary) bottom, top, left, right = func_space_1_lobatto.dof_map.dof_map_boundary # flux = 0 lhs[bottom] = 0 lhs[bottom, bottom] = 1
#H11_assembled = -assemble(H11, ui.function_space,uo.function_space) #ui_num_dof_internal = ui.basis.num_basis * ui.mesh.num_elements p0_num_dof_internal = p0.basis.num_basis * ui.mesh.num_elements # %% LHS 11 Mnm1 = inner(uo.basis, uo.basis) Mnm1_assembled = assemble(Mnm1, uo.function_space, uo.function_space) # %% LHS 21 W0n = f2.basis.wedged(p0.basis) W0n_assembled = assemble_(mesh, W0n, p0.function_space.dof_map.dof_map_internal, f2.function_space.dof_map.dof_map, mode='add') E21 = d(func_space_gl1) #E21_assembled = assemble_(mesh, E21, f2.function_space.dof_map.dof_map, # uo.function_space.dof_map.dof_map, mode='replace') LHS21_local = W0n.dot(E21) LHS12_local = LHS21_local.T LHS12_add = sparse.lil_matrix((np.shape(LHS21_local)[1], (px + 1) * 4)) Wb = integral1d_(1, ('lobatto_edge', px + 1), ('gauss_node', px + 1), ('gauss', px + 5)) P = (p + 1) * (p + 2) Q = (p + 1)**2 M = p + 1 for i in range(p + 1): for j in range(p + 1):
def multiple_element_v1(): mesh = CrazyMesh(2, (1, 1), ((-1, 1), (-1, 1)), curvature=0.0) p = 4, 4 func_space_vort = FunctionSpace(mesh, '0-lobatto', p, is_inner=False) func_space_outer_vel = FunctionSpace( mesh, '1-lobatto', p, is_inner=False) func_space_outer_vel.dof_map.continous_dof = True # func_space_outer_vel = FunctionSpace( # mesh, '1-gauss', (p[0], p[1]), is_inner=False) func_space_inner_vel = FunctionSpace( mesh, '1-gauss', (p[0], p[1]), is_inner=True) print('dof gauss :', func_space_inner_vel.num_dof) func_space_inner_vel.dof_map.continous_dof = False func_space_source = FunctionSpace(mesh, '2-gauss', (p[0] + 1, p[1] + 1), is_inner=True) print("dof source :", func_space_source.num_dof) basis_vort = BasisForm(func_space_vort) basis_vel_in = BasisForm(func_space_inner_vel) basis_vel_in.quad_grid = 'lobatto' basis_vel_out = BasisForm(func_space_outer_vel) basis_vel_out.quad_grid = 'lobatto' basis_2 = BasisForm(func_space_source) psi = Form(func_space_vort) u_in = Form(func_space_inner_vel) source = Form(func_space_source) source.discretize(ffun) M_1 = inner(basis_vel_in, basis_vel_in) # E_21_in = d(func_space_inner_vel) W_02 = basis_2.wedged(basis_vort) W_11 = basis_vel_in.wedged(basis_vel_out) E_10_out = d(func_space_vort) print(np.shape(W_11), np.shape(E_10_out)) W_E = W_11 @ E_10_out W_11_inv = basis_vel_out.wedged(basis_vel_in) E_W = np.transpose(E_10_out) @ W_11_inv print("shape ew : ", np.shape(W_E)) print(np.shape(W_02)) M_1 = assemble(M_1, (func_space_inner_vel, func_space_inner_vel)) print(func_space_source.num_local_dof) W_E = assemble(W_E, (func_space_outer_vel, func_space_vort)) E_W = assemble(E_W, (func_space_vort, func_space_outer_vel)) W_02 = assemble(W_02, (func_space_vort, func_space_source)) lhs = spr.bmat([[M_1, W_E], [W_E.transpose(), None]]) rhs = np.zeros(np.shape(lhs)[0]) rhs[-func_space_source.num_dof:] = W_02 @ source.cochain solution = spr.linalg.spsolve(lhs.tocsc(), rhs) u_in.cochain = solution[:func_space_inner_vel.num_dof] psi.cochain = solution[-func_space_vort.num_dof:] xi = eta = np.linspace(-1, 1, 40) u_in.reconstruct(xi, eta) (x, y), u_x, u_y = u_in.export_to_plot() plt.contourf(x, y, u_x) plt.colorbar() plt.title("u_x inner") plt.show() psi.reconstruct(xi, eta) (x, y), psi_value = psi.export_to_plot() plt.contourf(x, y, psi_value) plt.title("psi outer") plt.colorbar() plt.show()