Changeset 6902
- Timestamp:
- Apr 24, 2009, 5:22:14 PM (16 years ago)
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
anuga_core/source/anuga/utilities/log_test.py
r6587 r6902 31 31 if os.path.exists(STDOUT_LOG_NAME): 32 32 os.remove(STDOUT_LOG_NAME) 33 pass34 33 35 34 ## -
branches/numpy/anuga/abstract_2d_finite_volumes/domain.py
r6553 r6902 92 92 """ 93 93 94 number_of_full_nodes=None 95 number_of_full_triangles=None 96 94 97 # Determine whether source is a mesh filename or coordinates 95 98 if type(source) == types.StringType: … … 117 120 118 121 # Expose Mesh attributes (FIXME: Maybe turn into methods) 122 self.triangles = self.mesh.triangles 119 123 self.centroid_coordinates = self.mesh.centroid_coordinates 120 124 self.vertex_coordinates = self.mesh.vertex_coordinates … … 205 209 # the ghost triangles. 206 210 if not num.allclose(self.tri_full_flag[:self.number_of_full_nodes], 1): 207 print ('WARNING: ' 208 'Not all full triangles are store before ghost triangles') 211 if self.numproc>1: 212 print ('WARNING: ' 213 'Not all full triangles are store before ghost triangles') 209 214 210 215 # Defaults … … 306 311 def get_normal(self, *args, **kwargs): 307 312 return self.mesh.get_normal(*args, **kwargs) 313 def get_triangle_containing_point(self, *args, **kwargs): 314 return self.mesh.get_triangle_containing_point(*args, **kwargs) 308 315 309 316 def get_intersecting_segments(self, *args, **kwargs): … … 1745 1752 1746 1753 ## 1747 # @brief ??1754 # @brief Sequential update of ghost cells 1748 1755 def update_ghosts(self): 1749 pass 1750 1756 # We must send the information from the full cells and 1757 # receive the information for the ghost cells 1758 # We have a list with ghosts expecting updates 1759 1760 from Numeric import take,put 1761 1762 1763 #Update of ghost cells 1764 iproc = self.processor 1765 if self.full_send_dict.has_key(iproc): 1766 1767 # now store full as local id, global id, value 1768 Idf = self.full_send_dict[iproc][0] 1769 1770 # now store ghost as local id, global id, value 1771 Idg = self.ghost_recv_dict[iproc][0] 1772 1773 for i, q in enumerate(self.conserved_quantities): 1774 Q_cv = self.quantities[q].centroid_values 1775 put(Q_cv, Idg, take(Q_cv, Idf)) 1776 1777 1751 1778 ## 1752 1779 # @brief Extrapolate conserved quantities from centroid to vertices -
branches/numpy/anuga/abstract_2d_finite_volumes/generic_boundary_conditions.py
r6553 r6902 82 82 """Time dependent boundary returns values for the 83 83 conserved quantities as a function of time. 84 Must specify domain to get access to model time and a function f(t) 85 which must return conserved quantities as a function time 84 Must specify domain to get access to model time and a function of t 85 which must return conserved quantities as a function time. 86 87 Example: 88 B = Time_boundary(domain, 89 function=lambda t: [(60<t<3660)*2, 0, 0]) 90 91 This will produce a boundary condition with is a 2m high square wave 92 starting 60 seconds into the simulation and lasting one hour. 93 Momentum applied will be 0 at all times. 94 86 95 """ 87 96 … … 98 107 self.verbose = verbose 99 108 109 110 # FIXME: Temporary code to deal with both f and function 111 if function is not None and f is not None: 112 raise Exception, 'Specify either function or f to Time_boundary' 113 114 if function is None and f is None: 115 raise Exception, 'You must specify a function to Time_boundary' 116 117 if f is None: 118 f = function 119 ##### 120 100 121 try: 101 122 q = f(0.0) -
branches/numpy/anuga/abstract_2d_finite_volumes/mesh_factory.py
r6304 r6902 201 201 202 202 return points, elements, boundary 203 204 205 def rectangular_periodic(m_g, n_g, len1_g=1.0, len2_g=1.0, origin_g = (0.0, 0.0)): 206 207 208 """Setup a rectangular grid of triangles 209 with m+1 by n+1 grid points 210 and side lengths len1, len2. If side lengths are omitted 211 the mesh defaults to the unit square, divided between all the 212 processors 213 214 len1: x direction (left to right) 215 len2: y direction (bottom to top) 216 217 """ 218 219 processor = 0 220 numproc = 1 221 222 223 n = n_g 224 m_low = -1 225 m_high = m_g +1 226 227 m = m_high - m_low 228 229 delta1 = float(len1_g)/m_g 230 delta2 = float(len2_g)/n_g 231 232 len1 = len1_g*float(m)/float(m_g) 233 len2 = len2_g 234 origin = ( origin_g[0]+float(m_low)/float(m_g)*len1_g, origin_g[1] ) 235 236 #Calculate number of points 237 Np = (m+1)*(n+1) 238 239 class VIndex: 240 241 def __init__(self, n,m): 242 self.n = n 243 self.m = m 244 245 def __call__(self, i,j): 246 return j+i*(self.n+1) 247 248 class EIndex: 249 250 def __init__(self, n,m): 251 self.n = n 252 self.m = m 253 254 def __call__(self, i,j): 255 return 2*(j+i*self.n) 256 257 258 I = VIndex(n,m) 259 E = EIndex(n,m) 260 261 points = num.zeros( (Np,2), num.Float) 262 263 for i in range(m+1): 264 for j in range(n+1): 265 266 points[I(i,j),:] = [i*delta1 + origin[0], j*delta2 + origin[1]] 267 268 #Construct 2 triangles per rectangular element and assign tags to boundary 269 #Calculate number of triangles 270 Nt = 2*m*n 271 272 273 elements = num.zeros( (Nt,3), num.Int) 274 boundary = {} 275 Idgl = [] 276 Idfl = [] 277 Idgr = [] 278 Idfr = [] 279 280 full_send_dict = {} 281 ghost_recv_dict = {} 282 nt = -1 283 for i in range(m): 284 for j in range(n): 285 286 i1 = I(i,j+1) 287 i2 = I(i,j) 288 i3 = I(i+1,j+1) 289 i4 = I(i+1,j) 290 291 #Lower Element 292 nt = E(i,j) 293 if i == 0: 294 Idgl.append(nt) 295 296 if i == 1: 297 Idfl.append(nt) 298 299 if i == m-2: 300 Idfr.append(nt) 301 302 if i == m-1: 303 Idgr.append(nt) 304 305 if i == m-1: 306 if processor == numproc-1: 307 boundary[nt, 2] = 'right' 308 else: 309 boundary[nt, 2] = 'ghost' 310 311 if j == 0: 312 boundary[nt, 1] = 'bottom' 313 elements[nt,:] = [i4,i3,i2] 314 315 #Upper Element 316 nt = E(i,j)+1 317 if i == 0: 318 Idgl.append(nt) 319 320 if i == 1: 321 Idfl.append(nt) 322 323 if i == m-2: 324 Idfr.append(nt) 325 326 if i == m-1: 327 Idgr.append(nt) 328 329 if i == 0: 330 if processor == 0: 331 boundary[nt, 2] = 'left' 332 else: 333 boundary[nt, 2] = 'ghost' 334 if j == n-1: 335 boundary[nt, 1] = 'top' 336 elements[nt,:] = [i1,i2,i3] 337 338 Idfl.extend(Idfr) 339 Idgr.extend(Idgl) 340 341 Idfl = num.array(Idfl, num.Int) 342 Idgr = num.array(Idgr, num.Int) 343 344 full_send_dict[processor] = [Idfl, Idfl] 345 ghost_recv_dict[processor] = [Idgr, Idgr] 346 347 348 return points, elements, boundary, full_send_dict, ghost_recv_dict 349 203 350 204 351 def oblique(m, n, lenx = 1.0, leny = 1.0, theta = 8.95, origin = (0.0, 0.0)): -
branches/numpy/anuga/abstract_2d_finite_volumes/quantity.py
r6689 r6902 1178 1178 # Edges have already been deprecated in set_values, see changeset:5521, 1179 1179 # but *might* be useful in get_values. Any thoughts anyone? 1180 # YES (Ole): Edge values are necessary for volumetric balance check 1180 1181 1181 1182 if location not in ['vertices', 'centroids', -
branches/numpy/anuga/abstract_2d_finite_volumes/test_domain.py
r6553 r6902 397 397 398 398 def test_setting_timestepping_method(self): 399 """test_set _quanitities_to_be_monitored399 """test_setting_timestepping_method 400 400 """ 401 401 … … 803 803 [ 11.0, 11.0, 11.0]]) 804 804 805 def test_rectangular_periodic_and_ghosts(self): 806 807 from mesh_factory import rectangular_periodic 808 809 810 M=5 811 N=2 812 points, vertices, boundary, full_send_dict, ghost_recv_dict = rectangular_periodic(M, N) 813 814 assert num.allclose(ghost_recv_dict[0][0], [24, 25, 26, 27, 0, 1, 2, 3]) 815 assert num.allclose(full_send_dict[0][0] , [ 4, 5, 6, 7, 20, 21, 22, 23]) 816 817 #print 'HERE' 818 819 conserved_quantities = ['quant1', 'quant2'] 820 domain = Domain(points, vertices, boundary, conserved_quantities, 821 full_send_dict=full_send_dict, 822 ghost_recv_dict=ghost_recv_dict) 823 824 825 826 827 assert num.allclose(ghost_recv_dict[0][0], [24, 25, 26, 27, 0, 1, 2, 3]) 828 assert num.allclose(full_send_dict[0][0] , [ 4, 5, 6, 7, 20, 21, 22, 23]) 829 830 def xylocation(x,y): 831 return 15*x + 9*y 832 833 834 domain.set_quantity('quant1',xylocation,location='centroids') 835 domain.set_quantity('quant2',xylocation,location='centroids') 836 837 838 assert num.allclose(domain.quantities['quant1'].centroid_values, 839 [ 0.5, 1., 5., 5.5, 3.5, 4., 8., 8.5, 6.5, 7., 11., 11.5, 9.5, 840 10., 14., 14.5, 12.5, 13., 17., 17.5, 15.5, 16., 20., 20.5, 841 18.5, 19., 23., 23.5]) 842 843 844 845 assert num.allclose(domain.quantities['quant2'].centroid_values, 846 [ 0.5, 1., 5., 5.5, 3.5, 4., 8., 8.5, 6.5, 7., 11., 11.5, 9.5, 847 10., 14., 14.5, 12.5, 13., 17., 17.5, 15.5, 16., 20., 20.5, 848 18.5, 19., 23., 23.5]) 849 850 domain.update_ghosts() 851 852 853 assert num.allclose(domain.quantities['quant1'].centroid_values, 854 [ 15.5, 16., 20., 20.5, 3.5, 4., 8., 8.5, 6.5, 7., 11., 11.5, 9.5, 855 10., 14., 14.5, 12.5, 13., 17., 17.5, 15.5, 16., 20., 20.5, 856 3.5, 4., 8., 8.5]) 857 858 859 860 assert num.allclose(domain.quantities['quant2'].centroid_values, 861 [ 15.5, 16., 20., 20.5, 3.5, 4., 8., 8.5, 6.5, 7., 11., 11.5, 9.5, 862 10., 14., 14.5, 12.5, 13., 17., 17.5, 15.5, 16., 20., 20.5, 863 3.5, 4., 8., 8.5]) 864 865 866 assert num.allclose(domain.tri_full_flag, [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 867 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]) 868 869 #Test that points are arranged in a counter clock wise order 870 domain.check_integrity() 871 872 805 873 def test_that_mesh_methods_exist(self): 806 874 """test_that_mesh_methods_exist … … 828 896 domain.get_number_of_nodes() 829 897 domain.get_normal(0,0) 898 domain.get_triangle_containing_point([0.4,0.5]) 830 899 domain.get_intersecting_segments([[0.0, 0.0], [0.0, 1.0]]) 831 900 domain.get_disconnected_triangles() -
branches/numpy/anuga/coordinate_transforms/redfearn.py
r6553 r6902 48 48 If zone is specified reproject lat and long to specified zone instead of 49 49 standard zone 50 50 51 If meridian is specified, reproject lat and lon to that instead of zone. In this case 51 52 zone will be set to -1 to indicate non-UTM projection -
branches/numpy/anuga/culvert_flows/culvert_class.py
r6553 r6902 325 325 if time - self.last_update > self.update_interval or time == 0.0: 326 326 update = True 327 328 327 329 328 if self.log_filename is not None: -
branches/numpy/anuga/culvert_flows/culvert_routines.py
r6689 r6902 217 217 else: # inlet_depth < 0.01: 218 218 Q = barrel_velocity = outlet_culvert_depth = 0.0 219 219 220 # Temporary flow limit 220 221 if barrel_velocity > max_velocity: -
branches/numpy/anuga/culvert_flows/test_culvert_routines.py
r6790 r6902 19 19 20 20 21 def test_boyd_ 1(self):22 """test_boyd_ 123 24 This tests the Boyd routine with data obtained from ??? by Petar Milevski 25 """26 # FIXME(Ole): This test fails (20 Feb 2009)27 21 def test_boyd_0(self): 22 """test_boyd_0 23 24 This tests the Boyd routine with data obtained from ??? by Petar Milevski 25 This test is the only one that passed in late February 2009 26 """ 27 28 28 g=9.81 29 29 culvert_slope=0.1 # Downward … … 67 67 68 68 69 def test_boyd_2(self):70 """test_boyd_ 269 def Xtest_boyd_00(self): 70 """test_boyd_00 71 71 72 72 This tests the Boyd routine with data obtained from ??? by Petar Milevski … … 108 108 109 109 #print Q, v, d 110 #assert num.allclose(Q, 0.185, rtol=1.0e-3)110 assert num.allclose(Q, 0.185, rtol=1.0e-3) 111 111 #assert num.allclose(v, 0.93) 112 112 #assert num.allclose(d, 0.0) 113 113 114 def Xtest_boyd_1(self): 115 """test_boyd_1 116 117 This tests the Boyd routine with data obtained from ??? by Petar Milevski 118 """ 119 # FIXME(Ole): This test fails (20 Feb 2009) 120 121 g=9.81 122 culvert_slope=0.01 # Downward 123 124 inlet_depth=0.263 125 outlet_depth=0.0 126 127 culvert_length=4.0 128 culvert_width=0.75 129 culvert_height=0.75 130 131 culvert_type='pipe' 132 manning=0.013 133 sum_loss=1.5 134 135 inlet_specific_energy=inlet_depth #+0.5*v**2/g 136 z_in = 0.0 137 z_out = -culvert_length*culvert_slope/100 138 E_in = z_in+inlet_depth #+ 0.5*v**2/g 139 E_out = z_out+outlet_depth #+ 0.5*v**2/g 140 delta_total_energy = E_in-E_out 141 142 Q, v, d = boyd_generalised_culvert_model(inlet_depth, 143 outlet_depth, 144 inlet_specific_energy, 145 delta_total_energy, 146 g, 147 culvert_length, 148 culvert_width, 149 culvert_height, 150 culvert_type, 151 manning, 152 sum_loss) 153 154 print Q, v, d 155 assert num.allclose(Q, 0.10, rtol=1.0e-2) #inflow 156 assert num.allclose(v, 1.13, rtol=1.0e-2) #outflow velocity 157 assert num.allclose(d, 0.15, rtol=1.0e-2) #depth at outlet used to calc v 158 159 def Xtest_boyd_2(self): 160 """test_boyd_2 161 162 This tests the Boyd routine with data obtained from ??? by Petar Milevski 163 """ 164 # FIXME(Ole): This test fails (20 Feb 2009) 165 166 g=9.81 167 culvert_slope=0.01 # Downward 168 169 inlet_depth=1.135 170 outlet_depth=0.0 171 172 culvert_length=4.0 173 culvert_width=0.75 174 culvert_height=0.75 175 176 culvert_type='pipe' 177 manning=0.013 178 sum_loss=1.5 179 180 inlet_specific_energy=inlet_depth #+0.5*v**2/g 181 z_in = 0.0 182 z_out = -culvert_length*culvert_slope/100 183 E_in = z_in+inlet_depth #+ 0.5*v**2/g 184 E_out = z_out+outlet_depth #+ 0.5*v**2/g 185 delta_total_energy = E_in-E_out 186 187 Q, v, d = boyd_generalised_culvert_model(inlet_depth, 188 outlet_depth, 189 inlet_specific_energy, 190 delta_total_energy, 191 g, 192 culvert_length, 193 culvert_width, 194 culvert_height, 195 culvert_type, 196 manning, 197 sum_loss) 198 199 print Q, v, d 200 assert num.allclose(Q, 1.00, rtol=1.0e-2) #inflow 201 assert num.allclose(v, 2.59, rtol=1.0e-2) #outflow velocity 202 assert num.allclose(d, 0.563, rtol=1.0e-2) #depth at outlet used to calc v 203 204 def Xtest_boyd_3(self): 205 """test_boyd_3 206 207 This tests the Boyd routine with data obtained from ??? by Petar Milevski 208 """ 209 # FIXME(Ole): This test fails (20 Feb 2009) 210 211 g=9.81 212 culvert_slope=0.01 # Downward 213 214 inlet_depth=12.747 215 outlet_depth=0.0 216 217 culvert_length=4.0 218 culvert_width=0.75 219 culvert_height=0.75 220 221 culvert_type='pipe' 222 manning=0.013 223 sum_loss=1.5 224 225 inlet_specific_energy=inlet_depth #+0.5*v**2/g 226 z_in = 0.0 227 z_out = -culvert_length*culvert_slope/100 228 E_in = z_in+inlet_depth #+ 0.5*v**2/g 229 E_out = z_out+outlet_depth #+ 0.5*v**2/g 230 delta_total_energy = E_in-E_out 231 232 Q, v, d = boyd_generalised_culvert_model(inlet_depth, 233 outlet_depth, 234 inlet_specific_energy, 235 delta_total_energy, 236 g, 237 culvert_length, 238 culvert_width, 239 culvert_height, 240 culvert_type, 241 manning, 242 sum_loss) 243 244 print Q, v, d 245 assert num.allclose(Q, 5.00, rtol=1.0e-2) #inflow 246 assert num.allclose(v, 11.022, rtol=1.0e-2) #outflow velocity 247 assert num.allclose(d, 0.72, rtol=1.0e-2) #depth at outlet used to calc v 248 249 def Xtest_boyd_4(self): 250 """test_boyd_4 251 252 This tests the Boyd routine with data obtained from ??? by Petar Milevski 253 """ 254 # FIXME(Ole): This test fails (20 Feb 2009) 255 256 g=9.81 257 culvert_slope=0.01 # Downward 258 259 inlet_depth=1.004 260 outlet_depth=1.00 261 262 culvert_length=4.0 263 culvert_width=0.75 264 culvert_height=0.75 265 266 culvert_type='pipe' 267 manning=0.013 268 sum_loss=1.5 269 270 inlet_specific_energy=inlet_depth #+0.5*v**2/g 271 z_in = 0.0 272 z_out = -culvert_length*culvert_slope/100 273 E_in = z_in+inlet_depth #+ 0.5*v**2/g 274 E_out = z_out+outlet_depth #+ 0.5*v**2/g 275 delta_total_energy = E_in-E_out 276 277 Q, v, d = boyd_generalised_culvert_model(inlet_depth, 278 outlet_depth, 279 inlet_specific_energy, 280 delta_total_energy, 281 g, 282 culvert_length, 283 culvert_width, 284 culvert_height, 285 culvert_type, 286 manning, 287 sum_loss) 288 289 print Q, v, d 290 assert num.allclose(Q, 0.10, rtol=1.0e-2) #inflow 291 assert num.allclose(v, 0.22, rtol=1.0e-2) #outflow velocity 292 assert num.allclose(d, 0.76, rtol=1.0e-2) #depth at outlet used to calc v 293 294 def Xtest_boyd_5(self): 295 """test_boyd_5 296 297 This tests the Boyd routine with data obtained from ??? by Petar Milevski 298 """ 299 # FIXME(Ole): This test fails (20 Feb 2009) 300 301 g=9.81 302 culvert_slope=0.01 # Downward 303 304 inlet_depth=1.401 305 outlet_depth=1.00 306 307 culvert_length=4.0 308 culvert_width=0.75 309 culvert_height=0.75 310 311 culvert_type='pipe' 312 manning=0.013 313 sum_loss=1.5 314 315 inlet_specific_energy=inlet_depth #+0.5*v**2/g 316 z_in = 0.0 317 z_out = -culvert_length*culvert_slope/100 318 E_in = z_in+inlet_depth #+ 0.5*v**2/g 319 E_out = z_out+outlet_depth #+ 0.5*v**2/g 320 delta_total_energy = E_in-E_out 321 322 Q, v, d = boyd_generalised_culvert_model(inlet_depth, 323 outlet_depth, 324 inlet_specific_energy, 325 delta_total_energy, 326 g, 327 culvert_length, 328 culvert_width, 329 culvert_height, 330 culvert_type, 331 manning, 332 sum_loss) 333 334 print Q, v, d 335 assert num.allclose(Q, 1.00, rtol=1.0e-2) #inflow 336 assert num.allclose(v, 2.204, rtol=1.0e-2) #outflow velocity 337 assert num.allclose(d, 0.76, rtol=1.0e-2) #depth at outlet used to calc v 338 339 340 def Xtest_boyd_6(self): 341 """test_boyd_5 342 343 This tests the Boyd routine with data obtained from ??? by Petar Milevski 344 """ 345 # FIXME(Ole): This test fails (20 Feb 2009) 346 347 g=9.81 348 culvert_slope=0.01 # Downward 349 350 inlet_depth=12.747 351 outlet_depth=1.00 352 353 culvert_length=4.0 354 culvert_width=0.75 355 culvert_height=0.75 356 357 culvert_type='pipe' 358 manning=0.013 359 sum_loss=1.5 360 361 inlet_specific_energy=inlet_depth #+0.5*v**2/g 362 z_in = 0.0 363 z_out = -culvert_length*culvert_slope/100 364 E_in = z_in+inlet_depth #+ 0.5*v**2/g 365 E_out = z_out+outlet_depth #+ 0.5*v**2/g 366 delta_total_energy = E_in-E_out 367 368 Q, v, d = boyd_generalised_culvert_model(inlet_depth, 369 outlet_depth, 370 inlet_specific_energy, 371 delta_total_energy, 372 g, 373 culvert_length, 374 culvert_width, 375 culvert_height, 376 culvert_type, 377 manning, 378 sum_loss) 379 380 print Q, v, d 381 assert num.allclose(Q, 5.00, rtol=1.0e-2) #inflow 382 assert num.allclose(v, 11.022, rtol=1.0e-2) #outflow velocity 383 assert num.allclose(d, 0.76, rtol=1.0e-2) #depth at outlet used to calc v 384 385 386 def Xtest_boyd_7(self): 387 """test_boyd_7 388 389 This tests the Boyd routine with data obtained from ??? by Petar Milevski 390 """ 391 # FIXME(Ole): This test fails (20 Feb 2009) 392 393 g=9.81 394 culvert_slope=0.1 # Downward 395 396 inlet_depth=0.303 397 outlet_depth=0.00 398 399 culvert_length=4.0 400 culvert_width=0.75 401 culvert_height=0.75 402 403 culvert_type='pipe' 404 manning=0.013 405 sum_loss=1.5 406 407 inlet_specific_energy=inlet_depth #+0.5*v**2/g 408 z_in = 0.0 409 z_out = -culvert_length*culvert_slope/100 410 E_in = z_in+inlet_depth #+ 0.5*v**2/g 411 E_out = z_out+outlet_depth #+ 0.5*v**2/g 412 delta_total_energy = E_in-E_out 413 414 Q, v, d = boyd_generalised_culvert_model(inlet_depth, 415 outlet_depth, 416 inlet_specific_energy, 417 delta_total_energy, 418 g, 419 culvert_length, 420 culvert_width, 421 culvert_height, 422 culvert_type, 423 manning, 424 sum_loss) 425 426 print Q, v, d 427 assert num.allclose(Q, 0.10, rtol=1.0e-2) #inflow 428 assert num.allclose(v, 1.13, rtol=1.0e-2) #outflow velocity 429 assert num.allclose(d, 0.19, rtol=1.0e-2) #depth at outlet used to calc v 430 431 432 def Xtest_boyd_8(self): 433 """test_boyd_8 434 435 This tests the Boyd routine with data obtained from ??? by Petar Milevski 436 """ 437 # FIXME(Ole): This test fails (20 Feb 2009) 438 439 g=9.81 440 culvert_slope=0.1 # Downward 441 442 inlet_depth=1.135 443 outlet_depth=0.00 444 445 culvert_length=4.0 446 culvert_width=0.75 447 culvert_height=0.75 448 449 culvert_type='pipe' 450 manning=0.013 451 sum_loss=1.5 452 453 inlet_specific_energy=inlet_depth #+0.5*v**2/g 454 z_in = 0.0 455 z_out = -culvert_length*culvert_slope/100 456 E_in = z_in+inlet_depth #+ 0.5*v**2/g 457 E_out = z_out+outlet_depth #+ 0.5*v**2/g 458 delta_total_energy = E_in-E_out 459 460 Q, v, d = boyd_generalised_culvert_model(inlet_depth, 461 outlet_depth, 462 inlet_specific_energy, 463 delta_total_energy, 464 g, 465 culvert_length, 466 culvert_width, 467 culvert_height, 468 culvert_type, 469 manning, 470 sum_loss) 471 472 print Q, v, d 473 assert num.allclose(Q, 1.00, rtol=1.0e-2) #inflow 474 assert num.allclose(v, 2.204, rtol=1.0e-2) #outflow velocity 475 assert num.allclose(d, 0.76, rtol=1.0e-2) #depth at outlet used to calc v 476 477 def Xtest_boyd_9(self): 478 """test_boyd_9 479 480 This tests the Boyd routine with data obtained from ??? by Petar Milevski 481 """ 482 # FIXME(Ole): This test fails (20 Feb 2009) 483 484 g=9.81 485 culvert_slope=0.1 # Downward 486 487 inlet_depth=1.1504 488 outlet_depth=1.5 489 490 culvert_length=4.0 491 culvert_width=0.75 492 culvert_height=0.75 493 494 culvert_type='pipe' 495 manning=0.013 496 sum_loss=1.5 497 498 inlet_specific_energy=inlet_depth #+0.5*v**2/g 499 z_in = 0.0 500 z_out = -culvert_length*culvert_slope/100 501 E_in = z_in+inlet_depth #+ 0.5*v**2/g 502 E_out = z_out+outlet_depth #+ 0.5*v**2/g 503 delta_total_energy = E_in-E_out 504 505 Q, v, d = boyd_generalised_culvert_model(inlet_depth, 506 outlet_depth, 507 inlet_specific_energy, 508 delta_total_energy, 509 g, 510 culvert_length, 511 culvert_width, 512 culvert_height, 513 culvert_type, 514 manning, 515 sum_loss) 516 517 print Q, v, d 518 assert num.allclose(Q, 0.10, rtol=1.0e-2) #inflow 519 assert num.allclose(v, 0.22, rtol=1.0e-2) #outflow velocity 520 assert num.allclose(d, 0.76, rtol=1.0e-2) #depth at outlet used to calc v 521 522 523 def Xtest_boyd_10(self): 524 """test_boyd_9 525 526 This tests the Boyd routine with data obtained from ??? by Petar Milevski 527 """ 528 # FIXME(Ole): This test fails (20 Feb 2009) 529 530 g=9.81 531 culvert_slope=0.1 # Downward 532 533 inlet_depth=1.901 534 outlet_depth=1.5 535 536 culvert_length=4.0 537 culvert_width=0.75 538 culvert_height=0.75 539 540 culvert_type='pipe' 541 manning=0.013 542 sum_loss=1.5 543 544 inlet_specific_energy=inlet_depth #+0.5*v**2/g 545 z_in = 0.0 546 z_out = -culvert_length*culvert_slope/100 547 E_in = z_in+inlet_depth #+ 0.5*v**2/g 548 E_out = z_out+outlet_depth #+ 0.5*v**2/g 549 delta_total_energy = E_in-E_out 550 551 Q, v, d = boyd_generalised_culvert_model(inlet_depth, 552 outlet_depth, 553 inlet_specific_energy, 554 delta_total_energy, 555 g, 556 culvert_length, 557 culvert_width, 558 culvert_height, 559 culvert_type, 560 manning, 561 sum_loss) 562 563 print Q, v, d 564 assert num.allclose(Q, 1.00, rtol=1.0e-2) #inflow 565 assert num.allclose(v, 2.204, rtol=1.0e-2) #outflow velocity 566 assert num.allclose(d, 0.76, rtol=1.0e-2) #depth at outlet used to calc v 114 567 115 568 -
branches/numpy/anuga/geospatial_data/geospatial_data.py
r6768 r6902 862 862 self.file_pointer) = _read_csv_file_blocking(self.file_pointer, 863 863 self.header[:], 864 max_read_lines= \864 max_read_lines= 865 865 self.max_read_lines, 866 verbose= \866 verbose= 867 867 self.verbose) 868 868 -
branches/numpy/anuga/load_mesh/loadASCII.py
r6553 r6902 817 817 mesh['vertex_attributes'] = None 818 818 819 mesh['vertex_attribute_titles'] = []819 # mesh['vertex_attribute_titles'] = [] 820 820 try: 821 821 titles = fid.variables['vertex_attribute_titles'][:] … … 829 829 mesh['segments'] = num.array([], num.int) #array default# 830 830 831 mesh['segment_tags'] = []831 # mesh['segment_tags'] = [] 832 832 try: 833 833 tags = fid.variables['segment_tags'][:] … … 844 844 mesh['triangle_neighbors'] = num.array([], num.int) #array default# 845 845 846 mesh['triangle_tags'] = []846 # mesh['triangle_tags'] = [] 847 847 try: 848 848 tags = fid.variables['triangle_tags'][:] -
branches/numpy/anuga/load_mesh/test_loadASCII.py
r6553 r6902 410 410 self.failUnless(num.alltrue(loaded_dict['vertex_attributes'] == 411 411 dict['vertex_attributes']) or 412 (loaded_dict['vertex_attributes'] == None and 413 dict['vertex_attributes'] == []), 412 (loaded_dict['vertex_attributes'] == 413 None and 414 dict['vertex_attributes'] == []), 414 415 fail_string + ' failed!! Test vertex_attributes') 415 416 … … 423 424 self.failUnless(seg == ldseg, fail_string + ' failed\n' + msg) 424 425 425 dict_array = num.array(dict['vertex_attribute_titles'])426 loaded_dict_array = num.array(loaded_dict['vertex_attribute_titles'])426 # dict_array = num.array(dict['vertex_attribute_titles']) 427 # loaded_dict_array = num.array(loaded_dict['vertex_attribute_titles']) 427 428 try: 428 429 assert num.allclose(dict_array, loaded_dict_array) -
branches/numpy/anuga/shallow_water/data_manager.py
r6689 r6902 3575 3575 other_quantities.remove('z') 3576 3576 other_quantities.remove('volumes') 3577 #try:3578 #other_quantities.remove('stage_range')3579 #other_quantities.remove('xmomentum_range')3580 #other_quantities.remove('ymomentum_range')3581 #other_quantities.remove('elevation_range')3582 #except:3583 #pass3577 try: 3578 other_quantities.remove('stage_range') 3579 other_quantities.remove('xmomentum_range') 3580 other_quantities.remove('ymomentum_range') 3581 other_quantities.remove('elevation_range') 3582 except: 3583 pass 3584 3584 3585 3585 conserved_quantities.remove('time') … … 5338 5338 j += 1 5339 5339 5340 #if verbose: sww.verbose_quantities(outfile)5340 if verbose: sww.verbose_quantities(outfile) 5341 5341 5342 5342 outfile.close() … … 5855 5855 # @param smoothing True if smoothing is to be used. 5856 5856 # @param order 5857 # @param sww_precision Data type of the quantit iy written (netcdf constant)5857 # @param sww_precision Data type of the quantity written (netcdf constant) 5858 5858 # @param verbose True if this function is to be verbose. 5859 5859 # @note If 'times' is a list, the info will be made relative. … … 5936 5936 ('number_of_points',)) 5937 5937 q = 'elevation' 5938 #outfile.createVariable(q + Write_sww.RANGE, sww_precision, 5939 # ('numbers_in_range',)) 5940 5941 5942 ## Initialise ranges with small and large sentinels. 5943 ## If this was in pure Python we could have used None sensibly 5944 #outfile.variables[q+Write_sww.RANGE][0] = max_float # Min 5945 #outfile.variables[q+Write_sww.RANGE][1] = -max_float # Max 5938 outfile.createVariable(q + Write_sww.RANGE, sww_precision, 5939 ('numbers_in_range',)) 5940 5941 # Initialise ranges with small and large sentinels. 5942 # If this was in pure Python we could have used None sensibly 5943 outfile.variables[q+Write_sww.RANGE][0] = max_float # Min 5944 outfile.variables[q+Write_sww.RANGE][1] = -max_float # Max 5946 5945 5947 5946 # FIXME: Backwards compatibility … … 5958 5957 outfile.createVariable(q, sww_precision, ('number_of_timesteps', 5959 5958 'number_of_points')) 5960 #outfile.createVariable(q + Write_sww.RANGE, sww_precision,5961 #('numbers_in_range',))5959 outfile.createVariable(q + Write_sww.RANGE, sww_precision, 5960 ('numbers_in_range',)) 5962 5961 5963 5962 # Initialise ranges with small and large sentinels. 5964 5963 # If this was in pure Python we could have used None sensibly 5965 #outfile.variables[q+Write_sww.RANGE][0] = max_float # Min5966 #outfile.variables[q+Write_sww.RANGE][1] = -max_float # Max5964 outfile.variables[q+Write_sww.RANGE][0] = max_float # Min 5965 outfile.variables[q+Write_sww.RANGE][1] = -max_float # Max 5967 5966 5968 5967 if isinstance(times, (list, num.ndarray)): … … 6073 6072 q = 'elevation' 6074 6073 # This updates the _range values 6075 #outfile.variables[q + Write_sww.RANGE][0] =min(elevation)6076 #outfile.variables[q + Write_sww.RANGE][1] =max(elevation)6074 outfile.variables[q + Write_sww.RANGE][0] = num.min(elevation) 6075 outfile.variables[q + Write_sww.RANGE][1] = num.max(elevation) 6077 6076 6078 6077 … … 6126 6125 q_values.astype(sww_precision) 6127 6126 6128 ## This updates the _range values6129 #q_range = outfile.variables[q + Write_sww.RANGE][:]6130 # q_values_min =min(q_values)6131 #if q_values_min < q_range[0]:6132 #outfile.variables[q + Write_sww.RANGE][0] = q_values_min6133 # q_values_max =max(q_values)6134 #if q_values_max > q_range[1]:6135 #outfile.variables[q + Write_sww.RANGE][1] = q_values_max6127 # This updates the _range values 6128 q_range = outfile.variables[q + Write_sww.RANGE][:] 6129 q_values_min = num.min(q_values) 6130 if q_values_min < q_range[0]: 6131 outfile.variables[q + Write_sww.RANGE][0] = q_values_min 6132 q_values_max = num.max(q_values) 6133 if q_values_max > q_range[1]: 6134 outfile.variables[q + Write_sww.RANGE][1] = q_values_max 6136 6135 6137 6136 ## 6138 6137 # @brief Print the quantities in the underlying file. 6139 6138 # @param outfile UNUSED. 6140 #def verbose_quantities(self, outfile):6141 #print '------------------------------------------------'6142 #print 'More Statistics:'6143 #for q in Write_sww.sww_quantities:6144 #print ' %s in [%f, %f]' % (q,6145 #outfile.variables[q+Write_sww.RANGE][0],6146 #outfile.variables[q+Write_sww.RANGE][1])6147 #print '------------------------------------------------'6139 def verbose_quantities(self, outfile): 6140 print '------------------------------------------------' 6141 print 'More Statistics:' 6142 for q in Write_sww.sww_quantities: 6143 print ' %s in [%f, %f]' % (q, 6144 outfile.variables[q+Write_sww.RANGE][0], 6145 outfile.variables[q+Write_sww.RANGE][1]) 6146 print '------------------------------------------------' 6148 6147 6149 6148 … … 6496 6495 6497 6496 # This updates the _range values 6498 #q_range = outfile.variables[q + Write_sts.RANGE][:]6499 #q_values_min =min(q_values)6500 #if q_values_min < q_range[0]:6501 #outfile.variables[q + Write_sts.RANGE][0] = q_values_min6502 #q_values_max =max(q_values)6503 #if q_values_max > q_range[1]:6504 #outfile.variables[q + Write_sts.RANGE][1] = q_values_max6497 q_range = outfile.variables[q + Write_sts.RANGE][:] 6498 q_values_min = num.min(q_values) 6499 if q_values_min < q_range[0]: 6500 outfile.variables[q + Write_sts.RANGE][0] = q_values_min 6501 q_values_max = num.max(q_values) 6502 if q_values_max > q_range[1]: 6503 outfile.variables[q + Write_sts.RANGE][1] = q_values_max 6505 6504 6506 6505 … … 6673 6672 6674 6673 6675 # FIXME (DSG): Add unit test, make general, not just 2 files,6676 # but any number of files.6677 6674 ## 6678 6675 # @brief Copy a file to a directory, and optionally append another file to it. … … 6680 6677 # @param filename Path to file to copy to directory 'dir_name'. 6681 6678 # @param filename2 Optional path to file to append to copied file. 6682 def copy_code_files(dir_name, filename1, filename2=None): 6679 # @param verbose True if this function is to be verbose. 6680 # @note Allow filenames to be either a string or sequence of strings. 6681 def copy_code_files(dir_name, filename1, filename2=None, verbose=False): 6683 6682 """Copies "filename1" and "filename2" to "dir_name". 6684 Very useful for information management 6685 filename1 and filename2 are both absolute pathnames 6686 """ 6687 6683 6684 Each 'filename' may be a string or list of filename strings. 6685 6686 Filenames must be absolute pathnames 6687 """ 6688 6689 ## 6690 # @brief copies a file or sequence to destination directory. 6691 # @param dest The destination directory to copy to. 6692 # @param file A filename string or sequence of filename strings. 6693 def copy_file_or_sequence(dest, file): 6694 if hasattr(file, '__iter__'): 6695 for f in file: 6696 shutil.copy(f, dir_name) 6697 if verbose: 6698 print 'File %s copied' % (f) 6699 else: 6700 shutil.copy(file, dir_name) 6701 if verbose: 6702 print 'File %s copied' % (file) 6703 6704 # check we have a destination directory, create if necessary 6688 6705 if access(dir_name, F_OK) == 0: 6689 print 'Make directory %s' % dir_name 6690 mkdir (dir_name,0777) 6691 6692 shutil.copy(filename1, dir_name + sep + basename(filename1)) 6693 6694 if filename2 != None: 6695 shutil.copy(filename2, dir_name + sep + basename(filename2)) 6696 print 'Files %s and %s copied' %(filename1, filename2) 6697 else: 6698 print 'File %s copied' %(filename1) 6706 if verbose: 6707 print 'Make directory %s' % dir_name 6708 mkdir(dir_name, 0777) 6709 6710 copy_file_or_sequence(dir_name, filename1) 6711 6712 if not filename2 is None: 6713 copy_file_or_sequence(dir_name, filename2) 6699 6714 6700 6715 -
branches/numpy/anuga/shallow_water/shallow_water_ext.c
r6780 r6902 28 28 29 29 // Computational function for rotation 30 // FIXME: Perhaps inline this and profile 30 31 int _rotate(double *q, double n1, double n2) { 31 32 /*Rotate the momentum component q (q[1], q[2]) … … 52 53 53 54 int find_qmin_and_qmax(double dq0, double dq1, double dq2, 54 55 double *qmin, double *qmax){ 55 56 // Considering the centroid of an FV triangle and the vertices of its 56 57 // auxiliary triangle, find … … 67 68 if (dq1>=dq2){ 68 69 if (dq1>=0.0) 69 70 *qmax=dq0+dq1; 70 71 else 71 72 72 *qmax=dq0; 73 73 74 *qmin=dq0+dq2; 74 75 if (*qmin>=0.0) *qmin = 0.0; … … 76 77 else{// dq1<dq2 77 78 if (dq2>0) 78 79 *qmax=dq0+dq2; 79 80 else 80 81 82 *qmin=dq0+dq1; 81 *qmax=dq0; 82 83 *qmin=dq0+dq1; 83 84 if (*qmin>=0.0) *qmin=0.0; 84 85 } … … 87 88 if (dq1<=dq2){ 88 89 if (dq1<0.0) 89 90 *qmin=dq0+dq1; 90 91 else 91 92 93 *qmax=dq0+dq2; 92 *qmin=dq0; 93 94 *qmax=dq0+dq2; 94 95 if (*qmax<=0.0) *qmax=0.0; 95 96 } 96 97 else{// dq1>dq2 97 98 if (dq2<0.0) 98 99 *qmin=dq0+dq2; 99 100 else 100 101 101 *qmin=dq0; 102 102 103 *qmax=dq0+dq1; 103 104 if (*qmax<=0.0) *qmax=0.0; … … 133 134 134 135 phi=min(r*beta_w,1.0); 135 for (i=0;i<3;i++) 136 dqv[i]=dqv[i]*phi; 136 //for (i=0;i<3;i++) 137 dqv[0]=dqv[0]*phi; 138 dqv[1]=dqv[1]*phi; 139 dqv[2]=dqv[2]*phi; 137 140 138 141 return 0; … … 141 144 142 145 double compute_froude_number(double uh, 143 144 145 146 146 double h, 147 double g, 148 double epsilon) { 149 147 150 // Compute Froude number; v/sqrt(gh) 148 151 // FIXME (Ole): Not currently in use … … 166 169 // This is used by flux functions 167 170 // Input parameters uh and h may be modified by this function. 171 172 // FIXME: Perhaps inline this and profile 168 173 double _compute_speed(double *uh, 169 170 171 174 double *h, 175 double epsilon, 176 double h0) { 172 177 173 178 double u; … … 188 193 } 189 194 195 196 // Optimised squareroot computation 197 // 198 //See 199 //http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf 200 //and http://mail.opensolaris.org/pipermail/tools-gcc/2005-August/000047.html 201 float fast_squareroot_approximation(float number) { 202 float x; 203 const float f = 1.5; 204 205 // Allow i and y to occupy the same memory 206 union 207 { 208 long i; 209 float y; 210 } u; 211 212 // Good initial guess 213 x = number * 0.5; 214 u.y = number; 215 u.i = 0x5f3759df - ( u.i >> 1 ); 216 217 // Take a few iterations 218 u.y = u.y * ( f - ( x * u.y * u.y ) ); 219 u.y = u.y * ( f - ( x * u.y * u.y ) ); 220 221 return number * u.y; 222 } 223 224 225 226 // Optimised squareroot computation (double version, slower) 227 double Xfast_squareroot_approximation(double number) { 228 double x; 229 const double f = 1.5; 230 231 // Allow i and y to occupy the same memory 232 union 233 { 234 long long i; 235 double y; 236 } u; 237 238 // Good initial guess 239 x = number * 0.5; 240 u.y = number; 241 u.i = 0x5fe6ec85e7de30daLL - ( u.i >> 1 ); 242 243 // Take a few iterations 244 u.y = u.y * ( f - ( x * u.y * u.y ) ); 245 u.y = u.y * ( f - ( x * u.y * u.y ) ); 246 247 return number * u.y; 248 } 249 250 190 251 // Innermost flux function (using stage w=z+h) 191 252 int _flux_function_central(double *q_left, double *q_right, 192 double z_left, double z_right, 193 double n1, double n2, 194 double epsilon, double H0, double g, 195 double *edgeflux, double *max_speed) { 253 double z_left, double z_right, 254 double n1, double n2, 255 double epsilon, double H0, double g, 256 double *edgeflux, double *max_speed) 257 { 196 258 197 259 /*Compute fluxes between volumes for the shallow water wave equation … … 212 274 double v_left, v_right; 213 275 double s_min, s_max, soundspeed_left, soundspeed_right; 214 double denom, z;276 double denom, inverse_denominator, z; 215 277 216 278 // Workspace (allocate once, use many) … … 219 281 double h0 = H0*H0; // This ensures a good balance when h approaches H0. 220 282 // But evidence suggests that h0 can be as little as 221 283 // epsilon! 222 284 223 285 // Copy conserved quantities to protect from modification 224 for (i=0; i<3; i++) { 225 q_left_rotated[i] = q_left[i]; 226 q_right_rotated[i] = q_right[i]; 227 } 286 q_left_rotated[0] = q_left[0]; 287 q_right_rotated[0] = q_right[0]; 288 q_left_rotated[1] = q_left[1]; 289 q_right_rotated[1] = q_right[1]; 290 q_left_rotated[2] = q_left[2]; 291 q_right_rotated[2] = q_right[2]; 228 292 229 293 // Align x- and y-momentum with x-axis … … 231 295 _rotate(q_right_rotated, n1, n2); 232 296 233 z = (z_left+z_right)/2; // Average elevation values.234 // Even though this will nominally allow for discontinuities235 236 297 z = 0.5*(z_left + z_right); // Average elevation values. 298 // Even though this will nominally allow for discontinuities 299 // in the elevation data, there is currently no numerical 300 // support for this so results may be strange near jumps in the bed. 237 301 238 302 // Compute speeds in x-direction 239 303 w_left = q_left_rotated[0]; 240 h_left = w_left -z;304 h_left = w_left - z; 241 305 uh_left = q_left_rotated[1]; 242 306 u_left = _compute_speed(&uh_left, &h_left, epsilon, h0); 243 307 244 308 w_right = q_right_rotated[0]; 245 h_right = w_right -z;309 h_right = w_right - z; 246 310 uh_right = q_right_rotated[1]; 247 311 u_right = _compute_speed(&uh_right, &h_right, epsilon, h0); … … 257 321 // Maximal and minimal wave speeds 258 322 soundspeed_left = sqrt(g*h_left); 259 soundspeed_right = sqrt(g*h_right); 260 261 s_max = max(u_left+soundspeed_left, u_right+soundspeed_right); 262 if (s_max < 0.0) s_max = 0.0; 263 264 s_min = min(u_left-soundspeed_left, u_right-soundspeed_right); 265 if (s_min > 0.0) s_min = 0.0; 266 323 soundspeed_right = sqrt(g*h_right); 324 325 // Code to use fast square root optimisation if desired. 326 //soundspeed_left = fast_squareroot_approximation(g*h_left); 327 //soundspeed_right = fast_squareroot_approximation(g*h_right); 328 329 s_max = max(u_left + soundspeed_left, u_right + soundspeed_right); 330 if (s_max < 0.0) 331 { 332 s_max = 0.0; 333 } 334 335 s_min = min(u_left - soundspeed_left, u_right - soundspeed_right); 336 if (s_min > 0.0) 337 { 338 s_min = 0.0; 339 } 267 340 268 341 // Flux formulas … … 275 348 flux_right[2] = u_right*vh_right; 276 349 277 278 350 // Flux computation 279 denom = s_max-s_min; 280 if (denom < epsilon) { // FIXME (Ole): Try using H0 here 281 for (i=0; i<3; i++) edgeflux[i] = 0.0; 351 denom = s_max - s_min; 352 if (denom < epsilon) 353 { // FIXME (Ole): Try using H0 here 354 memset(edgeflux, 0, 3*sizeof(double)); 282 355 *max_speed = 0.0; 283 } else { 284 for (i=0; i<3; i++) { 356 } 357 else 358 { 359 inverse_denominator = 1.0/denom; 360 for (i = 0; i < 3; i++) 361 { 285 362 edgeflux[i] = s_max*flux_left[i] - s_min*flux_right[i]; 286 edgeflux[i] += s_max*s_min*(q_right_rotated[i] -q_left_rotated[i]);287 edgeflux[i] /= denom;363 edgeflux[i] += s_max*s_min*(q_right_rotated[i] - q_left_rotated[i]); 364 edgeflux[i] *= inverse_denominator; 288 365 } 289 366 … … 315 392 // Computational function for flux computation (using stage w=z+h) 316 393 int flux_function_kinetic(double *q_left, double *q_right, 317 318 319 320 394 double z_left, double z_right, 395 double n1, double n2, 396 double epsilon, double H0, double g, 397 double *edgeflux, double *max_speed) { 321 398 322 399 /*Compute fluxes between volumes for the shallow water wave equation … … 413 490 414 491 void _manning_friction(double g, double eps, int N, 415 416 417 492 double* w, double* z, 493 double* uh, double* vh, 494 double* eta, double* xmom, double* ymom) { 418 495 419 496 int k; … … 426 503 S = -g * eta[k]*eta[k] * sqrt((uh[k]*uh[k] + vh[k]*vh[k])); 427 504 S /= pow(h, 7.0/3); //Expensive (on Ole's home computer) 428 //S /= exp( 7.0/3.0*log(h)); //seems to save about 15% over manning_friction505 //S /= exp((7.0/3.0)*log(h)); //seems to save about 15% over manning_friction 429 506 //S /= h*h*(1 + h/3.0 - h*h/9.0); //FIXME: Could use a Taylor expansion 430 507 … … 441 518 /* 442 519 void _manning_friction_explicit(double g, double eps, int N, 443 444 445 520 double* w, double* z, 521 double* uh, double* vh, 522 double* eta, double* xmom, double* ymom) { 446 523 447 524 int k; … … 452 529 h = w[k]-z[k]; 453 530 if (h >= eps) { 454 455 456 457 458 459 460 461 462 531 S = -g * eta[k]*eta[k] * sqrt((uh[k]*uh[k] + vh[k]*vh[k])); 532 S /= pow(h, 7.0/3); //Expensive (on Ole's home computer) 533 //S /= exp(7.0/3.0*log(h)); //seems to save about 15% over manning_friction 534 //S /= h*h*(1 + h/3.0 - h*h/9.0); //FIXME: Could use a Taylor expansion 535 536 537 //Update momentum 538 xmom[k] += S*uh[k]; 539 ymom[k] += S*vh[k]; 463 540 } 464 541 } … … 471 548 472 549 double velocity_balance(double uh_i, 473 474 475 476 477 550 double uh, 551 double h_i, 552 double h, 553 double alpha, 554 double epsilon) { 478 555 // Find alpha such that speed at the vertex is within one 479 // order of magnitude of the centroid speed 556 // order of magnitude of the centroid speed 480 557 481 558 // FIXME(Ole): Work in progress … … 486 563 487 564 printf("alpha = %f, uh_i=%f, uh=%f, h_i=%f, h=%f\n", 488 565 alpha, uh_i, uh, h_i, h); 489 566 490 567 … … 500 577 if (h < epsilon) { 501 578 b = 1.0e10; // Limit 502 } else { 579 } else { 503 580 b = m*fabs(h_i - h)/h; 504 581 } … … 507 584 508 585 if (a > b) { 509 estimate = (m-1)/(a-b); 586 estimate = (m-1)/(a-b); 510 587 511 588 printf("Alpha %f, estimate %f\n", 512 513 589 alpha, estimate); 590 514 591 if (alpha < estimate) { 515 592 printf("Adjusting alpha from %f to %f\n", 516 593 alpha, estimate); 517 594 alpha = estimate; 518 595 } … … 520 597 521 598 if (h < h_i) { 522 estimate = (m-1)/(a-b); 599 estimate = (m-1)/(a-b); 523 600 524 601 printf("Alpha %f, estimate %f\n", 525 526 602 alpha, estimate); 603 527 604 if (alpha < estimate) { 528 529 530 605 printf("Adjusting alpha from %f to %f\n", 606 alpha, estimate); 607 alpha = estimate; 531 608 } 532 609 } … … 540 617 541 618 int _balance_deep_and_shallow(int N, 542 543 544 545 546 547 548 549 550 551 552 553 554 619 double* wc, 620 double* zc, 621 double* wv, 622 double* zv, 623 double* hvbar, // Retire this 624 double* xmomc, 625 double* ymomc, 626 double* xmomv, 627 double* ymomv, 628 double H0, 629 int tight_slope_limiters, 630 int use_centroid_velocities, 631 double alpha_balance) { 555 632 556 633 int k, k3, i; … … 579 656 // FIXME: Try with this one precomputed 580 657 for (i=0; i<3; i++) { 581 658 dz = max(dz, fabs(zv[k3+i]-zc[k])); 582 659 } 583 660 } … … 592 669 593 670 //if (hmin < 0.0 ) { 594 // 671 // printf("hmin = %f\n",hmin); 595 672 //} 596 673 … … 607 684 608 685 if (dz > 0.0) { 609 686 alpha = max( min( alpha_balance*hmin/dz, 1.0), 0.0 ); 610 687 } else { 611 688 alpha = 1.0; // Flat bed 612 689 } 613 690 //printf("Using old style limiter\n"); … … 622 699 623 700 if (hmin < H0) { 624 625 626 627 h_diff = hc_k - hv[i];628 629 630 631 632 633 634 635 636 alpha = min(alpha, (hc_k - H0)/h_diff);637 638 639 640 641 642 643 701 alpha = 1.0; 702 for (i=0; i<3; i++) { 703 704 h_diff = hc_k - hv[i]; 705 if (h_diff <= 0) { 706 // Deep water triangle is further away from bed than 707 // shallow water (hbar < h). Any alpha will do 708 709 } else { 710 // Denominator is positive which means that we need some of the 711 // h-limited stage. 712 713 alpha = min(alpha, (hc_k - H0)/h_diff); 714 } 715 } 716 717 // Ensure alpha in [0,1] 718 if (alpha>1.0) alpha=1.0; 719 if (alpha<0.0) alpha=0.0; 720 644 721 } else { 645 646 722 // Use w-limited stage exclusively in deeper water. 723 alpha = 1.0; 647 724 } 648 725 } 649 726 650 727 651 // 728 // Let 652 729 // 653 // 654 // 730 // wvi be the w-limited stage (wvi = zvi + hvi) 731 // wvi- be the h-limited state (wvi- = zvi + hvi-) 655 732 // 656 733 // 657 // 734 // where i=0,1,2 denotes the vertex ids 658 735 // 659 736 // Weighted balance between w-limited and h-limited stage is 660 737 // 661 // 738 // wvi := (1-alpha)*(zvi+hvi-) + alpha*(zvi+hvi) 662 739 // 663 740 // It follows that the updated wvi is 664 741 // wvi := zvi + (1-alpha)*hvi- + alpha*hvi 665 742 // 666 // 743 // Momentum is balanced between constant and limited 667 744 668 745 … … 670 747 for (i=0; i<3; i++) { 671 748 672 wv[k3+i] = zv[k3+i] + (1-alpha)*hc_k + alpha*hv[i]; 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 749 wv[k3+i] = zv[k3+i] + (1-alpha)*hc_k + alpha*hv[i]; 750 751 // Update momentum at vertices 752 if (use_centroid_velocities == 1) { 753 // This is a simple, efficient and robust option 754 // It uses first order approximation of velocities, but retains 755 // the order used by stage. 756 757 // Speeds at centroids 758 if (hc_k > epsilon) { 759 uc = xmomc[k]/hc_k; 760 vc = ymomc[k]/hc_k; 761 } else { 762 uc = 0.0; 763 vc = 0.0; 764 } 765 766 // Vertex momenta guaranteed to be consistent with depth guaranteeing 767 // controlled speed 768 hv[i] = wv[k3+i] - zv[k3+i]; // Recompute (balanced) vertex depth 769 xmomv[k3+i] = uc*hv[i]; 770 ymomv[k3+i] = vc*hv[i]; 771 772 } else { 773 // Update momentum as a linear combination of 774 // xmomc and ymomc (shallow) and momentum 775 // from extrapolator xmomv and ymomv (deep). 776 // This assumes that values from xmomv and ymomv have 777 // been established e.g. by the gradient limiter. 778 779 // FIXME (Ole): I think this should be used with vertex momenta 780 // computed above using centroid_velocities instead of xmomc 781 // and ymomc as they'll be more representative first order 782 // values. 783 784 xmomv[k3+i] = (1-alpha)*xmomc[k] + alpha*xmomv[k3+i]; 785 ymomv[k3+i] = (1-alpha)*ymomc[k] + alpha*ymomv[k3+i]; 786 787 } 711 788 } 712 789 } … … 719 796 720 797 int _protect(int N, 721 722 723 724 725 726 727 798 double minimum_allowed_height, 799 double maximum_allowed_speed, 800 double epsilon, 801 double* wc, 802 double* zc, 803 double* xmomc, 804 double* ymomc) { 728 805 729 806 int k; … … 738 815 739 816 if (hc < minimum_allowed_height) { 740 741 742 743 744 817 818 // Set momentum to zero and ensure h is non negative 819 xmomc[k] = 0.0; 820 ymomc[k] = 0.0; 821 if (hc <= 0.0) wc[k] = zc[k]; 745 822 } 746 823 } … … 757 834 758 835 if (hc <= 0.0) { 759 760 761 836 wc[k] = zc[k]; 837 xmomc[k] = 0.0; 838 ymomc[k] = 0.0; 762 839 } else { 763 840 //Reduce excessive speeds derived from division by small hc 764 765 841 //FIXME (Ole): This may be unnecessary with new slope limiters 842 //in effect. 766 843 767 844 u = xmomc[k]/hc; 768 769 770 771 //u, reduced_speed);772 773 845 if (fabs(u) > maximum_allowed_speed) { 846 reduced_speed = maximum_allowed_speed * u/fabs(u); 847 //printf("Speed (u) has been reduced from %.3f to %.3f\n", 848 // u, reduced_speed); 849 xmomc[k] = reduced_speed * hc; 850 } 774 851 775 852 v = ymomc[k]/hc; 776 777 778 779 //v, reduced_speed);780 781 853 if (fabs(v) > maximum_allowed_speed) { 854 reduced_speed = maximum_allowed_speed * v/fabs(v); 855 //printf("Speed (v) has been reduced from %.3f to %.3f\n", 856 // v, reduced_speed); 857 ymomc[k] = reduced_speed * hc; 858 } 782 859 } 783 860 } … … 790 867 791 868 int _assign_wind_field_values(int N, 792 793 794 795 796 869 double* xmom_update, 870 double* ymom_update, 871 double* s_vec, 872 double* phi_vec, 873 double cw) { 797 874 798 875 // Assign windfield values to momentum updates … … 839 916 840 917 if (!PyArg_ParseTuple(args, "OOOddOddd", 841 842 918 &normal, &ql, &qr, &zl, &zr, &edgeflux, 919 &epsilon, &g, &H0)) { 843 920 PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: flux_function_central could not parse input arguments"); 844 921 return NULL; … … 847 924 848 925 _flux_function_central((double*) ql -> data, 849 850 851 zr,852 853 ((double*) normal -> data)[1],854 855 856 926 (double*) qr -> data, 927 zl, 928 zr, 929 ((double*) normal -> data)[0], 930 ((double*) normal -> data)[1], 931 epsilon, H0, g, 932 (double*) edgeflux -> data, 933 &max_speed); 857 934 858 935 return Py_BuildValue("d", max_speed); … … 874 951 875 952 if (!PyArg_ParseTuple(args, "dOOOOO", 876 877 953 &g, &h, &v, &x, 954 &xmom, &ymom)) { 878 955 //&epsilon)) { 879 956 PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: gravity could not parse input arguments"); … … 940 1017 941 1018 if (!PyArg_ParseTuple(args, "ddOOOOOOO", 942 943 1019 &g, &eps, &w, &z, &uh, &vh, &eta, 1020 &xmom, &ymom)) { 944 1021 PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: manning_friction could not parse input arguments"); 945 1022 return NULL; … … 957 1034 N = w -> dimensions[0]; 958 1035 _manning_friction(g, eps, N, 959 960 961 962 963 964 965 1036 (double*) w -> data, 1037 (double*) z -> data, 1038 (double*) uh -> data, 1039 (double*) vh -> data, 1040 (double*) eta -> data, 1041 (double*) xmom -> data, 1042 (double*) ymom -> data); 966 1043 967 1044 return Py_BuildValue(""); … … 981 1058 982 1059 if (!PyArg_ParseTuple(args, "ddOOOOOOO", 983 984 1060 &g, &eps, &w, &z, &uh, &vh, &eta, 1061 &xmom, &ymom)) 985 1062 return NULL; 986 1063 … … 996 1073 N = w -> dimensions[0]; 997 1074 _manning_friction_explicit(g, eps, N, 998 999 1000 1001 1002 1003 1004 1075 (double*) w -> data, 1076 (double*) z -> data, 1077 (double*) uh -> data, 1078 (double*) vh -> data, 1079 (double*) eta -> data, 1080 (double*) xmom -> data, 1081 (double*) ymom -> data); 1005 1082 1006 1083 return Py_BuildValue(""); … … 1012 1089 // Computational routine 1013 1090 int _extrapolate_second_order_sw(int number_of_elements, 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1091 double epsilon, 1092 double minimum_allowed_height, 1093 double beta_w, 1094 double beta_w_dry, 1095 double beta_uh, 1096 double beta_uh_dry, 1097 double beta_vh, 1098 double beta_vh_dry, 1099 long* surrogate_neighbours, 1100 long* number_of_boundaries, 1101 double* centroid_coordinates, 1102 double* stage_centroid_values, 1103 double* xmom_centroid_values, 1104 double* ymom_centroid_values, 1105 double* elevation_centroid_values, 1106 double* vertex_coordinates, 1107 double* stage_vertex_values, 1108 double* xmom_vertex_values, 1109 double* ymom_vertex_values, 1110 double* elevation_vertex_values, 1111 int optimise_dry_cells) { 1112 1113 1037 1114 1038 1115 // Local variables 1039 1116 double a, b; // Gradient vector used to calculate vertex values from centroids 1040 int k, k0,k1,k2,k3,k6,coord_index,i;1041 double x, y,x0,y0,x1,y1,x2,y2,xv0,yv0,xv1,yv1,xv2,yv2; // Vertices of the auxiliary triangle1042 double dx1, dx2,dy1,dy2,dxv0,dxv1,dxv2,dyv0,dyv1,dyv2,dq0,dq1,dq2,area2;1117 int k, k0, k1, k2, k3, k6, coord_index, i; 1118 double x, y, x0, y0, x1, y1, x2, y2, xv0, yv0, xv1, yv1, xv2, yv2; // Vertices of the auxiliary triangle 1119 double dx1, dx2, dy1, dy2, dxv0, dxv1, dxv2, dyv0, dyv1, dyv2, dq0, dq1, dq2, area2, inv_area2; 1043 1120 double dqv[3], qmin, qmax, hmin, hmax; 1044 1121 double hc, h0, h1, h2, beta_tmp, hfactor; 1045 1122 1046 1047 for (k=0; k<number_of_elements; k++) { 1123 1124 for (k = 0; k < number_of_elements; k++) 1125 { 1048 1126 k3=k*3; 1049 1127 k6=k*6; 1050 1128 1051 1052 if (number_of_boundaries[k]==3){1129 if (number_of_boundaries[k]==3) 1130 { 1053 1131 // No neighbours, set gradient on the triangle to zero 1054 1132 … … 1065 1143 continue; 1066 1144 } 1067 else { 1145 else 1146 { 1068 1147 // Triangle k has one or more neighbours. 1069 1148 // Get centroid and vertex coordinates of the triangle 1070 1149 1071 1150 // Get the vertex coordinates 1072 xv0 = vertex_coordinates[k6]; yv0=vertex_coordinates[k6+1]; 1073 xv1 = vertex_coordinates[k6+2]; yv1=vertex_coordinates[k6+3]; 1074 xv2 = vertex_coordinates[k6+4]; yv2=vertex_coordinates[k6+5]; 1151 xv0 = vertex_coordinates[k6]; 1152 yv0 = vertex_coordinates[k6+1]; 1153 xv1 = vertex_coordinates[k6+2]; 1154 yv1 = vertex_coordinates[k6+3]; 1155 xv2 = vertex_coordinates[k6+4]; 1156 yv2 = vertex_coordinates[k6+5]; 1075 1157 1076 1158 // Get the centroid coordinates 1077 coord_index =2*k;1078 x =centroid_coordinates[coord_index];1079 y =centroid_coordinates[coord_index+1];1159 coord_index = 2*k; 1160 x = centroid_coordinates[coord_index]; 1161 y = centroid_coordinates[coord_index+1]; 1080 1162 1081 1163 // Store x- and y- differentials for the vertices of 1082 1164 // triangle k relative to the centroid 1083 dxv0=xv0-x; dxv1=xv1-x; dxv2=xv2-x; 1084 dyv0=yv0-y; dyv1=yv1-y; dyv2=yv2-y; 1165 dxv0 = xv0 - x; 1166 dxv1 = xv1 - x; 1167 dxv2 = xv2 - x; 1168 dyv0 = yv0 - y; 1169 dyv1 = yv1 - y; 1170 dyv2 = yv2 - y; 1085 1171 } 1086 1172 1087 1173 1088 1174 1089 if (number_of_boundaries[k]<=1) {1090 1175 if (number_of_boundaries[k]<=1) 1176 { 1091 1177 //============================================== 1092 1178 // Number of boundaries <= 1 … … 1099 1185 // from this centroid and its two neighbours 1100 1186 1101 k0 =surrogate_neighbours[k3];1102 k1 =surrogate_neighbours[k3+1];1103 k2 =surrogate_neighbours[k3+2];1187 k0 = surrogate_neighbours[k3]; 1188 k1 = surrogate_neighbours[k3 + 1]; 1189 k2 = surrogate_neighbours[k3 + 2]; 1104 1190 1105 1191 // Get the auxiliary triangle's vertex coordinates 1106 1192 // (really the centroids of neighbouring triangles) 1107 coord_index =2*k0;1108 x0 =centroid_coordinates[coord_index];1109 y0 =centroid_coordinates[coord_index+1];1110 1111 coord_index =2*k1;1112 x1 =centroid_coordinates[coord_index];1113 y1 =centroid_coordinates[coord_index+1];1114 1115 coord_index =2*k2;1116 x2 =centroid_coordinates[coord_index];1117 y2 =centroid_coordinates[coord_index+1];1193 coord_index = 2*k0; 1194 x0 = centroid_coordinates[coord_index]; 1195 y0 = centroid_coordinates[coord_index+1]; 1196 1197 coord_index = 2*k1; 1198 x1 = centroid_coordinates[coord_index]; 1199 y1 = centroid_coordinates[coord_index+1]; 1200 1201 coord_index = 2*k2; 1202 x2 = centroid_coordinates[coord_index]; 1203 y2 = centroid_coordinates[coord_index+1]; 1118 1204 1119 1205 // Store x- and y- differentials for the vertices 1120 1206 // of the auxiliary triangle 1121 dx1=x1-x0; dx2=x2-x0; 1122 dy1=y1-y0; dy2=y2-y0; 1207 dx1 = x1 - x0; 1208 dx2 = x2 - x0; 1209 dy1 = y1 - y0; 1210 dy2 = y2 - y0; 1123 1211 1124 1212 // Calculate 2*area of the auxiliary triangle … … 1128 1216 // If the mesh is 'weird' near the boundary, 1129 1217 // the triangle might be flat or clockwise: 1130 if (area2<=0) { 1131 PyErr_SetString(PyExc_RuntimeError, 1132 "shallow_water_ext.c: negative triangle area encountered"); 1133 return -1; 1218 if (area2 <= 0) 1219 { 1220 PyErr_SetString(PyExc_RuntimeError, 1221 "shallow_water_ext.c: negative triangle area encountered"); 1222 1223 return -1; 1134 1224 } 1135 1225 … … 1139 1229 h1 = stage_centroid_values[k1] - elevation_centroid_values[k1]; 1140 1230 h2 = stage_centroid_values[k2] - elevation_centroid_values[k2]; 1141 hmin = min(min(h0, min(h1,h2)),hc);1231 hmin = min(min(h0, min(h1, h2)), hc); 1142 1232 //hfactor = hc/(hc + 1.0); 1143 1233 1144 1234 hfactor = 0.0; 1145 if (hmin > 0.001 ) { 1146 hfactor = (hmin-0.001)/(hmin+0.004); 1147 } 1148 1149 if (optimise_dry_cells) { 1150 // Check if linear reconstruction is necessary for triangle k 1151 // This check will exclude dry cells. 1152 1153 hmax = max(h0,max(h1,h2)); 1154 if (hmax < epsilon) { 1155 continue; 1156 } 1157 } 1158 1159 1235 if (hmin > 0.001) 1236 { 1237 hfactor = (hmin - 0.001)/(hmin + 0.004); 1238 } 1239 1240 if (optimise_dry_cells) 1241 { 1242 // Check if linear reconstruction is necessary for triangle k 1243 // This check will exclude dry cells. 1244 1245 hmax = max(h0, max(h1, h2)); 1246 if (hmax < epsilon) 1247 { 1248 continue; 1249 } 1250 } 1251 1160 1252 //----------------------------------- 1161 1253 // stage … … 1164 1256 // Calculate the difference between vertex 0 of the auxiliary 1165 1257 // triangle and the centroid of triangle k 1166 dq0 =stage_centroid_values[k0]-stage_centroid_values[k];1258 dq0 = stage_centroid_values[k0] - stage_centroid_values[k]; 1167 1259 1168 1260 // Calculate differentials between the vertices 1169 1261 // of the auxiliary triangle (centroids of neighbouring triangles) 1170 dq1=stage_centroid_values[k1]-stage_centroid_values[k0]; 1171 dq2=stage_centroid_values[k2]-stage_centroid_values[k0]; 1172 1262 dq1 = stage_centroid_values[k1] - stage_centroid_values[k0]; 1263 dq2 = stage_centroid_values[k2] - stage_centroid_values[k0]; 1264 1265 inv_area2 = 1.0/area2; 1173 1266 // Calculate the gradient of stage on the auxiliary triangle 1174 1267 a = dy2*dq1 - dy1*dq2; 1175 a /=area2;1268 a *= inv_area2; 1176 1269 b = dx1*dq2 - dx2*dq1; 1177 b /=area2;1270 b *= inv_area2; 1178 1271 1179 1272 // Calculate provisional jumps in stage from the centroid 1180 1273 // of triangle k to its vertices, to be limited 1181 dqv[0] =a*dxv0+b*dyv0;1182 dqv[1] =a*dxv1+b*dyv1;1183 dqv[2] =a*dxv2+b*dyv2;1274 dqv[0] = a*dxv0 + b*dyv0; 1275 dqv[1] = a*dxv1 + b*dyv1; 1276 dqv[2] = a*dxv2 + b*dyv2; 1184 1277 1185 1278 // Now we want to find min and max of the centroid and the 1186 1279 // vertices of the auxiliary triangle and compute jumps 1187 1280 // from the centroid to the min and max 1188 find_qmin_and_qmax(dq0, dq1,dq2,&qmin,&qmax);1281 find_qmin_and_qmax(dq0, dq1, dq2, &qmin, &qmax); 1189 1282 1190 1283 // Playing with dry wet interface … … 1193 1286 //if (hmin>minimum_allowed_height) 1194 1287 beta_tmp = beta_w_dry + (beta_w - beta_w_dry) * hfactor; 1195 1288 1196 1289 //printf("min_alled_height = %f\n",minimum_allowed_height); 1197 1290 //printf("hmin = %f\n",hmin); … … 1199 1292 //printf("beta_tmp = %f\n",beta_tmp); 1200 1293 // Limit the gradient 1201 limit_gradient(dqv,qmin,qmax,beta_tmp); 1202 1203 for (i=0;i<3;i++) 1204 stage_vertex_values[k3+i]=stage_centroid_values[k]+dqv[i]; 1294 limit_gradient(dqv, qmin, qmax, beta_tmp); 1295 1296 //for (i=0;i<3;i++) 1297 stage_vertex_values[k3+0] = stage_centroid_values[k] + dqv[0]; 1298 stage_vertex_values[k3+1] = stage_centroid_values[k] + dqv[1]; 1299 stage_vertex_values[k3+2] = stage_centroid_values[k] + dqv[2]; 1205 1300 1206 1301 … … 1211 1306 // Calculate the difference between vertex 0 of the auxiliary 1212 1307 // triangle and the centroid of triangle k 1213 dq0 =xmom_centroid_values[k0]-xmom_centroid_values[k];1308 dq0 = xmom_centroid_values[k0] - xmom_centroid_values[k]; 1214 1309 1215 1310 // Calculate differentials between the vertices 1216 1311 // of the auxiliary triangle 1217 dq1 =xmom_centroid_values[k1]-xmom_centroid_values[k0];1218 dq2 =xmom_centroid_values[k2]-xmom_centroid_values[k0];1312 dq1 = xmom_centroid_values[k1] - xmom_centroid_values[k0]; 1313 dq2 = xmom_centroid_values[k2] - xmom_centroid_values[k0]; 1219 1314 1220 1315 // Calculate the gradient of xmom on the auxiliary triangle 1221 1316 a = dy2*dq1 - dy1*dq2; 1222 a /=area2;1317 a *= inv_area2; 1223 1318 b = dx1*dq2 - dx2*dq1; 1224 b /=area2;1319 b *= inv_area2; 1225 1320 1226 1321 // Calculate provisional jumps in stage from the centroid 1227 1322 // of triangle k to its vertices, to be limited 1228 dqv[0] =a*dxv0+b*dyv0;1229 dqv[1] =a*dxv1+b*dyv1;1230 dqv[2] =a*dxv2+b*dyv2;1323 dqv[0] = a*dxv0+b*dyv0; 1324 dqv[1] = a*dxv1+b*dyv1; 1325 dqv[2] = a*dxv2+b*dyv2; 1231 1326 1232 1327 // Now we want to find min and max of the centroid and the 1233 1328 // vertices of the auxiliary triangle and compute jumps 1234 1329 // from the centroid to the min and max 1235 find_qmin_and_qmax(dq0, dq1,dq2,&qmin,&qmax);1330 find_qmin_and_qmax(dq0, dq1, dq2, &qmin, &qmax); 1236 1331 //beta_tmp = beta_uh; 1237 1332 //if (hmin<minimum_allowed_height) … … 1240 1335 1241 1336 // Limit the gradient 1242 limit_gradient(dqv,qmin,qmax,beta_tmp); 1243 1244 for (i=0;i<3;i++) 1245 xmom_vertex_values[k3+i]=xmom_centroid_values[k]+dqv[i]; 1246 1337 limit_gradient(dqv, qmin, qmax, beta_tmp); 1338 1339 for (i=0; i < 3; i++) 1340 { 1341 xmom_vertex_values[k3+i] = xmom_centroid_values[k] + dqv[i]; 1342 } 1247 1343 1248 1344 //----------------------------------- … … 1252 1348 // Calculate the difference between vertex 0 of the auxiliary 1253 1349 // triangle and the centroid of triangle k 1254 dq0 =ymom_centroid_values[k0]-ymom_centroid_values[k];1350 dq0 = ymom_centroid_values[k0] - ymom_centroid_values[k]; 1255 1351 1256 1352 // Calculate differentials between the vertices 1257 1353 // of the auxiliary triangle 1258 dq1 =ymom_centroid_values[k1]-ymom_centroid_values[k0];1259 dq2 =ymom_centroid_values[k2]-ymom_centroid_values[k0];1354 dq1 = ymom_centroid_values[k1] - ymom_centroid_values[k0]; 1355 dq2 = ymom_centroid_values[k2] - ymom_centroid_values[k0]; 1260 1356 1261 1357 // Calculate the gradient of xmom on the auxiliary triangle 1262 1358 a = dy2*dq1 - dy1*dq2; 1263 a /=area2;1359 a *= inv_area2; 1264 1360 b = dx1*dq2 - dx2*dq1; 1265 b /=area2;1361 b *= inv_area2; 1266 1362 1267 1363 // Calculate provisional jumps in stage from the centroid 1268 1364 // of triangle k to its vertices, to be limited 1269 dqv[0] =a*dxv0+b*dyv0;1270 dqv[1] =a*dxv1+b*dyv1;1271 dqv[2] =a*dxv2+b*dyv2;1365 dqv[0] = a*dxv0 + b*dyv0; 1366 dqv[1] = a*dxv1 + b*dyv1; 1367 dqv[2] = a*dxv2 + b*dyv2; 1272 1368 1273 1369 // Now we want to find min and max of the centroid and the 1274 1370 // vertices of the auxiliary triangle and compute jumps 1275 1371 // from the centroid to the min and max 1276 find_qmin_and_qmax(dq0, dq1,dq2,&qmin,&qmax);1372 find_qmin_and_qmax(dq0, dq1, dq2, &qmin, &qmax); 1277 1373 1278 1374 //beta_tmp = beta_vh; … … 1280 1376 //if (hmin<minimum_allowed_height) 1281 1377 //beta_tmp = beta_vh_dry; 1282 beta_tmp = beta_vh_dry + (beta_vh - beta_vh_dry) * hfactor; 1378 beta_tmp = beta_vh_dry + (beta_vh - beta_vh_dry) * hfactor; 1283 1379 1284 1380 // Limit the gradient 1285 limit_gradient(dqv, qmin,qmax,beta_tmp);1381 limit_gradient(dqv, qmin, qmax, beta_tmp); 1286 1382 1287 1383 for (i=0;i<3;i++) 1288 ymom_vertex_values[k3+i]=ymom_centroid_values[k]+dqv[i]; 1289 1384 { 1385 ymom_vertex_values[k3 + i] = ymom_centroid_values[k] + dqv[i]; 1386 } 1290 1387 } // End number_of_boundaries <=1 1291 else{ 1388 else 1389 { 1292 1390 1293 1391 //============================================== … … 1298 1396 1299 1397 // Find the only internal neighbour (k1?) 1300 for (k2=k3;k2<k3+3;k2++){ 1301 // Find internal neighbour of triangle k 1302 // k2 indexes the edges of triangle k 1303 1304 if (surrogate_neighbours[k2]!=k) 1305 break; 1306 } 1307 1308 if ((k2==k3+3)) { 1309 // If we didn't find an internal neighbour 1310 PyErr_SetString(PyExc_RuntimeError, 1311 "shallow_water_ext.c: Internal neighbour not found"); 1312 return -1; 1313 } 1314 1315 k1=surrogate_neighbours[k2]; 1398 for (k2 = k3; k2 < k3 + 3; k2++) 1399 { 1400 // Find internal neighbour of triangle k 1401 // k2 indexes the edges of triangle k 1402 1403 if (surrogate_neighbours[k2] != k) 1404 { 1405 break; 1406 } 1407 } 1408 1409 if ((k2 == k3 + 3)) 1410 { 1411 // If we didn't find an internal neighbour 1412 PyErr_SetString(PyExc_RuntimeError, 1413 "shallow_water_ext.c: Internal neighbour not found"); 1414 return -1; 1415 } 1416 1417 k1 = surrogate_neighbours[k2]; 1316 1418 1317 1419 // The coordinates of the triangle are already (x,y). 1318 1420 // Get centroid of the neighbour (x1,y1) 1319 coord_index =2*k1;1320 x1 =centroid_coordinates[coord_index];1321 y1 =centroid_coordinates[coord_index+1];1421 coord_index = 2*k1; 1422 x1 = centroid_coordinates[coord_index]; 1423 y1 = centroid_coordinates[coord_index + 1]; 1322 1424 1323 1425 // Compute x- and y- distances between the centroid of 1324 1426 // triangle k and that of its neighbour 1325 dx1=x1-x; dy1=y1-y; 1427 dx1 = x1 - x; 1428 dy1 = y1 - y; 1326 1429 1327 1430 // Set area2 as the square of the distance 1328 area2 =dx1*dx1+dy1*dy1;1431 area2 = dx1*dx1 + dy1*dy1; 1329 1432 1330 1433 // Set dx2=(x1-x0)/((x1-x0)^2+(y1-y0)^2) … … 1332 1435 // respectively correspond to the x- and y- gradients 1333 1436 // of the conserved quantities 1334 dx2 =1.0/area2;1335 dy2 =dx2*dy1;1336 dx2 *=dx1;1437 dx2 = 1.0/area2; 1438 dy2 = dx2*dy1; 1439 dx2 *= dx1; 1337 1440 1338 1441 … … 1342 1445 1343 1446 // Compute differentials 1344 dq1 =stage_centroid_values[k1]-stage_centroid_values[k];1447 dq1 = stage_centroid_values[k1] - stage_centroid_values[k]; 1345 1448 1346 1449 // Calculate the gradient between the centroid of triangle k 1347 1450 // and that of its neighbour 1348 a =dq1*dx2;1349 b =dq1*dy2;1451 a = dq1*dx2; 1452 b = dq1*dy2; 1350 1453 1351 1454 // Calculate provisional vertex jumps, to be limited 1352 dqv[0] =a*dxv0+b*dyv0;1353 dqv[1] =a*dxv1+b*dyv1;1354 dqv[2] =a*dxv2+b*dyv2;1455 dqv[0] = a*dxv0 + b*dyv0; 1456 dqv[1] = a*dxv1 + b*dyv1; 1457 dqv[2] = a*dxv2 + b*dyv2; 1355 1458 1356 1459 // Now limit the jumps 1357 if (dq1>=0.0){ 1358 qmin=0.0; 1359 qmax=dq1; 1360 } 1361 else{ 1362 qmin=dq1; 1363 qmax=0.0; 1460 if (dq1>=0.0) 1461 { 1462 qmin=0.0; 1463 qmax=dq1; 1464 } 1465 else 1466 { 1467 qmin = dq1; 1468 qmax = 0.0; 1364 1469 } 1365 1470 1366 1471 // Limit the gradient 1367 limit_gradient(dqv,qmin,qmax,beta_w); 1368 1369 for (i=0;i<3;i++) 1370 stage_vertex_values[k3+i]=stage_centroid_values[k]+dqv[i]; 1371 1472 limit_gradient(dqv, qmin, qmax, beta_w); 1473 1474 //for (i=0; i < 3; i++) 1475 //{ 1476 stage_vertex_values[k3] = stage_centroid_values[k] + dqv[0]; 1477 stage_vertex_values[k3 + 1] = stage_centroid_values[k] + dqv[1]; 1478 stage_vertex_values[k3 + 2] = stage_centroid_values[k] + dqv[2]; 1479 //} 1372 1480 1373 1481 //----------------------------------- … … 1376 1484 1377 1485 // Compute differentials 1378 dq1 =xmom_centroid_values[k1]-xmom_centroid_values[k];1486 dq1 = xmom_centroid_values[k1] - xmom_centroid_values[k]; 1379 1487 1380 1488 // Calculate the gradient between the centroid of triangle k 1381 1489 // and that of its neighbour 1382 a =dq1*dx2;1383 b =dq1*dy2;1490 a = dq1*dx2; 1491 b = dq1*dy2; 1384 1492 1385 1493 // Calculate provisional vertex jumps, to be limited 1386 dqv[0] =a*dxv0+b*dyv0;1387 dqv[1] =a*dxv1+b*dyv1;1388 dqv[2] =a*dxv2+b*dyv2;1494 dqv[0] = a*dxv0+b*dyv0; 1495 dqv[1] = a*dxv1+b*dyv1; 1496 dqv[2] = a*dxv2+b*dyv2; 1389 1497 1390 1498 // Now limit the jumps 1391 if (dq1>=0.0){ 1392 qmin=0.0; 1393 qmax=dq1; 1394 } 1395 else{ 1396 qmin=dq1; 1397 qmax=0.0; 1499 if (dq1 >= 0.0) 1500 { 1501 qmin = 0.0; 1502 qmax = dq1; 1503 } 1504 else 1505 { 1506 qmin = dq1; 1507 qmax = 0.0; 1398 1508 } 1399 1509 1400 1510 // Limit the gradient 1401 limit_gradient(dqv,qmin,qmax,beta_w); 1402 1403 for (i=0;i<3;i++) 1404 xmom_vertex_values[k3+i]=xmom_centroid_values[k]+dqv[i]; 1405 1511 limit_gradient(dqv, qmin, qmax, beta_w); 1512 1513 //for (i=0;i<3;i++) 1514 //xmom_vertex_values[k3] = xmom_centroid_values[k] + dqv[0]; 1515 //xmom_vertex_values[k3 + 1] = xmom_centroid_values[k] + dqv[1]; 1516 //xmom_vertex_values[k3 + 2] = xmom_centroid_values[k] + dqv[2]; 1517 1518 for (i = 0; i < 3;i++) 1519 { 1520 xmom_vertex_values[k3 + i] = xmom_centroid_values[k] + dqv[i]; 1521 } 1406 1522 1407 1523 //----------------------------------- … … 1410 1526 1411 1527 // Compute differentials 1412 dq1 =ymom_centroid_values[k1]-ymom_centroid_values[k];1528 dq1 = ymom_centroid_values[k1] - ymom_centroid_values[k]; 1413 1529 1414 1530 // Calculate the gradient between the centroid of triangle k 1415 1531 // and that of its neighbour 1416 a =dq1*dx2;1417 b =dq1*dy2;1532 a = dq1*dx2; 1533 b = dq1*dy2; 1418 1534 1419 1535 // Calculate provisional vertex jumps, to be limited 1420 dqv[0] =a*dxv0+b*dyv0;1421 dqv[1] =a*dxv1+b*dyv1;1422 dqv[2] =a*dxv2+b*dyv2;1536 dqv[0] = a*dxv0 + b*dyv0; 1537 dqv[1] = a*dxv1 + b*dyv1; 1538 dqv[2] = a*dxv2 + b*dyv2; 1423 1539 1424 1540 // Now limit the jumps 1425 if (dq1>=0.0){ 1426 qmin=0.0; 1427 qmax=dq1; 1428 } 1429 else{ 1430 qmin=dq1; 1431 qmax=0.0; 1541 if (dq1>=0.0) 1542 { 1543 qmin = 0.0; 1544 qmax = dq1; 1545 } 1546 else 1547 { 1548 qmin = dq1; 1549 qmax = 0.0; 1432 1550 } 1433 1551 1434 1552 // Limit the gradient 1435 limit_gradient(dqv,qmin,qmax,beta_w); 1436 1437 for (i=0;i<3;i++) 1438 ymom_vertex_values[k3+i]=ymom_centroid_values[k]+dqv[i]; 1439 1553 limit_gradient(dqv, qmin, qmax, beta_w); 1554 1555 //for (i=0;i<3;i++) 1556 //ymom_vertex_values[k3] = ymom_centroid_values[k] + dqv[0]; 1557 //ymom_vertex_values[k3 + 1] = ymom_centroid_values[k] + dqv[1]; 1558 //ymom_vertex_values[k3 + 2] = ymom_centroid_values[k] + dqv[2]; 1559 1560 for (i=0;i<3;i++) 1561 { 1562 ymom_vertex_values[k3 + i] = ymom_centroid_values[k] + dqv[i]; 1563 } 1564 //ymom_vertex_values[k3] = ymom_centroid_values[k] + dqv[0]; 1565 //ymom_vertex_values[k3 + 1] = ymom_centroid_values[k] + dqv[1]; 1566 //ymom_vertex_values[k3 + 2] = ymom_centroid_values[k] + dqv[2]; 1440 1567 } // else [number_of_boundaries==2] 1441 1568 } // for k=0 to number_of_elements-1 1442 1569 1443 1570 return 0; 1444 } 1571 } 1445 1572 1446 1573 … … 1477 1604 Post conditions: 1478 1605 The vertices of each triangle have values from a 1479 1480 1606 limited linear reconstruction 1607 based on centroid values 1481 1608 1482 1609 */ … … 1505 1632 // Convert Python arguments to C 1506 1633 if (!PyArg_ParseTuple(args, "OOOOOOOOOOOOOi", 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 &optimise_dry_cells)) { 1521 1634 &domain, 1635 &surrogate_neighbours, 1636 &number_of_boundaries, 1637 ¢roid_coordinates, 1638 &stage_centroid_values, 1639 &xmom_centroid_values, 1640 &ymom_centroid_values, 1641 &elevation_centroid_values, 1642 &vertex_coordinates, 1643 &stage_vertex_values, 1644 &xmom_vertex_values, 1645 &ymom_vertex_values, 1646 &elevation_vertex_values, 1647 &optimise_dry_cells)) { 1648 1522 1649 PyErr_SetString(PyExc_RuntimeError, 1523 1650 "Input arguments to extrapolate_second_order_sw failed"); 1524 1651 return NULL; 1525 1652 } … … 1557 1684 // Call underlying computational routine 1558 1685 e = _extrapolate_second_order_sw(number_of_elements, 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1686 epsilon, 1687 minimum_allowed_height, 1688 beta_w, 1689 beta_w_dry, 1690 beta_uh, 1691 beta_uh_dry, 1692 beta_vh, 1693 beta_vh_dry, 1694 (long*) surrogate_neighbours -> data, 1695 (long*) number_of_boundaries -> data, 1696 (double*) centroid_coordinates -> data, 1697 (double*) stage_centroid_values -> data, 1698 (double*) xmom_centroid_values -> data, 1699 (double*) ymom_centroid_values -> data, 1700 (double*) elevation_centroid_values -> data, 1701 (double*) vertex_coordinates -> data, 1702 (double*) stage_vertex_values -> data, 1703 (double*) xmom_vertex_values -> data, 1704 (double*) ymom_vertex_values -> data, 1705 (double*) elevation_vertex_values -> data, 1706 optimise_dry_cells); 1580 1707 if (e == -1) { 1581 1708 // Use error string set inside computational routine 1582 1709 return NULL; 1583 } 1710 } 1584 1711 1585 1712 … … 1609 1736 // Convert Python arguments to C 1610 1737 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i", argnames, 1611 1738 &Q, &Normal, &direction)) { 1612 1739 PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: rotate could not parse input arguments"); 1613 1740 return NULL; … … 1654 1781 // Computational function for flux computation 1655 1782 double _compute_fluxes_central(int number_of_elements, 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 int optimise_dry_cells) { 1680 1783 double timestep, 1784 double epsilon, 1785 double H0, 1786 double g, 1787 long* neighbours, 1788 long* neighbour_edges, 1789 double* normals, 1790 double* edgelengths, 1791 double* radii, 1792 double* areas, 1793 long* tri_full_flag, 1794 double* stage_edge_values, 1795 double* xmom_edge_values, 1796 double* ymom_edge_values, 1797 double* bed_edge_values, 1798 double* stage_boundary_values, 1799 double* xmom_boundary_values, 1800 double* ymom_boundary_values, 1801 double* stage_explicit_update, 1802 double* xmom_explicit_update, 1803 double* ymom_explicit_update, 1804 long* already_computed_flux, 1805 double* max_speed_array, 1806 int optimise_dry_cells) 1807 { 1681 1808 // Local variables 1682 double max_speed, length, area, zl, zr;1809 double max_speed, length, inv_area, zl, zr; 1683 1810 int k, i, m, n; 1684 1811 int ki, nm=0, ki2; // Index shorthands … … 1687 1814 double ql[3], qr[3], edgeflux[3]; // Work array for summing up fluxes 1688 1815 1689 static long call=1; // Static local variable flagging already computed flux 1690 1691 1816 static long call = 1; // Static local variable flagging already computed flux 1817 1692 1818 // Start computation 1693 1819 call++; // Flag 'id' of flux calculation for this timestep 1694 1820 1695 1821 // Set explicit_update to zero for all conserved_quantities. 1696 1822 // This assumes compute_fluxes called before forcing terms 1697 for (k=0; k<number_of_elements; k++) { 1698 stage_explicit_update[k]=0.0; 1699 xmom_explicit_update[k]=0.0; 1700 ymom_explicit_update[k]=0.0; 1701 } 1702 1823 memset((char*) stage_explicit_update, 0, number_of_elements*sizeof(double)); 1824 memset((char*) xmom_explicit_update, 0, number_of_elements*sizeof(double)); 1825 memset((char*) ymom_explicit_update, 0, number_of_elements*sizeof(double)); 1826 1703 1827 // For all triangles 1704 for (k =0; k<number_of_elements; k++) {1705 1828 for (k = 0; k < number_of_elements; k++) 1829 { 1706 1830 // Loop through neighbours and compute edge flux for each 1707 for (i=0; i<3; i++) { 1708 ki = k*3+i; // Linear index (triangle k, edge i) 1831 for (i = 0; i < 3; i++) 1832 { 1833 ki = k*3 + i; // Linear index to edge i of triangle k 1709 1834 1710 1835 if (already_computed_flux[ki] == call) 1836 { 1711 1837 // We've already computed the flux across this edge 1712 continue; 1713 1714 1838 continue; 1839 } 1840 1841 // Get left hand side values from triangle k, edge i 1715 1842 ql[0] = stage_edge_values[ki]; 1716 1843 ql[1] = xmom_edge_values[ki]; … … 1718 1845 zl = bed_edge_values[ki]; 1719 1846 1720 // Quantities at neighbour on nearest face 1847 // Get right hand side values either from neighbouring triangle 1848 // or from boundary array (Quantities at neighbour on nearest face). 1721 1849 n = neighbours[ki]; 1722 if (n < 0) { 1850 if (n < 0) 1851 { 1723 1852 // Neighbour is a boundary condition 1724 m = -n-1; // Convert negative flag to boundary index 1725 1726 qr[0] = stage_boundary_values[m]; 1727 qr[1] = xmom_boundary_values[m]; 1728 qr[2] = ymom_boundary_values[m]; 1729 zr = zl; // Extend bed elevation to boundary 1730 } else { 1731 // Neighbour is a real element 1732 m = neighbour_edges[ki]; 1733 nm = n*3+m; // Linear index (triangle n, edge m) 1734 1735 qr[0] = stage_edge_values[nm]; 1736 qr[1] = xmom_edge_values[nm]; 1737 qr[2] = ymom_edge_values[nm]; 1738 zr = bed_edge_values[nm]; 1739 } 1740 1741 1742 if (optimise_dry_cells) { 1743 // Check if flux calculation is necessary across this edge 1744 // This check will exclude dry cells. 1745 // This will also optimise cases where zl != zr as 1746 // long as both are dry 1747 1748 if ( fabs(ql[0] - zl) < epsilon && 1749 fabs(qr[0] - zr) < epsilon ) { 1750 // Cell boundary is dry 1751 1752 already_computed_flux[ki] = call; // #k Done 1753 if (n>=0) 1754 already_computed_flux[nm] = call; // #n Done 1755 1756 max_speed = 0.0; 1757 continue; 1758 } 1759 } 1760 1853 m = -n - 1; // Convert negative flag to boundary index 1854 1855 qr[0] = stage_boundary_values[m]; 1856 qr[1] = xmom_boundary_values[m]; 1857 qr[2] = ymom_boundary_values[m]; 1858 zr = zl; // Extend bed elevation to boundary 1859 } 1860 else 1861 { 1862 // Neighbour is a real triangle 1863 m = neighbour_edges[ki]; 1864 nm = n*3 + m; // Linear index (triangle n, edge m) 1865 1866 qr[0] = stage_edge_values[nm]; 1867 qr[1] = xmom_edge_values[nm]; 1868 qr[2] = ymom_edge_values[nm]; 1869 zr = bed_edge_values[nm]; 1870 } 1871 1872 // Now we have values for this edge - both from left and right side. 1873 1874 if (optimise_dry_cells) 1875 { 1876 // Check if flux calculation is necessary across this edge 1877 // This check will exclude dry cells. 1878 // This will also optimise cases where zl != zr as 1879 // long as both are dry 1880 1881 if (fabs(ql[0] - zl) < epsilon && 1882 fabs(qr[0] - zr) < epsilon) 1883 { 1884 // Cell boundary is dry 1885 1886 already_computed_flux[ki] = call; // #k Done 1887 if (n >= 0) 1888 { 1889 already_computed_flux[nm] = call; // #n Done 1890 } 1891 1892 max_speed = 0.0; 1893 continue; 1894 } 1895 } 1761 1896 1762 1897 // Outward pointing normal vector (domain.normals[k, 2*i:2*i+2]) … … 1765 1900 // Edge flux computation (triangle k, edge i) 1766 1901 _flux_function_central(ql, qr, zl, zr, 1767 1768 1769 1902 normals[ki2], normals[ki2+1], 1903 epsilon, H0, g, 1904 edgeflux, &max_speed); 1770 1905 1771 1906 … … 1786 1921 1787 1922 // Update neighbour n with same flux but reversed sign 1788 if (n >=0) {1789 stage_explicit_update[n] += edgeflux[0]; 1790 xmom_explicit_update[n] += edgeflux[1];1791 ymom_explicit_update[n] += edgeflux[2];1792 1793 already_computed_flux[nm] = call; // #n Done 1794 }1795 1923 if (n >= 0) 1924 { 1925 stage_explicit_update[n] += edgeflux[0]; 1926 xmom_explicit_update[n] += edgeflux[1]; 1927 ymom_explicit_update[n] += edgeflux[2]; 1928 1929 already_computed_flux[nm] = call; // #n Done 1930 } 1796 1931 1797 1932 // Update timestep based on edge i and possibly neighbour n 1798 if (tri_full_flag[k] == 1) { 1799 if (max_speed > epsilon) { 1800 1801 // Apply CFL condition for triangles joining this edge (triangle k and triangle n) 1802 1803 // CFL for triangle k 1804 timestep = min(timestep, radii[k]/max_speed); 1805 1806 if (n>=0) 1807 // Apply CFL condition for neigbour n (which is on the ith edge of triangle k) 1808 timestep = min(timestep, radii[n]/max_speed); 1809 1810 // Ted Rigby's suggested less conservative version 1811 //if (n>=0) { 1812 // timestep = min(timestep, (radii[k]+radii[n])/max_speed); 1813 //} else { 1814 // timestep = min(timestep, radii[k]/max_speed); 1815 // } 1816 } 1933 if (tri_full_flag[k] == 1) 1934 { 1935 if (max_speed > epsilon) 1936 { 1937 // Apply CFL condition for triangles joining this edge (triangle k and triangle n) 1938 1939 // CFL for triangle k 1940 timestep = min(timestep, radii[k]/max_speed); 1941 1942 if (n >= 0) 1943 { 1944 // Apply CFL condition for neigbour n (which is on the ith edge of triangle k) 1945 timestep = min(timestep, radii[n]/max_speed); 1946 } 1947 1948 // Ted Rigby's suggested less conservative version 1949 //if (n>=0) { 1950 // timestep = min(timestep, (radii[k]+radii[n])/max_speed); 1951 //} else { 1952 // timestep = min(timestep, radii[k]/max_speed); 1953 // } 1954 } 1817 1955 } 1818 1956 … … 1822 1960 // Normalise triangle k by area and store for when all conserved 1823 1961 // quantities get updated 1824 area =areas[k];1825 stage_explicit_update[k] /=area;1826 xmom_explicit_update[k] /=area;1827 ymom_explicit_update[k] /=area;1962 inv_area = 1.0/areas[k]; 1963 stage_explicit_update[k] *= inv_area; 1964 xmom_explicit_update[k] *= inv_area; 1965 ymom_explicit_update[k] *= inv_area; 1828 1966 1829 1967 … … 1832 1970 1833 1971 } // End triangle k 1834 1835 1836 1972 1837 1973 return timestep; 1838 1974 } … … 1869 2005 1870 2006 PyObject 1871 1872 1873 1874 1875 2007 *domain, 2008 *stage, 2009 *xmom, 2010 *ymom, 2011 *bed; 1876 2012 1877 2013 PyArrayObject 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 2014 *neighbours, 2015 *neighbour_edges, 2016 *normals, 2017 *edgelengths, 2018 *radii, 2019 *areas, 2020 *tri_full_flag, 2021 *stage_edge_values, 2022 *xmom_edge_values, 2023 *ymom_edge_values, 2024 *bed_edge_values, 2025 *stage_boundary_values, 2026 *xmom_boundary_values, 2027 *ymom_boundary_values, 2028 *stage_explicit_update, 2029 *xmom_explicit_update, 2030 *ymom_explicit_update, 2031 *already_computed_flux, //Tracks whether the flux across an edge has already been computed 2032 *max_speed_array; //Keeps track of max speeds for each triangle 1897 2033 1898 2034 … … 1902 2038 // Convert Python arguments to C 1903 2039 if (!PyArg_ParseTuple(args, "dOOOO", ×tep, &domain, &stage, &xmom, &ymom, &bed )) { 1904 1905 2040 PyErr_SetString(PyExc_RuntimeError, "Input arguments failed"); 2041 return NULL; 1906 2042 } 1907 2043 … … 1940 2076 // the explicit update arrays 1941 2077 timestep = _compute_fluxes_central(number_of_elements, 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 2078 timestep, 2079 epsilon, 2080 H0, 2081 g, 2082 (long*) neighbours -> data, 2083 (long*) neighbour_edges -> data, 2084 (double*) normals -> data, 2085 (double*) edgelengths -> data, 2086 (double*) radii -> data, 2087 (double*) areas -> data, 2088 (long*) tri_full_flag -> data, 2089 (double*) stage_edge_values -> data, 2090 (double*) xmom_edge_values -> data, 2091 (double*) ymom_edge_values -> data, 2092 (double*) bed_edge_values -> data, 2093 (double*) stage_boundary_values -> data, 2094 (double*) xmom_boundary_values -> data, 2095 (double*) ymom_boundary_values -> data, 2096 (double*) stage_explicit_update -> data, 2097 (double*) xmom_explicit_update -> data, 2098 (double*) ymom_explicit_update -> data, 2099 (long*) already_computed_flux -> data, 2100 (double*) max_speed_array -> data, 2101 optimise_dry_cells); 1966 2102 1967 2103 Py_DECREF(neighbours); … … 2013 2149 domain.timestep = compute_fluxes(timestep, 2014 2150 domain.epsilon, 2015 2151 domain.H0, 2016 2152 domain.g, 2017 2153 domain.neighbours, … … 2033 2169 Ymom.explicit_update, 2034 2170 already_computed_flux, 2035 optimise_dry_cells)2171 optimise_dry_cells) 2036 2172 2037 2173 … … 2066 2202 // Convert Python arguments to C 2067 2203 if (!PyArg_ParseTuple(args, "ddddOOOOOOOOOOOOOOOOOOOi", 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2204 ×tep, 2205 &epsilon, 2206 &H0, 2207 &g, 2208 &neighbours, 2209 &neighbour_edges, 2210 &normals, 2211 &edgelengths, &radii, &areas, 2212 &tri_full_flag, 2213 &stage_edge_values, 2214 &xmom_edge_values, 2215 &ymom_edge_values, 2216 &bed_edge_values, 2217 &stage_boundary_values, 2218 &xmom_boundary_values, 2219 &ymom_boundary_values, 2220 &stage_explicit_update, 2221 &xmom_explicit_update, 2222 &ymom_explicit_update, 2223 &already_computed_flux, 2224 &max_speed_array, 2225 &optimise_dry_cells)) { 2090 2226 PyErr_SetString(PyExc_RuntimeError, "Input arguments failed"); 2091 2227 return NULL; … … 2118 2254 // the explicit update arrays 2119 2255 timestep = _compute_fluxes_central(number_of_elements, 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2256 timestep, 2257 epsilon, 2258 H0, 2259 g, 2260 (long*) neighbours -> data, 2261 (long*) neighbour_edges -> data, 2262 (double*) normals -> data, 2263 (double*) edgelengths -> data, 2264 (double*) radii -> data, 2265 (double*) areas -> data, 2266 (long*) tri_full_flag -> data, 2267 (double*) stage_edge_values -> data, 2268 (double*) xmom_edge_values -> data, 2269 (double*) ymom_edge_values -> data, 2270 (double*) bed_edge_values -> data, 2271 (double*) stage_boundary_values -> data, 2272 (double*) xmom_boundary_values -> data, 2273 (double*) ymom_boundary_values -> data, 2274 (double*) stage_explicit_update -> data, 2275 (double*) xmom_explicit_update -> data, 2276 (double*) ymom_explicit_update -> data, 2277 (long*) already_computed_flux -> data, 2278 (double*) max_speed_array -> data, 2279 optimise_dry_cells); 2144 2280 2145 2281 // Return updated flux timestep … … 2228 2364 // Convert Python arguments to C 2229 2365 if (!PyArg_ParseTuple(args, "ddddOOOOOOOOOOOOOOOOOO", 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2366 ×tep, 2367 &epsilon, 2368 &H0, 2369 &g, 2370 &neighbours, 2371 &neighbour_edges, 2372 &normals, 2373 &edgelengths, &radii, &areas, 2374 &tri_full_flag, 2375 &stage_edge_values, 2376 &xmom_edge_values, 2377 &ymom_edge_values, 2378 &bed_edge_values, 2379 &stage_boundary_values, 2380 &xmom_boundary_values, 2381 &ymom_boundary_values, 2382 &stage_explicit_update, 2383 &xmom_explicit_update, 2384 &ymom_explicit_update, 2385 &already_computed_flux)) { 2250 2386 PyErr_SetString(PyExc_RuntimeError, "Input arguments failed"); 2251 2387 return NULL; … … 2265 2401 ki = k*3+i; 2266 2402 if (((long *) already_computed_flux->data)[ki]==call)//we've already computed the flux across this edge 2267 2403 continue; 2268 2404 ql[0] = ((double *) stage_edge_values -> data)[ki]; 2269 2405 ql[1] = ((double *) xmom_edge_values -> data)[ki]; … … 2274 2410 n = ((long *) neighbours -> data)[ki]; 2275 2411 if (n < 0) { 2276 2277 2278 2279 2280 2412 m = -n-1; //Convert negative flag to index 2413 qr[0] = ((double *) stage_boundary_values -> data)[m]; 2414 qr[1] = ((double *) xmom_boundary_values -> data)[m]; 2415 qr[2] = ((double *) ymom_boundary_values -> data)[m]; 2416 zr = zl; //Extend bed elevation to boundary 2281 2417 } else { 2282 2283 2284 2285 2286 2287 2418 m = ((long *) neighbour_edges -> data)[ki]; 2419 nm = n*3+m; 2420 qr[0] = ((double *) stage_edge_values -> data)[nm]; 2421 qr[1] = ((double *) xmom_edge_values -> data)[nm]; 2422 qr[2] = ((double *) ymom_edge_values -> data)[nm]; 2423 zr = ((double *) bed_edge_values -> data)[nm]; 2288 2424 } 2289 2425 // Outward pointing normal vector … … 2294 2430 //Edge flux computation 2295 2431 flux_function_kinetic(ql, qr, zl, zr, 2296 2297 2298 2432 normal[0], normal[1], 2433 epsilon, H0, g, 2434 edgeflux, &max_speed); 2299 2435 //update triangle k 2300 2436 ((long *) already_computed_flux->data)[ki]=call; … … 2304 2440 //update the neighbour n 2305 2441 if (n>=0){ 2306 2307 2308 2309 2442 ((long *) already_computed_flux->data)[nm]=call; 2443 ((double *) stage_explicit_update -> data)[n] += edgeflux[0]*((double *) edgelengths -> data)[nm]; 2444 ((double *) xmom_explicit_update -> data)[n] += edgeflux[1]*((double *) edgelengths -> data)[nm]; 2445 ((double *) ymom_explicit_update -> data)[n] += edgeflux[2]*((double *) edgelengths -> data)[nm]; 2310 2446 } 2311 2447 ///for (j=0; j<3; j++) { 2312 2313 2314 2315 2316 2448 ///flux[j] -= edgeflux[j]*((double *) edgelengths -> data)[ki]; 2449 ///} 2450 //Update timestep 2451 //timestep = min(timestep, domain.radii[k]/max_speed) 2452 //FIXME: SR Add parameter for CFL condition 2317 2453 if ( ((long *) tri_full_flag -> data)[k] == 1) { 2318 2319 2320 2321 2322 2323 2454 if (max_speed > epsilon) { 2455 timestep = min(timestep, ((double *) radii -> data)[k]/max_speed); 2456 //maxspeed in flux_function is calculated as max(|u+a|,|u-a|) 2457 if (n>=0) 2458 timestep = min(timestep, ((double *) radii -> data)[n]/max_speed); 2459 } 2324 2460 } 2325 2461 } // end for i … … 2350 2486 // Convert Python arguments to C 2351 2487 if (!PyArg_ParseTuple(args, "dddOOOO", 2352 2353 2354 2355 2488 &minimum_allowed_height, 2489 &maximum_allowed_speed, 2490 &epsilon, 2491 &wc, &zc, &xmomc, &ymomc)) { 2356 2492 PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: protect could not parse input arguments"); 2357 2493 return NULL; … … 2361 2497 2362 2498 _protect(N, 2363 2364 2365 2366 2367 2368 2369 2499 minimum_allowed_height, 2500 maximum_allowed_speed, 2501 epsilon, 2502 (double*) wc -> data, 2503 (double*) zc -> data, 2504 (double*) xmomc -> data, 2505 (double*) ymomc -> data); 2370 2506 2371 2507 return Py_BuildValue(""); … … 2409 2545 // Convert Python arguments to C 2410 2546 if (!PyArg_ParseTuple(args, "OOOOOOOOOO", 2411 2412 2413 2414 2547 &domain, 2548 &wc, &zc, 2549 &wv, &zv, &hvbar, 2550 &xmomc, &ymomc, &xmomv, &ymomv)) { 2415 2551 PyErr_SetString(PyExc_RuntimeError, 2416 2552 "shallow_water_ext.c: balance_deep_and_shallow could not parse input arguments"); 2417 2553 return NULL; 2418 2554 } 2419 2420 2555 2556 2421 2557 // FIXME (Ole): I tested this without GetAttrString and got time down 2422 2558 // marginally from 4.0s to 3.8s. Consider passing everything in … … 2463 2599 N = wc -> dimensions[0]; 2464 2600 _balance_deep_and_shallow(N, 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 (int) use_centroid_velocities,2477 2601 (double*) wc -> data, 2602 (double*) zc -> data, 2603 (double*) wv -> data, 2604 (double*) zv -> data, 2605 (double*) hvbar -> data, 2606 (double*) xmomc -> data, 2607 (double*) ymomc -> data, 2608 (double*) xmomv -> data, 2609 (double*) ymomv -> data, 2610 H0, 2611 (int) tight_slope_limiters, 2612 (int) use_centroid_velocities, 2613 alpha_balance); 2478 2614 2479 2615 … … 2503 2639 // Convert Python arguments to C 2504 2640 if (!PyArg_ParseTuple(args, "OOOOd", 2505 2506 2507 2508 2641 &xmom_update, 2642 &ymom_update, 2643 &s_vec, &phi_vec, 2644 &cw)) { 2509 2645 PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: assign_windfield_values could not parse input arguments"); 2510 2646 return NULL; 2511 2647 } 2512 2648 2513 2649 2514 2650 N = xmom_update -> dimensions[0]; 2515 2651 2516 2652 _assign_wind_field_values(N, 2517 2518 2519 2520 2521 2653 (double*) xmom_update -> data, 2654 (double*) ymom_update -> data, 2655 (double*) s_vec -> data, 2656 (double*) phi_vec -> data, 2657 cw); 2522 2658 2523 2659 return Py_BuildValue(""); -
branches/numpy/anuga/shallow_water/test_data_manager.py
r6689 r6902 15 15 from struct import pack, unpack 16 16 from sets import ImmutableSet 17 import shutil 17 18 18 19 from anuga.shallow_water import * … … 47 48 48 49 self.verbose = Test_Data_Manager.verbose 49 # Create basic mesh50 # Create basic mesh 50 51 points, vertices, boundary = rectangular(2, 2) 51 52 52 # Create shallow water domain53 # Create shallow water domain 53 54 domain = Domain(points, vertices, boundary) 54 55 domain.default_order = 2 55 56 56 # Set some field values57 # Set some field values 57 58 domain.set_quantity('elevation', lambda x,y: -x) 58 59 domain.set_quantity('friction', 0.03) … … 252 253 253 254 # Get the variables 254 #range = fid.variables['stage_range'][:]255 range = fid.variables['stage_range'][:] 255 256 #print range 256 #assert num.allclose(range,[-0.93519, 0.15]) or\257 #num.allclose(range,[-0.9352743, 0.15]) or\258 #num.allclose(range,[-0.93522203, 0.15000001]) # Old slope limiters259 260 #range = fid.variables['xmomentum_range'][:]257 assert num.allclose(range,[-0.93519, 0.15]) or\ 258 num.allclose(range,[-0.9352743, 0.15]) or\ 259 num.allclose(range,[-0.93522203, 0.15000001]) # Old slope limiters 260 261 range = fid.variables['xmomentum_range'][:] 261 262 ##print range 262 #assert num.allclose(range,[0,0.4695096]) or \263 #num.allclose(range,[0,0.47790655]) or\264 #num.allclose(range,[0,0.46941957]) or\265 #num.allclose(range,[0,0.47769409])266 267 268 #range = fid.variables['ymomentum_range'][:]263 assert num.allclose(range,[0,0.4695096]) or \ 264 num.allclose(range,[0,0.47790655]) or\ 265 num.allclose(range,[0,0.46941957]) or\ 266 num.allclose(range,[0,0.47769409]) 267 268 269 range = fid.variables['ymomentum_range'][:] 269 270 ##print range 270 #assert num.allclose(range,[0,0.02174380]) or\271 #num.allclose(range,[0,0.02174439]) or\272 #num.allclose(range,[0,0.02283983]) or\273 #num.allclose(range,[0,0.0217342]) or\274 #num.allclose(range,[0,0.0227564]) # Old slope limiters271 assert num.allclose(range,[0,0.02174380]) or\ 272 num.allclose(range,[0,0.02174439]) or\ 273 num.allclose(range,[0,0.02283983]) or\ 274 num.allclose(range,[0,0.0217342]) or\ 275 num.allclose(range,[0,0.0227564]) # Old slope limiters 275 276 276 277 fid.close() … … 1232 1233 from Scientific.IO.NetCDF import NetCDFFile 1233 1234 1234 # Setup1235 # Setup 1235 1236 self.domain.set_name('datatest') 1236 1237 … … 1245 1246 self.domain.set_quantity('stage', 1.0) 1246 1247 1247 self.domain.geo_reference = Geo_reference(56, 308500,6189000)1248 self.domain.geo_reference = Geo_reference(56, 308500, 6189000) 1248 1249 1249 1250 sww = get_dataobject(self.domain) … … 5563 5564 quantities_init[0].append(this_ha) # HA 5564 5565 quantities_init[1].append(this_ua) # UA 5565 quantities_init[2].append(this_va) # VA 5566 quantities_init[2].append(this_va) # VA 5566 5567 5567 5568 file_handle, base_name = tempfile.mkstemp("") … … 6104 6105 #print 'writing', time, point_i, q_time[time, point_i] 6105 6106 f.write(pack('f', q_time[time, point_i])) 6106 6107 6107 f.close() 6108 6108 … … 6215 6215 6216 6216 msg='Incorrect gauge depths returned' 6217 assert num.allclose(elevation, -depth),msg6217 assert num.allclose(elevation, -depth),msg 6218 6218 msg='incorrect gauge height time series returned' 6219 assert num.allclose(stage, ha)6219 assert num.allclose(stage, ha) 6220 6220 msg='incorrect gauge ua time series returned' 6221 assert num.allclose(xvelocity, ua)6221 assert num.allclose(xvelocity, ua) 6222 6222 msg='incorrect gauge va time series returned' 6223 6223 assert num.allclose(yvelocity, -va) # South is positive in MUX … … 6397 6397 if j == 2: assert num.allclose(data[i][:parameters_index], -va0[permutation[i], :]) 6398 6398 6399 self.delete_mux(filesI) 6399 6400 6400 6401 … … 6407 6408 wrong values Win32 6408 6409 6409 This test does not pass on Windows but test_read_mux_platform_problem1 does 6410 This test does not pass on Windows but test_read_mux_platform_problem1 6411 does 6410 6412 """ 6411 6413 … … 6422 6424 times_ref = num.arange(0, time_step_count*time_step, time_step) 6423 6425 6424 lat_long_points = [(-21.5,114.5), (-21,114.5), (-21.5,115), (-21.,115.), (-22., 117.)] 6426 lat_long_points = [(-21.5,114.5), (-21,114.5), (-21.5,115), 6427 (-21.,115.), (-22., 117.)] 6425 6428 n = len(lat_long_points) 6426 6429 … … 6466 6469 for j in range(0, first_tstep[i]-1) + range(last_tstep[i], time_step_count): 6467 6470 # For timesteps before and after recording range 6468 ha1[i][j] = ua1[i][j] = va1[i][j] = 0.0 6471 ha1[i][j] = ua1[i][j] = va1[i][j] = 0.0 6469 6472 6470 6473 … … 6474 6477 #print 'va', va1[0,:] 6475 6478 6476 # Write second mux file to be combined by urs2sts 6479 # Write second mux file to be combined by urs2sts 6477 6480 base_nameII, filesII = self.write_mux2(lat_long_points, 6478 6481 time_step_count, time_step, … … 6605 6608 6606 6609 f.close() 6607 6608 6609 6610 6611 6612 6613 6614 6610 6615 6611 # Create ordering file 6616 6612 permutation = ensure_numeric([4,0,2]) 6617 6613 6618 _, ordering_filename = tempfile.mkstemp('') 6619 order_fid = open(ordering_filename, 'w') 6620 order_fid.write('index, longitude, latitude\n') 6621 for index in permutation: 6622 order_fid.write('%d, %f, %f\n' %(index, 6623 lat_long_points[index][1], 6624 lat_long_points[index][0])) 6625 order_fid.close() 6626 6627 6628 6614 # _, ordering_filename = tempfile.mkstemp('') 6615 # order_fid = open(ordering_filename, 'w') 6616 # order_fid.write('index, longitude, latitude\n') 6617 # for index in permutation: 6618 # order_fid.write('%d, %f, %f\n' %(index, 6619 # lat_long_points[index][1], 6620 # lat_long_points[index][0])) 6621 # order_fid.close() 6622 6629 6623 # ------------------------------------- 6630 6624 # Now read files back and check values … … 6638 6632 for j, file in enumerate(filesII): 6639 6633 # Read stage, u, v enumerated as j 6640 6641 6642 6634 #print 'Reading', j, file 6643 6635 data = read_mux2(1, [file], weights, file_params, permutation, verbose) … … 6645 6637 #print 'Data received by Python' 6646 6638 #print data[1][8] 6647 6648 6649 6639 number_of_selected_stations = data.shape[0] 6650 6640 … … 6659 6649 #print i, parameters_index 6660 6650 #print quantity[i][:] 6661 6662 6663 6651 if j == 0: assert num.allclose(data[i][:parameters_index], ha1[permutation[i], :]) 6664 6652 if j == 1: assert num.allclose(data[i][:parameters_index], ua1[permutation[i], :]) … … 6669 6657 #print j, i 6670 6658 #print 'Input' 6671 #print 'u', ua1[permutation[i], 8] 6659 #print 'u', ua1[permutation[i], 8] 6672 6660 #print 'v', va1[permutation[i], 8] 6673 6661 6674 6662 #print 'Output' 6675 #print 'v ', data[i][:parameters_index][8] 6663 #print 'v ', data[i][:parameters_index][8] 6664 6665 # South is positive in MUX 6666 #print "data[i][:parameters_index]", data[i][:parameters_index] 6667 #print "-va1[permutation[i], :]", -va1[permutation[i], :] 6668 assert num.allclose(data[i][:parameters_index], -va1[permutation[i], :]) 6669 6670 self.delete_mux(filesII) 6671 6672 def test_read_mux_platform_problem3(self): 6673 6674 # This is to test a situation where read_mux returned 6675 # wrong values Win32 6676 6677 6678 from urs_ext import read_mux2 6679 6680 from anuga.config import single_precision as epsilon 6681 6682 verbose = False 6676 6683 6677 # South is positive in MUX 6684 tide = 1.5 6685 time_step_count = 10 6686 time_step = 0.02 6687 6688 ''' 6689 Win results 6690 time_step = 0.2000001 6691 This is OK 6692 ''' 6693 6694 ''' 6695 Win results 6696 time_step = 0.20000001 6697 6698 ====================================================================== 6699 ERROR: test_read_mux_platform_problem3 (__main__.Test_Data_Manager) 6700 ---------------------------------------------------------------------- 6701 Traceback (most recent call last): 6702 File "test_data_manager.py", line 6718, in test_read_mux_platform_problem3 6703 ha1[0]=num.sin(times_ref) 6704 ValueError: matrices are not aligned for copy 6705 6706 ''' 6707 6708 ''' 6709 Win results 6710 time_step = 0.200000001 6711 FAIL 6712 assert num.allclose(data[i][:parameters_index], 6713 -va1[permutation[i], :]) 6714 ''' 6715 times_ref = num.arange(0, time_step_count*time_step, time_step) 6716 #print "times_ref", times_ref 6717 6718 lat_long_points = [(-21.5,114.5), (-21,114.5), (-21.5,115), 6719 (-21.,115.), (-22., 117.)] 6720 stations = len(lat_long_points) 6721 6722 # Create different timeseries starting and ending at different times 6723 first_tstep=num.ones(stations, num.int) 6724 first_tstep[0]+=2 # Point 0 starts at 2 6725 first_tstep[1]+=4 # Point 1 starts at 4 6726 first_tstep[2]+=3 # Point 2 starts at 3 6727 6728 last_tstep=(time_step_count)*num.ones(stations, num.int) 6729 last_tstep[0]-=1 # Point 0 ends 1 step early 6730 last_tstep[1]-=2 # Point 1 ends 2 steps early 6731 last_tstep[4]-=3 # Point 4 ends 3 steps early 6732 6733 # Create varying elevation data (positive values for seafloor) 6734 gauge_depth=20*num.ones(stations, num.float) 6735 for i in range(stations): 6736 gauge_depth[i] += i**2 6737 6738 # Create data to be written to second mux file 6739 ha1=num.ones((stations,time_step_count), num.float) 6740 ha1[0]=num.sin(times_ref) 6741 ha1[1]=2*num.sin(times_ref - 3) 6742 ha1[2]=5*num.sin(4*times_ref) 6743 ha1[3]=num.sin(times_ref) 6744 ha1[4]=num.sin(2*times_ref-0.7) 6745 6746 ua1=num.zeros((stations,time_step_count),num.float) 6747 ua1[0]=3*num.cos(times_ref) 6748 ua1[1]=2*num.sin(times_ref-0.7) 6749 ua1[2]=num.arange(3*time_step_count,4*time_step_count) 6750 ua1[4]=2*num.ones(time_step_count) 6751 6752 va1=num.zeros((stations,time_step_count),num.float) 6753 va1[0]=2*num.cos(times_ref-0.87) 6754 va1[1]=3*num.ones(time_step_count) 6755 va1[3]=2*num.sin(times_ref-0.71) 6756 #print "va1[0]", va1[0] # The 8th element is what will go bad. 6757 # Ensure data used to write mux file to be zero when gauges are 6758 # not recording 6759 for i in range(stations): 6760 # For each point 6761 for j in range(0, first_tstep[i]-1) + range(last_tstep[i], 6762 time_step_count): 6763 # For timesteps before and after recording range 6764 ha1[i][j] = ua1[i][j] = va1[i][j] = 0.0 6765 6766 6767 #print 'Second station to be written to MUX' 6768 #print 'ha', ha1[0,:] 6769 #print 'ua', ua1[0,:] 6770 #print 'va', va1[0,:] 6771 6772 # Write second mux file to be combined by urs2sts 6773 base_nameII, filesII = self.write_mux2(lat_long_points, 6774 time_step_count, time_step, 6775 first_tstep, last_tstep, 6776 depth=gauge_depth, 6777 ha=ha1, 6778 ua=ua1, 6779 va=va1) 6780 #print "filesII", filesII 6781 6782 6783 6784 6785 # Read mux file back and verify it's correcness 6786 6787 #################################################### 6788 # FIXME (Ole): This is where the test should 6789 # verify that the MUX files are correct. 6790 6791 #JJ: It appears as though 6792 #that certain quantities are not being stored with enough precision 6793 #inn muxfile or more likely that they are being cast into a 6794 #lower precision when read in using read_mux2 Time step and q_time 6795 # are equal but only to approx 1e-7 6796 #################################################### 6797 6798 #define information as it should be stored in mus2 files 6799 points_num=len(lat_long_points) 6800 depth=gauge_depth 6801 ha=ha1 6802 ua=ua1 6803 va=va1 6804 6805 quantities = ['HA','UA','VA'] 6806 mux_names = [WAVEHEIGHT_MUX2_LABEL, 6807 EAST_VELOCITY_MUX2_LABEL, 6808 NORTH_VELOCITY_MUX2_LABEL] 6809 quantities_init = [[],[],[]] 6810 latlondeps = [] 6811 #irrelevant header information 6812 ig=ilon=ilat=0 6813 mcolat=mcolon=centerlat=centerlon=offset=az=baz=id=0.0 6814 # urs binary is latitude fastest 6815 for i,point in enumerate(lat_long_points): 6816 lat = point[0] 6817 lon = point[1] 6818 _ , e, n = redfearn(lat, lon) 6819 if depth is None: 6820 this_depth = n 6821 else: 6822 this_depth = depth[i] 6823 latlondeps.append([lat, lon, this_depth]) 6824 6825 if ha is None: 6826 this_ha = e 6827 quantities_init[0].append(num.ones(time_step_count, 6828 num.float)*this_ha) # HA 6829 else: 6830 quantities_init[0].append(ha[i]) 6831 if ua is None: 6832 this_ua = n 6833 quantities_init[1].append(num.ones(time_step_count, 6834 num.float)*this_ua) # UA 6835 else: 6836 quantities_init[1].append(ua[i]) 6837 if va is None: 6838 this_va = e 6839 quantities_init[2].append(num.ones(time_step_count, 6840 num.float)*this_va) # 6841 else: 6842 quantities_init[2].append(va[i]) 6843 6844 for i, q in enumerate(quantities): 6845 #print 6846 #print i, q 6847 6848 q_time = num.zeros((time_step_count, points_num), num.float) 6849 quantities_init[i] = ensure_numeric(quantities_init[i]) 6850 for time in range(time_step_count): 6851 #print i, q, time, quantities_init[i][:,time] 6852 q_time[time,:] = quantities_init[i][:,time] 6853 #print i, q, time, q_time[time, :] 6854 6855 6856 filename = base_nameII + mux_names[i] 6857 f = open(filename, 'rb') 6858 if self.verbose: print 'Reading' + filename 6859 assert abs(points_num-unpack('i',f.read(4))[0])<epsilon 6860 #write mux 2 header 6861 for latlondep in latlondeps: 6862 assert abs(latlondep[0]-unpack('f',f.read(4))[0])<epsilon 6863 assert abs(latlondep[1]-unpack('f',f.read(4))[0])<epsilon 6864 assert abs(mcolat-unpack('f',f.read(4))[0])<epsilon 6865 assert abs(mcolon-unpack('f',f.read(4))[0])<epsilon 6866 assert abs(ig-unpack('i',f.read(4))[0])<epsilon 6867 assert abs(ilon-unpack('i',f.read(4))[0])<epsilon 6868 assert abs(ilat-unpack('i',f.read(4))[0])<epsilon 6869 assert abs(latlondep[2]-unpack('f',f.read(4))[0])<epsilon 6870 assert abs(centerlat-unpack('f',f.read(4))[0])<epsilon 6871 assert abs(centerlon-unpack('f',f.read(4))[0])<epsilon 6872 assert abs(offset-unpack('f',f.read(4))[0])<epsilon 6873 assert abs(az-unpack('f',f.read(4))[0])<epsilon 6874 assert abs(baz-unpack('f',f.read(4))[0])<epsilon 6875 6876 x = unpack('f', f.read(4))[0] 6877 #print time_step 6878 #print x 6879 assert abs(time_step-x)<epsilon 6880 assert abs(time_step_count-unpack('i',f.read(4))[0])<epsilon 6881 for j in range(4): # identifier 6882 assert abs(id-unpack('i',f.read(4))[0])<epsilon 6883 6884 #first_tstep=1 6885 #last_tstep=time_step_count 6886 for i,latlondep in enumerate(latlondeps): 6887 assert abs(first_tstep[i]-unpack('i',f.read(4))[0])<epsilon 6888 for i,latlondep in enumerate(latlondeps): 6889 assert abs(last_tstep[i]-unpack('i',f.read(4))[0])<epsilon 6890 6891 # Find when first station starts recording 6892 min_tstep = min(first_tstep) 6893 # Find when all stations have stopped recording 6894 max_tstep = max(last_tstep) 6895 6896 #for time in range(time_step_count): 6897 for time in range(min_tstep-1,max_tstep): 6898 assert abs(time*time_step-unpack('f',f.read(4))[0])<epsilon 6899 for point_i in range(points_num): 6900 if time+1>=first_tstep[point_i] and time+1<=last_tstep[point_i]: 6901 x = unpack('f',f.read(4))[0] 6902 #print time, x, q_time[time, point_i] 6903 if q == 'VA': x = -x # South is positive in MUX 6904 #print q+" q_time[%d, %d] = %f" %(time, point_i, 6905 #q_time[time, point_i]) 6906 assert abs(q_time[time, point_i]-x)<epsilon 6907 6908 f.close() 6909 6910 permutation = ensure_numeric([4,0,2]) 6911 6912 # Create ordering file 6913 # _, ordering_filename = tempfile.mkstemp('') 6914 # order_fid = open(ordering_filename, 'w') 6915 # order_fid.write('index, longitude, latitude\n') 6916 # for index in permutation: 6917 # order_fid.write('%d, %f, %f\n' %(index, 6918 # lat_long_points[index][1], 6919 # lat_long_points[index][0])) 6920 # order_fid.close() 6921 6922 # ------------------------------------- 6923 # Now read files back and check values 6924 weights = ensure_numeric([1.0]) 6925 6926 # For each quantity read the associated list of source mux2 file with 6927 # extention associated with that quantity 6928 file_params=-1*num.ones(3,num.float) # [nsta,dt,nt] 6929 OFFSET = 5 6930 6931 for j, file in enumerate(filesII): 6932 # Read stage, u, v enumerated as j 6933 #print 'Reading', j, file 6934 #print "file", file 6935 data = read_mux2(1, [file], weights, file_params, 6936 permutation, verbose) 6937 #print str(j) + "data", data 6938 6939 #print 'Data received by Python' 6940 #print data[1][8] 6941 number_of_selected_stations = data.shape[0] 6942 #print "number_of_selected_stations", number_of_selected_stations 6943 #print "stations", stations 6944 6945 # Index where data ends and parameters begin 6946 parameters_index = data.shape[1]-OFFSET 6947 6948 for i in range(number_of_selected_stations): 6949 6950 #print i, parameters_index 6951 if j == 0: 6952 assert num.allclose(data[i][:parameters_index], 6953 ha1[permutation[i], :]) 6954 6955 if j == 1: assert num.allclose(data[i][:parameters_index], ua1[permutation[i], :]) 6956 if j == 2: 6678 6957 assert num.allclose(data[i][:parameters_index], -va1[permutation[i], :]) 6679 6958 6959 self.delete_mux(filesII) 6680 6960 6681 6961 def test_urs2sts0(self): … … 6819 7099 6820 7100 base_name, files = self.write_mux2(lat_long_points, 6821 time_step_count, time_step,6822 first_tstep, last_tstep,6823 depth=gauge_depth,6824 ha=ha,6825 ua=ua,6826 va=va)7101 time_step_count, time_step, 7102 first_tstep, last_tstep, 7103 depth=gauge_depth, 7104 ha=ha, 7105 ua=ua, 7106 va=va) 6827 7107 6828 7108 urs2sts(base_name, … … 6850 7130 y = points[:,1] 6851 7131 6852 # Check that all coordinate are correctly represented6853 # Using the non standard projection (50)7132 # Check that all coordinate are correctly represented 7133 # Using the non standard projection (50) 6854 7134 for i in range(4): 6855 7135 zone, e, n = redfearn(lat_long_points[i][0], … … 6858 7138 assert num.allclose([x[i],y[i]], [e,n]) 6859 7139 assert zone==-1 7140 7141 self.delete_mux(files) 6860 7142 6861 7143 … … 6915 7197 y = points[:,1] 6916 7198 6917 # Check that all coordinate are correctly represented6918 # Using the non standard projection (50)7199 # Check that all coordinate are correctly represented 7200 # Using the non standard projection (50) 6919 7201 for i in range(4): 6920 7202 zone, e, n = redfearn(lat_long_points[i][0], lat_long_points[i][1], … … 6922 7204 assert num.allclose([x[i],y[i]], [e,n]) 6923 7205 assert zone==geo_reference.zone 7206 7207 self.delete_mux(files) 6924 7208 6925 7209 … … 7652 7936 raise Exception, msg 7653 7937 7938 7939 self.delete_mux(filesI) 7940 self.delete_mux(filesII) 7654 7941 7655 7942 … … 8034 8321 os.remove(sts_file) 8035 8322 8036 8037 8038 8323 #---------------------- 8039 8324 # Then read the mux files together and test … … 8148 8433 os.remove(sts_file) 8149 8434 8150 8151 8152 8435 #--------------- 8153 8436 # "Manually" add the timeseries up with weights and test … … 8157 8440 stage_man = weights[0]*(stage0-tide) + weights[1]*(stage1-tide) + tide 8158 8441 assert num.allclose(stage_man, stage) 8159 8160 8161 8162 8163 8164 8442 8165 8443 … … 8288 8566 8289 8567 assert num.allclose(domain_fbound.quantities['xmomentum'].vertex_values, 8290 domain_drchlt.quantities['xmomentum'].vertex_values) 8568 domain_drchlt.quantities['xmomentum'].vertex_values) 8291 8569 8292 8570 assert num.allclose(domain_fbound.quantities['ymomentum'].vertex_values, 8293 domain_drchlt.quantities['ymomentum'].vertex_values) 8571 domain_drchlt.quantities['ymomentum'].vertex_values) 8294 8572 8295 8573 8296 8574 os.remove(sts_file+'.sts') 8297 8575 os.remove(meshname) 8298 8299 8300 8301 8576 8302 8577 … … 8419 8694 8420 8695 8421 8422 8423 8424 8425 8426 8427 8428 8696 domain_drchlt = Domain(meshname) 8429 8697 domain_drchlt.set_quantity('stage', tide) … … 8447 8715 8448 8716 assert num.allclose(domain_fbound.quantities['xmomentum'].vertex_values, 8449 domain_drchlt.quantities['xmomentum'].vertex_values) 8717 domain_drchlt.quantities['xmomentum'].vertex_values) 8450 8718 8451 8719 assert num.allclose(domain_fbound.quantities['ymomentum'].vertex_values, 8452 domain_drchlt.quantities['ymomentum'].vertex_values) 8453 8720 domain_drchlt.quantities['ymomentum'].vertex_values) 8454 8721 8455 8722 os.remove(sts_file+'.sts') 8456 8723 os.remove(meshname) 8457 8458 8459 8460 8724 8461 8725 … … 10934 11198 domain.set_quantity('xmomentum', uh) 10935 11199 domain.set_boundary( {'left': Bd, 'right': Bd, 'top': Br, 'bottom': Br}) 11200 10936 11201 for t in domain.evolve(yieldstep=1, finaltime = t_end): 10937 11202 pass … … 11357 11622 11358 11623 11624 def test_copy_code_files(self): 11625 '''test that the copy_code_files() function is sane.''' 11626 11627 def create_file(f): 11628 fd = open(f, 'w') 11629 fd.write('%s\n' % f) 11630 fd.close() 11631 11632 # create working directories and test files 11633 work_dir = tempfile.mkdtemp() 11634 dst_dir = tempfile.mkdtemp(dir=work_dir) 11635 src_dir = tempfile.mkdtemp(dir=work_dir) 11636 11637 f1 = 'file1' 11638 filename1 = os.path.join(src_dir, f1) 11639 create_file(filename1) 11640 f2 = 'file2' 11641 filename2 = os.path.join(src_dir, f2) 11642 create_file(filename2) 11643 f3 = 'file3' 11644 filename3 = os.path.join(src_dir, f3) 11645 create_file(filename3) 11646 f4 = 'file4' 11647 filename4 = os.path.join(src_dir, f4) 11648 create_file(filename4) 11649 f5 = 'file5' 11650 filename5 = os.path.join(src_dir, f5) 11651 create_file(filename5) 11652 11653 # exercise the copy function 11654 copy_code_files(dst_dir, filename1) 11655 copy_code_files(dst_dir, filename1, filename2) 11656 copy_code_files(dst_dir, (filename4, filename5, filename3)) 11657 11658 # test that files were actually copied 11659 self.failUnless(access(os.path.join(dst_dir, f1), F_OK)) 11660 self.failUnless(access(os.path.join(dst_dir, f2), F_OK)) 11661 self.failUnless(access(os.path.join(dst_dir, f3), F_OK)) 11662 self.failUnless(access(os.path.join(dst_dir, f4), F_OK)) 11663 self.failUnless(access(os.path.join(dst_dir, f5), F_OK)) 11664 11665 # clean up 11666 shutil.rmtree(work_dir) 11359 11667 11360 11668 #------------------------------------------------------------- … … 11362 11670 if __name__ == "__main__": 11363 11671 suite = unittest.makeSuite(Test_Data_Manager,'test') 11364 11365 # FIXME (Ole): This is the test that fails under Windows11366 #suite = unittest.makeSuite(Test_Data_Manager,'test_read_mux_platform_problem2')11367 #suite = unittest.makeSuite(Test_Data_Manager,'test_file_boundary_stsIV')11368 11672 11369 11673 if len(sys.argv) > 1 and sys.argv[1][0].upper() == 'V': -
branches/numpy/anuga/shallow_water/test_shallow_water_domain.py
r6689 r6902 27 27 def linear_function(point): 28 28 point = num.array(point) 29 return point[:,0] + point[:,1] 30 29 return point[:,0]+point[:,1] 31 30 32 31 class Weir: 33 32 """Set a bathymetry for weir with a hole and a downstream gutter 34 35 33 x,y are assumed to be in the unit square 36 34 """ … … 45 43 z = num.zeros(N, num.float) 46 44 for i in range(N): 47 z[i] = -x[i] / 2 #General slope48 49 # 45 z[i] = -x[i]/2 #General slope 46 47 #Flattish bit to the left 50 48 if x[i] < 0.3: 51 49 z[i] = -x[i]/10 52 50 53 # 51 #Weir 54 52 if x[i] >= 0.3 and x[i] < 0.4: 55 53 z[i] = -x[i]+0.9 56 54 57 # 55 #Dip 58 56 x0 = 0.6 59 57 depth = -1.0 … … 62 60 if x[i] > x0 and x[i] < 0.9: 63 61 z[i] = depth 64 # 62 #RHS plateaux 65 63 if x[i] >= 0.9: 66 64 z[i] = plateaux 67 65 elif y[i] >= 0.7 and y[i] < 1.5: 68 # 66 #Restrict and deepen 69 67 if x[i] >= x0 and x[i] < 0.8: 70 68 z[i] = depth - (y[i]/3 - 0.3) 71 69 elif x[i] >= 0.8: 72 # 70 #RHS plateaux 73 71 z[i] = plateaux 74 72 elif y[i] >= 1.5: 75 73 if x[i] >= x0 and x[i] < 0.8 + (y[i]-1.5)/1.2: 76 # 77 z[i] = depth -1.5/578 elif x[i] >= 0.8 + (y[i] -1.5)/1.2:79 # 74 #Widen up and stay at constant depth 75 z[i] = depth-1.5/5 76 elif x[i] >= 0.8 + (y[i]-1.5)/1.2: 77 #RHS plateaux 80 78 z[i] = plateaux 81 79 82 # 80 #Hole in weir (slightly higher than inflow condition) 83 81 if x[i] >= 0.3 and x[i] < 0.4 and y[i] > 0.2 and y[i] < 0.4: 84 z[i] = -x[i] +self.inflow_stage + 0.0285 86 # 82 z[i] = -x[i]+self.inflow_stage + 0.02 83 84 #Channel behind weir 87 85 x0 = 0.5 88 86 if x[i] >= 0.4 and x[i] < x0 and y[i] > 0.2 and y[i] < 0.4: 89 z[i] = -x[i] +self.inflow_stage + 0.0287 z[i] = -x[i]+self.inflow_stage + 0.02 90 88 91 89 if x[i] >= x0 and x[i] < 0.6 and y[i] > 0.2 and y[i] < 0.4: 92 # 93 z[i] = -x0 + self.inflow_stage + 0.02 + (x0 -x[i])/590 #Flatten it out towards the end 91 z[i] = -x0+self.inflow_stage + 0.02 + (x0-x[i])/5 94 92 95 93 # Hole to the east … … 97 95 y0 = 0.35 98 96 if num.sqrt((2*(x[i]-x0))**2 + (2*(y[i]-y0))**2) < 0.2: 99 z[i] = num.sqrt(( x[i]-x0)**2 + (y[i]-y0)**2) -1.0100 101 # 97 z[i] = num.sqrt(((x[i]-x0))**2 + ((y[i]-y0))**2)-1.0 98 99 #Tiny channel draining hole 102 100 if x[i] >= 1.14 and x[i] < 1.2 and y[i] >= 0.4 and y[i] < 0.6: 103 z[i] = -0.9 #North south101 z[i] = -0.9 #North south 104 102 105 103 if x[i] >= 0.9 and x[i] < 1.18 and y[i] >= 0.58 and y[i] < 0.65: 106 z[i] = -1.0 + (x[i]-0.9)/3 #East west104 z[i] = -1.0 + (x[i]-0.9)/3 #East west 107 105 108 106 # Stuff not in use … … 136 134 z = num.zeros(N, num.float) 137 135 for i in range(N): 138 z[i] = -x[i] #General slope139 140 # 136 z[i] = -x[i] #General slope 137 138 #Flat bit to the left 141 139 if x[i] < 0.3: 142 z[i] = -x[i]/10 #General slope143 144 # 140 z[i] = -x[i]/10 #General slope 141 142 #Weir 145 143 if x[i] > 0.3 and x[i] < 0.4: 146 z[i] = -x[i] +0.9147 148 # 144 z[i] = -x[i]+0.9 145 146 #Dip 149 147 if x[i] > 0.6 and x[i] < 0.9: 150 z[i] = -x[i] - 0.5 #-y[i]/5151 152 # 148 z[i] = -x[i]-0.5 #-y[i]/5 149 150 #Hole in weir (slightly higher than inflow condition) 153 151 if x[i] > 0.3 and x[i] < 0.4 and y[i] > 0.2 and y[i] < 0.4: 154 z[i] = -x[i] + self.inflow_stage + 0.05 152 z[i] = -x[i]+self.inflow_stage + 0.05 153 155 154 156 155 return z/2 … … 170 169 171 170 N = len(x) 172 s = 0 * x #New array171 s = 0*x #New array 173 172 174 173 for k in range(N): … … 263 262 H0 = 0.0 264 263 265 max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux,266 267 268 assert num.allclose(edgeflux, [0, 0,0])264 265 max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0) 266 267 assert num.allclose(edgeflux, [0,0,0]) 269 268 assert max_speed == 0. 270 269 … … 272 271 w = 2.0 273 272 274 normal = num.array([1., 273 normal = num.array([1.,0]) 275 274 ql = num.array([w, 0, 0]) 276 275 qr = num.array([w, 0, 0]) … … 280 279 H0 = 0.0 281 280 282 max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, 283 epsilon, g, H0) 284 281 max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0) 285 282 assert num.allclose(edgeflux, [0., 0.5*g*h**2, 0.]) 286 283 assert max_speed == num.sqrt(g*h) … … 290 287 # w = 2.0 291 288 # 292 # normal = array([1., 289 # normal = array([1.,0]) 293 290 # ql = array([w, 0, 0]) 294 291 # qr = array([w, 0, 0]) … … 1517 1514 uh = u*h 1518 1515 1519 Br = Reflective_boundary(domain) # Side walls 1520 Bd = Dirichlet_boundary([w, uh, 0]) # 2 m/s across the 3 m inlet: 1516 Br = Reflective_boundary(domain) # Side walls 1517 Bd = Dirichlet_boundary([w, uh, 0]) # 2 m/s across the 3 m inlet: 1518 1521 1519 1522 1520 # Initial conditions -
branches/numpy/anuga/shallow_water/urs_ext.c
r6780 r6902 104 104 memcpy(data + it, muxData + offset, sizeof(float)); 105 105 106 //printf("%d: muxdata=%f\n", it, muxData[offset]); 107 //printf("data[%d]=%f, offset=%d\n", it, data[it], offset); 106 //printf("%d: muxdata=%f\n", it, muxData[offset]); 107 //printf("data[%d]=%f, offset=%d\n", it, data[it], offset); 108 108 offset++; 109 109 } … … 221 221 222 222 // Open the mux file 223 if((fp = fopen(muxFileName, "r ")) == NULL)223 if((fp = fopen(muxFileName, "rb")) == NULL) 224 224 { 225 225 char *err_msg = strerror(errno); … … 237 237 } 238 238 239 fros = (int*) malloc(*total_number_of_stations*numSrc*sizeof(int)); 239 fros = (int*) malloc(*total_number_of_stations*numSrc*sizeof(int)); 240 240 lros = (int*) malloc(*total_number_of_stations*numSrc*sizeof(int)); 241 241 … … 447 447 temp_sts_data = (float*) calloc(len_sts_data, sizeof(float)); 448 448 449 muxData = (float*) malloc(numDataMax*sizeof(float));449 muxData = (float*) calloc(numDataMax, sizeof(float)); 450 450 451 451 // Loop over all sources … … 460 460 // Read in data block from mux2 file 461 461 muxFileName = muxFileNameArray[isrc]; 462 if((fp = fopen(muxFileName, "r ")) == NULL)462 if((fp = fopen(muxFileName, "rb")) == NULL) 463 463 { 464 464 fprintf(stderr, "cannot open file %s\n", muxFileName); … … 470 470 } 471 471 472 offset = sizeof(int) + total_number_of_stations*(sizeof(struct tgsrwg) + 2*sizeof(int)); 473 fseek(fp, offset, 0); 472 offset = (long int)sizeof(int) + total_number_of_stations*(sizeof(struct tgsrwg) + 2*sizeof(int)); 473 //printf("\n offset %i ", (long int)offset); 474 fseek(fp, offset, 0); 474 475 475 476 numData = getNumData(fros_per_source, 476 477 lros_per_source, 477 478 total_number_of_stations); 478 479 480 481 elements_read = fread(muxData, ((int) numData)*sizeof(float), 1, fp); 479 // Note numData is larger than what it has to be. 480 //elements_read = fread(muxData, ((int) numData)*sizeof(float), 1, fp); 481 elements_read = fread(muxData, (size_t) sizeof(float), (size_t) numData, fp); 482 //printf("\n elements_read %d, ", (int)elements_read); 483 //printf("\n ferror(fp) %d, ", (int)ferror(fp)); 482 484 if ((int) elements_read == 0 && ferror(fp)) { 483 485 fprintf(stderr, "Error reading mux data\n"); 484 486 return NULL; 485 } 486 487 fclose(fp); 487 } 488 488 489 490 // FIXME (Ole): This is where Nariman and Ole traced the platform dependent 491 // difference on 11 November 2008. We don't think the problem lies in the 492 // C code. Maybe it is a problem with the MUX files written by the unit test 493 // that fails on Windows but works OK on Linux. JJ's test on 17th November shows 494 // that as far as Python is concerned this file should be OK on both platforms. 495 496 497 498 // These printouts are enough to show the problem when compared 499 // on the two platforms 500 //printf("\nRead %d elements, ", (int) numData); 501 //printf("muxdata[%d]=%f\n", 39, muxData[39]); 502 503 504 /* 505 In Windows we get 506 507 Read 85 elements, muxdata[39]=0.999574 508 Read 85 elements, muxdata[39]=-0.087599 509 Read 85 elements, muxdata[39]=-0.087599 510 511 512 In Linux we get (the correct) 513 514 Read 85 elements, muxdata[39]=0.999574 515 Read 85 elements, muxdata[39]=-0.087599 516 Read 85 elements, muxdata[39]=1.490349 517 */ 518 519 520 521 489 fclose(fp); 522 490 523 491 // loop over stations present in the permutation array -
branches/numpy/anuga/utilities/log.py
r6888 r6902 60 60 NOTSET = logging.NOTSET 61 61 62 # get True if python version 2.5 or later 63 (version_major, version_minor, _, _, _) = sys.version_info 64 new_python = ((version_major == 2 and version_minor >= 5) or version_major > 2) 65 62 66 63 67 ################################################################################ … … 79 83 global _setup, log_logging_level 80 84 81 # get running python version for later82 (version_major, version_minor, _, _, _) = sys.version_info83 84 85 # have we been setup? 85 86 if not _setup: … … 89 90 90 91 # setup the file logging system 91 if version_major >= 2 and version_minor >= 5:92 if new_python: 92 93 fmt = '%(asctime)s %(levelname)-8s %(mname)25s:%(lnum)-4d|%(message)s' 93 94 else: … … 109 110 logging.getLevelName(log_logging_level), 110 111 logging.getLevelName(console_logging_level))) 111 if version_major >= 2 and version_minor >= 5:112 if new_python: 112 113 logging.log(logging.CRITICAL, start_msg, 113 114 extra={'mname': __name__, 'lnum': 0}) … … 127 128 break 128 129 129 if version_major >= 2 and version_minor >= 5:130 if new_python: 130 131 logging.log(level, msg, extra={'mname': fname, 'lnum': lnum}) 131 132 else: … … 139 140 # @brief Shortcut for log(DEBUG, msg). 140 141 # @param msg Message string to log at logging.DEBUG level. 141 def debug(msg ):142 def debug(msg=''): 142 143 log(logging.DEBUG, msg) 143 144 … … 145 146 # @brief Shortcut for log(INFO, msg). 146 147 # @param msg Message string to log at logging.INFO level. 147 def info(msg ):148 def info(msg=''): 148 149 log(logging.INFO, msg) 149 150 … … 151 152 # @brief Shortcut for log(WARNING, msg). 152 153 # @param msg Message string to log at logging.WARNING level. 153 def warning(msg ):154 def warning(msg=''): 154 155 log(logging.WARNING, msg) 155 156 … … 157 158 # @brief Shortcut for log(ERROR, msg). 158 159 # @param msg Message string to log at logging.ERROR level. 159 def error(msg ):160 def error(msg=''): 160 161 log(logging.ERROR, msg) 161 162 … … 163 164 # @brief Shortcut for log(CRITICAL, msg). 164 165 # @param msg Message string to log at logging.CRITICAL level. 165 def critical(msg ):166 def critical(msg=''): 166 167 log(logging.CRITICAL, msg) 167 168 … … 219 220 else: 220 221 pass 221 222 if __name__ == "__main__":223 debug('DEBUG message')224 info('INFO message')225 warning('WARNING message') -
branches/numpy/anuga/utilities/log_test.py
r6702 r6902 27 27 28 28 def tearDown(self): 29 pass 30 # if os.path.exists(LOGFILE_NAME): 31 # os.remove(LOGFILE_NAME) 32 # if os.path.exists(STDOUT_LOG_NAME): 33 # os.remove(STDOUT_LOG_NAME) 29 if os.path.exists(LOGFILE_NAME): 30 os.remove(LOGFILE_NAME) 31 if os.path.exists(STDOUT_LOG_NAME): 32 os.remove(STDOUT_LOG_NAME) 34 33 35 34 ##
Note: See TracChangeset
for help on using the changeset viewer.