Exemple #1
0
    def test_assembly_inner_product_2_forms(self):
        """Test the assembly of 1-forms inner products."""
        func_space_lob = FunctionSpace(self.mesh, '2-lobatto', self.p)
        func_space_gauss = FunctionSpace(self.mesh, '2-gauss', self.p)
        func_space_extgauss = FunctionSpace(self.mesh, '2-ext_gauss', self.p)

        basis_lob = BasisForm(func_space_lob)
        basis_lob.quad_grid = 'gauss'
        M_lob = inner(basis_lob, basis_lob)

        basis_gauss = BasisForm(func_space_gauss)
        basis_gauss.quad_grid = 'lobatto'
        M_gauss = inner(basis_gauss, basis_gauss)

        basis_ext_gauss = BasisForm(func_space_extgauss)
        print(basis_ext_gauss.num_basis)
        basis_ext_gauss.quad_grid = 'lobatto'
        M_extgauss = inner(basis_ext_gauss, basis_ext_gauss)

        M_lob_ass_ref = assemble_slow(self.mesh, M_lob, func_space_lob.dof_map.dof_map,
                                      func_space_lob.dof_map.dof_map)
        M_gauss_ass_ref = assemble_slow(self.mesh, M_gauss, func_space_gauss.dof_map.dof_map,
                                        func_space_gauss.dof_map.dof_map)
        M_extgauss_ass_ref = assemble_slow(
            self.mesh, M_extgauss, func_space_extgauss.dof_map.dof_map_internal, func_space_extgauss.dof_map.dof_map_internal)

        M_lob_ass = assemble(M_lob, func_space_lob, func_space_lob).toarray()
        M_gauss_ass = assemble(M_gauss, func_space_gauss, func_space_gauss).toarray()
        M_extgauss_ass = assemble(M_extgauss, func_space_extgauss,
                                  func_space_extgauss).toarray()

        npt.assert_array_almost_equal(M_lob_ass_ref, M_lob_ass)
        npt.assert_array_almost_equal(M_gauss_ass_ref, M_gauss_ass)
        npt.assert_array_almost_equal(M_extgauss_ass_ref, M_extgauss_ass)
Exemple #2
0
 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)
Exemple #3
0
    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_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)
Exemple #7
0
    def test_inner(self):
        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]):
            print("Test case n : ", i)
            # basis = basis_forms.
            # print("theo size ", (p[i] + 1)**2 *
            #       (p[i] + 1)**2 * n[i][0] * n[i][1])
            M_2_ref = np.loadtxt(
                os.getcwd() + '/src/tests/test_M_2/M_2_' + case + '.dat',
                delimiter=',').reshape((p[i])**2, n[i][0] * n[i][1], (p[i])**2)
            # print("actual size ", np.size(M_0_ref))

            # print(np.shape(M_0_ref))
            my_mesh = CrazyMesh(2,
                                n[i], ((-1, 1), (-1, 1)),
                                curvature=curvature[i])
            function_space = FunctionSpace(my_mesh, '2-lobatto', p[i])
            basis_0 = BasisForm(function_space)
            basis_0.quad_grid = 'lobatto'
            basis_1 = BasisForm(function_space)
            basis_1.quad_grid = 'lobatto'
            M_2 = inner(basis_0, basis_1)
            # print("REF ------------------ \n", M_2_ref[:, 0, :])
            # print("CALCULATED _----------------\n", M_2[:, :, 0])
            for el in range(n[i][0] * n[i][1]):
                npt.assert_array_almost_equal(M_2_ref[:, el, :],
                                              M_2[:, :, el],
                                              decimal=7)
Exemple #8
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()
Exemple #9
0
    def test_inner(self):
        list_cases = [
            'p2_n2-2', 'p2_n3-2', 'p5_n1-10', 'p10_n2-2', 'p18_n14-14'
        ]
        p = [2, 2, 5, 10, 18]
        n = [(2, 2), (3, 2), (1, 10), (2, 2), (14, 10)]
        curvature = [0.2, 0.1, 0.2, 0.2, 0.2]
        for i, case in enumerate(list_cases[:-1]):
            print("Test case n : ", i)
            # basis = basis_forms.
            # print("theo size ", (p[i] + 1)**2 *
            #       (p[i] + 1)**2 * n[i][0] * n[i][1])
            M_0_ref = np.loadtxt(
                os.getcwd() + '/src/tests/test_M_0/M_0_' + case + '.dat',
                delimiter=',').reshape((p[i] + 1)**2, n[i][0] * n[i][1],
                                       (p[i] + 1)**2)

            # print(np.shape(M_0_ref))
            my_mesh = CrazyMesh(2,
                                n[i], ((-1, 1), (-1, 1)),
                                curvature=curvature[i])
            function_space = FunctionSpace(my_mesh, '0-lobatto', p[i])
            basis = BasisForm(function_space)
            basis.quad_grid = 'lobatto'
            basis_1 = BasisForm(function_space)
            basis_1.quad_grid = 'lobatto'
            M_0 = inner(basis, basis_1)
            for el in range(n[i][0] * n[i][1]):
                npt.assert_array_almost_equal(M_0_ref[:, el, :],
                                              M_0[:, :, el],
                                              decimal=4)
