Пример #1
0
def test_near_evaluations(R, mesh):
    # Test that we allow point evaluation that are slightly outside
    u0 = Function(R)
    u0.vector.set(1.0)

    offset = 0.99 * np.finfo(float).eps
    bb_tree = geometry.BoundingBoxTree(mesh, mesh.geometry.dim)
    a = mesh.geometry.x[0]

    cells = geometry.compute_colliding_cells(bb_tree, mesh, a, n=1)
    a_shift_x = np.array([a[0] - offset, a[1], a[2]])
    cells_shift_x = geometry.compute_colliding_cells(bb_tree,
                                                     mesh,
                                                     a_shift_x,
                                                     n=1)

    assert u0.eval(a, cells)[0] == pytest.approx(
        u0.eval(a_shift_x, cells_shift_x)[0])

    a_shift_xyz = np.array([
        a[0] - offset / math.sqrt(3), a[1] - offset / math.sqrt(3),
        a[2] - offset / math.sqrt(3)
    ])
    cells_shift_xyz = geometry.compute_colliding_cells(bb_tree,
                                                       mesh,
                                                       a_shift_xyz,
                                                       n=1)
    assert u0.eval(a, cells)[0] == pytest.approx(
        u0.eval(a_shift_xyz, cells_shift_xyz)[0])
Пример #2
0
def test_eval(V, W, Q, mesh):
    u1 = Function(V)
    u2 = Function(W)
    u3 = Function(Q)

    def e2(x):
        values = np.empty((3, x.shape[1]))
        values[0] = x[0] + x[1] + x[2]
        values[1] = x[0] - x[1] - x[2]
        values[2] = x[0] + x[1] + x[2]
        return values

    def e3(x):
        values = np.empty((9, x.shape[1]))
        values[0] = x[0] + x[1] + x[2]
        values[1] = x[0] - x[1] - x[2]
        values[2] = x[0] + x[1] + x[2]
        values[3] = x[0]
        values[4] = x[1]
        values[5] = x[2]
        values[6] = -x[0]
        values[7] = -x[1]
        values[8] = -x[2]
        return values

    u1.interpolate(lambda x: x[0] + x[1] + x[2])
    u2.interpolate(e2)
    u3.interpolate(e3)

    x0 = (mesh.geometry.x[0] + mesh.geometry.x[1]) / 2.0
    tree = BoundingBoxTree(mesh, mesh.geometry.dim)
    cell_candidates = compute_collisions(tree, x0)
    cell = compute_colliding_cells(mesh, cell_candidates, x0)
    first_cell = cell[0]
    assert np.allclose(u3.eval(x0, first_cell)[:3], u2.eval(x0, first_cell), rtol=1e-15, atol=1e-15)
Пример #3
0
def evaluate(points, mesh, u):
    tree = geometry.BoundingBoxTree(mesh, mesh.geometry.dim)

    num_local_cells = mesh.topology.index_map(mesh.topology.dim).size_local
    colliding_cells = -np.ones(points.shape[1], dtype=np.int32)
    for i, point in enumerate(points.T):
        # Find first colliding cell
        colliding_cell = geometry.compute_colliding_cells(tree, mesh, point, 1)
        # Only add cell to list if it is owned by the processor
        if len(colliding_cell) > 0 and colliding_cell[0] < num_local_cells:
            colliding_cells[i] = colliding_cell[0]

    local_cells = np.argwhere(colliding_cells != -1).T[0]
    on_proc = np.zeros(colliding_cells.shape[0])
    on_proc[local_cells] = 1
    # Workaround since the cell exists on multiple processors, not respecting
    # ghosting.
    num_proc = MPI.COMM_WORLD.allgather(on_proc)
    # from IPython import embed; embed()

    u_on_proc = u.eval(points.T, colliding_cells)
    u_g = MPI.COMM_WORLD.allgather(u_on_proc)
    u_gathered = sum(u_g).T[0]  #/ sum(num_proc)

    return u_gathered
