Changeset 1486
- Timestamp:
- May 31, 2005, 2:24:14 PM (20 years ago)
- Location:
- inundation/ga/storm_surge/pyvolution
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pyvolution/quantity.py
r1393 r1486 792 792 793 793 #Gradient 794 det = x0*y1 - x1*y0 795 if det != 0.0: 796 a[k] = (y1*q0 - y0*q1)/det 797 b[k] = (x0*q1 - x1*q0)/det 798 794 a[k], b[k] = gradient2(x0, y0, x1, y1, q0, q1) 799 795 else: 800 796 #No true neighbours - -
inundation/ga/storm_surge/pyvolution/quantity_ext.c
r1156 r1486 29 29 30 30 int i, k, k0, k1, k2, index3; 31 double x0, x1, x2, y0, y1, y2, q0, q1, q2 , det;31 double x0, x1, x2, y0, y1, y2, q0, q1, q2; //, det; 32 32 33 33 … … 80 80 x1 = centroids[k1*2]; y1 = centroids[k1*2+1]; 81 81 82 //Gradient 83 det = x0*y1 - x1*y0; 84 if (det != 0.0) { 85 a[k] = (y1*q0 - y0*q1)/det; 86 b[k] = (x0*q1 - x1*q0)/det; 87 } 82 //Two point gradient 83 _gradient2(x0, y0, x1, y1, q0, q1, &a[k], &b[k]); 84 85 86 //Old (wrong code) 87 //det = x0*y1 - x1*y0; 88 //if (det != 0.0) { 89 // a[k] = (y1*q0 - y0*q1)/det; 90 // b[k] = (x0*q1 - x1*q0)/det; 91 //} 88 92 } 89 93 // else: -
inundation/ga/storm_surge/pyvolution/test_quantity.py
r1393 r1486 84 84 quantity.extrapolate_second_order() 85 85 86 assert allclose(quantity.vertex_values, [[2., 2., 2.], 87 [3.+2./3, 6.+2./3, 4.+2./3], 88 [7.5, 0.5, 1.], 89 [-5, -2.5, 7.5]]) 90 86 #print quantity.vertex_values 87 #assert allclose(quantity.vertex_values, [[2., 2., 2.], 88 # [3.+2./3, 6.+2./3, 4.+2./3], 89 # [7.5, 0.5, 1.], 90 # [-5, -2.5, 7.5]]) 91 92 assert allclose(quantity.vertex_values[1,:],[3.+2./3, 6.+2./3, 4.+2./3]) 93 #FIXME: Work out the others 94 95 91 96 #print quantity.edge_values 92 97 assert allclose(quantity.edge_values, [[2.5, 2.0, 1.5], … … 267 272 quantity = Conserved_quantity(self.mesh4) 268 273 269 #Set up for a gradient of ( 3,0) at mid triangle270 quantity.set_values([2.0, 4.0, 8.0, 2.0],274 #Set up for a gradient of (2,0) at mid triangle 275 quantity.set_values([2.0, 4.0, 6.0, 2.0], 271 276 location = 'centroids') 272 273 277 274 278 … … 276 280 a, b = quantity.compute_gradients() 277 281 278 #gradient bewteen t0 and t1 is undefined as det==0 279 assert a[0] == 0.0 280 assert b[0] == 0.0 281 #The others are OK 282 for i in range(1,4): 283 assert a[i] == 3.0 284 assert b[i] == 0.0 285 286 282 #print self.mesh4.centroid_coordinates 283 #print a, b 284 285 #The central triangle (1) 286 #(using standard gradient based on neigbours controid values) 287 assert a[1] == 2.0 288 assert b[1] == 0.0 289 290 291 #Left triangle (0) using two point gradient 292 #q0 = q1 + a*(x0-x1) + b*(y0-y1) <=> 293 #2 = 4 + a*(-2/3) + b*(-2/3) 294 assert a[0] + b[0] == 3 295 #From orthogonality (a*(y0-y1) + b*(x0-x1) == 0) 296 assert a[0] - b[0] == 0 297 298 299 #Right triangle (2) using two point gradient 300 #q2 = q1 + a*(x2-x1) + b*(y2-y1) <=> 301 #6 = 4 + a*(4/3) + b*(-2/3) 302 assert 2*a[2] - b[2] == 3 303 #From orthogonality (a*(y1-y2) + b*(x2-x1) == 0) 304 assert a[2] + 2*b[2] == 0 305 306 307 #Top triangle (3) using two point gradient 308 #q3 = q1 + a*(x3-x1) + b*(y3-y1) <=> 309 #2 = 4 + a*(-2/3) + b*(4/3) 310 assert a[3] - 2*b[3] == 3 311 #From orthogonality (a*(y1-y3) + b*(x3-x1) == 0) 312 assert 2*a[3] + b[3] == 0 313 314 315 316 #print a, b 287 317 quantity.extrapolate_second_order() 288 318 289 #print quantity.vertex_values 290 assert allclose(quantity.vertex_values, [[2., 2., 2.], 291 [0., 6., 6.], 292 [6., 6., 12.], 293 [0., 0., 6.]]) 319 #Apply q(x,y) = qc + a*(x-xc) + b*(y-yc) 320 assert allclose(quantity.vertex_values[0,:], [3., 0., 3.]) 321 assert allclose(quantity.vertex_values[1,:], [4./3, 16./3, 16./3]) 322 323 324 #a = 1.2, b=-0.6 325 #q(4,0) = 6 + a*(4 - 8/3) + b*(-2/3) 326 assert allclose(quantity.vertex_values[2,2], 8) 294 327 295 328 … … 304 337 a, b = quantity.compute_gradients() 305 338 306 #gradient bewteen t0 and t1 is undefined as det==0 307 assert a[0] == 0.0 308 assert b[0] == 0.0 309 #The others are OK 310 for i in range(1,4): 311 assert allclose(a[i], 3.0) 312 assert allclose(b[i], 1.0) 313 339 #print a, b 340 341 assert a[1] == 3.0 342 assert b[1] == 1.0 343 344 #Work out the others 345 314 346 quantity.extrapolate_second_order() 315 347 -
inundation/ga/storm_surge/pyvolution/test_util.py
r1137 r1486 31 31 assert zy == 0.0 32 32 33 34 35 36 def test_gradient2(self): 37 38 from util import gradient 33 def test_gradient_more(self): 39 34 x0 = 2.0/3; y0 = 2.0/3 40 35 x1= 8.0/3; y1 = 2.0/3 … … 51 46 assert abs(b - 1.0) < epsilon 52 47 48 49 def test_gradient2(self): 50 """Test two-point gradient 51 """ 52 53 x0 = 5.0; y0 = 5.0; z0 = 10.0 54 x1 = 8.0; y1 = 2.0; z1 = 1.0 55 x2 = 8.0; y2 = 8.0; z2 = 10.0 56 57 #Reference 58 zx, zy = gradient(x0, y0, x1, y1, x2, y2, z0, z1, z2) 59 a, b = gradient2(x0, y0, x1, y1, z0, z1) 60 61 assert zx == a 62 assert zy == b 63 64 z2_computed = z0 + a*(x2-x0) + b*(y2-y0) 65 assert z2_computed == z2 66 67 def test_gradient2_more(self): 68 """Test two-point gradient more 69 """ 70 x0 = 2.0; y0 = 2.0 71 x1 = 8.0; y1 = 3.0 72 x2 = 1.0; y2 = 8.0 73 74 q0 = 2.0 75 q1 = 8.0 76 q2 = q0 77 78 #Gradient of fitted pwl surface 79 a_ref, b_ref = gradient(x0, y0, x1, y1, x2, y2, q0, q1, q2) 80 a, b = gradient2(x0, y0, x1, y1, q0, q1) 81 82 assert a == a_ref 83 assert b == b_ref 53 84 54 85 -
inundation/ga/storm_surge/pyvolution/util.py
r1387 r1486 1401 1401 1402 1402 1403 def gradient2_python(x0, y0, x1, y1, q0, q1): 1404 """Compute radient based on two points and enforce zero gradient 1405 in the direction orthogonal to (x1-x0), (y1-y0) 1406 """ 1407 1408 #Old code 1409 #det = x0*y1 - x1*y0 1410 #if det != 0.0: 1411 # a = (y1*q0 - y0*q1)/det 1412 # b = (x0*q1 - x1*q0)/det 1413 1414 #Correct code (ON) 1415 det = (x1-x0)**2 + (y1-y0)**2 1416 if det != 0.0: 1417 a = (x1-x0)*(q1-q0)/det 1418 b = (y1-y0)*(q1-q0)/det 1419 1420 return a, b 1421 1403 1422 1404 1423 ############################################## … … 1407 1426 import compile 1408 1427 if compile.can_use_C_extension('util_ext.c'): 1409 from util_ext import gradient, point_on_line1428 from util_ext import gradient, gradient2, point_on_line 1410 1429 separate_points_by_polygon = separate_points_by_polygon_c 1411 1430 else: 1412 1431 gradient = gradient_python 1432 gradient2 = gradient2_python 1413 1433 1414 1434 -
inundation/ga/storm_surge/pyvolution/util_ext.c
r1093 r1486 272 272 } 273 273 274 PyObject *gradient2(PyObject *self, PyObject *args) { 275 // 276 // a,b = gradient2(x0, y0, x1, y1, q0, q1) 277 // 278 279 double x0, y0, x1, y1, q0, q1, a, b; 280 PyObject *result; 281 282 // Convert Python arguments to C 283 if (!PyArg_ParseTuple(args, "dddddd", &x0, &y0, &x1, &y1, &q0, &q1)) 284 return NULL; 285 286 287 // Call underlying routine 288 _gradient2(x0, y0, x1, y1, q0, q1, &a, &b); 289 290 // Return values a and b 291 result = Py_BuildValue("dd", a, b); 292 return result; 293 } 274 294 275 295 // Method table for python module … … 282 302 //{"rotate", (PyCFunction)rotate, METH_VARARGS | METH_KEYWORDS, "Print out"}, 283 303 {"gradient", gradient, METH_VARARGS, "Print out"}, 304 {"gradient2", gradient2, METH_VARARGS, "Print out"}, 284 305 {"point_on_line", point_on_line, METH_VARARGS, "Print out"}, 285 306 //{"inside_polygon", inside_polygon, METH_VARARGS, "Print out"}, -
inundation/ga/storm_surge/pyvolution/util_ext.h
r1137 r1486 47 47 *b /= det; 48 48 49 return 0; 50 } 51 52 53 int _gradient2(double x0, double y0, 54 double x1, double y1, 55 double q0, double q1, 56 double *a, double *b) { 57 /*Compute gradient (a,b) between two points (x0,y0) and (x1,y1) 58 with values q0 and q1 such that the plane is constant in the direction 59 orthogonal to (x1-x0, y1-y0). 60 61 Extrapolation formula 62 q(x,y) = q0 + a*(x-x0) + b*(y-y0) (1) 63 64 Substituting the known values for q1 into (1) yields an 65 under determined equation for a and b 66 q1-q0 = a*(x1-x0) + b*(y1-y0) (2) 67 68 69 Now add the additional requirement that the gradient in the direction 70 orthogonal to (x1-x0, y1-y0) should be zero. The orthogonal direction 71 is given by the vector (y0-y1, x1-x0). 72 73 Define the point (x2, y2) = (x0 + y0-y1, y0 + x1-x0) on the orthognal line. 74 Then we know that the corresponding value q2 should be equal to q0 in order 75 to obtain the zero gradient, hence applying (1) again 76 q0 = q2 = q(x2, y2) = q0 + a*(x2-x0) + b*(y2-y0) 77 = q0 + a*(x0 + y0-y1-x0) + b*(y0 + x1-x0 - y0) 78 = q0 + a*(y0-y1) + b*(x1-x0) 79 80 leads to the orthogonality constraint 81 a*(y0-y1) + b*(x1-x0) = 0 (3) 82 83 which closes the system and yields 84 85 / \ / \ / \ 86 | x1-x0 y1-y0 | | a | | q1-q0 | 87 | | | | = | | 88 | y0-y1 x1-x0 | | b | | 0 | 89 \ / \ / \ / 90 91 which is solved using the standard determinant technique 92 93 */ 94 95 double det, xx, yy, qq; 96 97 xx = x1-x0; 98 yy = y1-y0; 99 qq = q1-q0; 100 101 det = xx*xx + yy*yy; //FIXME catch det == 0 102 *a = xx*qq/det; 103 *b = yy*qq/det; 104 49 105 return 0; 50 106 }
Note: See TracChangeset
for help on using the changeset viewer.