[4590] | 1 | #!/usr/bin/env python |
---|
| 2 | |
---|
| 3 | |
---|
| 4 | import unittest |
---|
[4859] | 5 | from search_functions import search_tree_of_vertices, set_last_triangle |
---|
[4593] | 6 | from search_functions import _search_triangles_of_vertices |
---|
[6553] | 7 | from search_functions import compute_interpolation_values |
---|
[4590] | 8 | |
---|
| 9 | from anuga.abstract_2d_finite_volumes.neighbour_mesh import Mesh |
---|
| 10 | from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular |
---|
[4593] | 11 | from anuga.utilities.polygon import is_inside_polygon |
---|
[4655] | 12 | from anuga.utilities.quad import build_quadtree, Cell |
---|
[6553] | 13 | from anuga.utilities.numerical_tools import ensure_numeric |
---|
| 14 | from anuga.utilities.polygon import is_inside_polygon, is_inside_triangle |
---|
[4590] | 15 | |
---|
[6553] | 16 | import numpy as num |
---|
[4590] | 17 | |
---|
| 18 | class Test_search_functions(unittest.TestCase): |
---|
| 19 | def setUp(self): |
---|
| 20 | pass |
---|
| 21 | |
---|
| 22 | def tearDown(self): |
---|
| 23 | pass |
---|
| 24 | |
---|
| 25 | def NOtest_that_C_extension_compiles(self): |
---|
| 26 | FN = 'search_functions_ext.c' |
---|
| 27 | try: |
---|
| 28 | import search_functions_ext |
---|
| 29 | except: |
---|
| 30 | from compile import compile |
---|
| 31 | |
---|
| 32 | try: |
---|
| 33 | compile(FN) |
---|
| 34 | except: |
---|
| 35 | raise 'Could not compile %s' %FN |
---|
| 36 | else: |
---|
| 37 | import search_functions_ext |
---|
| 38 | |
---|
| 39 | |
---|
| 40 | |
---|
| 41 | def test_small(self): |
---|
| 42 | """test_small: Two triangles |
---|
| 43 | """ |
---|
| 44 | |
---|
| 45 | points, vertices, boundary = rectangular(1, 1, 1, 1) |
---|
| 46 | mesh = Mesh(points, vertices, boundary) |
---|
| 47 | |
---|
| 48 | #Test that points are arranged in a counter clock wise order |
---|
| 49 | mesh.check_integrity() |
---|
| 50 | |
---|
| 51 | root = build_quadtree(mesh, max_points_per_cell = 1) |
---|
[4859] | 52 | set_last_triangle() |
---|
[4590] | 53 | |
---|
[4593] | 54 | x = [0.2, 0.7] |
---|
[6553] | 55 | found, s0, s1, s2, k = search_tree_of_vertices(root, x) |
---|
[4593] | 56 | assert k == 1 # Triangle one |
---|
[4590] | 57 | assert found is True |
---|
| 58 | |
---|
[4593] | 59 | def test_bigger(self): |
---|
[6553] | 60 | """test_bigger |
---|
| 61 | |
---|
| 62 | test larger mesh |
---|
[4593] | 63 | """ |
---|
| 64 | |
---|
| 65 | points, vertices, boundary = rectangular(4, 4, 1, 1) |
---|
| 66 | mesh = Mesh(points, vertices, boundary) |
---|
| 67 | |
---|
| 68 | #Test that points are arranged in a counter clock wise order |
---|
| 69 | mesh.check_integrity() |
---|
| 70 | |
---|
| 71 | root = build_quadtree(mesh, max_points_per_cell = 4) |
---|
[4859] | 72 | set_last_triangle() |
---|
[4593] | 73 | |
---|
| 74 | for x in [[0.6, 0.3], [0.1, 0.2], [0.7,0.7], |
---|
| 75 | [0.1,0.9], [0.4,0.6], [0.9,0.1], |
---|
| 76 | [10, 3]]: |
---|
[6553] | 77 | |
---|
| 78 | found, s0, s1, s2, k = search_tree_of_vertices(root, |
---|
| 79 | ensure_numeric(x)) |
---|
[4593] | 80 | |
---|
| 81 | if k >= 0: |
---|
| 82 | V = mesh.get_vertex_coordinates(k) # nodes for triangle k |
---|
| 83 | assert is_inside_polygon(x, V) |
---|
| 84 | assert found is True |
---|
| 85 | #print k, x |
---|
| 86 | else: |
---|
| 87 | assert found is False |
---|
| 88 | |
---|
[4590] | 89 | |
---|
[4593] | 90 | |
---|
| 91 | def test_large(self): |
---|
| 92 | """test_larger mesh and different quad trees |
---|
| 93 | """ |
---|
| 94 | |
---|
| 95 | points, vertices, boundary = rectangular(10, 12, 1, 1) |
---|
| 96 | mesh = Mesh(points, vertices, boundary) |
---|
| 97 | |
---|
| 98 | #Test that points are arranged in a counter clock wise order |
---|
| 99 | mesh.check_integrity() |
---|
| 100 | |
---|
[4590] | 101 | |
---|
[4593] | 102 | for m in range(8): |
---|
| 103 | root = build_quadtree(mesh, max_points_per_cell = m) |
---|
[4859] | 104 | set_last_triangle() |
---|
[4593] | 105 | #print m, root.show() |
---|
[4590] | 106 | |
---|
[4593] | 107 | for x in [[0.6, 0.3], [0.1, 0.2], [0.7,0.7], |
---|
| 108 | [0.1,0.9], [0.4,0.6], [0.9,0.1], |
---|
| 109 | [10, 3]]: |
---|
| 110 | |
---|
[6553] | 111 | found, s0, s1, s2, k = search_tree_of_vertices(root, x) |
---|
[4593] | 112 | |
---|
| 113 | if k >= 0: |
---|
| 114 | V = mesh.get_vertex_coordinates(k) # nodes for triangle k |
---|
[6689] | 115 | assert is_inside_triangle(x, V, closed=True) |
---|
[4593] | 116 | assert is_inside_polygon(x, V) |
---|
| 117 | assert found is True |
---|
| 118 | else: |
---|
| 119 | assert found is False |
---|
| 120 | |
---|
[6553] | 121 | |
---|
| 122 | if m == k == 0: return |
---|
[4593] | 123 | |
---|
| 124 | def test_underlying_function(self): |
---|
| 125 | """test_larger mesh and different quad trees |
---|
| 126 | """ |
---|
| 127 | |
---|
| 128 | points, vertices, boundary = rectangular(2, 2, 1, 1) |
---|
| 129 | mesh = Mesh(points, vertices, boundary) |
---|
| 130 | |
---|
| 131 | root = build_quadtree(mesh, max_points_per_cell = 4) |
---|
[4859] | 132 | set_last_triangle() |
---|
[4593] | 133 | |
---|
| 134 | # One point |
---|
[6553] | 135 | x = ensure_numeric([0.5, 0.5]) |
---|
[4593] | 136 | candidate_vertices = root.search(x[0], x[1]) |
---|
| 137 | |
---|
| 138 | #print x, candidate_vertices |
---|
| 139 | found, sigma0, sigma1, sigma2, k = \ |
---|
[6553] | 140 | _search_triangles_of_vertices(candidate_vertices, |
---|
[4593] | 141 | x) |
---|
| 142 | |
---|
| 143 | if k >= 0: |
---|
| 144 | V = mesh.get_vertex_coordinates(k) # nodes for triangle k |
---|
| 145 | assert is_inside_polygon(x, V) |
---|
| 146 | assert found is True |
---|
| 147 | else: |
---|
| 148 | assert found is False |
---|
| 149 | |
---|
[4590] | 150 | |
---|
[4593] | 151 | |
---|
| 152 | # More points |
---|
| 153 | for x in [[0.6, 0.3], [0.1, 0.2], [0.7,0.7], |
---|
| 154 | [0.1,0.9], [0.4,0.6], [0.9,0.1], |
---|
| 155 | [10, 3]]: |
---|
| 156 | |
---|
| 157 | candidate_vertices = root.search(x[0], x[1]) |
---|
| 158 | |
---|
| 159 | #print x, candidate_vertices |
---|
| 160 | found, sigma0, sigma1, sigma2, k = \ |
---|
[6553] | 161 | _search_triangles_of_vertices(candidate_vertices, |
---|
| 162 | ensure_numeric(x)) |
---|
[4593] | 163 | if k >= 0: |
---|
| 164 | V = mesh.get_vertex_coordinates(k) # nodes for triangle k |
---|
| 165 | assert is_inside_polygon(x, V) |
---|
| 166 | assert found is True |
---|
| 167 | else: |
---|
[4655] | 168 | assert found is False |
---|
| 169 | |
---|
| 170 | |
---|
| 171 | |
---|
| 172 | def expanding_search(self): |
---|
| 173 | """test_larger mesh and different quad trees |
---|
| 174 | """ |
---|
| 175 | |
---|
| 176 | p0 = [2,1] |
---|
| 177 | p1 = [4,1] |
---|
| 178 | p2 = [4.,4] |
---|
| 179 | p3 = [2,4] |
---|
| 180 | p4 = [5,4] |
---|
| 181 | |
---|
| 182 | p5 = [-1,-1] |
---|
| 183 | p6 = [1,-1] |
---|
| 184 | p7 = [1,1] |
---|
| 185 | p8 = [-1,1] |
---|
| 186 | |
---|
| 187 | points = [p0,p1,p2, p3,p4,p5,p6,p7,p8] |
---|
| 188 | # |
---|
| 189 | vertices = [[0,1,2],[0,2,3],[1,4,2],[5,6,7], [5,7,8]] |
---|
| 190 | mesh = Mesh(points, vertices) |
---|
| 191 | |
---|
[4666] | 192 | # Don't do this, want to control the max and mins |
---|
[4655] | 193 | #root = build_quadtree(mesh, max_points_per_cell=4) |
---|
| 194 | |
---|
| 195 | |
---|
[4666] | 196 | root = Cell(-3, 9, -3, 9, mesh, |
---|
[4655] | 197 | max_points_per_cell = 4) |
---|
| 198 | #Insert indices of all vertices |
---|
| 199 | root.insert( range(mesh.number_of_nodes) ) |
---|
| 200 | |
---|
| 201 | #Build quad tree and return |
---|
| 202 | root.split() |
---|
| 203 | |
---|
| 204 | # One point |
---|
| 205 | #x = [3.5, 1.5] |
---|
| 206 | x = [2.5, 1.5] |
---|
| 207 | element_found, sigma0, sigma1, sigma2, k = \ |
---|
[6553] | 208 | search_tree_of_vertices(root, x) |
---|
[4655] | 209 | # One point |
---|
| 210 | x = [3.00005, 2.999994] |
---|
| 211 | element_found, sigma0, sigma1, sigma2, k = \ |
---|
[6553] | 212 | search_tree_of_vertices(root, x) |
---|
[4655] | 213 | assert element_found is True |
---|
| 214 | assert k == 1 |
---|
| 215 | |
---|
[6553] | 216 | |
---|
| 217 | def test_compute_interpolation_values(self): |
---|
| 218 | """test_compute_interpolation_values |
---|
| 219 | |
---|
| 220 | Test that interpolation values are correc |
---|
| 221 | |
---|
| 222 | This test used to check element_found as output from |
---|
| 223 | find_triangle_compute_interpolation(triangle, n0, n1, n2, x) |
---|
| 224 | and that failed before 18th March 2009. |
---|
| 225 | |
---|
| 226 | Now this function no longer returns this flag, so the test |
---|
| 227 | is merely checknig the sigmas. |
---|
| 228 | |
---|
| 229 | """ |
---|
| 230 | |
---|
| 231 | triangle = num.array([[306951.77151059, 6194462.14596986], |
---|
| 232 | [306952.58403545, 6194459.65001246], |
---|
| 233 | [306953.55109034, 6194462.0041216]]) |
---|
[4655] | 234 | |
---|
[6553] | 235 | |
---|
| 236 | n0 = [0.92499377, -0.37998227] |
---|
| 237 | n1 = [0.07945684, 0.99683831] |
---|
| 238 | n2 = [-0.95088404, -0.30954732] |
---|
| 239 | |
---|
| 240 | x = [306953.344, 6194461.5] |
---|
| 241 | |
---|
| 242 | # Test that point is indeed inside triangle |
---|
| 243 | assert is_inside_polygon(x, triangle, |
---|
| 244 | closed=True, verbose=False) |
---|
| 245 | assert is_inside_triangle(x, triangle, |
---|
| 246 | closed=True, verbose=False) |
---|
| 247 | |
---|
| 248 | sigma0, sigma1, sigma2 = \ |
---|
| 249 | compute_interpolation_values(triangle, n0, n1, n2, x) |
---|
| 250 | |
---|
| 251 | msg = 'Point which is clearly inside triangle was not found' |
---|
| 252 | assert abs(sigma0 + sigma1 + sigma2 - 1) < 1.0e-6, msg |
---|
| 253 | |
---|
| 254 | #------------------------------------------------------------- |
---|
[4590] | 255 | if __name__ == "__main__": |
---|
[6553] | 256 | suite = unittest.makeSuite(Test_search_functions, 'test') |
---|
| 257 | runner = unittest.TextTestRunner(verbosity=1) |
---|
[4590] | 258 | runner.run(suite) |
---|
| 259 | |
---|