Exemple #10
0
def hodge_from_func_space(function_space, extend):
    """Calculate the hodge matrix  from the function space."""
    dual_space = DualSpace(function_space, extend)
    dual_form = Form(dual_space)
    form = Form(function_space)
    wedge_prod = form.basis.wedged(dual_form.basis)
    inner_prod = inner(dual_form.basis, dual_form.basis)
    inverse_inner = inv(np.rollaxis(inner_prod, 2, 0))
    hodge_matrix = np.tensordot(inverse_inner, wedge_prod, axes=((2), (0)))
    hodge_matrix = np.moveaxis(hodge_matrix, 0, -1)
    return hodge_matrix
Exemple #11
0
def hodge_from_form(form, extend):
    """Calculate the hodge matrix and resulting form."""
    dual_space = DualSpace(form.function_space, extend)
    dual_form = Form(dual_space)
    wedge_prod = form.basis.wedged(dual_form.basis)
    inner_prod = inner(dual_form.basis, dual_form.basis)
    inverse_inner = inv(np.rollaxis(inner_prod, 2, 0))
    hodge_matrix = np.tensordot(inverse_inner, wedge_prod, axes=((2), (0)))
    dual_form.cochain_local = np.einsum('kij,jk->ik', hodge_matrix,
                                        form.cochain_local)
    hodge_matrix = np.moveaxis(hodge_matrix, 0, -1)
    return dual_form, hodge_matrix
 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 #13
0
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
    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))
Exemple #14
0
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
    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

