Changeset 2189
- Timestamp:
- Jan 9, 2006, 4:09:06 PM (19 years ago)
- Location:
- inundation/fit_interpolate
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/fit_interpolate/interpolate.py
r2187 r2189 33 33 vertex_coordinates, 34 34 triangles, 35 point_coordinates = None,35 #point_coordinates = None, 36 36 mesh_origin = None, 37 37 verbose=False, … … 68 68 from pyvolution.util import ensure_numeric 69 69 70 # Initialise variabels 71 self.A_can_be_reused = False 72 self.point_coordinates = None 73 70 74 #Convert input to Numeric arrays 71 75 triangles = ensure_numeric(triangles, Int) … … 143 147 144 148 if verbose and i%((n+10)/10)==0: print 'Doing %d of %d' %(i, n) 149 145 150 x = point_coordinates[i] 146 147 #Find vertices near x 148 candidate_vertices = self.root.search(x[0], x[1]) 149 is_more_elements = True 150 151 151 152 element_found, sigma0, sigma1, sigma2, k = \ 152 self.search_triangles_of_vertices(candidate_vertices, x) 153 first_expansion = True 154 while not element_found and is_more_elements: 155 #if verbose: print 'Expanding search' 156 if first_expansion == True: 157 #self.expanded_quad_searches.append(1) 158 first_expansion = False 159 #else: 160 #end = len(self.expanded_quad_searches) - 1 161 #assert end >= 0 162 #self.expanded_quad_searches[end] += 1 163 candidate_vertices, branch = self.root.expand_search() 164 if branch == []: 165 # Searching all the verts from the root cell that haven't 166 # been searched. This is the last try 167 element_found, sigma0, sigma1, sigma2, k = \ 168 self.search_triangles_of_vertices(candidate_vertices, x) 169 is_more_elements = False 170 else: 171 element_found, sigma0, sigma1, sigma2, k = \ 172 self.search_triangles_of_vertices(candidate_vertices, x) 173 174 153 self._search_tree_of_vertices(x) 175 154 #Update interpolation matrix A if necessary 176 155 if element_found is True: … … 186 165 for j in js: 187 166 A[i,j] = sigmas[j] 188 189 167 else: 190 print 'Could not find triangle for point', x 191 192 193 168 print 'Could not find triangle for point', x 169 194 170 return A 195 171 196 197 def search_triangles_of_vertices(self, 172 def _search_tree_of_vertices(self, x): 173 """ 174 Find the triangle (element) that the point x is in. 175 176 Return the associated sigma and k values 177 (and if the element was found) . 178 """ 179 #Find triangle containing x: 180 element_found = False 181 182 # This will be returned if element_found = False 183 sigma2 = -10.0 184 sigma0 = -10.0 185 sigma1 = -10.0 186 k = -10.0 187 188 #Find vertices near x 189 candidate_vertices = self.root.search(x[0], x[1]) 190 is_more_elements = True 191 192 element_found, sigma0, sigma1, sigma2, k = \ 193 self._search_triangles_of_vertices(candidate_vertices, x) 194 #FIXME Do we need this var? 195 # Exclude points outside the mesh before removing this. 196 #first_expansion = True 197 while not element_found and is_more_elements: 198 #if verbose: print 'Expanding search' 199 #if first_expansion == True: 200 #self.expanded_quad_searches.append(1) 201 #first_expansion = False 202 #else: 203 #end = len(self.expanded_quad_searches) - 1 204 #assert end >= 0 205 #self.expanded_quad_searches[end] += 1 206 candidate_vertices, branch = self.root.expand_search() 207 if branch == []: 208 # Searching all the verts from the root cell that haven't 209 # been searched. This is the last try 210 element_found, sigma0, sigma1, sigma2, k = \ 211 self._search_triangles_of_vertices(candidate_vertices, x) 212 is_more_elements = False 213 else: 214 element_found, sigma0, sigma1, sigma2, k = \ 215 self._search_triangles_of_vertices(candidate_vertices, x) 216 217 return element_found, sigma0, sigma1, sigma2, k 218 219 def _search_triangles_of_vertices(self, 198 220 candidate_vertices, x): 199 221 #Find triangle containing x: … … 215 237 #for each triangle id (k) which has v as a vertex 216 238 for k, _ in self.mesh.vertexlist[v]: 217 218 239 #Get the three vertex_points of candidate triangle 219 240 xi0 = self.mesh.get_vertex_coordinate(k, 0) … … 221 242 xi2 = self.mesh.get_vertex_coordinate(k, 2) 222 243 223 #print "PDSG - k", k224 #print "PDSG - xi0", xi0225 #print "PDSG - xi1", xi1226 #print "PDSG - xi2", xi2227 #print "PDSG element %i verts((%f, %f),(%f, %f),(%f, %f))"\228 # % (k, xi0[0], xi0[1], xi1[0], xi1[1], xi2[0], xi2[1])229 230 244 #Get the three normals 231 245 n0 = self.mesh.get_normal(k, 0) … … 233 247 n2 = self.mesh.get_normal(k, 2) 234 248 235 236 249 #Compute interpolation 237 250 sigma2 = dot((x-xi0), n2)/dot((xi2-xi0), n2) 238 251 sigma0 = dot((x-xi1), n0)/dot((xi0-xi1), n0) 239 252 sigma1 = dot((x-xi2), n1)/dot((xi1-xi2), n1) 240 241 #print "PDSG - sigma0", sigma0242 #print "PDSG - sigma1", sigma1243 #print "PDSG - sigma2", sigma2244 253 245 254 #FIXME: Maybe move out to test or something … … 264 273 265 274 266 #def get_A(self): 267 # return self.A.todense() 268 269 def interpolate(self, f): 270 """Interpolate mesh data f to points. 275 # FIXME: What is a good start_blocking_count value? 276 def interpolate(self, f, point_coordinates = None, 277 start_blocking_len = 500000, verbose=False): 278 """Interpolate mesh data f to determine values, z, at points. 271 279 272 280 f is the data on the mesh vertices. 273 281 274 275 282 The mesh values representing a smooth surface are 276 assumed to be specified in f. This argument could, 277 for example have been obtained from the method self.fit() 278 279 Pre Condition: 280 self.A has been initialised 283 assumed to be specified in f. 281 284 282 285 Inputs: 283 286 f: Vector or array of data at the mesh vertices. 284 If f is an array, interpolation will be done for each column as 285 per underlying matrix-matrix multiplication 287 If f is an array, interpolation will be done for each column as 288 per underlying matrix-matrix multiplication 289 point_coordinates: Interpolate mesh data to these positions. 290 start_blocking_len: If the # of points is more or greater than this, 291 start blocking 286 292 287 293 Output: 288 Interpolated values at data points implied in self.A 289 290 """ 291 294 Interpolated values at inputted points (z). 295 """ 296 297 # Can I interpolate, based on previous point_coordinates? 298 if point_coordinates is None: 299 if self.A_can_be_reused is True and \ 300 len(self.point_coordinates) < start_blocking_len: 301 z = self._get_point_data_z(f, 302 verbose=verbose) 303 elif self.point_coordinates is not None: 304 # if verbose, give warning 305 if verbose: 306 print 'WARNING: Recalculating A matrix, due to blocking.' 307 point_coordinates = self.point_coordinates 308 else: 309 #There are no good point_coordinates. import sys; sys.exit() 310 msg = 'ERROR (interpolate.py): No point_coordinates inputted' 311 raise msg 312 313 if point_coordinates is not None: 314 self.point_coordinates = point_coordinates 315 if len(point_coordinates) < start_blocking_len or \ 316 start_blocking_len == 0: 317 self.A_can_be_reused = True 318 z = self.interpolate_block(f, point_coordinates, 319 verbose=verbose) 320 else: 321 #Handle blocking 322 self.A_can_be_reused = False 323 start=0 324 z = self.interpolate_block(f, point_coordinates[0:0]) 325 for end in range(start_blocking_len 326 ,len(point_coordinates) 327 ,start_blocking_len): 328 t = self.interpolate_block(f, point_coordinates[start:end], 329 verbose=verbose) 330 z = concatenate((z,t)) 331 start = end 332 end = len(point_coordinates) 333 t = self.interpolate_block(f, point_coordinates[start:end], 334 verbose=verbose) 335 z = concatenate((z,t)) 336 return z 337 338 def interpolate_block(self, f, point_coordinates = None, verbose=False): 339 """ 340 Call this if you want to control the blocking or make sure blocking 341 doesn't occur. 342 343 See interpolate for doc info. 344 """ 345 if point_coordinates is not None: 346 self.A =self._build_interpolation_matrix_A(point_coordinates, 347 verbose=verbose) 348 return self._get_point_data_z(f) 349 350 def _get_point_data_z(self, f, verbose=False): 292 351 return self.A * f 352 293 353 #------------------------------------------------------------- 294 354 if __name__ == "__main__": -
inundation/fit_interpolate/test_interpolate.py
r2187 r2189 239 239 240 240 241 241 def test_interpolate_attributes_to_points(self): 242 v0 = [0.0, 0.0] 243 v1 = [0.0, 5.0] 244 v2 = [5.0, 0.0] 245 246 vertices = [v0, v1, v2] 247 triangles = [ [1,0,2] ] #bac 248 249 d0 = [1.0, 1.0] 250 d1 = [1.0, 2.0] 251 d2 = [3.0, 1.0] 252 point_coords = [ d0, d1, d2] 253 254 interp = Interpolate(vertices, triangles, point_coords) 255 f = linear_function(vertices) 256 z = interp.interpolate(f, point_coords) 257 answer = linear_function(point_coords) 258 259 260 assert allclose(z, answer) 261 262 263 264 def test_interpolate_attributes_to_pointsII(self): 265 a = [-1.0, 0.0] 266 b = [3.0, 4.0] 267 c = [4.0, 1.0] 268 d = [-3.0, 2.0] #3 269 e = [-1.0, -2.0] 270 f = [1.0, -2.0] #5 271 272 vertices = [a, b, c, d,e,f] 273 triangles = [[0,1,3], [1,0,2], [0,4,5], [0,5,2]] #abd bac aef afc 274 275 276 point_coords = [[-2.0, 2.0], 277 [-1.0, 1.0], 278 [0.0, 2.0], 279 [1.0, 1.0], 280 [2.0, 1.0], 281 [0.0, 0.0], 282 [1.0, 0.0], 283 [0.0, -1.0], 284 [-0.2, -0.5], 285 [-0.9, -1.5], 286 [0.5, -1.9], 287 [3.0, 1.0]] 288 289 interp = Interpolate(vertices, triangles) 290 f = linear_function(vertices) 291 z = interp.interpolate(f, point_coords) 292 answer = linear_function(point_coords) 293 #print "z",z 294 #print "answer",answer 295 assert allclose(z, answer) 296 297 def test_interpolate_attributes_to_pointsIII(self): 298 """Test linear interpolation of known values at vertices to 299 new points inside a triangle 300 """ 301 a = [0.0, 0.0] 302 b = [0.0, 5.0] 303 c = [5.0, 0.0] 304 d = [5.0, 5.0] 305 306 vertices = [a, b, c, d] 307 triangles = [ [1,0,2], [2,3,1] ] #bac, cdb 308 309 #Points within triangle 1 310 d0 = [1.0, 1.0] 311 d1 = [1.0, 2.0] 312 d2 = [3.0, 1.0] 313 314 #Point within triangle 2 315 d3 = [4.0, 3.0] 316 317 #Points on common edge 318 d4 = [2.5, 2.5] 319 d5 = [4.0, 1.0] 320 321 #Point on common vertex 322 d6 = [0., 5.] 323 324 point_coords = [d0, d1, d2, d3, d4, d5, d6] 325 326 interp = Interpolate(vertices, triangles) 327 328 #Known values at vertices 329 #Functions are x+y, x+2y, 2x+y, x-y-5 330 f = [ [0., 0., 0., -5.], # (0,0) 331 [5., 10., 5., -10.], # (0,5) 332 [5., 5., 10.0, 0.], # (5,0) 333 [10., 15., 15., -5.]] # (5,5) 334 335 z = interp.interpolate(f, point_coords) 336 answer = [ [2., 3., 3., -5.], # (1,1) 337 [3., 5., 4., -6.], # (1,2) 338 [4., 5., 7., -3.], # (3,1) 339 [7., 10., 11., -4.], # (4,3) 340 [5., 7.5, 7.5, -5.], # (2.5, 2.5) 341 [5., 6., 9., -2.], # (4,1) 342 [5., 10., 5., -10.]] # (0,5) 343 344 #print "***********" 345 #print "z",z 346 #print "answer",answer 347 #print "***********" 348 349 #Should an error message be returned if points are outside 350 # of the mesh? Not currently. 351 352 assert allclose(z, answer) 353 354 355 def test_interpolate_point_outside_of_mesh(self): 356 """Test linear interpolation of known values at vertices to 357 new points inside a triangle 358 """ 359 a = [0.0, 0.0] 360 b = [0.0, 5.0] 361 c = [5.0, 0.0] 362 d = [5.0, 5.0] 363 364 vertices = [a, b, c, d] 365 triangles = [ [1,0,2], [2,3,1] ] #bac, cdb 366 367 #Far away point 368 d7 = [-1., -1.] 369 370 point_coords = [ d7] 371 interp = Interpolate(vertices, triangles) 372 373 #Known values at vertices 374 #Functions are x+y, x+2y, 2x+y, x-y-5 375 f = [ [0., 0., 0., -5.], # (0,0) 376 [5., 10., 5., -10.], # (0,5) 377 [5., 5., 10.0, 0.], # (5,0) 378 [10., 15., 15., -5.]] # (5,5) 379 380 z = interp.interpolate(f, point_coords) 381 answer = [ [0., 0., 0., 0.]] # (-1,-1) 382 383 #print "***********" 384 #print "z",z 385 #print "answer",answer 386 #print "***********" 387 388 #Should an error message be returned if points are outside 389 # of the mesh? Not currently. 390 391 assert allclose(z, answer) 392 393 def test_interpolate_attributes_to_pointsIV(self): 394 a = [-1.0, 0.0] 395 b = [3.0, 4.0] 396 c = [4.0, 1.0] 397 d = [-3.0, 2.0] #3 398 e = [-1.0, -2.0] 399 f = [1.0, -2.0] #5 400 401 vertices = [a, b, c, d,e,f] 402 triangles = [[0,1,3], [1,0,2], [0,4,5], [0,5,2]] #abd bac aef afc 403 404 405 point_coords = [[-2.0, 2.0], 406 [-1.0, 1.0], 407 [0.0, 2.0], 408 [1.0, 1.0], 409 [2.0, 1.0], 410 [0.0, 0.0], 411 [1.0, 0.0], 412 [0.0, -1.0], 413 [-0.2, -0.5], 414 [-0.9, -1.5], 415 [0.5, -1.9], 416 [3.0, 1.0]] 417 418 interp = Interpolate(vertices, triangles) 419 f = array([linear_function(vertices),2*linear_function(vertices) ]) 420 f = transpose(f) 421 #print "f",f 422 z = interp.interpolate(f, point_coords) 423 answer = [linear_function(point_coords), 424 2*linear_function(point_coords) ] 425 answer = transpose(answer) 426 #print "z",z 427 #print "answer",answer 428 assert allclose(z, answer) 429 430 431 def test_interpolate_blocking(self): 432 a = [-1.0, 0.0] 433 b = [3.0, 4.0] 434 c = [4.0, 1.0] 435 d = [-3.0, 2.0] #3 436 e = [-1.0, -2.0] 437 f = [1.0, -2.0] #5 438 439 vertices = [a, b, c, d,e,f] 440 triangles = [[0,1,3], [1,0,2], [0,4,5], [0,5,2]] #abd bac aef afc 441 442 443 point_coords = [[-2.0, 2.0], 444 [-1.0, 1.0], 445 [0.0, 2.0], 446 [1.0, 1.0], 447 [2.0, 1.0], 448 [0.0, 0.0], 449 [1.0, 0.0], 450 [0.0, -1.0], 451 [-0.2, -0.5], 452 [-0.9, -1.5], 453 [0.5, -1.9], 454 [3.0, 1.0]] 455 456 interp = Interpolate(vertices, triangles) 457 f = array([linear_function(vertices),2*linear_function(vertices) ]) 458 f = transpose(f) 459 #print "f",f 460 for blocking_max in range(len(point_coords)+2): 461 #if True: 462 # blocking_max = 5 463 z = interp.interpolate(f, point_coords, 464 start_blocking_len=blocking_max) 465 answer = [linear_function(point_coords), 466 2*linear_function(point_coords) ] 467 answer = transpose(answer) 468 #print "z",z 469 #print "answer",answer 470 assert allclose(z, answer) 471 472 def test_interpolate_reuse(self): 473 a = [-1.0, 0.0] 474 b = [3.0, 4.0] 475 c = [4.0, 1.0] 476 d = [-3.0, 2.0] #3 477 e = [-1.0, -2.0] 478 f = [1.0, -2.0] #5 479 480 vertices = [a, b, c, d,e,f] 481 triangles = [[0,1,3], [1,0,2], [0,4,5], [0,5,2]] #abd bac aef afc 482 483 484 point_coords = [[-2.0, 2.0], 485 [-1.0, 1.0], 486 [0.0, 2.0], 487 [1.0, 1.0], 488 [2.0, 1.0], 489 [0.0, 0.0], 490 [1.0, 0.0], 491 [0.0, -1.0], 492 [-0.2, -0.5], 493 [-0.9, -1.5], 494 [0.5, -1.9], 495 [3.0, 1.0]] 496 497 interp = Interpolate(vertices, triangles) 498 f = array([linear_function(vertices),2*linear_function(vertices) ]) 499 f = transpose(f) 500 z = interp.interpolate(f, point_coords, 501 start_blocking_len=20) 502 answer = [linear_function(point_coords), 503 2*linear_function(point_coords) ] 504 answer = transpose(answer) 505 #print "z",z 506 #print "answer",answer 507 assert allclose(z, answer) 508 assert allclose(interp.A_can_be_reused, True) 509 510 z = interp.interpolate(f) 511 assert allclose(z, answer) 512 513 # This causes blocking to occur. 514 z = interp.interpolate(f, start_blocking_len=10) 515 assert allclose(z, answer) 516 assert allclose(interp.A_can_be_reused, False) 517 518 #A is recalculated 519 z = interp.interpolate(f) 520 assert allclose(z, answer) 521 assert allclose(interp.A_can_be_reused, True) 522 523 interp = Interpolate(vertices, triangles) 524 #Must raise an exception, no points specified 525 try: 526 z = interp.interpolate(f) 527 except: 528 pass 529 242 530 243 531 #-------------------------------------------------------------
Note: See TracChangeset
for help on using the changeset viewer.