Beispiel #1
0
    def monolithic_solve():
        """Monolithic version"""
        E = P * P
        W = FunctionSpace(mesh, E)
        U = Function(W)
        dU = ufl.TrialFunction(W)
        u0, u1 = ufl.split(U)
        v0, v1 = ufl.TestFunctions(W)

        F = inner((u0**2 + 1) * ufl.grad(u0), ufl.grad(v0)) * dx \
            + inner((u1**2 + 1) * ufl.grad(u1), ufl.grad(v1)) * dx \
            - inner(f, v0) * ufl.dx - inner(g, v1) * dx
        J = derivative(F, U, dU)

        F, J = form(F), form(J)

        u0_bc = Function(V0)
        u0_bc.interpolate(bc_val_0)
        u1_bc = Function(V1)
        u1_bc.interpolate(bc_val_1)
        bdofsW0_V0 = locate_dofs_topological((W.sub(0), V0), facetdim,
                                             bndry_facets)
        bdofsW1_V1 = locate_dofs_topological((W.sub(1), V1), facetdim,
                                             bndry_facets)
        bcs = [
            dirichletbc(u0_bc, bdofsW0_V0, W.sub(0)),
            dirichletbc(u1_bc, bdofsW1_V1, W.sub(1))
        ]

        Jmat = create_matrix(J)
        Fvec = create_vector(F)

        snes = PETSc.SNES().create(MPI.COMM_WORLD)
        snes.setTolerances(rtol=1.0e-15, max_it=10)

        snes.getKSP().setType("preonly")
        snes.getKSP().getPC().setType("lu")

        problem = NonlinearPDE_SNESProblem(F, J, U, bcs)
        snes.setFunction(problem.F_mono, Fvec)
        snes.setJacobian(problem.J_mono, J=Jmat, P=None)

        U.sub(0).interpolate(initial_guess_u)
        U.sub(1).interpolate(initial_guess_p)

        x = create_vector(F)
        x.array = U.vector.array_r

        snes.solve(None, x)
        assert snes.getKSP().getConvergedReason() > 0
        assert snes.getConvergedReason() > 0
        return x.norm()
def test_plus_minus_matrix(cell_type, pm1, pm2):
    """Test that ('+') and ('-') match up with the correct DOFs for DG functions"""
    results = []
    spaces = []
    orders = []
    for count in range(3):
        for agree in [True, False]:
            # Two cell mesh with randomly numbered points
            mesh, order = two_unit_cells(cell_type, agree, return_order=True)

            V = FunctionSpace(mesh, ("DG", 1))
            u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

            # Assemble matrices with combinations of + and - for a few
            # different numberings
            a = form(ufl.inner(u(pm1), v(pm2)) * ufl.dS)
            result = assemble_matrix(a, [])
            result.assemble()
            spaces.append(V)
            results.append(result)
            orders.append(order)

    # Check that the above matrices all have the same values, but
    # permuted due to differently ordered dofs
    dofmap0 = spaces[0].mesh.geometry.dofmap
    for result, space in zip(results[1:], spaces[1:]):
        # Get the data relating to two results
        dofmap1 = space.mesh.geometry.dofmap

        dof_order = []

        # For each cell
        for cell in range(2):
            # For each point in cell 0 in the first mesh
            for dof0, point0 in zip(spaces[0].dofmap.cell_dofs(cell),
                                    dofmap0.links(cell)):
                # Find the point in the cell 0 in the second mesh
                for dof1, point1 in zip(space.dofmap.cell_dofs(cell),
                                        dofmap1.links(cell)):
                    if np.allclose(spaces[0].mesh.geometry.x[point0],
                                   space.mesh.geometry.x[point1]):
                        break
                else:
                    # If no matching point found, fail
                    assert False

                dof_order.append((dof0, dof1))

        # For all dof pairs, check that entries in the matrix agree
        for a, b in dof_order:
            for c, d in dof_order:
                assert np.isclose(results[0][a, c], result[b, d])
Beispiel #3
0
def test_block_size(mesh):
    meshes = [
        create_unit_square(8, 8),
        create_unit_cube(4, 4, 4),
        create_unit_square(8, 8, CellType.quadrilateral),
        create_unit_cube(4, 4, 4, CellType.hexahedron)
    ]
    for mesh in meshes:
        P2 = FiniteElement("Lagrange", mesh.ufl_cell(), 2)

        V = FunctionSpace(mesh, P2)
        assert V.dofmap.bs == 1

        V = FunctionSpace(mesh, P2 * P2)
        assert V.dofmap.index_map_bs == 2

        for i in range(1, 6):
            W = FunctionSpace(mesh, MixedElement(i * [P2]))
            assert W.dofmap.index_map_bs == i

        V = VectorFunctionSpace(mesh, ("Lagrange", 2))
        assert V.dofmap.index_map_bs == mesh.geometry.dim