# anisotropic_tensor =
M_1 = inner(basis_1, basis_1, anisotropic_tensor)
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
#Wn0_assembled = assemble_(mesh, Wn0, f2.function_space.dof_map.dof_map,
#                          p0.function_space.dof_map.dof_map_internal,mode='add')
#
#Mn           = inner   (    f2.basis,          f2.basis)
#Mn_assembled = assemble(Mn, f2.function_space, f2.function_space)
#
#M0           = inner   (    p0.basis         , p0.basis)
#M0_assembled = assemble(M0, p0.function_space, p0.function_space)
#
#H11           = hodge    (func_space_gl1)
#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)
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()
Exemple #17
0
def solver(p, n, c):
    print("----------------------------------------------------")
    print('p=', p, ';n=', n, ';c=', c, ':')
    px = py = p
    nx = ny = n
    mesh = CrazyMesh(2, (nx, ny), ((0, 1), (0, 1)), c)
    #    xi = eta = np.linspace( -1, 1, np.ceil(100 / (nx * ny)) + 1 )

    # %% define function space
    #    func_space_g0  = FunctionSpace(mesh, '0-gauss'  , (px + 1, py + 1), is_inner=False)
    #    func_space_g1  = FunctionSpace(mesh, '1-gauss'  , (px + 1, py + 1), is_inner=False)
    func_space_gl0 = FunctionSpace(mesh,
                                   '0-lobatto', (px + 1, py + 1),
                                   is_inner=False,
                                   separated_dof=False)
    func_space_gl1 = FunctionSpace(mesh,
                                   '1-lobatto', (px + 1, py + 1),
                                   is_inner=False)
    func_space_gl2 = FunctionSpace(mesh,
                                   '2-lobatto', (px + 1, py + 1),
                                   is_inner=False)
    func_space_eg0 = FunctionSpace(mesh, '0-ext_gauss', (px, py))
    #    func_space_eg1 = FunctionSpace(mesh, '1-ext_gauss', (px, py))
    #    func_space_eg2 = FunctionSpace(mesh, '2-ext_gauss', (px, py))

    # %%
    un1 = Form(func_space_gl1)
    f0 = Form(func_space_eg0)
    fn = Form(func_space_gl2)
    wn2 = Form(func_space_gl0)
    #wn2 = Form(func_space_g0)

    un1_exact = Form(func_space_gl1)
    un1_exact.discretize((v, u))
    rn1 = Form(func_space_gl1)
    rn1.discretize((r_v, r_u))

    # %% LHS 24 and LHS 42
    def d_21_lobatto_outer(p):
        px, py = p
        total_vol = px * py
        total_edges = px * (py + 1) + py * (px + 1)
        E21 = np.zeros((total_vol, total_edges))

        for i in range(px):
            for j in range(py):
                volij = i * py + j
                edge_bottom = i * (py + 1) + j
                edge_top = i * (py + 1) + j + 1
                edge_left = (py + 1) * px + i * py + j
                edge_right = (py + 1) * px + (i + 1) * py + j

                E21[volij, edge_left] = -1
                E21[volij, edge_right] = +1
                E21[volij, edge_bottom] = +1
                E21[volij, edge_top] = -1
        return E21

    glE21 = d_21_lobatto_outer((px + 1, py + 1))

    W0n = fn.basis.wedged(f0.basis)
    LHS13_local = W0n.dot(glE21)
    LHS31_local = LHS13_local.T

    Wb = integral1d_(1, ('lobatto_edge', p + 1), ('gauss_node', p + 1),
                     ('gauss', p + 1))
    LHS31_add = sparse.lil_matrix((2 * (p + 1) * (p + 2), 4 * (p + 1)))
    M = (p + 1) * (p + 2)
    N = p + 1
    E = p + 2
    for i in range(N):
        for j in range(N):
            # left
            LHS31_add[M + i, j] = +Wb[i, j]
            # right
            LHS31_add[-N + i, N + j] = -Wb[i, j]
            # bottom
            LHS31_add[i * E, 2 * N + j] = -Wb[i, j]
            #        # top
            LHS31_add[(i + 1) * E - 1, 3 * N + j] = +Wb[i, j]

    LHS31_local = sparse.hstack((LHS31_local, LHS31_add))
    LHS31 = assemble(LHS31_local.toarray(),
                     (un1.function_space, f0.function_space))

    LHS13_local = sparse.vstack((LHS13_local, LHS31_add.T))
    LHS13 = sparse.lil_matrix(
        assemble(LHS13_local.toarray(),
                 (f0.function_space, un1.function_space)))

    # %% LHS 11
    f0.basis.quad_grid = ('gauss', px + 1)
    egM0 = inner(f0.basis, f0.basis)
    LHS11 = assemble(egM0, (func_space_eg0, func_space_eg0))
    temp = sparse.lil_matrix(
        (f0.function_space.num_dof, f0.function_space.num_dof))
    temp[0:f0.function_space.num_internal_dof,
         0:f0.function_space.num_internal_dof] = LHS11
    LHS11 = temp

    # %% LHS 22
    wn2.basis.quad_grid = ('lobatto', px + 1)
    glMn2 = inner(wn2.basis, wn2.basis)
    LHS22 = assemble(glMn2, (func_space_gl0, func_space_gl0))

    #wn2.basis.quad_grid = ( 'gauss', px+1 )
    #glMn2 = inner(wn2.basis, wn2.basis)
    #LHS22 = assemble(glMn2, (func_space_g0, func_space_g0))

    # %% LHS 23 , 32
    def d_10_lobatto_outer(p):
        px, py = p
        total_edges = px * (py + 1) + py * (px + 1)
        total_nodes = (px + 1) * (py + 1)
        E10 = np.zeros((total_edges, total_nodes))

        for i in range(px):
            for j in range(py + 1):
                edgeij = i * (py + 1) + j
                node_1 = i * (py + 1) + j
                node_2 = (i + 1) * (py + 1) + j

                E10[edgeij, node_1] = +1
                E10[edgeij, node_2] = -1

        for i in range(px + 1):
            for j in range(py):
                edgeij = px * (py + 1) + py * i + j
                node_1 = i * (py + 1) + j
                node_2 = i * (py + 1) + j + 1

                E10[edgeij, node_1] = +1
                E10[edgeij, node_2] = -1

        return -E10

    glE10 = d_10_lobatto_outer((px + 1, py + 1))
    glE10 = assemble(glE10, (func_space_gl1, func_space_gl0))

    glMn1 = inner(un1.basis, un1.basis)
    glMn1 = assemble(glMn1, (func_space_gl1, func_space_gl1))
    LHS32 = glMn1.dot(glE10)
    LHS23 = LHS32.T

    #def d_10_gauss_outer(p):
    #    px, py = p
    #    total_edges = px * (py + 1) + py * (px + 1)
    #    total_nodes = (px + 1) * (py + 1)
    #    E10 = np.zeros((total_edges, total_nodes))
    #
    #    for i in range(px):
    #        for j in range(py + 1):
    #            edgeij = i * (py + 1) + j
    #            node_1 = i * (py + 1) + j
    #            node_2 = (i + 1) * (py + 1) + j
    #
    #            E10[edgeij, node_1] = +1
    #            E10[edgeij, node_2] = -1
    #
    #    for i in range(px + 1):
    #        for j in range(py):
    #            edgeij = px * (py + 1) + py * i + j
    #            node_1 = i * (py + 1) + j
    #            node_2 = i * (py + 1) + j + 1
    #
    #            E10[edgeij, node_1] = +1
    #            E10[edgeij, node_2] = -1
    #
    #    return -E10
    #
    #glE10 = d_10_gauss_outer((px+1, py+1))
    #glE10 = assemble(glE10, (func_space_g1, func_space_g0))
    #
    #glMn1 = inner(un1.basis, Form(func_space_g1).basis )
    #glMn1 = assemble(glMn1, (func_space_gl1, func_space_g1))
    #LHS32 = glMn1.dot(glE10)
    #LHS23 = LHS32.T

    # %% boundary edges
    def lobatto_boundary_edges(mesh, p, gathering_matrix):

        nx = mesh.n_x
        ny = mesh.n_y

        Left = np.zeros(shape=(ny * (p)), dtype=np.int32)
        Right = np.zeros(shape=(ny * (p)), dtype=np.int32)
        Bottom = np.zeros(shape=(nx * (p)), dtype=np.int32)
        Top = np.zeros(shape=(nx * (p)), dtype=np.int32)

        M = p * (p + 1)
        N = p

        for J in range(ny):
            eleidLeft = J
            Left[J * N:J * N + N] = gathering_matrix[eleidLeft, M:M + N]

            eleidRight = (nx - 1) * ny + J
            Right[J * N:J * N + N] = gathering_matrix[eleidRight, -N:]

        for I in range(nx):
            eleidBottom = I * ny
            Bottom[I * N:I * N + N] = gathering_matrix[eleidBottom, 0:M:N + 1]

            eleidTop = I * ny + ny - 1
            Top[I * N:I * N + N] = gathering_matrix[eleidTop, N:M:N + 1]

        return Left, Right, Bottom, Top

    eLeft, eRight, eBottom, eTop = lobatto_boundary_edges(
        mesh, p + 1, un1.function_space.dof_map.dof_map)

    def ext_gauss_boundary_points(mesh, p, gathering_matrix):
        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

    nLeft, nRight, nBottom, nTop = ext_gauss_boundary_points(
        mesh, p + 1, f0.function_space.dof_map.dof_map)

    RHS1 = np.zeros(shape=(f0.function_space.num_dof, 1))
    for i in range(np.size(nLeft)):
        LHS13[nLeft[i], :] = 0
        LHS13[nLeft[i], eLeft[i]] = 1
        RHS1[nLeft[i]] = un1_exact.cochain[eLeft[i]]

        LHS13[nRight[i], :] = 0
        LHS13[nRight[i], eRight[i]] = 1
        RHS1[nRight[i]] = un1_exact.cochain[eRight[i]]

        LHS13[nBottom[i], :] = 0
        LHS13[nBottom[i], eBottom[i]] = 1
        RHS1[nBottom[i]] = un1_exact.cochain[eBottom[i]]

        LHS13[nTop[i], :] = 0
        LHS13[nTop[i], eTop[i]] = 1
        RHS1[nTop[i]] = un1_exact.cochain[eTop[i]]

    # %%
    LHS = sparse.bmat([[
        LHS11,
        sparse.csc_matrix(
            (f0.function_space.num_dof, wn2.function_space.num_dof)), LHS13
    ],
                       [
                           sparse.csc_matrix((wn2.function_space.num_dof,
                                              f0.function_space.num_dof)),
                           LHS22, -LHS23
                       ],
                       [
                           LHS31, -LHS32,
                           sparse.csc_matrix((un1.function_space.num_dof,
                                              un1.function_space.num_dof))
                       ]])

    # %% RHS2
    RHS2 = np.zeros(shape=(wn2.function_space.num_dof, 1))

    # %% RHS3
    RHS3 = glMn1.dot(rn1.cochain)
    RHS3 = np.expand_dims(RHS3, axis=1)

    #%% solve it
    RHS = np.vstack((RHS1, RHS2, RHS3))
    print("LHS shape:", np.shape(LHS))
    #
    LHS = sparse.csr_matrix(LHS)
    print("------ solve the square sparse system:......")
    Res = sparse.linalg.spsolve(LHS, RHS)

    # %% split the Res
    f0.cochain = Res[:f0.function_space.num_dof].reshape(
        f0.function_space.num_dof)
    wn2.cochain = Res[f0.function_space.
                      num_dof:-un1.function_space.num_dof].reshape(
                          wn2.function_space.num_dof)
    un1.cochain = Res[-un1.function_space.num_dof:].reshape(
        un1.function_space.num_dof)

    # %%
    #f0.reconstruct(xi, eta)
    #(x, y), data = f0.export_to_plot()
    #plt.contourf(x, y, data)
    #plt.title("3). ext_gauss \\tilde{f}^{(0)}")
    #plt.colorbar()
    #plt.show()
    #
    #wn2.reconstruct(xi, eta)
    #(x, y), data = wn2.export_to_plot()
    #plt.contourf(x, y, data)
    #plt.title('8). lobatto w^{(n-2)}')
    #plt.colorbar()
    #plt.show()
    #
    #un1.reconstruct(xi, eta)
    #(x, y), data_dx, data_dy = un1.export_to_plot()
    #plt.contourf(x, y, data_dx)
    #plt.title('1.1). lobatto u^{(n-1)} dx')
    #plt.colorbar()
    #plt.show()
    #
    #plt.contourf(x, y, data_dy)
    #plt.title('1.2). lobatto u^{(n-1)} dy')
    #plt.colorbar()
    #plt.show()

    # %%
    L2_error_un1 = un1.l_2_norm((v, u), ('lobatto', p + 5))[0]

    def wn2_fun(x, y):
        return 0 * x * y

    L2_error_wn2 = wn2.l_2_norm(wn2_fun, ('lobatto', p + 5))[0]

    def f0_fun(x, y):
        return 4 * np.pi * np.sin(2 * np.pi * x) * np.sin(2 * np.pi * y)

    L2_error_f0 = f0.l_2_norm(f0_fun, ('gauss', p + 5))[0]

    print("------ L2_error_un1 =", L2_error_un1)
    print("------ L2_error_wn2 =", L2_error_wn2)
    print("------ L2_error_f0  =", L2_error_f0)
    return L2_error_un1, L2_error_wn2, L2_error_f0
