示例#1
0
def test_compute_closest_entity_1d(dim):
    ref_distance = 0.75
    N = 16
    points = np.array([[-ref_distance, 0, 0], [2 / N, 2 * ref_distance, 0]])
    mesh = create_unit_interval(MPI.COMM_WORLD, N)
    tree = BoundingBoxTree(mesh, dim)
    num_entities_local = mesh.topology.index_map(dim).size_local + mesh.topology.index_map(dim).num_ghosts
    entities = np.arange(num_entities_local, dtype=np.int32)
    midpoint_tree = create_midpoint_tree(mesh, dim, entities)
    closest_entities = compute_closest_entity(tree, midpoint_tree, mesh, points)

    # Find which entity is colliding with known closest point on mesh
    p_c = np.array([[0, 0, 0], [2 / N, 0, 0]])
    colliding_entity_bboxes = compute_collisions(tree, p_c)

    # Refine search by checking for actual collision if the entities are
    # cells
    if dim == mesh.topology.dim:

        colliding_cells = compute_colliding_cells(mesh, colliding_entity_bboxes, p_c)
        for i in range(points.shape[0]):
            # If colliding entity is on process
            if colliding_cells.links(i).size > 0:
                assert np.isin(closest_entities[i], colliding_cells.links(i))
    else:
        for i in range(points.shape[0]):
            # Only check closest entity if any bounding box on the
            # process intersects with the point
            if colliding_entity_bboxes.links(i).size > 0:
                assert np.isin(closest_entities[i], colliding_entity_bboxes.links(i))
示例#2
0
def test_ghost_facet_1d():
    N = 40
    mesh = create_unit_interval(MPI.COMM_WORLD,
                                N,
                                ghost_mode=GhostMode.shared_facet)
    assert mesh.topology.index_map(0).size_global == N + 1
    assert mesh.topology.index_map(1).size_global == N
def mesh_factory(tdim, n, ghost_mode=GhostMode.shared_facet):
    if tdim == 1:
        return create_unit_interval(MPI.COMM_WORLD, n, ghost_mode=ghost_mode)
    elif tdim == 2:
        return create_unit_square(MPI.COMM_WORLD, n, n, ghost_mode=ghost_mode)
    elif tdim == 3:
        return create_unit_cube(MPI.COMM_WORLD, n, n, n, ghost_mode=ghost_mode)
示例#4
0
def mesh_1d():
    """Create 1D mesh with degenerate cell"""
    mesh1d = create_unit_interval(MPI.COMM_WORLD, 4)
    i1 = np.where((mesh1d.geometry.x == (0.75, 0, 0)).all(axis=1))[0][0]
    i2 = np.where((mesh1d.geometry.x == (1, 0, 0)).all(axis=1))[0][0]
    mesh1d.geometry.x[i2] = mesh1d.geometry.x[i1]
    return mesh1d
示例#5
0
def test_save_1d_scalar(tempdir):
    mesh = create_unit_interval(MPI.COMM_WORLD, 32)
    u = Function(FunctionSpace(mesh, ("Lagrange", 2)))
    u.interpolate(lambda x: x[0])
    filename = os.path.join(tempdir, "u.pvd")
    with VTKFile(MPI.COMM_WORLD, filename, "w") as vtk:
        vtk.write_function(u, 0.)
示例#6
0
def mesh_factory(tdim, n):
    if tdim == 1:
        return create_unit_interval(MPI.COMM_WORLD, n)
    elif tdim == 2:
        return create_unit_square(MPI.COMM_WORLD, n, n)
    elif tdim == 3:
        return create_unit_cube(MPI.COMM_WORLD, n, n, n)
示例#7
0
def test_save_1d_tensor(tempdir):
    mesh = create_unit_interval(MPI.COMM_WORLD, 32)
    element = ufl.TensorElement("Lagrange", mesh.ufl_cell(), 2, shape=(2, 2))
    u = Function(FunctionSpace(mesh, element))
    u.x.array[:] = 1.0
    filename = os.path.join(tempdir, "u.pvd")
    with VTKFile(mesh.comm, filename, "w") as vtk:
        vtk.write_function(u, 0.)