def test_refine_create_form():
    """Check that forms can be assembled on refined mesh"""
    mesh = create_unit_cube(MPI.COMM_WORLD, 3, 3, 3)
    mesh.topology.create_entities(1)
    mesh = refine(mesh, redistribute=True)

    V = FunctionSpace(mesh, ("Lagrange", 1))

    # Define variational problem
    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    a = form(ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx)
    assemble_matrix(a)
Beispiel #5
0
def test_coefficents_non_constant():
    "Test packing coefficients with non-constant values"
    mesh = create_unit_square(MPI.COMM_WORLD, 3, 5)
    V = FunctionSpace(mesh, ("Lagrange", 3))  # degree 3 so that interpolation is exact

    u = Function(V)
    u.interpolate(lambda x: x[0] * x[1]**2)
    x = SpatialCoordinate(mesh)

    v = ufl.TestFunction(V)

    # -- Volume integral vector
    F = form((ufl.inner(u, v) - ufl.inner(x[0] * x[1]**2, v)) * dx)
    b0 = assemble_vector(F)
    b0.assemble()
    assert np.linalg.norm(b0.array) == pytest.approx(0.0)

    # -- Exterior facet integral vector
    F = form((ufl.inner(u, v) - ufl.inner(x[0] * x[1]**2, v)) * ds)
    b0 = assemble_vector(F)
    b0.assemble()
    assert np.linalg.norm(b0.array) == pytest.approx(0.0)

    # -- Interior facet integral vector
    V = FunctionSpace(mesh, ("DG", 3))  # degree 3 so that interpolation is exact

    u0 = Function(V)
    u0.interpolate(lambda x: x[1]**2)
    u1 = Function(V)
    u1.interpolate(lambda x: x[0])
    x = SpatialCoordinate(mesh)

    v = ufl.TestFunction(V)

    F = (ufl.inner(u1('+') * u0('-'), ufl.avg(v)) - ufl.inner(x[0] * x[1]**2, ufl.avg(v))) * ufl.dS
    F = form(F)
    b0 = assemble_vector(F)
    b0.assemble()
    assert np.linalg.norm(b0.array) == pytest.approx(0.0)
Beispiel #6
0
def test_vtx_single_function(tempdir, dim, simplex):
    "Test saving a single first order Lagrange functions"
    mesh = generate_mesh(dim, simplex)
    v = Function(FunctionSpace(mesh, ("Lagrange", 1)))

    filename = os.path.join(tempdir, "v.bp")
    writer = VTXWriter(mesh.comm, filename, v)
    writer.write(0)
    writer.close()

    filename = os.path.join(tempdir, "v2.bp")
    writer = VTXWriter(mesh.comm, filename, v._cpp_object)
    writer.write(0)
    writer.close()
Beispiel #7
0
def run_symmetry_test(cell_type, element, form_f):
    if cell_type == CellType.triangle or cell_type == CellType.quadrilateral:
        mesh = create_unit_square(MPI.COMM_WORLD, 2, 2, cell_type)
    else:
        mesh = create_unit_cube(MPI.COMM_WORLD, 2, 2, 2, cell_type)

    space = FunctionSpace(mesh, element)
    u = ufl.TrialFunction(space)
    v = ufl.TestFunction(space)
    f = form(form_f(u, v))

    A = dolfinx.fem.assemble_matrix(f)
    A.assemble()
    check_symmetry(A)
def test_complex_assembly():
    """Test assembly of complex matrices and vectors"""

    mesh = create_unit_square(MPI.COMM_WORLD, 10, 10)
    P2 = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 2)
    V = FunctionSpace(mesh, P2)
    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    g = -2 + 3.0j
    j = 1.0j

    a_real = form(inner(u, v) * dx)
    L1 = form(inner(g, v) * dx)

    b = assemble_vector(L1)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    bnorm = b.norm(PETSc.NormType.N1)
    b_norm_ref = abs(-2 + 3.0j)
    assert bnorm == pytest.approx(b_norm_ref)

    A = assemble_matrix(a_real)
    A.assemble()
    A0_norm = A.norm(PETSc.NormType.FROBENIUS)

    x = ufl.SpatialCoordinate(mesh)

    a_imag = form(j * inner(u, v) * dx)
    f = 1j * ufl.sin(2 * np.pi * x[0])
    L0 = form(inner(f, v) * dx)
    A = assemble_matrix(a_imag)
    A.assemble()
    A1_norm = A.norm(PETSc.NormType.FROBENIUS)
    assert A0_norm == pytest.approx(A1_norm)

    b = assemble_vector(L0)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    b1_norm = b.norm(PETSc.NormType.N2)

    a_complex = form((1 + j) * inner(u, v) * dx)
    f = ufl.sin(2 * np.pi * x[0])
    L2 = form(inner(f, v) * dx)
    A = assemble_matrix(a_complex)
    A.assemble()
    A2_norm = A.norm(PETSc.NormType.FROBENIUS)
    assert A1_norm == pytest.approx(A2_norm / np.sqrt(2))
    b = assemble_vector(L2)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    b2_norm = b.norm(PETSc.NormType.N2)
    assert b2_norm == pytest.approx(b1_norm)