# -*- coding: utf-8 -*-
"""
(SHORT NAME EXPLANATION)
"""
from mesh import CrazyMesh
from function_space import FunctionSpace
from forms import Form
from inner_product import inner

mesh = CrazyMesh(2, (2, 2), ((-1, 1), (-1, 1)), 0.1)
func_space_eg0 = FunctionSpace(mesh, '0-ext_gauss', (5, 5))
f0 = Form(func_space_eg0)
#f0.basis.quad_grid = ('gauss',6)
egM0 = inner(f0.basis, f0.basis)
Exemple #19
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()
Exemple #20
0
from scipy.integrate import quad
from sympy import Matrix
import scipy.io
from scipy import sparse
import scipy as sp
from inner_product import inner

# %% exact solution define
# u^{(1)} = { u,  v }^T
def u(x,y):
	return   +np.cos(np.pi*x) * np.sin(np.pi*y)

def v(x,y):
	return   -np.sin(np.pi*x) * np.cos(np.pi*y)

def r_u(x,y):
    return   -2* np.pi**2 * np.cos(np.pi*x) * np.sin(np.pi*y)

def r_v(x,y):
    return    2* np.pi**2 * np.sin(np.pi*x) * np.cos(np.pi*y)

# %% define the mesh
mesh = CrazyMesh( 2, (2, 2), ((-1, 1), (-1, 1)), 0.05 )
func_space_gauss1   = FunctionSpace(mesh, '1-gauss', (5, 5), is_inner=False)
func_space_lobatto1 = FunctionSpace(mesh, '1-lobatto', (5, 5), is_inner=False)

form_1_gauss   = Form(func_space_gauss1)
form_1_lobatto = Form(func_space_lobatto1)

M = inner(form_1_lobatto.basis,form_1_gauss.basis)
#
# # 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
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()