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] cell_candidates = geometry.compute_collisions_point(bb_tree, a) cells = geometry.select_colliding_cells(mesh, cell_candidates, a, 1) a_shift_x = np.array([a[0] - offset, a[1], a[2]]) cell_candidates = geometry.compute_collisions_point(bb_tree, a_shift_x) cells_shift_x = geometry.select_colliding_cells(mesh, cell_candidates, a_shift_x, 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) ]) cell_candidates = geometry.compute_collisions_point(bb_tree, a) cells_shift_xyz = geometry.select_colliding_cells(mesh, cell_candidates, a_shift_xyz, 1) assert u0.eval(a, cells)[0] == pytest.approx( u0.eval(a_shift_xyz, cells_shift_xyz)[0])
def test_sub_bbtree(): """ Testing point collision with a BoundingBoxTree of sub entitites """ mesh = UnitCubeMesh(MPI.COMM_WORLD, 4, 4, 4, cell_type=cpp.mesh.CellType.hexahedron) tdim = mesh.topology.dim fdim = tdim - 1 def top_surface(x): return numpy.isclose(x[2], 1) top_facets = locate_entities_boundary(mesh, fdim, top_surface) f_to_c = mesh.topology.connectivity(tdim - 1, tdim) cells = [f_to_c.links(f)[0] for f in top_facets] bbtree = BoundingBoxTree(mesh, tdim, cells) # Compute a BBtree for all processes process_bbtree = bbtree.compute_global_tree(mesh.mpi_comm()) # Find possible ranks for this point point = numpy.array([0.2, 0.2, 1.0]) ranks = compute_collisions_point(process_bbtree, point) # Compute local collisions cells = compute_collisions_point(bbtree, point) if MPI.COMM_WORLD.rank in ranks: assert(len(cells) > 0) else: assert(len(cells) == 0)
def test_collision_2nd_order_triangle(): points = np.array([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [0.65, 0.65], [0.0, 0.5], [0.5, 0.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], [0.2, 0.5, 0.0], [0.6, 0.6, 0.0]]) # Create boundingboxtree tree = geometry.BoundingBoxTree(mesh, mesh.geometry.dim) for point in sample_points: cell_candidates = geometry.compute_collisions_point(tree, point) colliding_cell = geometry.select_colliding_cells( mesh, cell_candidates, 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)
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 p = numpy.array([0.5 + ref_distance, 0.5, 0.5]) mesh = UnitCubeMesh(MPI.COMM_WORLD, 8, 8, 8) mesh.topology.create_entities(dim) left_entities = locate_entities(mesh, dim, lambda x: x[0] <= 0.5) tree = BoundingBoxTree(mesh, dim, left_entities) entity, distance = compute_closest_entity(tree, p, mesh) min_distance = MPI.COMM_WORLD.allreduce(distance, op=MPI.MIN) assert min_distance == pytest.approx(ref_distance, 1.0e-12) # Find which entity is colliding with known closest point on mesh p_c = numpy.array([0.5, 0.5, 0.5]) entities = compute_collisions_point(tree, p_c) # Refine search by checking for actual collision if the entities are # cells if dim == mesh.topology.dim: entities = select_colliding_cells(mesh, entities, p_c, len(entities)) if len(entities) > 0: assert numpy.isin(entity, entities)
def test_midpoint_tree(N): """ Test that midpoint tree speed up compute_closest_entity """ mesh = UnitCubeMesh(MPI.COMM_WORLD, N, N, N) mesh.topology.create_entities(mesh.topology.dim) left_cells = locate_entities(mesh, mesh.topology.dim, lambda x: x[0] <= 0.4) tree = BoundingBoxTree(mesh, mesh.topology.dim, left_cells) midpoint_tree = create_midpoint_tree(mesh, mesh.topology.dim, left_cells) p = numpy.array([1 / 3, 2 / 3, 2]) # Find entity closest to point in two steps # 1. Find closest midpoint using midpoint tree entity_m, distance_m = compute_closest_entity(midpoint_tree, p, mesh) # 2. Refine search by using exact distance query entity, distance = compute_closest_entity(tree, p, mesh, R=distance_m) # Find entity closest to point in one step e_r, d_r = compute_closest_entity(tree, p, mesh) assert entity == e_r assert distance == d_r if len(left_cells) > 0: assert distance < distance_m else: assert distance == -1 p_c = numpy.array([1 / 3, 2 / 3, 1]) entities = compute_collisions_point(tree, p_c) entities = select_colliding_cells(mesh, entities, p_c, len(entities)) if len(entities) > 0: assert numpy.isin(e_r, entities)
def test_compute_collisions_point_1d(): reference = {1: set([4])} p = numpy.array([0.3, 0, 0]) mesh = UnitIntervalMesh(MPI.COMM_WORLD, 16) for dim in range(1, 2): tree = BoundingBoxTree(mesh, mesh.topology.dim) entities = compute_collisions_point(tree, p) assert set(entities) == reference[dim]
def test_manifold_point_search(): # 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)] domain = ufl.Mesh(ufl.VectorElement("Lagrange", "triangle", 1)) mesh = create_mesh(MPI.COMM_WORLD, cells, vertices, domain) bb = BoundingBoxTree(mesh, mesh.topology.dim) p = numpy.array([0.5, 0.25, 0.75]) cell_candidates = geometry.compute_collisions_point(bb, p) cell = cpp.geometry.select_colliding_cells(mesh, cell_candidates, p, 1) assert cell[0] == 0 p = numpy.array([0.25, 0.5, 0.75]) cell_candidates = geometry.compute_collisions_point(bb, p) cell = cpp.geometry.select_colliding_cells(mesh, cell_candidates, p, 1) assert cell[0] == 1
def test_manifold_point_search(): # 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, CellType.triangle, numpy.array(vertices, dtype=numpy.float64), numpy.array(cells, dtype=numpy.int32), []) bb = BoundingBoxTree(mesh, mesh.topology.dim) p = numpy.array([0.5, 0.25, 0.75]) cell_candidates = geometry.compute_collisions_point(bb, p) cell = cpp.geometry.select_colliding_cells(mesh, cell_candidates, p, 1) assert cell[0] == 0 p = numpy.array([0.25, 0.5, 0.75]) cell_candidates = geometry.compute_collisions_point(bb, p) cell = cpp.geometry.select_colliding_cells(mesh, cell_candidates, p, 1) assert cell[0] == 1
def test_surface_bbtree(): """Test creation of BBTree on subset of entities(surface cells)""" mesh = UnitCubeMesh(MPI.COMM_WORLD, 8, 8, 8) sf = cpp.mesh.exterior_facet_indices(mesh) tdim = mesh.topology.dim f_to_c = mesh.topology.connectivity(tdim - 1, tdim) cells = [f_to_c.links(f)[0] for f in sf] bbtree = BoundingBoxTree(mesh, tdim, cells) # test collision (should not collide with any) p = numpy.array([0.5, 0.5, 0.5]) assert len(compute_collisions_point(bbtree, p)) == 0
def test_eval_multiple(W): u = Function(W) u.vector.set(1.0) mesh = W.mesh x0 = (mesh.geometry.x[0] + mesh.geometry.x[1]) / 2.0 x = np.array([x0, x0 + 1.0e8]) tree = geometry.BoundingBoxTree(mesh, mesh.geometry.dim) cell_candidates = [geometry.compute_collisions_point(tree, xi) for xi in x] assert len(cell_candidates[1]) == 0 cell_candidates = cell_candidates[0] cell = dolfinx.cpp.geometry.select_colliding_cells(mesh, cell_candidates, x0, 1) u.eval(x[0], cell)
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)) 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) xp = np.array([0.33, 0.33, 0.0]) tree = geometry.BoundingBoxTree(mesh, mesh.geometry.dim) cells = geometry.compute_collisions_point(tree, xp) up = uh.eval(xp, cells[0]) print("test0:", up) print("test1:", xp[0]**degree) u_exact = np.zeros(mesh.geometry.dim) u_exact[0] = xp[0]**degree assert np.allclose(up, u_exact)
def test_manifold_point_search(): # Simple two-triangle surface in 3d vertices = numpy.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 = numpy.array([[0, 1, 2], [0, 1, 3]], dtype=numpy.int64) domain = ufl.Mesh(ufl.VectorElement("Lagrange", "triangle", 1)) mesh = create_mesh(MPI.COMM_WORLD, cells, vertices, domain) x = mesh.geometry.x tdim = mesh.topology.dim bb = BoundingBoxTree(mesh, tdim) # Find cell colliding with point p = numpy.array([0.5, 0.25, 0.75]) cell_candidates = geometry.compute_collisions_point(bb, p) cell = cpp.geometry.select_colliding_cells(mesh, cell_candidates, p, 1) # Extract vertices of cell top_indices = cpp.mesh.entities_to_geometry(mesh, tdim, [cell], False) cell_vertices = x[top_indices] # Compare vertices with input (should be in cell 0) assert numpy.allclose(cell_vertices, vertices[cells[0]]) # Find cell colliding with point p = numpy.array([0.25, 0.5, 0.75]) cell_candidates = geometry.compute_collisions_point(bb, p) cell = cpp.geometry.select_colliding_cells(mesh, cell_candidates, p, 1) # Extract vertices of cell top_indices = cpp.mesh.entities_to_geometry(mesh, tdim, [cell], False) x = mesh.geometry.x cell_vertices = x[top_indices] # Compare vertices with input (should be in cell 1) assert numpy.allclose(cell_vertices, vertices[cells[1]])
def test_eval(R, V, W, Q, mesh): u0 = Function(R) u1 = Function(V) u2 = Function(W) u3 = Function(Q) def e1(x): return x[0] + x[1] + x[2] 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 u0.vector.set(1.0) u1.interpolate(e1) u2.interpolate(e2) u3.interpolate(e3) x0 = (mesh.geometry.x[0] + mesh.geometry.x[1]) / 2.0 tree = geometry.BoundingBoxTree(mesh, mesh.geometry.dim) cell_candidates = geometry.compute_collisions_point(tree, x0) cell = dolfinx.cpp.geometry.select_colliding_cells(mesh, cell_candidates, x0, 1) assert np.allclose(u3.eval(x0, cell)[:3], u2.eval(x0, cell), rtol=1e-15, atol=1e-15) with pytest.raises(ValueError): u0.eval([0, 0, 0, 0], 0) with pytest.raises(ValueError): u0.eval([0, 0], 0)
def test_compute_collisions_point_3d(): reference = { 1: set([1364]), 2: set([1967, 1968, 1970, 1972, 1974, 1976]), 3: set([876, 877, 878, 879, 880, 881]) } p = numpy.array([0.3, 0.3, 0.3]) mesh = UnitCubeMesh(MPI.comm_world, 8, 8, 8) tree = BoundingBoxTree(mesh, mesh.topology.dim) for dim in range(1, 4): entities, _ = geometry.compute_collisions_point(tree, p) # FIXME: Face and edges tests are excluded because test # mistakenly relies on the face and edge indices tdim = mesh.topology.dim if dim != tdim - 1 and dim != tdim - 2: assert set(entities) == reference[dim]
def test_compute_closest_entity_2d(dim): p = numpy.array([-1.0, -0.01, 0.0]) mesh = UnitSquareMesh(MPI.COMM_WORLD, 15, 15) tree = BoundingBoxTree(mesh, dim) entity, distance = compute_closest_entity(tree, p, mesh) min_distance = MPI.COMM_WORLD.allreduce(distance, op=MPI.MIN) ref_distance = numpy.sqrt(p[0]**2 + p[1]**2) assert min_distance == pytest.approx(ref_distance, 1.0e-12) # Find which entity is colliding with known closest point on mesh p_c = numpy.array([0, 0, 0]) entities = compute_collisions_point(tree, p_c) # Refine search by checking for actual collision if the entities are # cells # NOTE: Could be done for all entities if we generalize # select_colliding_cells to select_colliding_entities if dim == mesh.topology.dim: entities = select_colliding_cells(mesh, entities, p_c, len(entities)) if len(entities) > 0: assert numpy.isin(entity, entities)
def test_compute_collisions_point_1d(): N = 16 p = numpy.array([0.3, 0, 0]) mesh = UnitIntervalMesh(MPI.COMM_WORLD, N) dx = 1 / N cell_index = int(p[0] // dx) # Vertices of cell we should collide with vertices = numpy.array([[dx * cell_index, 0, 0], [dx * (cell_index + 1), 0, 0]]) # Compute collision tdim = mesh.topology.dim tree = BoundingBoxTree(mesh, tdim) entities = list(set(compute_collisions_point(tree, p))) assert len(entities) == 1 # Get the vertices of the geometry geom_entities = cpp.mesh.entities_to_geometry(mesh, tdim, entities, False)[0] x = mesh.geometry.x cell_vertices = x[geom_entities] # Check that we get the cell with correct vertices assert numpy.allclose(cell_vertices, vertices)
def test_compute_closest_entity_3d(dim): ref_distance = 0.135 p = numpy.array([0.9, 0, 1 + ref_distance]) mesh = UnitCubeMesh(MPI.COMM_WORLD, 8, 8, 8) mesh.topology.create_entities(dim) tree = BoundingBoxTree(mesh, dim) entity, distance = compute_closest_entity(tree, p, mesh) min_distance = MPI.COMM_WORLD.allreduce(distance, op=MPI.MIN) assert min_distance == pytest.approx(ref_distance, 1.0e-12) # Find which entity is colliding with known closest point on mesh p_c = numpy.array([0.9, 0, 1]) entities = compute_collisions_point(tree, p_c) # Refine search by checking for actual collision if the entities are # cells # NOTE: Could be done for all entities if we generalize # select_colliding_cells to select_colliding_entities if dim == mesh.topology.dim: entities = select_colliding_cells(mesh, entities, p_c, len(entities)) if len(entities) > 0: assert numpy.isin(entity, entities)
df.value = args.sigma else: df.value = 0.0 fecoda.main.solve_displ_system(J[0], F[0], intern_var0, intern_var1, expr_compiled, w0, w1, bcs_displ, df, dt, t, k) fecoda.main.post_update(expr_compiled, intern_var0, intern_var1, w0, w1) fecoda.main.copyout_state(w0, w1, intern_var0, intern_var1) force.value += df.value bb_tree = BoundingBoxTree(mesh, 3) p = numpy.array([0.0, 0.0, 0.3], dtype=numpy.float64) cell_candidates = compute_collisions_point(bb_tree, p) cell = select_colliding_cells(mesh, cell_candidates, p, 1) interpolate(ufl.sym(ufl.grad(w1["displ"])), strain) if len(cell) > 0: value = strain.eval(p, cell) value = value[-1] else: value = None values = comm.gather(value, root=0) if rank == 0: value = [x for x in values if x is not None][0] compl = value * -1.0e+6 / args.sigma log["compl"].append(compl)
plot_grid[1].ravel(), np.zeros(plot_grid[0].size))) points_2d = points[:2, :] # Locate grid points inside the circle. These are outside the computation # domain so we will ultimately set the field here to zero. in_circ = points[0, :]**2 + points[1, :]**2 <= (radius)**2 in_circ_2d = points_2d[0, :]**2 + points_2d[1, :]**2 <= (radius)**2 points[0, in_circ] = -radius - wave_len / 10 points[1, in_circ] = radius + wave_len / 10 points[2, in_circ] = 0. # Bounding box tree etc for function evaluations tree = geometry.BoundingBoxTree(mesh, 2) cell_candidates = [geometry.compute_collisions_point(tree, xi) for xi in points.T] cells = [dolfinx.cpp.geometry.select_colliding_cells(mesh, cell_candidates[i], points.T[i], 1)[0] for i in range(len(cell_candidates))] # Evaluate scattered and incident fields at grid points u_sca_temp = u.eval(points.T, cells) u_sca_temp[in_circ_2d] = 0.0 # Set field inside circle to zero u_sca = u_sca_temp.reshape((Nx, Ny)) # Reshape inc_field = incident(points_2d) inc_field[in_circ_2d] = 0.0 # Set field inside circle to zero u_inc = inc_field.reshape((Nx, Ny)) # Sum to give total field u_total = u_inc + u_sca
dim_in_x = dim_x - 2 * d_absorb dim_in_y = dim_y - 2 * d_absorb # Grid points xmin, xmax, ymin, ymax = [ -dim_in_x / 2, dim_in_x / 2, -dim_in_y / 2, dim_in_y / 2 ] plot_grid = np.mgrid[xmin:xmax:Nx * 1j, ymin:ymax:Ny * 1j] points = np.vstack( (plot_grid[0].ravel(), plot_grid[1].ravel(), np.zeros(plot_grid[0].size))) # Bounding box tree etc for function evaluations tree = geometry.BoundingBoxTree(mesh, 2) points_2d = points[0:2, :] cell_candidates = [ geometry.compute_collisions_point(tree, xi) for xi in points.T ] cells = [ dolfinx.cpp.geometry.select_colliding_cells(mesh, cell_candidates[i], points.T[i], 1)[0] for i in range(len(cell_candidates)) ] # Evaluate scattered and incident fields at grid points u_sca = u.eval(points.T, cells).reshape((Nx, Ny)) inc_field = incident(points_2d) u_inc = inc_field.reshape((Nx, Ny)) # Sum to give total field u_total = u_inc + u_sca ''' Plot field and save figure '''