Пример #1
0
def test_N2curl_interpolation(cell_type, order):
    mesh = one_cell_mesh(cell_type)
    tdim = mesh.topology.dim

    # TODO: fix higher order elements
    if tdim == 2 and order > 1:
        pytest.skip("N2curl order > 1 in 2D needs fixing")

    V = FunctionSpace(mesh, ("Nedelec 2nd kind H(curl)", order))
    v = Function(V)

    if tdim == 2:

        def f(x):
            return (x[1]**order, 2 * x[0])
    else:

        def f(x):
            return (x[1]**order + 2 * x[0], x[2]**order, -3 * x[2])

    v.interpolate(f)
    points = [random_point_in_cell(cell_type) for count in range(5)]
    cells = [0 for count in range(5)]
    values = v.eval(points, cells)
    assert np.allclose(values, [f(p) for p in points])
Пример #2
0
def test_save_and_read_function(tempdir):
    filename = os.path.join(tempdir, "function.h5")

    mesh = UnitSquareMesh(MPI.comm_world, 10, 10)
    Q = FunctionSpace(mesh, ("CG", 3))
    F0 = Function(Q)
    F1 = Function(Q)

    def E(x):
        return x[0]

    F0.interpolate(E)

    # Save to HDF5 File

    hdf5_file = HDF5File(mesh.mpi_comm(), filename, "w")
    hdf5_file.write(F0, "/function")
    hdf5_file.close()

    # Read back from file
    hdf5_file = HDF5File(mesh.mpi_comm(), filename, "r")
    F1 = hdf5_file.read_function(Q, "/function")
    F0.vector.axpy(-1.0, F1.vector)
    assert F0.vector.norm() < 1.0e-12
    hdf5_file.close()
Пример #3
0
def test_scatter_reverse(element):

    comm = MPI.COMM_WORLD
    mesh = UnitSquareMesh(MPI.COMM_WORLD, 5, 5)
    V = FunctionSpace(mesh, element)
    u = Function(V)
    bs = V.dofmap.bs

    u.interpolate(lambda x: [x[i] for i in range(bs)])

    # Reverse scatter (insert) should have no effect
    w0 = u.x.array.copy()
    u.x.scatter_reverse(cpp.common.ScatterMode.insert)
    assert np.allclose(w0, u.x.array)

    # Fill with MPI rank, and sum all entries in the vector (including ghosts)
    u.x.array.fill(comm.rank)
    all_count0 = MPI.COMM_WORLD.allreduce(u.x.array.sum(), op=MPI.SUM)

    # Reverse scatter (add)
    u.x.scatter_reverse(cpp.common.ScatterMode.add)
    num_ghosts = V.dofmap.index_map.num_ghosts
    ghost_count = MPI.COMM_WORLD.allreduce(num_ghosts * comm.rank, op=MPI.SUM)

    # New count should have gone up by the number of ghosts times their rank
    # on all processes
    all_count1 = MPI.COMM_WORLD.allreduce(u.x.array.sum(), op=MPI.SUM)
    assert all_count1 == (all_count0 + bs * ghost_count)
Пример #4
0
def test_save_and_checkpoint_scalar(tempdir, encoding, fe_degree, fe_family,
                                    tdim, n):
    if invalid_fe(fe_family, fe_degree):
        pytest.skip("Trivial finite element")

    filename = os.path.join(tempdir, "u1_checkpoint.xdmf")
    mesh = mesh_factory(tdim, n)
    FE = FiniteElement(fe_family, mesh.ufl_cell(), fe_degree)
    V = FunctionSpace(mesh, FE)
    u_in = Function(V)
    u_out = Function(V)

    if has_petsc_complex:

        def expr_eval(x):
            return x[0] + 1.0j * x[0]

        u_out.interpolate(expr_eval)
    else:

        def expr_eval(x):
            return x[0]

        u_out.interpolate(expr_eval)

    with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file:
        file.write_checkpoint(u_out, "u_out", 0)

    with XDMFFile(mesh.mpi_comm(), filename) as file:
        u_in = file.read_checkpoint(V, "u_out", 0)

    u_in.vector.axpy(-1.0, u_out.vector)
    assert u_in.vector.norm() < 1.0e-12
Пример #5
0
def test_interpolation_mismatch_rank1(W):
    def f(values, x):
        return np.ones((2, x.shape[1]))

    u = Function(W)
    with pytest.raises(RuntimeError):
        u.interpolate(f)
Пример #6
0
def test_scatter_forward(element):

    mesh = UnitSquareMesh(MPI.COMM_WORLD, 5, 5)
    V = FunctionSpace(mesh, element)
    u = Function(V)
    bs = V.dofmap.bs

    u.interpolate(lambda x: [x[i] for i in range(bs)])

    # Forward scatter should have no effect
    w0 = u.x.array.copy()
    u.x.scatter_forward()
    assert np.allclose(w0, u.x.array)

    # Fill local array with the mpi rank
    u.x.array.fill(MPI.COMM_WORLD.rank)
    w0 = u.x.array.copy()
    u.x.scatter_forward()

    # Now the ghosts should have the value of the rank of
    # the owning process
    ghost_owners = u.function_space.dofmap.index_map.ghost_owner_rank()
    ghost_owners = np.repeat(ghost_owners, bs)
    local_size = u.function_space.dofmap.index_map.size_local * bs
    assert np.allclose(u.x.array[local_size:], ghost_owners)
