def test_bin_points(self): # # Cell vertices # v1 = Vertex((0, 0)) v2 = Vertex((1, 0)) v3 = Vertex((1, 1)) v4 = Vertex((0, 1)) # Cell HalfEdges h12 = HalfEdge(v1, v2) h23 = HalfEdge(v2, v3) h34 = HalfEdge(v3, v4) h41 = HalfEdge(v4, v1) # Cell cell = QuadCell([h12, h23, h34, h41]) # Split cell twice cell.split() cell.get_child(1).split() # # Error: point not in cell # x = np.array([[-1, -1]]) self.assertRaises(Exception, cell.bin_points, *(x, )) # # Corner points # x = convert_to_array([v1, v2, v3, v4]) bins = cell.bin_points(x) # There should be four bins self.assertEqual(len(bins), 4) # No binning cells should have children for c, dummy in bins: self.assertFalse(c.has_children()) # # Center point # x = np.array([[0.5, 0.5]]) bins = cell.bin_points(x) self.assertEqual(len(bins), 1) # # Mark # sf = '1' for child in cell.get_children(): child.mark(sf) x = np.array([[0.75, 0.25]]) bins = cell.bin_points(x, subforest_flag=sf) for c, dummy in bins: self.assertTrue(c.is_marked(sf)) self.assertFalse(c.has_children(flag=sf))
def test_constructor(self): v1 = Vertex((0,0)) v2 = Vertex((1,1)) v3 = Vertex((2,2)) half_edge_1 = HalfEdge(v1, v2) half_edge_2 = HalfEdge(v2, v3) # Should complain about tuple input self.assertRaises(Exception, HalfEdge, *[v1,(1,1)]) # Should complain about incompatible twin self.assertRaises(Exception, HalfEdge, \ *(v2, v3), **{'twin':half_edge_1}) # Should complain about incompatible previous self.assertRaises(Exception, HalfEdge, \ *(v3, v2), **{'previous':half_edge_1}) # Should complain about incompatible nxt self.assertRaises(Exception, HalfEdge, *(v3, v2), \ **{'next':half_edge_1}) # Should complain about nxt of incompatible type self.assertRaises(Exception, HalfEdge, *(v3, v2), \ **{'next':2}) # Should complain about incompatible parent self.assertRaises(Exception, HalfEdge, *(v3, v2), \ **{'parent':half_edge_2})
def test_subcell_position(self): # Define HalfEdge v1, v2 = Vertex((1,1)), Vertex((2,3)) he_ref = HalfEdge(v1,v2) # Define Bad HalfEdge he_bad = HalfEdge(Vertex((1.5,1.3)), Vertex((2,3))) # Assert Error self.assertRaises(Exception, he_ref.subcell_position, he_bad) # Define Good HalfEdge V = convert_to_array([v1,v2]) # Specify points along Half-Edge t_min, t_max = 0.3, 0.5 W_base = Vertex(tuple(V[0] + t_min*(V[1]-V[0]))) W_head = Vertex(tuple(V[0] + t_max*(V[1]-V[0]))) he_good = HalfEdge(W_base, W_head) pos, width = he_ref.subcell_position(he_good) # Check whether computed value matches reference self.assertAlmostEqual(pos, t_min) self.assertAlmostEqual(width, t_max-t_min)
def test_head(self): # # Retrieve head # v1 = Vertex((0,0)) v2 = Vertex((1,1)) half_edge = HalfEdge(v1,v2) self.assertEqual(half_edge.head(), v2, 'Incorrect head.')
def test_base(self): # # Retrieve base # v1 = Vertex((0,0)) v2 = Vertex((1,1)) half_edge = HalfEdge(v1,v2) self.assertEqual(half_edge.base(), v1, 'Incorrect base.')
def test_subcell_position(self): """ Locate sub-cell within a skew quadcell """ # # Define ROOT Cell # # Define vertices v1 = Vertex((1, 1)) v2 = Vertex((2, 3)) v3 = Vertex((1.5, 5)) v4 = Vertex((0, 2)) vertices = [v1, v2, v3, v4] # Define HalfEdges h12 = HalfEdge(v1, v2) h23 = HalfEdge(v2, v3) h34 = HalfEdge(v3, v4) h41 = HalfEdge(v4, v1) halfedges = [h12, h23, h34, h41] # Define QuadCell cell = QuadCell(halfedges) # Check that cell is not a rectangle self.assertFalse(cell.is_rectangle()) # # Refine ROOT cell twice and pick a grandchild # cell.split() child = cell.get_child(2) child.split() grandchild = child.get_child(1) # # Determine relative position of the grandchild within cell # pos, width = cell.subcell_position(grandchild) # # Map the associated region the reference cell to physical cell # x_ref = np.array([ pos, pos + np.array([width, 0]), pos + np.array([width, width]), pos + np.array([0, width]) ]) x_vertices = cell.reference_map(x_ref) # # Check that points match up # for v, vh in zip(grandchild.get_vertices(), x_vertices): self.assertTrue(np.allclose(np.array(v.coordinates()), vh))
def test_contains_points(self): # # Triangle # v1 = Vertex((0,0)) v2 = Vertex((1,0)) v3 = Vertex((0,1)) h12 = HalfEdge(v1, v2) h23 = HalfEdge(v2, v3) h31 = HalfEdge(v3, v1) cell = Cell([h12, h23, h31]) # Vertices in_cell = cell.contains_points([v1,v2,v3]) in_cell_ref = np.ones(3, dtype=np.bool) for i in range(3): self.assertEqual(in_cell_ref[i], in_cell[i]) # Random points points = np.random.rand(100,2) in_cell_ref = (points[:,1]<1-points[:,0]) in_cell = cell.contains_points(points) for i in range(100): self.assertEqual(in_cell_ref[i], in_cell[i]) # # Square # v4 = Vertex((1,1)) h24 = HalfEdge(v2,v4) h43 = HalfEdge(v4,v3) square_half_edges = [h12, h24, h43, h31] cell = Cell(square_half_edges) points = [(2,0), (-1,0), (0.5,0.5)] in_cell_ref = np.array([0,0,1], dtype=np.bool) in_cell = cell.contains_points(points) for i in range(3): self.assertEqual(in_cell_ref[i], in_cell[i]) # # Single points # # Vertex point = Vertex((3,3)) self.assertFalse(cell.contains_points(point)) # Tuple point = (1,0) self.assertTrue(cell.contains_points(point)) # Array point = np.array([1,0]) self.assertTrue(cell.contains_points(point))
def test_reference_map(self): v1 = Vertex((1,1)) v2 = Vertex((2,3)) h = HalfEdge(v1,v2) x = np.linspace(0, 1, 5) points = h.reference_map(x) y = h.reference_map(points, mapsto='reference') for (yi,xi) in zip(x,y): self.assertAlmostEqual(xi,yi)
def test_next(self): # # New HalfEdge # v1 = Vertex((0,0)) v2 = Vertex((2,2)) v3 = Vertex((3,4)) next_half_edge = HalfEdge(v1, v2) half_edge = HalfEdge(v3, v1, nxt=next_half_edge) # Check self.assertEqual(half_edge.next(),next_half_edge,\ 'Next HalfEdge incorrect.')
def test_previous(self): # # New HalfEdge # v1 = Vertex((0,0)) v2 = Vertex((2,2)) v3 = Vertex((3,4)) previous_half_edge = HalfEdge(v1, v2) half_edge = HalfEdge(v2, v3, previous=previous_half_edge) # Check self.assertEqual(half_edge.previous(),previous_half_edge,\ 'Previous HalfEdge incorrect.')
def test_locate_point(self): v_sw = Vertex((0, 0)) v_se = Vertex((3, 1)) v_ne = Vertex((2, 3)) v_nw = Vertex((-1, 1)) h12 = HalfEdge(v_sw, v_se) h23 = HalfEdge(v_se, v_ne) h34 = HalfEdge(v_ne, v_nw) h41 = HalfEdge(v_nw, v_sw) cell = QuadCell([h12, h23, h34, h41]) points = np.random.rand(5, 2)
def test_get_parent(self): # # New HalfEdge # v1 = Vertex((0,0)) v2 = Vertex((2,2)) half_edge = HalfEdge(v1, v2) # Split half_edge.split() # Check if half_edge is children's parent for child in half_edge.get_children(): self.assertEqual(half_edge, child.get_parent(),\ 'HalfEdge should be child"s parent')
def test_cell(self): points = [(0,0),(1,0),(1,1),(0,1)] vertices = [Vertex(point) for point in points] half_edges = [HalfEdge(vertices[i], vertices[(i+1)%4]) for i in range(4)] cell = Cell(half_edges) for he in half_edges: self.assertEqual(he.cell(), cell)
def test_intersects_line_segment(self): vertices = [Vertex((0,0)), Vertex((3,1)), Vertex((2,3)), Vertex((-1,1))] h_edges = [] for i in range(4): h_edges.append(HalfEdge(vertices[i], vertices[(i+1)%4])) cell = Cell(h_edges) # # Line beginning in cell and ending outside # line_1 = [(1,1),(3,0)] self.assertTrue(cell.intersects_line_segment(line_1),\ 'Cell should intersect line segment.') # # Line inside cell # line_2 = [(1,1),(1.1,1.1)] self.assertTrue(cell.intersects_line_segment(line_2),\ 'Cell contains line segment.') # # Line outside cell # line_3 = [(3,0),(5,6)] self.assertFalse(cell.intersects_line_segment(line_3),\ 'Cell does not intersect line segment.')
def test_get_half_edges(self): # # Construct Cell # v1 = Vertex((0,0)) v2 = Vertex((1,0)) v3 = Vertex((0,1)) h12 = HalfEdge(v1, v2) h23 = HalfEdge(v2, v3) h31 = HalfEdge(v3, v1) # Check whether you get the right he's back hes = [h12, h23, h31] cell = Cell(hes) self.assertEqual(cell.get_half_edges(), hes)
def test_constructor(self): # Check the right number of halfedges self.assertRaises(Exception, QuadCell, *([1, 2, 2, 2, 2])) # Rectangle v1 = Vertex((0, 0)) v2 = Vertex((1, 0)) v3 = Vertex((1, 1)) v4 = Vertex((0, 1)) h12 = HalfEdge(v1, v2) h23 = HalfEdge(v2, v3) h34 = HalfEdge(v3, v4) h41 = HalfEdge(v4, v1) cell = QuadCell([h12, h23, h34, h41]) self.assertTrue(cell.is_rectangle())
def test_get_vertex(self): # # Construct Cell # v1 = Vertex((0,0)) v2 = Vertex((1,0)) v3 = Vertex((0,1)) h12 = HalfEdge(v1, v2) h23 = HalfEdge(v2, v3) h31 = HalfEdge(v3, v1) # Check whether you get the right he's back vs = [v1, v2, v3] cell = Cell([h12,h23,h31]) for i in range(3): self.assertEqual(cell.get_vertex(i), vs[i])
def test_constructor(self): """ Constructor """ # # Triangle # v1 = Vertex((0,0)) v2 = Vertex((1,0)) v3 = Vertex((0,1)) h12 = HalfEdge(v1, v2) h23 = HalfEdge(v2, v3) h31 = HalfEdge(v3, v1) # Vertices not in order bad_list_1 = [h12, h31, h23] self.assertRaises(Exception, Cell, *[bad_list_1]) # Not a closed loop bad_list_2 = [h12, h23] self.assertRaises(Exception, Cell, *[bad_list_2]) triangle_half_edges = [h12, h23, h31] cell = Cell(triangle_half_edges) self.assertAlmostEqual(cell.area(),0.5) self.assertEqual(cell.n_vertices(),3) self.assertEqual(cell.n_half_edges(),3) half_edge = cell.get_half_edge(0) for i in range(3): self.assertEqual(half_edge.next(), triangle_half_edges[(i+1)%3]) half_edge = half_edge.next() # # Square # v4 = Vertex((1,1)) h24 = HalfEdge(v2,v4) h43 = HalfEdge(v4,v3) square_half_edges = [h12, h24, h43, h31] cell = Cell(square_half_edges) self.assertAlmostEqual(cell.area(),1) self.assertEqual(cell.n_vertices(),4) self.assertEqual(cell.n_half_edges(),4)
def test_intersects_line_segment(self): # # Define a HalfEdge # v1 = Vertex((0,0)) v2 = Vertex((0,1)) h_edge = HalfEdge(v1,v2) # # Line 1 intersects h_edge in the middle # line_1 = [(-0.5,0.5),(0.5,0.5)] self.assertTrue(h_edge.intersects_line_segment(line_1),\ 'HalfEdge should intersect line_1.') # # Line 2 intersects h_edge at the vertex # line_2 = [(-1,1),(0,1)] self.assertTrue(h_edge.intersects_line_segment(line_2),\ 'HalfEdge should intersect line_2.') # # Line 3 is on top of h_edge # line_3 = [(0,0),(0,1)] self.assertTrue(h_edge.intersects_line_segment(line_3),\ 'HalfEdge should intersect line_3.') # # Line 4 does not intersect h_edge # line_4 = [(1,2), (3,3)] self.assertFalse(h_edge.intersects_line_segment(line_4),\ 'HalfEdge should intersect line_4.')
def test_split(self): # Rectangle v1 = Vertex((0, 0)) v2 = Vertex((1, 0)) v3 = Vertex((1, 1)) v4 = Vertex((0, 1)) v5 = Vertex((2, 0)) v6 = Vertex((2, 1)) h12 = HalfEdge(v1, v2) h23 = HalfEdge(v2, v3) h34 = HalfEdge(v3, v4) h41 = HalfEdge(v4, v1) cell = QuadCell([h12, h23, h34, h41]) cell.split() self.assertTrue(cell.has_children()) # Check that interior half_edges are twinned child_0 = cell.get_child(0) child_1 = cell.get_child(1) self.assertEqual(child_0.get_half_edge(1).twin(), \ child_1.get_half_edge(3)) # Make another cell, check that it is a neighbor, and then split it h25 = HalfEdge(v2, v5) h56 = HalfEdge(v5, v6) h63 = HalfEdge(v6, v3) h32 = h23.make_twin() cell_1 = QuadCell([h25, h56, h63, h32]) # Check that they are neighbors self.assertEqual(cell_1.get_neighbors(h32), cell) # Child_s doesn't have a neighbor self.assertIsNone(child_1.get_neighbors(child_1.get_half_edge(1))) cell_1.split() # Now the child has a neighbor self.assertEqual(child_1.get_neighbors(child_1.get_half_edge(1)), cell_1.get_child(0))
def test_unmark(self): # # Define a HalfEdge # v1 = Vertex((0,0)) v2 = Vertex((0,1)) h_edge = HalfEdge(v1,v2) # # Mark it with a specific flag # h_edge.mark(1) self.assertTrue(h_edge.is_marked(1),'HalfEdge should be marked.') # # Unmark it # h_edge.unmark(1) self.assertFalse(h_edge.is_marked(),'HalfEdge should be marked.') self.assertFalse(h_edge.is_marked(1),'HalfEdge should be marked.')
def test_line_integral(self): # Define quadrature rule rule = GaussRule(2, shape='interval') w = rule.weights() x_ref = rule.nodes() # function f to be integrated over edge e f = lambda x, y: x**2 * y e = HalfEdge(Vertex((0, 0)), Vertex((1, 1))) # Map rule to physical entity x_phys, mg = e.reference_map(x_ref, jac_r2p=True) jacobian = mg['jac_r2p'] x_phys = convert_to_array(x_phys, dim=2) fvec = f(x_phys[:, 0], x_phys[:, 1]) jac = np.linalg.norm(jacobian[0]) self.assertAlmostEqual(np.dot(fvec,w)*jac,np.sqrt(2)/4,places=10,\ msg='Failed to integrate x^2y.') self.assertAlmostEqual(np.sum(w)*jac, np.sqrt(2), places=10,\ msg='Failed to integrate 1.')
def test_twin(self): v1 = Vertex((0,0)) v2 = Vertex((1,1)) half_edge_1 = HalfEdge(v1,v2) half_edge_2 = HalfEdge(v2,v1, twin=half_edge_1) self.assertEqual(half_edge_2.twin(), half_edge_1,\ 'Twin incorrectly specified.') self.assertIsNone(half_edge_1.twin(), \ 'half_edge_2 has no twin yet.')
def test_incident_half_edge(self): # # Triangle # v1 = Vertex((0,0)) v2 = Vertex((1,0)) v3 = Vertex((0,1)) h12 = HalfEdge(v1, v2) h23 = HalfEdge(v2, v3) h31 = HalfEdge(v3, v1) cell = Cell([h12, h23, h31]) hes_forward = [h31, h12, h23] hes_reverse = [h12, h23, h31] vs = [v1,v2,v3] for i in range(3): # forward self.assertEqual(cell.incident_half_edge(vs[i]),hes_forward[i]) # backward self.assertEqual(cell.incident_half_edge(vs[i], reverse=True),\ hes_reverse[i])
def test_make_twin(self): # # New HalfEdge # v1 = Vertex((0,0)) v2 = Vertex((2,2)) h12 = HalfEdge(v1,v2) h21 = h12.make_twin() self.assertIsNotNone(h12.twin()) self.assertIsNotNone(h21.twin()) self.assertEqual(h12.base(),h21.head()) self.assertEqual(h21.base(),h12.head())
def test_assign_cell(self): # Make a cell points = [(0,0),(1,0),(1,1),(0,1)] vertices = [Vertex(point) for point in points] half_edges = [HalfEdge(vertices[i], vertices[(i+1)%4]) for i in range(4)] cell = Cell(half_edges) # Make a (different) half_edge he = HalfEdge(Vertex((0,0)), Vertex((1,1))) he.assign_cell(cell) self.assertEqual(he.cell(),cell)
def test_assign_next(self): # # New HalfEdge # v1 = Vertex((0,0)) v2 = Vertex((2,2)) v3 = Vertex((3,4)) h = HalfEdge(v1, v2) # # Incompatible next half_edge # bad_h_next = HalfEdge(v1, v3) self.assertRaises(Exception, h.assign_next, (bad_h_next)) # # Assign good next half-edge # good_h_next = HalfEdge(v2, v3) h.assign_next(good_h_next) # Check self.assertEqual(h.next(),good_h_next,\ 'Next HalfEdge incorrect.') self.assertEqual(h.head(), h.next().base(), \ 'Bases and heads should align.')
def test_assign_previous(self): # # New HalfEdge # v1 = Vertex((0,0)) v2 = Vertex((2,2)) v3 = Vertex((3,4)) h = HalfEdge(v1, v2) # # Incompatible previous half_edge # bad_h_prev = HalfEdge(v1, v3) self.assertRaises(Exception, h.assign_previous, (bad_h_prev)) # # Assign good next half-edge # good_h_previous = HalfEdge(v2, v1) h.assign_previous(good_h_previous) # Check self.assertEqual(h.previous(),good_h_previous,\ 'Next HalfEdge incorrect.') self.assertEqual(h.base(), h.previous().head(), \ 'Bases and heads should align.')
def test_has_children(self): # # New HalfEdge # v1 = Vertex((0,0)) v2 = Vertex((2,2)) half_edge = HalfEdge(v1, v2) # Shouldn't have children self.assertFalse(half_edge.has_children(),\ 'Half Edge should not have children') # Split edge half_edge.split() # Should have children self.assertTrue(half_edge.has_children(),\ 'HalfEdge should have children.')
def test_contains_points(self): # # Define 2D HalfEdge # v1 = Vertex((0,0)) v2 = Vertex((1,1)) h = HalfEdge(v1,v2) points = np.array([[0,0],[0.5,0.5],[3,2]]) on_half_edge = h.contains_points(points) self.assertTrue(all(on_half_edge==[True, True, False])) v1 = Vertex(0) v2 = Vertex(1) h = HalfEdge(v1,v2) points = [Vertex(0), Vertex(0.5), Vertex(3)] on_half_edge = h.contains_points(points) self.assertTrue(all(on_half_edge==[True, True, False]))