Пример #4
0
def test_collision_2nd_order_triangle():
    points = np.array([[0, 0], [1, 0], [0, 1], [0.65, 0.65], [0, 0.5], [0.5, 0]])
    cells = np.array([[0, 1, 2, 3, 4, 5]])
    cell = ufl.Cell("triangle", geometric_dimension=2)
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 2))
    mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)

    # Sample points along an interior line of the domain. The last point
    # is outside the simplex made by the vertices.
    sample_points = np.array([[0.1, 0.3, 0], [0.2, 0.5, 0], [0.6, 0.6, 0]])

    # Create boundingboxtree
    tree = geometry.BoundingBoxTree(mesh, mesh.geometry.dim)
    for point in sample_points:
        colliding_cell = geometry.compute_colliding_cells(tree, mesh, point, 1)
        assert(len(colliding_cell) == 1)

    # Check if there is a point on the linear approximation of the
    # curved facet
    def line_through_points(p0, p1):
        return lambda x: (p1[1] - p0[1]) / (p1[0] - p0[0]) * (x - p0[0]) + p0[1]
    line_func = line_through_points(points[2], points[3])
    point = np.array([0.2, line_func(0.2), 0])
    # Point inside 2nd order geometry, outside linear approximation
    # Usefull for debugging on a later stage
    # point = np.array([0.25, 0.89320760, 0])
    distance = cpp.geometry.squared_distance(mesh, mesh.topology.dim - 1, 2, point)
    assert np.isclose(distance, 0)
Пример #5
0
def test_compute_closest_sub_entity(dim):
    """Compute distance from subset of cells in a mesh to a point inside the mesh"""
    ref_distance = 0.31
    xc, yc, zc = 0.5, 0.5, 0.5
    points = np.array([xc + ref_distance, yc, zc])
    mesh = create_unit_cube(MPI.COMM_WORLD, 8, 8, 8)
    mesh.topology.create_entities(dim)
    left_entities = locate_entities(mesh, dim, lambda x: x[0] <= xc)
    tree = BoundingBoxTree(mesh, dim, left_entities)
    midpoint_tree = create_midpoint_tree(mesh, dim, left_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([xc, yc, zc])
    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)
        if len(colliding_cells) > 0:
            assert np.isin(closest_entities[0], colliding_cells)
    else:
        if len(colliding_entity_bboxes.links(0)) > 0:
            assert np.isin(closest_entities[0], colliding_entity_bboxes.links(0))
Пример #6
0
def test_compute_closest_entity_3d(dim):
    points = np.array([0.9, 0, 1.135])
    mesh = create_unit_cube(MPI.COMM_WORLD, 8, 8, 8)
    mesh.topology.create_entities(dim)

    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.9, 0, 1])
    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)
        if len(colliding_cells) > 0:
            assert np.isin(closest_entities[0], colliding_cells)
    else:
        if len(colliding_entity_bboxes.links(0)) > 0:
            assert np.isin(closest_entities[0], colliding_entity_bboxes.links(0))
Пример #7
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))
def test_manifold_point_search():
    # Simple two-triangle surface in 3d
    vertices = np.array([[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 = np.array([[0, 1, 2], [0, 1, 3]], dtype=np.int64)
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "triangle", 1))
    mesh = create_mesh(MPI.COMM_WORLD, cells, vertices, domain)
    bb = BoundingBoxTree(mesh, mesh.topology.dim)

    # Find cell colliding with point
    points = np.array([[0.5, 0.25, 0.75], [0.25, 0.5, 0.75]])
    cell_candidates = geometry.compute_collisions(bb, points)
    colliding_cells = geometry.compute_colliding_cells(mesh, cell_candidates,
                                                       points)

    # Extract vertices of cell
    indices = _cpp.mesh.entities_to_geometry(
        mesh, mesh.topology.dim,
        [colliding_cells.links(0)[0],
         colliding_cells.links(1)[0]], False)
    cell_vertices = mesh.geometry.x[indices]

    # Compare vertices with input
    assert np.allclose(cell_vertices, vertices[cells])
b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
set_bc(b, [bc])

uc = Function(U)
solver = PETSc.KSP().create(A_cond.getComm())
solver.setOperators(A_cond)
solver.solve(b, uc.vector)

# Pure displacement based formulation
a = form(- ufl.inner(sigma_u(u), ufl.grad(v)) * ufl.dx)
A = assemble_matrix(a, bcs=[bc])
A.assemble()

# Create bounding box for function evaluation
bb_tree = geometry.BoundingBoxTree(mesh, 2)

# Check against standard table value
p = np.array([48.0, 52.0, 0.0], dtype=np.float64)
cell_candidates = geometry.compute_collisions(bb_tree, p)
cells = geometry.compute_colliding_cells(mesh, cell_candidates, p)

uc.x.scatter_forward()
if len(cells) > 0:
    value = uc.eval(p, cells[0])
    print(value[1])
    assert np.isclose(value[1], 23.95, rtol=1.e-2)

# Check the equality of displacement based and mixed condensed global
# matrices, i.e. check that condensation is exact
assert np.isclose((A - A_cond).norm(), 0.0)