def test_plus_minus(cell_type, space_type):
    """Test that ('+') and ('-') give the same value for continuous functions"""
    results = []
    for count in range(3):
        for agree in [True, False]:
            mesh = two_unit_cells(cell_type, agree)
            V = FunctionSpace(mesh, (space_type, 1))
            v = Function(V)
            v.interpolate(lambda x: x[0] - 2 * x[1])
            # Check that these two integrals are equal
            for pm1, pm2 in product(["+", "-"], repeat=2):
                a = form(v(pm1) * v(pm2) * ufl.dS)
                results.append(assemble_scalar(a))
    for i, j in combinations(results, 2):
        assert np.isclose(i, j)
Beispiel #10
0
def test_save_vtkx_cell_point(tempdir):
    """Test writing point-wise data"""
    mesh = create_unit_square(MPI.COMM_WORLD, 8, 5)
    P = ufl.FiniteElement("Discontinuous Lagrange", mesh.ufl_cell(), 0)

    V = FunctionSpace(mesh, P)
    u = Function(V)
    u.interpolate(lambda x: 0.5 * x[0])
    u.name = "A"

    filename = os.path.join(tempdir, "v.bp")
    with pytest.raises(RuntimeError):
        f = VTXWriter(mesh.comm, filename, [u])
        f.write(0)
        f.close()
Beispiel #11
0
def test_extract_forms():
    """Test extraction on unique function spaces for rows and columns of
    a block system"""
    mesh = create_unit_square(MPI.COMM_WORLD, 32, 31)
    V0 = FunctionSpace(mesh, ("Lagrange", 1))
    V1 = FunctionSpace(mesh, ("Lagrange", 2))
    V2 = V0.clone()
    V3 = V1.clone()

    v0, u0 = TestFunction(V0), TrialFunction(V0)
    v1, u1 = TestFunction(V1), TrialFunction(V1)
    v2, u2 = TestFunction(V2), TrialFunction(V2)
    v3, u3 = TestFunction(V3), TrialFunction(V3)

    a = form([[inner(u0, v0) * dx, inner(u1, v1) * dx],
              [inner(u2, v2) * dx, inner(u3, v3) * dx]])
    with pytest.raises(AssertionError):
        extract_function_spaces(a, 0)
    with pytest.raises(AssertionError):
        extract_function_spaces(a, 1)

    a = form([[inner(u0, v0) * dx, inner(u2, v1) * dx],
              [inner(u0, v2) * dx, inner(u2, v2) * dx]])
    with pytest.raises(AssertionError):
        extract_function_spaces(a, 0)
    Vc = extract_function_spaces(a, 1)
    assert Vc[0] is V0._cpp_object
    assert Vc[1] is V2._cpp_object

    a = form([[inner(u0, v0) * dx, inner(u1, v0) * dx],
              [inner(u2, v1) * dx, inner(u3, v1) * dx]])
    Vr = extract_function_spaces(a, 0)
    assert Vr[0] is V0._cpp_object
    assert Vr[1] is V1._cpp_object
    with pytest.raises(AssertionError):
        extract_function_spaces(a, 1)
 def perform_test(points, cells):
     domain = ufl.Mesh(ufl.VectorElement("Lagrange", "tetrahedron", 1))
     mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
     V = FunctionSpace(mesh, (space_type, order))
     f = Function(V)
     output = []
     for dof in range(len(f.vector[:])):
         f.vector[:] = np.zeros(len(f.vector[:]))
         f.vector[dof] = 1
         points = np.array([[1 / 3, 1 / 3, 1 / 3], [1 / 3, 1 / 3, 1 / 3]])
         cells = np.array([0, 1])
         result = f.eval(points, cells)
         normal = np.array([1., 1., 1.])
         output.append(result.dot(normal))
     return output
Beispiel #13
0
def test_save_1d_vector(tempdir):
    mesh = create_unit_interval(MPI.COMM_WORLD, 32)

    def f(x):
        vals = np.zeros((2, x.shape[1]))
        vals[0] = x[0]
        vals[1] = 2 * x[0] * x[0]
        return vals

    element = ufl.VectorElement("Lagrange", mesh.ufl_cell(), 2, dim=2)
    u = Function(FunctionSpace(mesh, element))
    u.interpolate(f)
    filename = os.path.join(tempdir, "u.pvd")
    with VTKFile(MPI.COMM_WORLD, filename, "w") as vtk:
        vtk.write_function(u, 0.)