def test_vector_p1_3d():
    meshc = UnitCubeMesh(MPI.comm_world, 2, 3, 4)
    meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5)

    Vc = VectorFunctionSpace(meshc, ("CG", 1))
    Vf = VectorFunctionSpace(meshf, ("CG", 1))

    def u(x):
        values0 = x[0] + 2.0 * x[1]
        values1 = 4.0 * x[0]
        values2 = 3.0 * x[2] + x[0]
        return np.stack([values0, values1, values2], axis=0)

    uc, uf = Function(Vc), Function(Vf)
    uc.interpolate(u)
    uf.interpolate(u)

    mat = PETScDMCollection.create_transfer_matrix(Vc._cpp_object,
                                                   Vf._cpp_object)
    Vuc = Function(Vf)
    mat.mult(uc.vector, Vuc.vector)

    diff = Vuc.vector
    diff.axpy(-1, uf.vector)
    assert diff.norm() < 1.0e-12
def test_taylor_hood_cube():
    pytest.xfail("Problem with Mixed Function Spaces")
    meshc = UnitCubeMesh(MPI.comm_world, 2, 2, 2)
    meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5)

    Ve = VectorElement("CG", meshc.ufl_cell(), 2)
    Qe = FiniteElement("CG", meshc.ufl_cell(), 1)
    Ze = MixedElement([Ve, Qe])

    Zc = FunctionSpace(meshc, Ze)
    Zf = FunctionSpace(meshf, Ze)

    def z(x):
        return np.row_stack((x[0] * x[1],
                             x[1] * x[2],
                             x[2] * x[0],
                             x[0] + 3.0 * x[1] + x[2]))

    zc, zf = Function(Zc), Function(Zf)
    zc.interpolate(z)
    zf.interpolate(z)

    mat = PETScDMCollection.create_transfer_matrix(Zc, Zf)
    Zuc = Function(Zf)
    mat.mult(zc.vector, Zuc.vector)
    Zuc.vector.update_ghost_values()

    diff = Function(Zf)
    diff.assign(Zuc - zf)
    assert diff.vector.norm("l2") < 1.0e-12
Пример #9
0
def test_mixed_interpolation(cell_type, order):
    """Test that interpolation is correct in a MixedElement."""
    mesh = one_cell_mesh(cell_type)
    tdim = mesh.topology.dim

    A = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), order)
    B = ufl.VectorElement("Lagrange", mesh.ufl_cell(), order)

    V = FunctionSpace(mesh, ufl.MixedElement([A, B]))
    v = Function(V)

    if tdim == 1:

        def f(x):
            return (x[0]**order, 2 * x[0])
    elif tdim == 2:

        def f(x):
            return (x[1], 2 * x[0]**order, 3 * x[1])
    else:

        def f(x):
            return (x[1], 2 * x[0]**order, 3 * x[2], 4 * x[0])

    v.interpolate(f)
    points = [random_point_in_cell(cell_type) for count in range(5)]
    cells = [0 for count in range(5)]
    values = v.eval(points, cells)

    for p, v in zip(points, values):
        assert np.allclose(v, f(p))
Пример #10
0
def test_facet_normals(cell_type):
    """Test that FacetNormal is outward facing"""
    for count in range(5):
        mesh = unit_cell(cell_type)
        tdim = mesh.topology.dim

        V = VectorFunctionSpace(mesh, ("Lagrange", 1))
        normal = FacetNormal(mesh)
        v = Function(V)

        map_f = mesh.topology.index_map(tdim - 1)
        num_facets = map_f.size_local + map_f.num_ghosts
        indices = np.arange(0, num_facets)
        values = np.arange(0, num_facets, dtype=np.intc)
        marker = MeshTags(mesh, tdim - 1, indices, values)

        # For each facet, check that the inner product of the normal and
        # the vector that has a positive normal component on only that facet
        # is positive
        for i in range(num_facets):
            if cell_type == CellType.interval:
                co = mesh.geometry.x[i]
                v.interpolate(lambda x: x[0] - co[0])
            if cell_type == CellType.triangle:
                co = mesh.geometry.x[i]
                # Vector function that is zero at `co` and points away from `co`
                # so that there is no normal component on two edges and the integral
                # over the other edge is 1
                v.interpolate(lambda x: ((x[0] - co[0]) / 2,
                                         (x[1] - co[1]) / 2))
            elif cell_type == CellType.tetrahedron:
                co = mesh.geometry.x[i]
                # Vector function that is zero at `co` and points away from `co`
                # so that there is no normal component on three faces and the integral
                # over the other edge is 1
                v.interpolate(lambda x: ((x[0] - co[0]) / 3, (x[1] - co[1]) /
                                         3, (x[2] - co[2]) / 3))
            elif cell_type == CellType.quadrilateral:
                # function that is 0 on one edge and points away from that edge
                # so that there is no normal component on three edges
                v.interpolate(lambda x: tuple(x[j] - i % 2 if j == i // 2 else
                                              0 * x[j] for j in range(2)))
            elif cell_type == CellType.hexahedron:
                # function that is 0 on one face and points away from that face
                # so that there is no normal component on five faces
                v.interpolate(lambda x: tuple(x[j] - i % 2 if j == i // 3 else
                                              0 * x[j] for j in range(3)))

            # assert that the integrals these functions dotted with the normal over a face
            # is 1 on one face and 0 on the others
            ones = 0
            for j in range(num_facets):
                a = inner(v, normal) * ds(subdomain_data=marker,
                                          subdomain_id=j)
                result = fem.assemble_scalar(a)
                if np.isclose(result, 1):
                    ones += 1
                else:
                    assert np.isclose(result, 0)
            assert ones == 1