示例#8
0
def test_save_and_load_1d_mesh(tempdir, encoding):
    filename = os.path.join(tempdir, "mesh.xdmf")
    mesh = create_unit_interval(MPI.COMM_WORLD, 32)
    with XDMFFile(mesh.comm, filename, "w", encoding=encoding) as file:
        file.write_mesh(mesh)
    with XDMFFile(MPI.COMM_WORLD, filename, "r", encoding=encoding) as file:
        mesh2 = file.read_mesh()
    assert mesh.topology.index_map(0).size_global == mesh2.topology.index_map(0).size_global
    assert mesh.topology.index_map(mesh.topology.dim).size_global == mesh2.topology.index_map(
        mesh.topology.dim).size_global
示例#9
0
def test_save_1d_scalar(tempdir, encoding, use_pathlib):
    filename2 = (Path(tempdir).joinpath("u1_.xdmf")
                 if use_pathlib else os.path.join(tempdir, "u1_.xdmf"))
    mesh = create_unit_interval(MPI.COMM_WORLD, 32)
    V = FunctionSpace(mesh, ("Lagrange", 2))
    u = Function(V)
    u.vector.set(1.0 + (
        1j if np.issubdtype(PETSc.ScalarType, np.complexfloating) else 0))
    with XDMFFile(mesh.comm, filename2, "w", encoding=encoding) as file:
        file.write_mesh(mesh)
        file.write_function(u)
def test_facet_area1D():
    mesh = create_unit_interval(MPI.COMM_WORLD, 10)

    # NOTE: Area of a vertex is defined to 1 in ufl
    c0 = ufl.FacetArea(mesh)
    c = Constant(mesh, ScalarType(1))

    ds = ufl.Measure("ds", domain=mesh)
    a0 = mesh.comm.allreduce(assemble_scalar(form(c * ds)), op=MPI.SUM)
    a = mesh.comm.allreduce(assemble_scalar(form(c0 * ds)), op=MPI.SUM)
    assert numpy.isclose(a.real, 2)
    assert numpy.isclose(a0.real, 2)
示例#11
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.)
示例#12
0
def test_compute_collisions_tree_1d(point):
    mesh_A = create_unit_interval(MPI.COMM_WORLD, 16)

    def locator_A(x):
        return x[0] >= point[0]
    # Locate all vertices of mesh A that should collide
    vertices_A = _cpp.mesh.locate_entities(mesh_A, 0, locator_A)
    mesh_A.topology.create_connectivity(0, mesh_A.topology.dim)
    v_to_c = mesh_A.topology.connectivity(0, mesh_A.topology.dim)

    # Find all cells connected to vertex in the collision bounding box
    cells_A = np.sort(np.unique(np.hstack([v_to_c.links(vertex) for vertex in vertices_A])))

    mesh_B = create_unit_interval(MPI.COMM_WORLD, 16)
    bgeom = mesh_B.geometry.x
    bgeom += point

    def locator_B(x):
        return x[0] <= 1

    # Locate all vertices of mesh B that should collide
    vertices_B = _cpp.mesh.locate_entities(mesh_B, 0, locator_B)
    mesh_B.topology.create_connectivity(0, mesh_B.topology.dim)
    v_to_c = mesh_B.topology.connectivity(0, mesh_B.topology.dim)

    # Find all cells connected to vertex in the collision bounding box
    cells_B = np.sort(np.unique(np.hstack([v_to_c.links(vertex) for vertex in vertices_B])))

    # Find colliding entities using bounding box trees
    tree_A = BoundingBoxTree(mesh_A, mesh_A.topology.dim)
    tree_B = BoundingBoxTree(mesh_B, mesh_B.topology.dim)
    entities = compute_collisions(tree_A, tree_B)
    entities_A = np.sort(np.unique([q[0] for q in entities]))
    entities_B = np.sort(np.unique([q[1] for q in entities]))
    assert np.allclose(entities_A, cells_A)
    assert np.allclose(entities_B, cells_B)