Beispiel #14
0
def test_Refinecreate_unit_cube_repartition():
    """Refine mesh of unit cube."""
    mesh = create_unit_cube(MPI.COMM_WORLD, 5, 7, 9, ghost_mode=GhostMode.none)
    mesh.topology.create_entities(1)
    mesh = refine(mesh, redistribute=True)
    assert mesh.topology.index_map(0).size_global == 3135
    assert mesh.topology.index_map(3).size_global == 15120

    mesh = create_unit_cube(MPI.COMM_WORLD, 5, 7, 9, ghost_mode=GhostMode.shared_facet)
    mesh.topology.create_entities(1)
    mesh = refine(mesh, redistribute=True)
    assert mesh.topology.index_map(0).size_global == 3135
    assert mesh.topology.index_map(3).size_global == 15120

    Q = FunctionSpace(mesh, ("Lagrange", 1))
    assert Q
Beispiel #15
0
def test_argument_equality(mesh, V, V2, W, W2):
    """Placed this test here because it's mainly about detecting differing
    function spaces"""
    mesh2 = create_unit_cube(MPI.COMM_WORLD, 8, 8, 8)
    V3 = FunctionSpace(mesh2, ("Lagrange", 1))
    W3 = VectorFunctionSpace(mesh2, ("Lagrange", 1))

    for TF in (TestFunction, TrialFunction):
        v = TF(V)
        v2 = TF(V2)
        v3 = TF(V3)
        assert v == v2
        assert v2 == v
        assert V != V3
        assert V2 != V3
        assert not v == v3
        assert not v2 == v3
        assert v != v3
        assert v2 != v3
        assert v != v3
        assert v2 != v3

        w = TF(W)
        w2 = TF(W2)
        w3 = TF(W3)
        assert w == w2
        assert w2 == w
        assert w != w3
        assert w2 != w3

        assert v != w
        assert w != v

        s1 = set((v, w))
        s2 = set((v2, w2))
        s3 = set((v, v2, w, w2))
        assert len(s1) == 2
        assert len(s2) == 2
        assert len(s3) == 2
        assert s1 == s2
        assert s1 == s3
        assert s2 == s3

        # Test that the dolfinx implementation of Argument.__eq__ is
        # triggered when comparing ufl expressions
        assert grad(v) == grad(v2)
        assert grad(v) != grad(v3)
def test_complex_assembly_solve():
    """Solve a positive definite helmholtz problem and verify solution
    with the method of manufactured solutions"""

    degree = 3
    mesh = create_unit_square(MPI.COMM_WORLD, 20, 20)
    P = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), degree)
    V = FunctionSpace(mesh, P)

    x = ufl.SpatialCoordinate(mesh)

    # Define source term
    A = 1.0 + 2.0 * (2.0 * np.pi)**2
    f = (1. + 1j) * A * ufl.cos(2 * np.pi * x[0]) * ufl.cos(2 * np.pi * x[1])

    # Variational problem
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
    C = 1.0 + 1.0j
    a = form(C * inner(grad(u), grad(v)) * dx + C * inner(u, v) * dx)
    L = form(inner(f, v) * dx)

    # Assemble
    A = assemble_matrix(a)
    A.assemble()
    b = assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    # Create solver
    solver = PETSc.KSP().create(mesh.comm)
    solver.setOptionsPrefix("test_lu_")
    opts = PETSc.Options("test_lu_")
    opts["ksp_type"] = "preonly"
    opts["pc_type"] = "lu"
    solver.setFromOptions()
    x = A.createVecRight()
    solver.setOperators(A)
    solver.solve(b, x)

    # Reference Solution
    def ref_eval(x):
        return np.cos(2 * np.pi * x[0]) * np.cos(2 * np.pi * x[1])

    u_ref = Function(V)
    u_ref.interpolate(ref_eval)

    diff = (x - u_ref.vector).norm(PETSc.NormType.N2)
    assert diff == pytest.approx(0.0, abs=1e-1)
Beispiel #17
0
def test_rank0():
    """Test evaluation of UFL expression.
    This test evaluates gradient of P2 function at interpolation points
    of vector dP1 element.
    For a donor function f(x, y) = x^2 + 2*y^2 result is compared with the
    exact gradient grad f(x, y) = [2*x, 4*y].
    """
    mesh = create_unit_square(MPI.COMM_WORLD, 5, 5)
    P2 = FunctionSpace(mesh, ("P", 2))
    vdP1 = VectorFunctionSpace(mesh, ("DG", 1))

    f = Function(P2)

    def expr1(x):
        return x[0]**2 + 2.0 * x[1]**2

    f.interpolate(expr1)

    ufl_expr = ufl.grad(f)
    points = vdP1.element.interpolation_points

    compiled_expr = Expression(ufl_expr, points)
    num_cells = mesh.topology.index_map(2).size_local
    array_evaluated = compiled_expr.eval(np.arange(num_cells, dtype=np.int32))

    @numba.njit
    def scatter(vec, array_evaluated, dofmap):
        for i in range(num_cells):
            for j in range(3):
                for k in range(2):
                    vec[2 * dofmap[i * 3 + j] + k] = array_evaluated[i,
                                                                     2 * j + k]

    # Data structure for the result
    b = Function(vdP1)

    dofmap = vdP1.dofmap.list.array
    scatter(b.x.array, array_evaluated, dofmap)
    b.x.scatter_forward()

    def grad_expr1(x):
        return np.vstack((2.0 * x[0], 4.0 * x[1]))

    b2 = Function(vdP1)
    b2.interpolate(grad_expr1)

    assert np.allclose(b2.x.array, b.x.array)
