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_weighted_inner_continous(self):
     """Test for weighted inner product."""
     mesh = CrazyMesh(2, (2, 2), ((-1, 1), (-1, 1)), curvature=0.2)
     func_space = FunctionSpace(mesh, '1-lobatto', (3, 4))
     basis = BasisForm(func_space)
     basis.quad_grid = 'gauss'
     K = MeshFunction(mesh)
     K.continous_tensor = [diff_tens_11, diff_tens_12, diff_tens_22]
     M_1_weighted = inner(basis, basis, K)
     M_1 = inner(basis, basis)
     npt.assert_array_almost_equal(M_1, M_1_weighted)
 def test_weighted_metric(self):
     # TODO: figure out why if the metric tensor is set to ones the result is very different
     """Compare weighted and unweighted metric terms with K set to identity."""
     mesh = CrazyMesh(2, (1, 1), ((-1, 1), (-1, 1)), curvature=0.2)
     K = MeshFunction(mesh)
     func_space = FunctionSpace(mesh, '1-lobatto', (3, 3))
     basis = BasisForm(func_space)
     K.continous_tensor = [diff_tens_11, diff_tens_12, diff_tens_22]
     xi = eta = np.linspace(-1, 1, 5)
     xi, eta = np.meshgrid(xi, eta)
     g_11_k, g_12_k, g_22_k = basis.weighted_metric_tensor(xi.ravel('F'), eta.ravel('F'), K)
     g_11, g_12, g_22 = mesh.metric_tensor(xi.ravel('F'), eta.ravel('F'))
     npt.assert_array_almost_equal(g_11, g_11_k)
 def test_inner(self):
     """Test inner product of one forms."""
     list_cases = ['p2_n2-2', 'p2_n3-2',
                   'p5_n1-10', 'p10_n2-2', 'p13_n12-8']
     p = [2, 2, 5, 10, 13]
     n = [(2, 2), (3, 2), (1, 10), (2, 2), (12, 8)]
     curvature = [0.1, 0.1, 0.1, 0.1, 0.1]
     for i, case in enumerate(list_cases[:-1]):
         M_1_ref = np.loadtxt(
             os.getcwd() + '/src/tests/test_M_1/M_1k_' + case + '.dat', delimiter=',').reshape(2 * p[i] * (p[i] + 1),  n[i][0] * n[i][1], 2 * p[i] * (p[i] + 1))
         my_mesh = CrazyMesh(
             2,  n[i], ((-1, 1), (-1, 1)), curvature=curvature[i])
         function_space = FunctionSpace(my_mesh, '1-lobatto', p[i])
         form = BasisForm(function_space)
         form.quad_grid = 'gauss'
         form_1 = BasisForm(function_space)
         form_1.quad_grid = 'gauss'
         K = MeshFunction(my_mesh)
         K.continous_tensor = [diff_tens_11, diff_tens_12, diff_tens_22]
         M_1 = inner(form, form_1, K)
         for el in range(n[i][0] * n[i][1]):
             npt.assert_array_almost_equal(
                 M_1_ref[:, el, :], M_1[:, :, el])
Exemple #6
0

gamma = (gamma1, gamma2, gamma3, gamma4)
dgamma = (dgamma1, dgamma2, dgamma3, dgamma4)

ref_mesh = TransfiniteMesh(dim, elements_layout, gamma, dgamma)

func_space_1_lobatto = FunctionSpace(ref_mesh, '1-lobatto', p, primal_is_inner)
func_space_1_lobatto.dof_map.continous_dof = False

func_space_0_ext_gauss = FunctionSpace(ref_mesh, '0-ext_gauss', p2,
                                       primal_is_inner)

func_space_2_lobatto = FunctionSpace(ref_mesh, '2-lobatto', p, primal_is_inner)

anisotropic_tensor = MeshFunction(ref_mesh)
anisotropic_tensor.discrete_tensor = [k_11(), k_12(), k_22()]

source_form = Form(func_space_2_lobatto)
source_form.discretize(source)

phi_0_exact = Form(func_space_0_ext_gauss)
phi_0_exact.discretize(manufactured_solution)

print(np.shape(phi_0_exact.cochain))
print(phi_0_exact.cochain)
# define basis forms from function space

basis_0 = BasisForm(func_space_0_ext_gauss)
basis_1 = BasisForm(func_space_1_lobatto)
basis_2 = BasisForm(func_space_2_lobatto)
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()
    row_idx = [value - 1 for value in row_idx]
    column_idx = [value - 1 for value in column_idx]
    data = 10**-6 * np.ones(np.size(row_idx))
    k_11 = coo_matrix((data, (row_idx, column_idx)), shape=(20, 20)).toarray().ravel('F')
    k_11[np.where(k_11 < 10**-12)] = 1
    return k_11.reshape(1, 400)


def k_12(): return np.zeros((1, 400))


def k_22():
    return k_11()


anisotropic_tensor = MeshFunction(sand_shale_mesh)
anisotropic_tensor.discrete_tensor = [k_11(), k_12(), k_22()]

# define source term


def source(x, y):
    return np.zeros(np.shape(x))


form_source = Form(func_space_2_lobatto)
form_source.discretize(source)

# define basis forms

basis_1 = BasisForm(func_space_1_lobatto)