示例#13
0
def test_compute_collisions_point_1d():
    N = 16
    p = np.array([0.3, 0, 0])
    mesh = create_unit_interval(MPI.COMM_WORLD, N)
    dx = 1 / N
    cell_index = int(p[0] // dx)
    # Vertices of cell we should collide with
    vertices = np.array([[dx * cell_index, 0, 0], [dx * (cell_index + 1), 0, 0]])

    # Compute collision
    tdim = mesh.topology.dim
    tree = BoundingBoxTree(mesh, tdim)
    entities = compute_collisions(tree, p)
    assert len(entities.array) == 1

    # Get the vertices of the geometry
    geom_entities = _cpp.mesh.entities_to_geometry(mesh, tdim, entities.array, False)[0]
    x = mesh.geometry.x
    cell_vertices = x[geom_entities]
    # Check that we get the cell with correct vertices
    assert np.allclose(cell_vertices, vertices)
示例#14
0
def test_distance_interval():
    mesh = create_unit_interval(MPI.COMM_SELF, 1)
    assert squared_distance(mesh, mesh.topology.dim, [0],
                            [-1.0, 0, 0]) == pytest.approx(1.0)
    assert squared_distance(mesh, mesh.topology.dim, [0],
                            [0.5, 0, 0]) == pytest.approx(0.0)
示例#15
0
def test_ghost_vertex_1d():
    mesh = create_unit_interval(MPI.COMM_WORLD,
                                20,
                                ghost_mode=GhostMode.shared_vertex)
    assert mesh.topology.index_map(0).size_global == 21
    assert mesh.topology.index_map(1).size_global == 20
示例#16
0
def test_block_size_real(mesh):
    mesh = create_unit_interval(MPI.COMM_WORLD, 12)
    V = FiniteElement('DG', mesh.ufl_cell(), 0)
    R = FiniteElement('R', mesh.ufl_cell(), 0)
    X = FunctionSpace(mesh, V * R)
    assert X.dofmap.index_map_bs == 1
def test_diff_then_integrate():

    # Define 1D geometry
    n = 21
    mesh = create_unit_interval(MPI.COMM_WORLD, n)

    # Shift and scale mesh
    x0, x1 = 1.5, 3.14
    mesh.coordinates()[:] *= (x1 - x0)
    mesh.coordinates()[:] += x0

    x = SpatialCoordinate(mesh)[0]
    xs = 0.1 + 0.8 * x / x1  # scaled to be within [0.1,0.9]

    # Define list of expressions to test, and configure
    # accuracies these expressions are known to pass with.
    # The reason some functions are less accurately integrated is
    # likely that the default choice of quadrature rule is not perfect
    F_list = []

    def reg(exprs, acc=10):
        for expr in exprs:
            F_list.append((expr, acc))

    # FIXME: 0*dx and 1*dx fails in the ufl-ffcx-jit framework somewhere
    # reg([Constant(0.0, cell=cell)])
    # reg([Constant(1.0, cell=cell)])
    monomial_list = [x**q for q in range(2, 6)]
    reg(monomial_list)
    reg([2.3 * p + 4.5 * q for p in monomial_list for q in monomial_list])
    reg([x**x])
    reg([x**(x**2)], 8)
    reg([x**(x**3)], 6)
    reg([x**(x**4)], 2)
    # Special functions:
    reg([atan(xs)], 8)
    reg([sin(x), cos(x), exp(x)], 5)
    reg([ln(xs), pow(x, 2.7), pow(2.7, x)], 3)
    reg([asin(xs), acos(xs)], 1)
    reg([tan(xs)], 7)

    try:
        import scipy
    except ImportError:
        scipy = None

    if hasattr(math, 'erf') or scipy is not None:
        reg([erf(xs)])
    else:
        print(
            "Warning: skipping test of erf, old python version and no scipy.")

    # if 0:
    #     print("Warning: skipping tests of bessel functions, doesn't build on all platforms.")
    # elif scipy is None:
    #     print("Warning: skipping tests of bessel functions, missing scipy.")
    # else:
    #     for nu in (0, 1, 2):
    #         # Many of these are possibly more accurately integrated,
    #         # but 4 covers all and is sufficient for this test
    #         reg([bessel_J(nu, xs), bessel_Y(nu, xs), bessel_I(nu, xs), bessel_K(nu, xs)], 4)

    # To handle tensor algebra, make an x dependent input tensor
    # xx and square all expressions
    def reg2(exprs, acc=10):
        for expr in exprs:
            F_list.append((inner(expr, expr), acc))

    xx = as_matrix([[2 * x**2, 3 * x**3], [11 * x**5, 7 * x**4]])
    x3v = as_vector([3 * x**2, 5 * x**3, 7 * x**4])
    cc = as_matrix([[2, 3], [4, 5]])
    reg2([xx])
    reg2([x3v])
    reg2([cross(3 * x3v, as_vector([-x3v[1], x3v[0], x3v[2]]))])
    reg2([xx.T])
    reg2([tr(xx)])
    reg2([det(xx)])
    reg2([dot(xx, 0.1 * xx)])
    reg2([outer(xx, xx.T)])
    reg2([dev(xx)])
    reg2([sym(xx)])
    reg2([skew(xx)])
    reg2([elem_mult(7 * xx, cc)])
    reg2([elem_div(7 * xx, xx + cc)])
    reg2([elem_pow(1e-3 * xx, 1e-3 * cc)])
    reg2([elem_pow(1e-3 * cc, 1e-3 * xx)])
    reg2([elem_op(lambda z: sin(z) + 2, 0.03 * xx)], 2)  # pretty inaccurate...

    # FIXME: Add tests for all UFL operators:
    # These cause discontinuities and may be harder to test in the
    # above fashion:
    # 'inv', 'cofac',
    # 'eq', 'ne', 'le', 'ge', 'lt', 'gt', 'And', 'Or', 'Not',
    # 'conditional', 'sign',
    # 'jump', 'avg',
    # 'LiftingFunction', 'LiftingOperator',

    # FIXME: Test other derivatives: (but algorithms for operator
    # derivatives are the same!):
    # 'variable', 'diff',
    # 'Dx', 'grad', 'div', 'curl', 'rot', 'Dn', 'exterior_derivative',

    # Run through all operators defined above and compare integrals
    debug = 0
    for F, acc in F_list:
        # Apply UFL differentiation
        f = diff(F, SpatialCoordinate(mesh))[..., 0]
        if debug:
            print(F)
            print(x)
            print(f)

        # Apply integration with DOLFINx
        # (also passes through form compilation and jit)
        M = f * dx
        f_integral = assemble_scalar(M)  # noqa
        f_integral = mesh.comm.allreduce(f_integral, op=MPI.SUM)

        # Compute integral of f manually from anti-derivative F
        # (passes through pybind11 interface and uses UFL evaluation)
        F_diff = F((x1, )) - F((x0, ))

        # Compare results. Using custom relative delta instead
        # of decimal digits here because some numbers are >> 1.
        delta = min(abs(f_integral), abs(F_diff)) * 10**-acc
        assert f_integral - F_diff <= delta
示例#18
0
def test_empty_tree():
    mesh = create_unit_interval(MPI.COMM_WORLD, 16)
    bbtree = BoundingBoxTree(mesh, mesh.topology.dim, [])
    assert bbtree.num_bboxes == 0
示例#19
0
def test_save_1d_mesh(tempdir):
    filename = os.path.join(tempdir, "mesh.pvd")
    mesh = create_unit_interval(MPI.COMM_WORLD, 32)
    with VTKFile(MPI.COMM_WORLD, filename, "w") as vtk:
        vtk.write_mesh(mesh)
        vtk.write_mesh(mesh, 1)
示例#20
0
def interval():
    return create_unit_interval(MPI.COMM_WORLD, 18)
示例#21
0
    cell = ufl.Cell(shape, geometric_dimension=gdim)
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, degree))
    x = [[0., 0., 0.], [0., 1., 0.], [0., 1., 1.], [1, 1., 1]]
    cells = [[0, 1, 2, 3]]
    mesh = create_mesh(MPI.COMM_WORLD, cells, x, domain)
    assert squared_distance(mesh, mesh.topology.dim, [0],
                            [-1.0, -1.0, -1.0]) == pytest.approx(3.0)
    assert squared_distance(mesh, mesh.topology.dim, [0],
                            [-1.0, 0.5, 0.5]) == pytest.approx(1.0)
    assert squared_distance(mesh, mesh.topology.dim, [0],
                            [0.5, 0.5, 0.5]) == pytest.approx(0.0)


@pytest.mark.skip("volume_entities needs fixing")
@pytest.mark.parametrize('mesh', [
    create_unit_interval(MPI.COMM_WORLD, 18),
    create_unit_square(MPI.COMM_WORLD, 8, 9, CellType.triangle),
    create_unit_square(MPI.COMM_WORLD, 8, 9, CellType.quadrilateral),
    create_unit_cube(MPI.COMM_WORLD, 8, 9, 5, CellType.tetrahedron)
])
def test_volume_cells(mesh):
    tdim = mesh.topology.dim
    map = mesh.topology.index_map(tdim)
    num_cells = map.size_local
    v = _cpp.mesh.volume_entities(mesh, range(num_cells), mesh.topology.dim)
    assert mesh.comm.allreduce(v.sum(), MPI.SUM) == pytest.approx(1.0,
                                                                  rel=1e-9)


@pytest.mark.skip("volume_entities needs fixing")
def test_volume_quadrilateralR2():