Пример #11
0
def run_vector_test(V, poly_order):
    """Test that interpolation is correct in a scalar valued space."""
    random.seed(12)
    tdim = V.mesh.topology.dim

    if tdim == 1:

        def f(x):
            return x[0]**poly_order
    elif tdim == 2:

        def f(x):
            return (x[1]**min(poly_order, 1), 2 * x[0]**poly_order)
    else:

        def f(x):
            return (x[1]**min(poly_order, 1), 2 * x[0]**poly_order,
                    3 * x[2]**min(poly_order, 2))

    v = Function(V)
    v.interpolate(f)
    points = [random_point_in_cell(V.mesh) for count in range(5)]
    cells = [0 for count in range(5)]
    values = v.eval(points, cells)
    for p, val in zip(points, values):
        assert np.allclose(val, f(p))
Пример #12
0
def test_scalar_interpolation(cell_type, order):
    """Test that interpolation is correct in a FunctionSpace"""
    mesh = one_cell_mesh(cell_type)
    tdim = mesh.topology.dim
    V = FunctionSpace(mesh, ("Lagrange", order))
    v = Function(V)

    if tdim == 1:

        def f(x):
            return x[0]**order
    elif tdim == 2:

        def f(x):
            return x[1]**order + 2 * x[0]
    else:

        def f(x):
            return x[1]**order + 2 * x[0] - 3 * x[2]

    v.interpolate(f)
    points = [random_point_in_cell(cell_type) for count in range(5)]
    cells = [0 for count in range(5)]
    values = v.eval(points, cells)
    for p, v in zip(points, values):
        assert np.allclose(v, f(p))
Пример #13
0
def test_fourth_order_quad(L, H, Z):
    """Test by comparing integration of z+x*y against sympy/scipy integration
    of a quad element. Z>0 implies curved element.

      *---------*   20-21-22-23-24-41--42--43--44
      |         |   |           |              |
      |         |   15 16 17 18 19 37  38  39  40
      |         |   |           |              |
      |         |   10 11 12 13 14 33  34  35  36
      |         |   |           |              |
      |         |   5  6  7  8  9  29  30  31  32
      |         |   |           |              |
      *---------*   0--1--2--3--4--25--26--27--28

    """
    points = np.array([[0, 0, 0], [L / 4, 0, 0], [L / 2, 0, 0],               # 0 1 2
                       [3 * L / 4, 0, 0], [L, 0, 0],                          # 3 4
                       [0, H / 4, -Z / 3], [L / 4, H / 4, -Z / 3], [L / 2, H / 4, -Z / 3],   # 5 6 7
                       [3 * L / 4, H / 4, -Z / 3], [L, H / 4, -Z / 3],                  # 8 9
                       [0, H / 2, 0], [L / 4, H / 2, 0], [L / 2, H / 2, 0],   # 10 11 12
                       [3 * L / 4, H / 2, 0], [L, H / 2, 0],                  # 13 14
                       [0, (3 / 4) * H, 0], [L / 4, (3 / 4) * H, 0],          # 15 16
                       [L / 2, (3 / 4) * H, 0], [3 * L / 4, (3 / 4) * H, 0],  # 17 18
                       [L, (3 / 4) * H, 0], [0, H, Z], [L / 4, H, Z],         # 19 20 21
                       [L / 2, H, Z], [3 * L / 4, H, Z], [L, H, Z],           # 22 23 24
                       [(5 / 4) * L, 0, 0], [(6 / 4) * L, 0, 0],              # 25 26
                       [(7 / 4) * L, 0, 0], [2 * L, 0, 0],                    # 27 28
                       [(5 / 4) * L, H / 4, -Z / 3], [(6 / 4) * L, H / 4, -Z / 3],      # 29 30
                       [(7 / 4) * L, H / 4, -Z / 3], [2 * L, H / 4, -Z / 3],            # 31 32
                       [(5 / 4) * L, H / 2, 0], [(6 / 4) * L, H / 2, 0],      # 33 34
                       [(7 / 4) * L, H / 2, 0], [2 * L, H / 2, 0],            # 35 36
                       [(5 / 4) * L, 3 / 4 * H, 0],                           # 37
                       [(6 / 4) * L, 3 / 4 * H, 0],                           # 38
                       [(7 / 4) * L, 3 / 4 * H, 0], [2 * L, 3 / 4 * H, 0],    # 39 40
                       [(5 / 4) * L, H, Z], [(6 / 4) * L, H, Z],              # 41 42
                       [(7 / 4) * L, H, Z], [2 * L, H, Z]])                   # 43 44

    # VTK ordering
    cells = np.array([[0, 4, 24, 20, 1, 2, 3, 9, 14, 19, 21, 22, 23, 5, 10, 15, 6, 7, 8, 11, 12, 13, 16, 17, 18],
                      [4, 28, 44, 24, 25, 26, 27, 32, 36, 40, 41, 42, 43, 9, 14, 19,
                       29, 30, 31, 33, 34, 35, 37, 38, 39]])
    cells = cells[:, perm_vtk(CellType.quadrilateral, cells.shape[1])]
    cell = ufl.Cell("quadrilateral", geometric_dimension=points.shape[1])
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 4))
    mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)

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

    V = FunctionSpace(mesh, ("CG", 4))
    u = Function(V)
    u.interpolate(e2)

    intu = assemble_scalar(u * dx(mesh))
    intu = mesh.mpi_comm().allreduce(intu, op=MPI.SUM)

    nodes = [0, 5, 10, 15, 20]
    ref = sympy_scipy(points, nodes, 2 * L, H)
    assert ref == pytest.approx(intu, rel=1e-5)
