Exemple #1
0
    def test03_solve_2d(self):
        """
        Test problem with Neumann conditions
        """
        #
        # Define Mesh
        #
        mesh = QuadMesh(resolution=(2, 1))
        mesh.cells.get_child(1).mark(1)
        mesh.cells.refine(refinement_flag=1)

        # Mark left and right boundaries
        bm_left = lambda x, dummy: np.abs(x) < 1e-9
        bm_right = lambda x, dummy: np.abs(1 - x) < 1e-9
        mesh.mark_region('left', bm_left, entity_type='half_edge')
        mesh.mark_region('right', bm_right, entity_type='half_edge')

        for etype in ['Q1', 'Q2', 'Q3']:
            #
            # Define element and basis type
            #
            element = QuadFE(2, etype)
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()

            u = Basis(dofhandler, 'u')
            ux = Basis(dofhandler, 'ux')
            uy = Basis(dofhandler, 'uy')

            #
            # Exact solution
            #
            ue = Nodal(f=lambda x: x[:, 0], basis=u)

            #
            # Set up forms
            #
            one = Constant(1)
            ax = Form(kernel=Kernel(one), trial=ux, test=ux)
            ay = Form(kernel=Kernel(one), trial=uy, test=uy)
            L = Form(kernel=Kernel(Constant(0)), test=u)
            Ln = Form(kernel=Kernel(one), test=u, dmu='ds', flag='right')

            problem = [ax, ay, L, Ln]

            assembler = Assembler(problem, mesh)
            assembler.add_dirichlet('left', dir_fn=0)
            assembler.add_hanging_nodes()
            assembler.assemble()

            #
            # Automatic solve
            #
            ya = assembler.solve()
            self.assertTrue(np.allclose(ue.data()[:, 0], ya))

            #
            # Explicit solve
            #

            # System Matrices
            A = assembler.get_matrix().toarray()
            b = assembler.get_vector()
            x0 = assembler.assembled_bnd()

            # Solve linear system
            xa = np.zeros(u.n_dofs())
            int_dofs = assembler.get_dofs('interior')
            xa[int_dofs] = np.linalg.solve(A, b - x0)

            # Resolve Dirichlet conditions
            dir_dofs, dir_vals = assembler.get_dirichlet(asdict=False)
            xa[dir_dofs] = dir_vals[:, 0]

            # Resolve hanging nodes
            C = assembler.hanging_node_matrix()
            xa += C.dot(xa)

            self.assertTrue(np.allclose(ue.data()[:, 0], xa))
Exemple #2
0
    def test02_solve_2d(self):
        """
        Solve 2D problem with hanging nodes
        """
        # Mesh
        mesh = QuadMesh(resolution=(2, 2))
        mesh.cells.get_leaves()[0].mark(0)
        mesh.cells.refine(refinement_flag=0)

        mesh.mark_region('left',
                         lambda x, y: abs(x) < 1e-9,
                         entity_type='half_edge')
        mesh.mark_region('right',
                         lambda x, y: abs(x - 1) < 1e-9,
                         entity_type='half_edge')

        # Element
        Q1 = QuadFE(2, 'Q1')
        dofhandler = DofHandler(mesh, Q1)
        dofhandler.distribute_dofs()
        dofhandler.set_hanging_nodes()

        # Basis functions
        phi = Basis(dofhandler, 'u')
        phi_x = Basis(dofhandler, 'ux')
        phi_y = Basis(dofhandler, 'uy')

        #
        # Define problem
        #
        problem = [
            Form(1, trial=phi_x, test=phi_x),
            Form(1, trial=phi_y, test=phi_y),
            Form(0, test=phi)
        ]

        ue = Nodal(f=lambda x: x[:, 0], basis=phi)
        xe = ue.data().ravel()

        #
        # Assemble without Dirichlet and without Hanging Nodes
        #
        assembler = Assembler(problem, mesh)
        assembler.add_dirichlet('left', dir_fn=0)
        assembler.add_dirichlet('right', dir_fn=1)
        assembler.add_hanging_nodes()
        assembler.assemble()

        # Get dofs for different regions
        int_dofs = assembler.get_dofs('interior')

        # Get matrix and vector
        A = assembler.get_matrix().toarray()
        b = assembler.get_vector()
        x0 = assembler.assembled_bnd()

        # Solve linear system
        xa = np.zeros(phi.n_dofs())
        xa[int_dofs] = np.linalg.solve(A, b - x0)

        # Resolve Dirichlet conditions
        dir_dofs, dir_vals = assembler.get_dirichlet(asdict=False)
        xa[dir_dofs] = dir_vals[:, 0]

        # Resolve hanging nodes
        C = assembler.hanging_node_matrix()
        xa += C.dot(xa)

        self.assertTrue(np.allclose(xa, xe))