Beispiel #18
0
def test_basic_interior_facet_assembly():
    mesh = create_rectangle(MPI.COMM_WORLD, [np.array([0.0, 0.0]), np.array([1.0, 1.0])],
                            [5, 5], cell_type=CellType.triangle,
                            ghost_mode=GhostMode.shared_facet)
    V = FunctionSpace(mesh, ("DG", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
    a = ufl.inner(ufl.avg(u), ufl.avg(v)) * ufl.dS
    a = form(a)
    A = assemble_matrix(a)
    A.assemble()
    assert isinstance(A, PETSc.Mat)

    L = ufl.conj(ufl.avg(v)) * ufl.dS
    L = form(L)
    b = assemble_vector(L)
    b.assemble()
    assert isinstance(b, PETSc.Vec)
def test_ghost_mesh_dS_assembly(mode, dS):
    mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, ghost_mode=mode)
    V = FunctionSpace(mesh, ("Lagrange", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
    dS = dS(mesh)
    a = form(inner(avg(u), avg(v)) * dS)

    # Initial assembly
    A = fem.assemble_matrix(a)
    A.assemble()
    assert isinstance(A, PETSc.Mat)

    # Check that the norms are the same for all three modes
    normA = A.norm()
    print(normA)

    assert normA == pytest.approx(2.1834054713561906, rel=1.e-6, abs=1.e-12)
Beispiel #20
0
def test_basic_assembly(mode):
    mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, ghost_mode=mode)
    V = FunctionSpace(mesh, ("Lagrange", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

    f = Function(V)
    f.x.array[:] = 10.0
    a = inner(f * u, v) * dx + inner(u, v) * ds
    L = inner(f, v) * dx + inner(2.0, v) * ds
    a, L = form(a), form(L)

    # Initial assembly
    A = assemble_matrix(a)
    A.assemble()
    assert isinstance(A, PETSc.Mat)
    b = assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    assert isinstance(b, PETSc.Vec)

    # Second assembly
    normA = A.norm()
    A.zeroEntries()
    A = assemble_matrix(A, a)
    A.assemble()
    assert isinstance(A, PETSc.Mat)
    assert normA == pytest.approx(A.norm())
    normb = b.norm()
    with b.localForm() as b_local:
        b_local.set(0.0)
    b = assemble_vector(b, L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    assert isinstance(b, PETSc.Vec)
    assert normb == pytest.approx(b.norm())

    # Vector re-assembly - no zeroing (but need to zero ghost entries)
    with b.localForm() as b_local:
        b_local.array[b.local_size:] = 0.0
    assemble_vector(b, L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    assert 2.0 * normb == pytest.approx(b.norm())

    # Matrix re-assembly (no zeroing)
    assemble_matrix(A, a)
    A.assemble()
    assert 2.0 * normA == pytest.approx(A.norm())
Beispiel #21
0
def test_two_fides_functions(tempdir, dim, simplex):
    """Test saving two functions with Fides"""
    mesh = generate_mesh(dim, simplex)
    v = Function(VectorFunctionSpace(mesh, ("Lagrange", 1)))
    q = Function(FunctionSpace(mesh, ("Lagrange", 1)))
    filename = os.path.join(tempdir, "v.bp")
    with FidesWriter(mesh.comm, filename, [v._cpp_object, q]) as f:
        f.write(0)

        def vel(x):
            values = np.zeros((dim, x.shape[1]))
            values[0] = x[1]
            values[1] = x[0]
            return values

        v.interpolate(vel)
        q.interpolate(lambda x: x[0])
        f.write(1)
Beispiel #22
0
def test_overlapping_bcs():
    """Test that, when boundaries condition overlap, the last provided
    boundary condition is applied"""
    n = 23
    mesh = create_unit_square(MPI.COMM_WORLD, n, n)
    V = FunctionSpace(mesh, ("Lagrange", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
    a = form(inner(u, v) * dx)
    L = form(inner(1, v) * dx)

    dofs_left = locate_dofs_geometrical(V, lambda x: x[0] < 1.0 / (2.0 * n))
    dofs_top = locate_dofs_geometrical(V, lambda x: x[1] > 1.0 - 1.0 /
                                       (2.0 * n))
    dof_corner = np.array(list(set(dofs_left).intersection(set(dofs_top))),
                          dtype=np.int64)

    # Check only one dof pair is found globally
    assert len(set(np.concatenate(MPI.COMM_WORLD.allgather(dof_corner)))) == 1

    bcs = [
        dirichletbc(PETSc.ScalarType(0), dofs_left, V),
        dirichletbc(PETSc.ScalarType(123.456), dofs_top, V)
    ]

    A, b = create_matrix(a), create_vector(L)
    assemble_matrix(A, a, bcs=bcs)
    A.assemble()

    # Check the diagonal (only on the rank that owns the row)
    d = A.getDiagonal()
    if len(dof_corner) > 0 and dof_corner[0] < V.dofmap.index_map.size_local:
        assert np.isclose(d.array_r[dof_corner[0]], 1.0)

    with b.localForm() as b_loc:
        b_loc.set(0)
    assemble_vector(b, L)
    apply_lifting(b, [a], [bcs])
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    set_bc(b, bcs)
    b.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)

    if len(dof_corner) > 0:
        with b.localForm() as b_loc:
            assert b_loc[dof_corner[0]] == 123.456
Beispiel #23
0
def plot_scalar():
    # Plotting a Function using warp by scalar
    # ========================================

    # We start by creating a unit square mesh and interpolating a function
    # into a first order Lagrange space
    mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, cell_type=CellType.quadrilateral)
    V = FunctionSpace(mesh, ("Lagrange", 1))
    u = Function(V, dtype=np.float64)
    u.interpolate(lambda x: np.sin(np.pi * x[0]) * np.sin(2 * x[1] * np.pi))

    # As we want to visualize the function u, we have to create a grid to
    # attached the dof values to We do this by creating a topology and
    # geometry based on the function space V
    cells, types, x = plot.create_vtk_mesh(V)
    grid = pyvista.UnstructuredGrid(cells, types, x)
    grid.point_data["u"] = u.x.array

    # We set the function "u" as the active scalar for the mesh, and warp
    # the mesh in z-direction by its values
    grid.set_active_scalars("u")
    warped = grid.warp_by_scalar()

    # We create a plotting window consisting of to plots, one of the scalar
    # values, and one where the mesh is warped by these values
    subplotter = pyvista.Plotter(shape=(1, 2))
    subplotter.subplot(0, 0)
    subplotter.add_text("Scalar countour field", font_size=14, color="black", position="upper_edge")
    subplotter.add_mesh(grid, show_edges=True, show_scalar_bar=True)
    subplotter.view_xy()

    subplotter.subplot(0, 1)
    subplotter.add_text("Warped function", position="upper_edge", font_size=14, color="black")
    sargs = dict(height=0.8, width=0.1, vertical=True, position_x=0.05,
                 position_y=0.05, fmt="%1.2e", title_font_size=40, color="black", label_font_size=25)
    subplotter.set_position([-3, 2.6, 0.3])
    subplotter.set_focus([3, -1, -0.15])
    subplotter.set_viewup([0, 0, 1])
    subplotter.add_mesh(warped, show_edges=True, scalar_bar_args=sargs)
    if pyvista.OFF_SCREEN:
        subplotter.screenshot("2D_function_warp.png", transparent_background=transparent,
                              window_size=[figsize, figsize])
    else:
        subplotter.show()
Beispiel #24
0
def test_nonlinear_pde_snes():
    """Test Newton solver for a simple nonlinear PDE"""
    # Create mesh and function space
    mesh = create_unit_square(MPI.COMM_WORLD, 12, 15)
    V = FunctionSpace(mesh, ("Lagrange", 1))
    u = Function(V)
    v = TestFunction(V)
    F = inner(5.0, v) * dx - ufl.sqrt(u * u) * inner(
        grad(u), grad(v)) * dx - inner(u, v) * dx

    u_bc = Function(V)
    u_bc.x.array[:] = 1.0
    bc = dirichletbc(
        u_bc,
        locate_dofs_geometrical(
            V, lambda x: np.logical_or(np.isclose(x[0], 0.0),
                                       np.isclose(x[0], 1.0))))

    # Create nonlinear problem
    problem = NonlinearPDE_SNESProblem(F, u, bc)

    u.x.array[:] = 0.9
    b = la.create_petsc_vector(V.dofmap.index_map, V.dofmap.index_map_bs)
    J = create_matrix(problem.a)

    # Create Newton solver and solve
    snes = PETSc.SNES().create()
    snes.setFunction(problem.F, b)
    snes.setJacobian(problem.J, J)

    snes.setTolerances(rtol=1.0e-9, max_it=10)
    snes.getKSP().setType("preonly")
    snes.getKSP().setTolerances(rtol=1.0e-9)
    snes.getKSP().getPC().setType("lu")

    snes.solve(None, u.vector)
    assert snes.getConvergedReason() > 0
    assert snes.getIterationNumber() < 6

    # Modify boundary condition and solve again
    u_bc.x.array[:] = 0.6
    snes.solve(None, u.vector)
    assert snes.getConvergedReason() > 0
    assert snes.getIterationNumber() < 6
Beispiel #25
0
def test_custom_mesh_loop_ctypes_rank2():
    """Test numba assembler for bilinear form"""

    # Create mesh and function space
    mesh = create_unit_square(MPI.COMM_WORLD, 64, 64)
    V = FunctionSpace(mesh, ("Lagrange", 1))

    # Extract mesh and dofmap data
    num_owned_cells = mesh.topology.index_map(mesh.topology.dim).size_local
    num_cells = num_owned_cells + mesh.topology.index_map(
        mesh.topology.dim).num_ghosts
    x_dofs = mesh.geometry.dofmap.array.reshape(num_cells, 3)
    x = mesh.geometry.x
    dofmap = V.dofmap.list.array.reshape(num_cells,
                                         3).astype(np.dtype(PETSc.IntType))

    # Generated case with general assembler
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
    a = form(inner(u, v) * dx)
    A0 = assemble_matrix(a)
    A0.assemble()
    A0.zeroEntries()

    start = time.time()
    dolfinx.fem.assemble_matrix(A0, a)
    end = time.time()
    print("Time (C++, pass 2):", end - start)
    A0.assemble()

    # Custom case
    A1 = A0.copy()
    for i in range(2):
        A1.zeroEntries()
        mat = A1.handle
        start = time.time()
        assemble_matrix_ctypes(mat, (x_dofs, x), dofmap, num_owned_cells,
                               MatSetValues_ctypes,
                               PETSc.InsertMode.ADD_VALUES)
        end = time.time()
        print("Time (numba, pass {}): {}".format(i, end - start))
        A1.assemble()

    assert (A0 - A1).norm() == pytest.approx(0.0, abs=1.0e-9)
Beispiel #26
0
def test_mixed_sub_interpolation():
    """Test interpolation of sub-functions"""
    mesh = create_unit_cube(MPI.COMM_WORLD, 3, 3, 3)

    def f(x):
        return np.vstack((10 + x[0], -10 - x[1], 25 + x[0]))

    P2 = ufl.VectorElement("Lagrange", mesh.ufl_cell(), 2)
    P1 = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
    for i, P in enumerate((P2 * P1, P1 * P2)):
        W = FunctionSpace(mesh, P)
        U = Function(W)
        U.sub(i).interpolate(f)

        # Same element
        V = FunctionSpace(mesh, P2)
        u, v = Function(V), Function(V)
        u.interpolate(U.sub(i))
        v.interpolate(f)
        assert np.allclose(u.vector.array, v.vector.array)

        # Same map, different elements
        V = VectorFunctionSpace(mesh, ("Lagrange", 1))
        u, v = Function(V), Function(V)
        u.interpolate(U.sub(i))
        v.interpolate(f)
        assert np.allclose(u.vector.array, v.vector.array)

        # Different maps (0)
        V = FunctionSpace(mesh, ("N1curl", 1))
        u, v = Function(V), Function(V)
        u.interpolate(U.sub(i))
        v.interpolate(f)
        assert np.allclose(u.vector.array, v.vector.array)

        # Different maps (1)
        V = FunctionSpace(mesh, ("RT", 2))
        u, v = Function(V), Function(V)
        u.interpolate(U.sub(i))
        v.interpolate(f)
        assert np.allclose(u.vector.array, v.vector.array)

        # Test with wrong shape
        V0 = FunctionSpace(mesh, P.sub_elements()[0])
        V1 = FunctionSpace(mesh, P.sub_elements()[1])
        v0, v1 = Function(V0), Function(V1)
        with pytest.raises(RuntimeError):
            v0.interpolate(U.sub(1))
        with pytest.raises(RuntimeError):
            v1.interpolate(U.sub(0))
Beispiel #27
0
def test_evaluation(cell_type, space_type, space_order):
    if cell_type == "hexahedron" and space_order >= 3:
        pytest.skip("Skipping expensive test on hexahedron")

    random.seed(4)
    for repeat in range(10):
        mesh = random_evaluation_mesh(cell_type)
        V = FunctionSpace(mesh, (space_type, space_order))
        dofs = [i for i in V.dofmap.cell_dofs(0) if i in V.dofmap.cell_dofs(1)]

        N = 5
        if cell_type == "tetrahedron":
            eval_points = np.array([[0., i / N, j / N] for i in range(N + 1)
                                    for j in range(N + 1 - i)])
        elif cell_type == "hexahedron":
            eval_points = np.array([[0., i / N, j / N] for i in range(N + 1)
                                    for j in range(N + 1)])
        else:
            eval_points = np.array([[0., i / N, 0.] for i in range(N + 1)])

        for d in dofs:
            v = Function(V)
            v.vector[:] = [
                1 if i == d else 0 for i in range(v.vector.local_size)
            ]
            values0 = v.eval(eval_points, [0 for i in eval_points])
            values1 = v.eval(eval_points, [1 for i in eval_points])
            if len(eval_points) == 1:
                values0 = [values0]
                values1 = [values1]
            if space_type in ["RT", "BDM", "RTCF", "NCF", "BDMCF", "AAF"]:
                # Hdiv
                for i, j in zip(values0, values1):
                    assert np.isclose(i[0], j[0])
            elif space_type in [
                    "N1curl", "N2curl", "RTCE", "NCE", "BDMCE", "AAE"
            ]:
                # Hcurl
                for i, j in zip(values0, values1):
                    assert np.allclose(i[1:], j[1:])
            else:
                assert np.allclose(values0, values1)
Beispiel #28
0
def test_fides_function_at_nodes(tempdir, dim, simplex):
    """Test saving P1 functions with Fides (with changing geometry)"""
    from dolfinx.cpp.io import FidesWriter
    mesh = generate_mesh(dim, simplex)
    v = Function(VectorFunctionSpace(mesh, ("Lagrange", 1)))
    q = Function(FunctionSpace(mesh, ("Lagrange", 1)))

    filename = os.path.join(tempdir, "v.bp")
    with FidesWriter(mesh.comm, filename, [v._cpp_object, q._cpp_object]) as f:
        for t in [0.1, 0.5, 1]:
            # Only change one function
            q.interpolate(lambda x: t * (x[0] - 0.5)**2)
            f.write(t)

            mesh.geometry.x[:, :2] += 0.1
            if mesh.geometry.dim == 2:
                v.interpolate(lambda x: (t * x[0], x[1] + x[1] * 1j))
            elif mesh.geometry.dim == 3:
                v.interpolate(lambda x: (t * x[2], x[0] + x[2] * 2j, x[1]))
            f.write(t)
def test_basic_assembly_petsc_matrixcsr(mode):
    mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, ghost_mode=mode)
    V = FunctionSpace(mesh, ("Lagrange", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
    a = inner(u, v) * dx + inner(u, v) * ds
    a = form(a)

    A0 = fem.assemble_matrix(a)
    A0.finalize()
    assert isinstance(A0, la.MatrixCSRMetaClass)
    A1 = fem.petsc.assemble_matrix(a)
    A1.assemble()
    assert isinstance(A1, PETSc.Mat)
    assert np.sqrt(A0.norm_squared()) == pytest.approx(A1.norm())

    V = VectorFunctionSpace(mesh, ("Lagrange", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
    a = form(inner(u, v) * dx + inner(u, v) * ds)
    with pytest.raises(RuntimeError):
        A0 = fem.assemble_matrix(a)
Beispiel #30
0
def test_higher_order_tetra_coordinate_map(order):
    """
    Computes physical coordinates of a cell, based on the coordinate map.
    """
    celltype = CellType.tetrahedron
    points = np.array([[0, 0, 0], [1, 0, 0], [0, 2, 0], [0, 0, 3],
                       [0, 4 / 3, 1], [0, 2 / 3, 2], [2 / 3, 0, 1],
                       [1 / 3, 0, 2], [2 / 3, 2 / 3, 0], [1 / 3, 4 / 3, 0],
                       [0, 0, 1], [0, 0, 2], [0, 2 / 3, 0], [0, 4 / 3, 0],
                       [1 / 3, 0, 0], [2 / 3, 0, 0], [1 / 3, 2 / 3, 1],
                       [0, 2 / 3, 1], [1 / 3, 0, 1], [1 / 3, 2 / 3, 0]])

    if order == 1:
        points = np.array(
            [points[0, :], points[1, :], points[2, :], points[3, :]])
    elif order == 2:
        points = np.array([
            points[0, :], points[1, :], points[2, :], points[3, :],
            [0, 1, 3 / 2], [1 / 2, 0, 3 / 2], [1 / 2, 1, 0], [0, 0, 3 / 2],
            [0, 1, 0], [1 / 2, 0, 0]
        ])
    cells = np.array([range(len(points))])
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", celltype.name, order))
    mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
    V = FunctionSpace(mesh, ("Lagrange", order))
    X = V.element.interpolation_points
    coord_dofs = mesh.geometry.dofmap
    x_g = mesh.geometry.x

    cmap = mesh.geometry.cmap
    x_coord_new = np.zeros([len(points), mesh.geometry.dim])

    i = 0
    for node in range(len(points)):
        x_coord_new[i] = x_g[coord_dofs.links(0)[node], :mesh.geometry.dim]
        i += 1

    x = cmap.push_forward(X, x_coord_new)
    assert np.allclose(x[:, 0], X[:, 0])
    assert np.allclose(x[:, 1], 2 * X[:, 1])
    assert np.allclose(x[:, 2], 3 * X[:, 2])