Пример #14
0
def xtest_quadrilateral_integral(space_type, space_order):
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "quadrilateral", 1))
    temp_points = np.array([[-1., -1.], [0., 0.], [1., 0.], [-1., 1.],
                            [0., 1.], [2., 2.]])

    for repeat in range(10):
        order = [i for i, j in enumerate(temp_points)]
        shuffle(order)
        points = np.zeros(temp_points.shape)
        for i, j in enumerate(order):
            points[j] = temp_points[i]

        connections = {0: [1, 2], 1: [0, 3], 2: [0, 3], 3: [1, 2]}

        cells = []
        for cell in [[0, 1, 3, 4], [1, 2, 4, 5]]:
            # Randomly number the cell
            start = choice(range(4))
            cell_order = [start]
            for i in range(2):
                diff = choice([
                    i for i in connections[start] if i not in cell_order
                ]) - cell_order[0]
                cell_order += [c + diff for c in cell_order]
            cells.append([order[cell[i]] for i in cell_order])

        mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
        V = FunctionSpace(mesh, (space_type, space_order))
        Vvec = VectorFunctionSpace(mesh, ("P", 1))
        dofs = [i for i in V.dofmap.cell_dofs(0) if i in V.dofmap.cell_dofs(1)]

        for d in dofs:
            v = Function(V)
            v.vector[:] = [1 if i == d else 0 for i in range(V.dim)]
            if space_type in ["RTCF"]:
                # Hdiv
                def normal(x):
                    values = np.zeros((2, x.shape[1]))
                    values[0] = [1 for i in values[0]]
                    return values

                n = Function(Vvec)
                n.interpolate(normal)
                form = ufl.inner(ufl.jump(v), n) * ufl.dS
            elif space_type in ["RTCE"]:
                # Hcurl
                def tangent(x):
                    values = np.zeros((2, x.shape[1]))
                    values[1] = [1 for i in values[1]]
                    return values

                t = Function(Vvec)
                t.interpolate(tangent)
                form = ufl.inner(ufl.jump(v), t) * ufl.dS
            else:
                form = ufl.jump(v) * ufl.dS

            value = fem.assemble_scalar(form)
            assert np.isclose(value, 0)
Пример #15
0
def test_mixed_interpolation():
    """Test that interpolation raised an exception."""
    mesh = one_cell_mesh(CellType.triangle)
    A = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
    B = ufl.VectorElement("Lagrange", mesh.ufl_cell(), 1)
    v = Function(FunctionSpace(mesh, ufl.MixedElement([A, B])))
    with pytest.raises(RuntimeError):
        v.interpolate(lambda x: (x[1], 2 * x[0], 3 * x[1]))
Пример #16
0
def test_interpolation_function(mesh):
    V = FunctionSpace(mesh, ("CG", 1))
    u = Function(V)
    u.vector.set(1)
    Vh = FunctionSpace(mesh, ("CG", 1))
    uh = Function(Vh)
    uh.interpolate(u)
    assert np.allclose(uh.vector.array, 1)
Пример #17
0
def solve_system(N):
    fenics_mesh = dolfinx.UnitCubeMesh(fenicsx_comm, N, N, N)
    fenics_space = dolfinx.FunctionSpace(fenics_mesh, ("CG", 1))
    u = ufl.TrialFunction(fenics_space)
    v = ufl.TestFunction(fenics_space)
    k = 2
    # print(u*v*ufl.ds)
    form = (ufl.inner(ufl.grad(u), ufl.grad(v)) -
            k**2 * ufl.inner(u, v)) * ufl.dx

    # locate facets on the cube boundary
    facets = locate_entities_boundary(
        fenics_mesh, 2, lambda x: np.logical_or(
            np.logical_or(
                np.logical_or(np.isclose(x[2], 0.0), np.isclose(x[2], 1.0)),
                np.logical_or(np.isclose(x[1], 0.0), np.isclose(x[1], 1.0))),
            np.logical_or(np.isclose(x[0], 0.0), np.isclose(x[0], 1.0))))

    facets.sort()

    # alternative - more general approach
    boundary = entities_to_geometry(
        fenics_mesh,
        fenics_mesh.topology.dim - 1,
        exterior_facet_indices(fenics_mesh),
        True,
    )
    # print(len(facets)
    assert len(facets) == len(exterior_facet_indices(fenics_mesh))

    u0 = fem.Function(fenics_space)

    with u0.vector.localForm() as u0_loc:
        u0_loc.set(0)
    # solution vector
    bc = DirichletBC(u0, locate_dofs_topological(fenics_space, 2, facets))

    A = 1 + 1j
    f = Function(fenics_space)
    f.interpolate(lambda x: A * k**2 * np.cos(k * x[0]) * np.cos(k * x[1]))

    L = ufl.inner(f, v) * ufl.dx
    u0.name = "u"
    problem = fem.LinearProblem(form,
                                L,
                                u=u0,
                                petsc_options={
                                    "ksp_type": "preonly",
                                    "pc_type": "lu"
                                })
    # problem = fem.LinearProblem(form, L, bcs=[bc], u=u0, petsc_options={"ksp_type": "preonly", "pc_type": "lu"})

    start_time = time.time()
    soln = problem.solve()
    if world_rank == 0:
        print("--- fenics solve done in %s seconds ---" %
              (time.time() - start_time))
