Changeset 9018
- Timestamp:
- Nov 8, 2013, 8:45:50 PM (11 years ago)
- Location:
- trunk/anuga_core/source/anuga
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/anuga_core/source/anuga/file/sww.py
r8810 r9018 71 71 self.recursion = recursion 72 72 self.mode = mode 73 73 74 if hasattr(domain, 'max_size'): 74 75 self.max_size = domain.max_size # File size max is 2Gig 75 76 else: 76 77 self.max_size = max_size 78 79 if hasattr(domain, 'store_centroids'): 80 self.store_centroids = domain.store_centroids 81 else: 82 self.store_centroids = False 83 77 84 if hasattr(domain, 'minimum_storable_height'): 78 85 self.minimum_storable_height = domain.minimum_storable_height … … 105 112 'suitable for plotting' 106 113 107 self.writer = Write_sww(static_quantities, dynamic_quantities )114 self.writer = Write_sww(static_quantities, dynamic_quantities, store_centroids=self.store_centroids) 108 115 self.writer.store_header(fid, 109 116 domain.starttime, … … 194 201 # Get names of static quantities 195 202 static_quantities = {} 203 static_quantities_centroid = {} 196 204 for name in self.writer.static_quantities: 197 205 Q = domain.quantities[name] … … 199 207 precision=self.precision) 200 208 static_quantities[name] = A 209 210 if self.store_centroids: 211 static_quantities_centroid[name] = Q.centroid_values 201 212 202 213 # Store static quantities 203 214 self.writer.store_static_quantities(fid, **static_quantities) 204 215 216 if self.store_centroids: 217 self.writer.store_static_quantities_centroid(fid, **static_quantities_centroid) 218 205 219 fid.close() 206 220 … … 319 333 # Now store dynamic quantities 320 334 dynamic_quantities = {} 335 dynamic_quantities_centroid = {} 336 321 337 for name in self.writer.dynamic_quantities: 322 338 #netcdf_array = fid.variables[name] … … 341 357 dynamic_quantities[name] = A 342 358 359 if self.store_centroids: 360 dynamic_quantities_centroid[name] = Q.centroid_values 361 343 362 344 363 # Store dynamic quantities 345 s elf.writer.store_quantities(fid,364 slice_index = self.writer.store_quantities(fid, 346 365 time=self.domain.time, 347 366 sww_precision=self.precision, 348 367 **dynamic_quantities) 368 369 # Store dynamic quantities 370 if self.store_centroids: 371 self.writer.store_quantities_centroid(fid, 372 slice_index= slice_index, 373 sww_precision=self.precision, 374 **dynamic_quantities_centroid) 349 375 350 376 … … 430 456 431 457 for q in filter(lambda n:n != 'x' and n != 'y' and n != 'time' and n != 'volumes' and \ 432 '_range' not in n , \458 '_range' not in n and '_c' not in n , \ 433 459 fin.variables.keys()): 460 #print q 434 461 if len(fin.variables[q].shape) == 1: # Not a time-varying quantity 435 462 self.quantities[q] = num.ravel(num.array(fin.variables[q], num.float)).reshape(M,3) … … 466 493 """ 467 494 468 def __init__(self, static_quantities, dynamic_quantities ):495 def __init__(self, static_quantities, dynamic_quantities, store_centroids=False): 469 496 """Initialise Write_sww with two list af quantity names: 470 497 … … 479 506 self.static_quantities = static_quantities 480 507 self.dynamic_quantities = dynamic_quantities 508 self.store_centroids = store_centroids 481 509 482 510 … … 577 605 outfile.createVariable(q + Write_sww.RANGE, sww_precision, 578 606 ('numbers_in_range',)) 607 608 if self.store_centroids: 609 outfile.createVariable(q + '_c', sww_precision, 610 ('number_of_volumes',)) 579 611 580 612 # Initialise ranges with small and large sentinels. … … 702 734 703 735 736 def write_dynamic_quantities(self, outfile, quantities, 737 times, precis = netcdf_float32, verbose = False): 738 """ 739 Write out given quantities to file. 740 """ 741 742 743 for q in quantities: 744 outfile.createVariable(q, precis, ('number_of_timesteps', 745 'number_of_points')) 746 outfile.createVariable(q + Write_sts.RANGE, precis, 747 ('numbers_in_range',)) 748 749 if self.store_centroids: 750 outfile.createVariable(q + '_c', precis, 751 ('number_of_timesteps','number_of_volumes')) 752 753 # Initialise ranges with small and large sentinels. 754 # If this was in pure Python we could have used None sensibly 755 outfile.variables[q+Write_sts.RANGE][0] = max_float # Min 756 outfile.variables[q+Write_sts.RANGE][1] = -max_float # Max 757 758 # Doing sts_precision instead of Float gives cast errors. 759 outfile.createVariable('time', netcdf_float, ('number_of_timesteps',)) 760 761 if isinstance(times, (list, num.ndarray)): 762 outfile.variables['time'][:] = times # Store time relative 763 764 if verbose: 765 log.critical('------------------------------------------------') 766 log.critical('Statistics:') 767 log.critical(' t in [%f, %f], len(t) == %d' 768 % (num.min(times), num.max(times), len(times.flat))) 704 769 705 770 def store_parallel_data(self, … … 795 860 796 861 797 862 863 def store_static_quantities_centroid(self, 864 outfile, 865 sww_precision=num.float32, 866 verbose=False, 867 **quant): 868 """ 869 Write the static centroid quantity info. 870 871 **quant is extra keyword arguments passed in. These must be 872 the numpy arrays to be stored in the sww file at each timestep. 873 874 The argument sww_precision allows for storing as either 875 * single precision (default): num.float32 876 * double precision: num.float64 or num.float 877 878 Precondition: 879 store_triangulation and 880 store_header have been called. 881 """ 882 883 # The dictionary quant must contain numpy arrays for each name. 884 # These will typically be quantities from Domain such as friction 885 # 886 # Arrays not listed in static_quantitiues will be ignored, silently. 887 # 888 # This method will also write the ranges for each quantity, 889 # e.g. stage_range, xmomentum_range and ymomentum_range 890 for q in self.static_quantities: 891 if not quant.has_key(q): 892 msg = 'Values for quantity %s was not specified in ' % q 893 msg += 'store_quantities so they cannot be stored.' 894 raise NewQuantity, msg 895 else: 896 q_values = ensure_numeric(quant[q]) 897 898 x = q_values.astype(sww_precision) 899 outfile.variables[q+'_c'][:] = x 900 901 902 903 798 904 799 905 def store_quantities(self, … … 862 968 if q_values_max > q_range[1]: 863 969 outfile.variables[q + Write_sww.RANGE][1] = q_values_max 864 970 971 return slice_index 972 973 974 975 def store_quantities_centroid(self, 976 outfile, 977 sww_precision=num.float32, 978 slice_index=None, 979 verbose=False, 980 **quant): 981 """ 982 Write the quantity centroid info at each timestep. 983 984 **quant is extra keyword arguments passed in. These must be 985 the numpy arrays to be stored in the sww file at each timestep. 986 987 if the time array is already been built, use the slice_index 988 to specify the index. 989 990 Otherwise, use time to increase the time dimension 991 992 Maybe make this general, but the viewer assumes these quantities, 993 so maybe we don't want it general - unless the viewer is general 994 995 The argument sww_precision allows for storing as either 996 * single precision (default): num.float32 997 * double precision: num.float64 or num.float 998 999 Precondition: 1000 store_triangulation and 1001 store_header have been called. 1002 """ 1003 1004 assert slice_index is not None, 'slice_index should be set in store_quantities' 1005 1006 1007 # Write the named dynamic quantities 1008 # The dictionary quant must contain numpy arrays for each name. 1009 # These will typically be the conserved quantities from Domain 1010 # (Typically stage, xmomentum, ymomentum). 1011 # 1012 # Arrays not listed in dynamic_quantitiues will be ignored, silently. 1013 # 1014 # This method will also write the ranges for each quantity, 1015 # e.g. stage_range, xmomentum_range and ymomentum_range 1016 for q in self.dynamic_quantities: 1017 if not quant.has_key(q): 1018 msg = 'Values for quantity %s was not specified in ' % q 1019 msg += 'store_quantities so they cannot be stored.' 1020 raise NewQuantity, msg 1021 else: 1022 q_values = ensure_numeric(quant[q]) 1023 1024 q_retyped = q_values.astype(sww_precision) 1025 outfile.variables[q+'_c'][slice_index] = q_retyped 865 1026 866 1027 … … 947 1108 # or concatenate((x[:,num.newaxis], x[:,num.newaxis]), axis=1) 948 1109 949 conserved_quantities = []1110 dynamic_quantities = [] 950 1111 interpolated_quantities = {} 951 other_quantities = []1112 static_quantities = [] 952 1113 953 1114 # get geo_reference … … 962 1123 dimensions = fid.variables[quantity].dimensions 963 1124 if 'number_of_timesteps' in dimensions: 964 conserved_quantities.append(quantity)1125 dynamic_quantities.append(quantity) 965 1126 interpolated_quantities[quantity] = \ 966 1127 interpolated_quantity(fid.variables[quantity][:], time_interp) 967 1128 else: 968 other_quantities.append(quantity) 969 970 other_quantities.remove('x') 971 other_quantities.remove('y') 972 #other_quantities.remove('z') 973 other_quantities.remove('volumes') 1129 static_quantities.append(quantity) 1130 1131 #print static_quantities 1132 #print dynamic_quantities 1133 974 1134 try: 975 other_quantities.remove('stage_range')976 other_quantities.remove('xmomentum_range')977 other_quantities.remove('ymomentum_range')978 other_quantities.remove('elevation_range')1135 dynamic_quantities.remove('stage_c') 1136 dynamic_quantities.remove('xmomentum_c') 1137 dynamic_quantities.remove('ymomentum_c') 1138 dynamic_quantities.remove('elevation_c') 979 1139 except: 980 1140 pass 981 982 conserved_quantities.remove('time') 1141 1142 try: 1143 static_quantities.remove('elevation_c') 1144 except: 1145 pass 1146 1147 1148 static_quantities.remove('x') 1149 static_quantities.remove('y') 1150 #other_quantities.remove('z') 1151 static_quantities.remove('volumes') 1152 try: 1153 static_quantities.remove('stage_range') 1154 static_quantities.remove('xmomentum_range') 1155 static_quantities.remove('ymomentum_range') 1156 static_quantities.remove('elevation_range') 1157 except: 1158 pass 1159 1160 dynamic_quantities.remove('time') 983 1161 984 1162 if verbose: log.critical(' building domain') … … 999 1177 unique = True 1000 1178 if unique: 1001 coordinates, volumes, boundary = weed(coordinates, volumes, boundary)1179 coordinates, volumes, boundary = weed(coordinates, volumes, boundary) 1002 1180 1003 1181 … … 1016 1194 domain.geo_reference = geo_reference 1017 1195 1018 for quantity in other_quantities:1196 for quantity in static_quantities: 1019 1197 try: 1020 1198 NaN = fid.variables[quantity].missing_value … … 1041 1219 domain.set_quantity(quantity, X) 1042 1220 # 1043 for quantity in conserved_quantities:1221 for quantity in dynamic_quantities: 1044 1222 try: 1045 1223 NaN = fid.variables[quantity].missing_value -
trunk/anuga_core/source/anuga/file/test_read_sww.py
r8405 r9018 112 112 assert num.allclose(sww_file.y, domain.get_vertex_coordinates()[:,1]) 113 113 114 114 115 115 assert num.allclose(sww_file.time, [0.0, 1.0, 2.0, 3.0, 4.0]) 116 116 … … 179 179 os.remove(source) 180 180 181 def test_read_sww_with_centroids(self): 182 """ 183 Save to an sww file and then read back the info. 184 Here we store the info "uniquely" 185 """ 186 187 #--------------------------------------------------------------------- 188 # Import necessary modules 189 #--------------------------------------------------------------------- 190 from anuga.abstract_2d_finite_volumes.mesh_factory import \ 191 rectangular_cross 192 from anuga.shallow_water.shallow_water_domain import Domain 193 from boundaries import Reflective_boundary 194 from anuga.abstract_2d_finite_volumes.generic_boundary_conditions\ 195 import Dirichlet_boundary, Time_boundary 196 197 #--------------------------------------------------------------------- 198 # Setup computational domain 199 #--------------------------------------------------------------------- 200 length = 8. 201 width = 4. 202 dx = dy = 2 # Resolution: Length of subdivisions on both axes 203 204 inc = 0.05 # Elevation increment 205 206 points, vertices, boundary = rectangular_cross(int(length/dx), 207 int(width/dy), 208 len1=length, 209 len2=width) 210 domain = Domain(points, vertices, boundary) 211 domain.set_name('read_sww_test_c'+str(domain.processor)) # Output name 212 domain.set_quantities_to_be_stored({'elevation': 2, 213 'stage': 2, 214 'xmomentum': 2, 215 'ymomentum': 2, 216 'friction': 1}) 217 218 domain.set_store_vertices_uniquely(True) 219 domain.set_store_centroids(True) 220 221 #--------------------------------------------------------------------- 222 # Setup initial conditions 223 #--------------------------------------------------------------------- 224 domain.set_quantity('elevation', 0.0) # Flat bed initially 225 domain.set_quantity('friction', 0.01) # Constant friction 226 domain.set_quantity('stage', 0.0) # Dry initial condition 227 228 #------------------------------------------------------------------ 229 # Setup boundary conditions 230 #------------------------------------------------------------------ 231 Bi = Dirichlet_boundary([0.4, 0, 0]) # Inflow 232 Br = Reflective_boundary(domain) # Solid reflective wall 233 Bo = Dirichlet_boundary([-5, 0, 0]) # Outflow 234 235 domain.set_boundary({'left': Bi, 'right': Bo, 'top': Br, 'bottom': Br}) 236 237 #------------------------------------------------------------------- 238 # Evolve system through time 239 #------------------------------------------------------------------- 240 241 for t in domain.evolve(yieldstep=1, finaltime=4.0): 242 pass 243 244 245 # Check that quantities have been stored correctly 246 source = domain.get_name() + '.sww' 247 248 249 #x = fid.variables['x'][:] 250 #y = fid.variables['y'][:] 251 #stage = fid.variables['stage'][:] 252 #elevation = fid.variables['elevation'][:] 253 #fid.close() 254 255 #assert len(stage.shape) == 2 256 #assert len(elevation.shape) == 2 257 258 #M, N = stage.shape 259 260 sww_file = sww.Read_sww(source) 261 262 #print 'last frame number',sww_file.get_last_frame_number() 263 264 assert num.allclose(sww_file.x, domain.get_vertex_coordinates()[:,0]) 265 assert num.allclose(sww_file.y, domain.get_vertex_coordinates()[:,1]) 266 267 268 assert num.allclose(sww_file.time, [0.0, 1.0, 2.0, 3.0, 4.0]) 269 270 M = domain.get_number_of_triangles() 271 272 assert num.allclose(num.reshape(num.arange(3*M), (M,3)), sww_file.vertices) 273 274 last_frame_number = sww_file.get_last_frame_number() 275 assert last_frame_number == 4 276 277 assert num.allclose(sww_file.get_bounds(), [0.0, length, 0.0, width]) 278 279 assert 'stage' in sww_file.quantities.keys() 280 assert 'friction' in sww_file.quantities.keys() 281 assert 'elevation' in sww_file.quantities.keys() 282 assert 'xmomentum' in sww_file.quantities.keys() 283 assert 'ymomentum' in sww_file.quantities.keys() 284 285 286 for qname, q in sww_file.read_quantities(last_frame_number).items(): 287 assert num.allclose(domain.get_quantity(qname).get_values(), q) 288 289 #----------------------------------------- 290 # Start the evolution off again at frame 3 291 #----------------------------------------- 292 sww_file.read_quantities(last_frame_number-1) 293 294 points, vertices, boundary = rectangular_cross(int(length/dx), 295 int(width/dy), 296 len1=length, 297 len2=width) 298 new_domain = Domain(points, vertices, boundary) 299 new_domain.set_quantities_to_be_stored(None) 300 301 new_domain.set_store_vertices_uniquely(True) 302 303 for qname, q in sww_file.read_quantities(last_frame_number-1).items(): 304 new_domain.set_quantity(qname, q) 305 306 #------------------------------------------------------------------ 307 # Setup boundary conditions 308 #------------------------------------------------------------------ 309 Bi = Dirichlet_boundary([0.4, 0, 0]) # Inflow 310 Br = Reflective_boundary(new_domain) # Solid reflective wall 311 Bo = Dirichlet_boundary([-5, 0, 0]) # Outflow 312 313 new_domain.set_boundary({'left': Bi, 'right': Bo, 'top': Br, 'bottom': Br}) 314 315 #------------------------------------------------------------------- 316 # Evolve system through time 317 #------------------------------------------------------------------- 318 319 for t in new_domain.evolve(yieldstep=1.0, finaltime=1.0): 320 pass 321 322 # Compare new_domain and domain quantities 323 for quantity in domain.get_quantity_names(): 324 dv = domain.get_quantity(quantity).get_values() 325 ndv = new_domain.get_quantity(quantity).get_values() 326 327 #print dv-ndv 328 329 assert num.allclose( dv, ndv, rtol=5.e-2, atol=5.e-2) 330 331 # Clean up 332 #os.remove(source) 333 181 334 182 335 if __name__ == "__main__": -
trunk/anuga_core/source/anuga/file/test_sww.py
r8780 r9018 460 460 if __name__ == "__main__": 461 461 suite = unittest.makeSuite(Test_sww, 'test') 462 runner = unittest.TextTestRunner(verbosity= 1)462 runner = unittest.TextTestRunner(verbosity=2) 463 463 runner.run(suite) -
trunk/anuga_core/source/anuga/shallow_water/shallow_water_domain.py
r9003 r9018 208 208 #------------------------------- 209 209 self.set_store(True) 210 self.set_store_centroids(False) 210 211 self.set_store_vertices_uniquely(False) 211 212 self.quantities_to_be_stored = {'elevation': 1, … … 213 214 'xmomentum': 2, 214 215 'ymomentum': 2} 215 216 217 218 216 219 217 #------------------------------- … … 231 229 def set_defaults(self): 232 230 """Set the default values in this routine. That way we can inherit class 233 and just overredefine the defaults for the new class231 and just redefine the defaults for the new class 234 232 """ 235 233 … … 451 449 return self.store 452 450 451 452 def set_store_centroids(self, flag=True): 453 """Set whether centroid data is saved to sww file. 454 """ 455 456 self.store_centroids = flag 457 458 def get_store_centroids(self): 459 """Get whether data saved to sww file. 460 """ 461 462 return self.store_centroids 463 464 453 465 454 466 def set_sloped_mannings_function(self, flag=True):
Note: See TracChangeset
for help on using the changeset viewer.