Пример #1
0
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()
Пример #2
0
    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
    virtual_E21[vol_id - px**2, edge_id] = 1
    virtual_E21[vol_id - px**2 + px, edge_id + px] = -1

# define the mass and wedge matrices

M_1 = inner(basis_1, basis_1)
M1_assembled = assemble(M_1, (func_space_1_lobatto, func_space_1_lobatto))

W_i_2 = basis_2.wedged(basis_0)
Wi_2_E_21 = np.dot(W_i_2, E21)

lhs = sparse.bmat(
    [[M1_assembled,
      Wi_2_E_21.transpose(),
      virtual_E21.transpose()], [Wi_2_E_21, None, None],
     [virtual_E21, None, None]]).tolil()

rhs_1 = np.zeros(2 * px * (px + 1))
rhs_2 = np.dot(W_i_2, source_form.cochain)
rhs_3 = np.zeros(4 * px)
rhs = np.hstack((rhs_1, rhs_2, rhs_3))

# implementing BC's
    elements_layout[1] + 1) + py * elements_layout[1] * (elements_layout[0] +
                                                         1)
num_local_element_edges = 2 * px * (px + 1)
num_total_edges = func_space_1_lobatto.num_dof
num_total_surfaces = func_space_2_lobatto.num_dof
num_local_surfaces = func_space_2_lobatto.num_local_dof

dof_map_ext_gauss_nodes = func_space_0_ext_gauss.dof_map.dof_map
dof_map_lobatto_edges_discontinous = func_space_1_lobatto.dof_map.dof_map
dof_map_lobatto_faces = dof_map_ext_gauss_nodes
"""Define 1-form mass matrix"""
M_1 = inner(basis_1, basis_1)
M1_assembled = assemble(M_1, (func_space_1_lobatto, func_space_1_lobatto))
"""Define wedge 1"""
E21 = d_21_lobatto_outer(p)
W1 = basis_2.wedged(basis_0)

W1_E21 = np.dot(W1, E21)
W1_E21_3D = np.repeat(W1_E21[:, :, np.newaxis], num_total_elements, axis=2)

W1_E21_assembled = assemble(W1_E21_3D,
                            (func_space_0_ext_gauss, func_space_1_lobatto))
"""Define Wedge 2"""
"""Define the second wedge / duality pairing / element connectivity matrix"""
virtual_E21 = d_21_lobatto_outer_virtual(p)
W2 = wedge_2()

W2_vE21 = np.dot(W2, virtual_E21)
W2_vE21_3D = np.repeat(W2_vE21[:, :, np.newaxis], num_total_elements, axis=2)

W2_vE21_assembled = assemble_virtual_E21(W2_vE21_3D)
Пример #4
0
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()
Пример #5
0
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()
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()