Пример #18
0
def run_scalar_test(mesh, V, degree):
    """ Manufactured Poisson problem, solving u = x[1]**p, where p is the
    degree of the Lagrange function space.

    """
    u, v = TrialFunction(V), TestFunction(V)
    a = inner(grad(u), grad(v)) * dx

    # Get quadrature degree for bilinear form integrand (ignores effect of non-affine map)
    a = inner(grad(u), grad(v)) * dx(metadata={"quadrature_degree": -1})
    a.integrals()[0].metadata()["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree(a)

    # Source term
    x = SpatialCoordinate(mesh)
    u_exact = x[1]**degree
    f = - div(grad(u_exact))

    # Set quadrature degree for linear form integrand (ignores effect of non-affine map)
    L = inner(f, v) * dx(metadata={"quadrature_degree": -1})

    L.integrals()[0].metadata()["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree(L)
    L = fem.Form(L)

    u_bc = Function(V)
    u_bc.interpolate(lambda x: x[1]**degree)

    # Create Dirichlet boundary condition
    facetdim = mesh.topology.dim - 1
    mesh.topology.create_connectivity(facetdim, mesh.topology.dim)
    bndry_facets = np.where(np.array(cpp.mesh.compute_boundary_facets(mesh.topology)) == 1)[0]
    bdofs = locate_dofs_topological(V, facetdim, bndry_facets)
    bc = DirichletBC(u_bc, bdofs)

    b = assemble_vector(L)
    apply_lifting(b, [a], [[bc]])
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    set_bc(b, [bc])

    a = fem.Form(a)
    A = assemble_matrix(a, [bc])
    A.assemble()

    # Create LU linear solver
    solver = PETSc.KSP().create(MPI.COMM_WORLD)
    solver.setType(PETSc.KSP.Type.PREONLY)
    solver.getPC().setType(PETSc.PC.Type.LU)
    solver.setOperators(A)

    uh = Function(V)
    solver.solve(b, uh.vector)
    uh.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)

    M = (u_exact - uh)**2 * dx
    M = fem.Form(M)

    error = mesh.mpi_comm().allreduce(assemble_scalar(M), op=MPI.SUM)
    assert np.absolute(error) < 1.0e-14
Пример #19
0
def xtest_third_order_tri():
    #  *---*---*---*   3--11--10--2
    #  | \         |   | \        |
    #  *   *   *   *   8   7  15  13
    #  |     \     |   |    \     |
    #  *  *    *   *   9  14  6   12
    #  |         \ |   |        \ |
    #  *---*---*---*   0--4---5---1
    for H in (1.0, 2.0):
        for Z in (0.0, 0.5):
            L = 1
            points = np.array([
                [0, 0, 0],
                [L, 0, 0],
                [L, H, Z],
                [0, H, Z],  # 0, 1, 2, 3
                [L / 3, 0, 0],
                [2 * L / 3, 0, 0],  # 4, 5
                [2 * L / 3, H / 3, 0],
                [L / 3, 2 * H / 3, 0],  # 6, 7
                [0, 2 * H / 3, 0],
                [0, H / 3, 0],  # 8, 9
                [2 * L / 3, H, Z],
                [L / 3, H, Z],  # 10, 11
                [L, H / 3, 0],
                [L, 2 * H / 3, 0],  # 12, 13
                [L / 3, H / 3, 0],  # 14
                [2 * L / 3, 2 * H / 3, 0]
            ])  # 15
            cells = np.array([[0, 1, 3, 4, 5, 6, 7, 8, 9, 14],
                              [1, 2, 3, 12, 13, 10, 11, 7, 6, 15]])
            cells = permute_cell_ordering(
                cells,
                permutation_vtk_to_dolfin(CellType.triangle, cells.shape[1]))
            mesh = Mesh(MPI.COMM_WORLD,
                        CellType.triangle,
                        points,
                        cells, [],
                        degree=3)

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

            degree = mesh.geometry.dofmap_layout().degree()
            # Interpolate function
            V = FunctionSpace(mesh, ("CG", degree))
            u = Function(V)
            u.interpolate(e2)

            intu = assemble_scalar(u * dx(metadata={"quadrature_degree": 40}))
            intu = mesh.mpi_comm().allreduce(intu, op=MPI.SUM)

            nodes = [0, 9, 8, 3]
            ref = sympy_scipy(points, nodes, L, H)
            assert ref == pytest.approx(intu, rel=1e-6)
Пример #20
0
def test_plus_minus_vector(cell_type, pm1, pm2):
    """Test that ('+') and ('-') match up with the correct DOFs for DG functions"""
    results = []
    orders = []
    spaces = []
    for count in range(3):
        for agree in [True, False]:
            mesh, order = two_unit_cells(cell_type, agree, return_order=True)

            if cell_type in [
                    CellType.interval, CellType.triangle, CellType.tetrahedron
            ]:
                V = FunctionSpace(mesh, ("DG", 1))
            else:
                V = FunctionSpace(mesh, ("DQ", 1))
            f = Function(V)
            f.interpolate(lambda x: x[0] - 2 * x[1])
            v = TestFunction(V)
            a = inner(f(pm1), v(pm2)) * dS
            result = fem.assemble_vector(a)
            result.assemble()
            spaces.append(V)
            results.append(result)
            orders.append(order)

    for i, j in combinations(zip(results, spaces, orders), 2):
        dof_order = []
        for cell in range(2):
            for point in range(len(mesh.geometry.points)):
                point_n = j[2][point]
                cell_points = list(j[1].mesh.cells()[cell])
                if point_n in cell_points:
                    point_n_in_cell = cell_points.index(point_n)
                    dofmap = j[1].dofmap.cell_dofs(cell)
                    j_dof_n = dofmap[point_n_in_cell]
                else:
                    j_dof_n = None

                point_n = i[2][point]
                cell_points = list(i[1].mesh.cells()[cell])
                if point_n in cell_points:
                    point_n_in_cell = cell_points.index(point_n)
                    dofmap = i[1].dofmap.cell_dofs(cell)
                    i_dof_n = dofmap[point_n_in_cell]
                else:
                    i_dof_n = None

                if i_dof_n is None:
                    assert j_dof_n is None
                else:
                    dof_order.append((i_dof_n, j_dof_n))

        for a, b in dof_order:
            assert np.isclose(i[0][a], j[0][b])
Пример #21
0
def xtest_triangle_integral(space_type, space_order):
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "triangle", 1))
    temp_points = np.array([[-1., -1.], [0., 0.], [1., 0.], [0., 1.]])

    for repeat in range(10):
        order = [i for i, j in enumerate(temp_points)]
        shuffle(order)
        points = np.zeros(temp_points.shape)
        for i, j in enumerate(order):
            points[j] = temp_points[i]

        cells = []
        for cell in [[0, 1, 3], [1, 2, 3]]:
            # Randomly number the cell
            cell_order = list(range(3))
            shuffle(cell_order)
            cells.append([order[cell[i]] for i in cell_order])

        mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
        V = FunctionSpace(mesh, (space_type, space_order))
        Vvec = VectorFunctionSpace(mesh, ("P", 1))
        dofs = [i for i in V.dofmap.cell_dofs(0) if i in V.dofmap.cell_dofs(1)]

        for d in dofs:
            v = Function(V)
            v.vector[:] = [
                1 if i == d else 0 for i in range(v.vector.local_size)
            ]
            if space_type in ["RT", "BDM"]:
                # Hdiv
                def normal(x):
                    values = np.zeros((2, x.shape[1]))
                    values[0] = [1 for i in values[0]]
                    return values

                n = Function(Vvec)
                n.interpolate(normal)
                form = ufl.inner(ufl.jump(v), n) * ufl.dS
            elif space_type in ["N1curl", "N2curl"]:
                # Hcurl
                def tangent(x):
                    values = np.zeros((2, x.shape[1]))
                    values[1] = [1 for i in values[1]]
                    return values

                t = Function(Vvec)
                t.interpolate(tangent)
                form = ufl.inner(ufl.jump(v), t) * ufl.dS
            else:
                form = ufl.jump(v) * ufl.dS

            value = fem.assemble_scalar(form)
            assert np.isclose(value, 0)
Пример #22
0
def test_eval_manifold():
    # Simple two-triangle surface in 3d
    vertices = [(0.0, 0.0, 1.0), (1.0, 1.0, 1.0), (1.0, 0.0, 0.0),
                (0.0, 1.0, 0.0)]
    cells = [(0, 1, 2), (0, 1, 3)]
    cell = ufl.Cell("triangle", geometric_dimension=3)
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 1))
    mesh = create_mesh(MPI.COMM_WORLD, cells, vertices, domain)
    Q = FunctionSpace(mesh, ("Lagrange", 1))
    u = Function(Q)
    u.interpolate(lambda x: x[0] + x[1])
    assert np.isclose(u.eval([0.75, 0.25, 0.5], 0)[0], 1.0)
Пример #23
0
def test_third_order_quad(L, H, Z):
    """Test by comparing integration of z+x*y against sympy/scipy integration
    of a quad element. Z>0 implies curved element.

      *---------*   3--8--9--2-22-23-17
      |         |   |        |       |
      |         |   11 14 15 7 26 27 21
      |         |   |        |       |
      |         |   10 12 13 6 24 25 20
      |         |   |        |       |
      *---------*   0--4--5--1-18-19-16

    """
    points = np.array([[0, 0, 0], [L, 0, 0], [L, H, Z], [0, H, Z],        # 0  1 2 3
                       [L / 3, 0, 0], [2 * L / 3, 0, 0],                  # 4  5
                       [L, H / 3, 0], [L, 2 * H / 3, 0],                  # 6  7
                       [L / 3, H, Z], [2 * L / 3, H, Z],                  # 8  9
                       [0, H / 3, 0], [0, 2 * H / 3, 0],                  # 10 11
                       [L / 3, H / 3, 0], [2 * L / 3, H / 3, 0],          # 12 13
                       [L / 3, 2 * H / 3, 0], [2 * L / 3, 2 * H / 3, 0],  # 14 15
                       [2 * L, 0, 0], [2 * L, H, Z],                      # 16 17
                       [4 * L / 3, 0, 0], [5 * L / 3, 0, 0],              # 18 19
                       [2 * L, H / 3, 0], [2 * L, 2 * H / 3, 0],          # 20 21
                       [4 * L / 3, H, Z], [5 * L / 3, H, Z],              # 22 23
                       [4 * L / 3, H / 3, 0], [5 * L / 3, H / 3, 0],           # 24 25
                       [4 * L / 3, 2 * H / 3, 0], [5 * L / 3, 2 * H / 3, 0]])  # 26 27

    # Change to multiple cells when matthews dof-maps work for quads
    cells = np.array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
                      [1, 16, 17, 2, 18, 19, 20, 21, 22, 23, 6, 7, 24, 25, 26, 27]])

    cells = permute_cell_ordering(cells, permutation_vtk_to_dolfin(CellType.quadrilateral, cells.shape[1]))
    mesh = Mesh(MPI.comm_world, CellType.quadrilateral, points, cells,
                [], GhostMode.none)

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

    # Interpolate function
    V = FunctionSpace(mesh, ("CG", 3))
    u = Function(V)
    cmap = fem.create_coordinate_map(mesh.ufl_domain())

    mesh.geometry.coord_mapping = cmap

    u.interpolate(e2)

    intu = assemble_scalar(u * dx(mesh))
    intu = MPI.sum(mesh.mpi_comm(), intu)

    nodes = [0, 3, 10, 11]
    ref = sympy_scipy(points, nodes, 2 * L, H)
    assert ref == pytest.approx(intu, rel=1e-6)
Пример #24
0
def test_plus_minus_vector(cell_type, pm1, pm2):
    """Test that ('+') and ('-') match up with the correct DOFs for DG functions"""
    results = []
    orders = []
    spaces = []
    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)

            if cell_type in [
                    CellType.interval, CellType.triangle, CellType.tetrahedron
            ]:
                V = FunctionSpace(mesh, ("DG", 1))
            else:
                V = FunctionSpace(mesh, ("DQ", 1))

            # Assemble vectors with combinations of + and - for a few
            # different numberings
            f = Function(V)
            f.interpolate(lambda x: x[0] - 2 * x[1])
            v = ufl.TestFunction(V)
            a = ufl.inner(f(pm1), v(pm2)) * ufl.dS
            result = fem.assemble_vector(a)
            result.assemble()
            spaces.append(V)
            results.append(result)
            orders.append(order)

    # Check that the above vectors all have the same values as the first
    # one, 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

        # For each cell
        for cell in range(2):
            # For each point in cell 0 in the 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

                assert np.isclose(results[0][dof0], result[dof1])
Пример #25
0
def test_interpolation_rank1(W):
    def f(x):
        values = np.empty((3, x.shape[1]))
        values[0] = 1.0
        values[1] = 1.0
        values[2] = 1.0
        return values

    w = Function(W)
    w.interpolate(f)
    x = w.vector
    assert x.max()[1] == 1.0
    assert x.min()[1] == 1.0
Пример #26
0
def test_eval_manifold():
    # Simple two-triangle surface in 3d
    vertices = [(0.0, 0.0, 1.0), (1.0, 1.0, 1.0), (1.0, 0.0, 0.0),
                (0.0, 1.0, 0.0)]
    cells = [(0, 1, 2), (0, 1, 3)]
    mesh = Mesh(MPI.COMM_WORLD, cpp.mesh.CellType.triangle,
                np.array(vertices, dtype=np.float64),
                np.array(cells, dtype=np.int32), [])

    Q = FunctionSpace(mesh, ("CG", 1))
    u = Function(Q)
    u.interpolate(lambda x: x[0] + x[1])
    assert np.isclose(u.eval([0.75, 0.25, 0.5], 0)[0], 1.0)
Пример #27
0
def test_third_order_tri():
    #  *---*---*---*   3--11--10--2
    #  | \         |   | \        |
    #  *   *   *   *   8   7  15  13
    #  |     \     |   |    \     |
    #  *  *    *   *   9  14  6   12
    #  |         \ |   |        \ |
    #  *---*---*---*   0--4---5---1
    for H in (1.0, 2.0):
        for Z in (0.0, 0.5):
            L = 1
            points = np.array([
                [0, 0, 0],
                [L, 0, 0],
                [L, H, Z],
                [0, H, Z],  # 0, 1, 2, 3
                [L / 3, 0, 0],
                [2 * L / 3, 0, 0],  # 4, 5
                [2 * L / 3, H / 3, 0],
                [L / 3, 2 * H / 3, 0],  # 6, 7
                [0, 2 * H / 3, 0],
                [0, H / 3, 0],  # 8, 9
                [2 * L / 3, H, Z],
                [L / 3, H, Z],  # 10, 11
                [L, H / 3, 0],
                [L, 2 * H / 3, 0],  # 12, 13
                [L / 3, H / 3, 0],  # 14
                [2 * L / 3, 2 * H / 3, 0]
            ])  # 15
            cells = np.array([[0, 1, 3, 4, 5, 6, 7, 8, 9, 14],
                              [1, 2, 3, 12, 13, 10, 11, 7, 6, 15]])
            cells = cells[:, perm_vtk(CellType.triangle, cells.shape[1])]

            cell = ufl.Cell("triangle", geometric_dimension=points.shape[1])
            domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 3))
            mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)

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

            # Interpolate function
            V = FunctionSpace(mesh, ("Lagrange", 3))
            u = Function(V)
            u.interpolate(e2)

            intu = assemble_scalar(u * dx(metadata={"quadrature_degree": 40}))
            intu = mesh.mpi_comm().allreduce(intu, op=MPI.SUM)

            nodes = [0, 9, 8, 3]
            ref = sympy_scipy(points, nodes, L, H)
            assert ref == pytest.approx(intu, rel=1e-6)
Пример #28
0
def test_facet_integral(cell_type):
    """Test that the integral of a function over a facet is correct"""
    for count in range(5):
        mesh = unit_cell(cell_type)
        tdim = mesh.topology.dim

        V = FunctionSpace(mesh, ("Lagrange", 2))
        v = Function(V)

        map_f = mesh.topology.index_map(tdim - 1)
        num_facets = map_f.size_local + map_f.num_ghosts
        indices = np.arange(0, num_facets)
        values = np.arange(0, num_facets, dtype=np.intc)
        marker = MeshTags(mesh, tdim - 1, indices, values)

        # Functions that will have the same integral over each facet
        if cell_type == CellType.triangle:
            root = 3 ** 0.25  # 4th root of 3
            v.interpolate(lambda x: (x[0] - 1 / root) ** 2 + (x[1] - root / 3) ** 2)
        elif cell_type == CellType.quadrilateral:
            v.interpolate(lambda x: x[0] * (1 - x[0]) + x[1] * (1 - x[1]))
        elif cell_type == CellType.tetrahedron:
            s = 2 ** 0.5 * 3 ** (1 / 3)  # side length
            v.interpolate(lambda x: (x[0] - s / 2) ** 2 + (x[1] - s / 2 / np.sqrt(3)) ** 2
                          + (x[2] - s * np.sqrt(2 / 3) / 4) ** 2)
        elif cell_type == CellType.hexahedron:
            v.interpolate(lambda x: x[0] * (1 - x[0]) + x[1] * (1 - x[1]) + x[2] * (1 - x[2]))

        # assert that the integral of these functions over each face are equal
        out = []
        for j in range(num_facets):
            a = v * ds(subdomain_data=marker, subdomain_id=j)
            result = fem.assemble_scalar(a)
            out.append(result)
            assert np.isclose(result, out[0])
Пример #29
0
def test_save_1d_scalar(tempdir):
    mesh = UnitIntervalMesh(MPI.COMM_WORLD, 32)

    def f(x):
        return x[0]

    u = Function(FunctionSpace(mesh, ("CG", 2)))
    u.interpolate(f)
    u.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)

    filename = os.path.join(tempdir, "u.pvd")
    with VTKFile(MPI.COMM_WORLD, filename, "w") as vtk:
        vtk.write_function(u, 0.)
        vtk.write_function(u, 1.)
Пример #30
0
def test_manufactured_vector1(family, degree, filename, datadir):
    """Projection into H(div/curl) spaces"""

    with XDMFFile(MPI.COMM_WORLD,
                  os.path.join(datadir, filename),
                  "r",
                  encoding=XDMFFile.Encoding.ASCII) as xdmf:
        mesh = xdmf.read_mesh(name="Grid")

    V = FunctionSpace(mesh, (family, degree))
    W = VectorFunctionSpace(mesh, ("CG", degree))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
    a = inner(u, v) * dx

    # Source term
    x = SpatialCoordinate(mesh)
    u_ref = x[0]**degree
    L = inner(u_ref, v[0]) * dx

    b = assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    A = assemble_matrix(a)
    A.assemble()

    # Create LU linear solver (Note: need to use a solver that
    # re-orders to handle pivots, e.g. not the PETSc built-in LU
    # solver)
    solver = PETSc.KSP().create(MPI.COMM_WORLD)
    solver.setType("preonly")
    solver.getPC().setType('lu')
    solver.setOperators(A)

    # Solve
    uh = Function(V)
    solver.solve(b, uh.vector)
    uh.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                          mode=PETSc.ScatterMode.FORWARD)

    u_exact = Function(W)
    u_exact.interpolate(lambda x: np.array([
        x[0]**degree if i == 0 else 0 * x[0] for i in range(mesh.topology.dim)
    ]))

    M = inner(uh - u_exact, uh - u_exact) * dx
    M = fem.Form(M)
    error = mesh.mpi_comm().allreduce(assemble_scalar(M), op=MPI.SUM)

    assert np.absolute(error) < 1.0e-14