Changeset 4704
- Timestamp:
- Sep 5, 2007, 4:42:58 PM (18 years ago)
- Location:
- anuga_core/source/anuga
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
anuga_core/source/anuga/abstract_2d_finite_volumes/domain.py
r4702 r4704 26 26 from anuga.abstract_2d_finite_volumes.region\ 27 27 import Set_region as region_set_region 28 29 from anuga.utilities.polygon import inside_polygon 30 from anuga.abstract_2d_finite_volumes.util import get_textual_float 28 31 29 32 import types … … 205 208 self.monitor_polygon = None 206 209 self.monitor_time_interval = None 207 210 self.monitor_indices = None 208 211 209 212 # Checkpointing and storage … … 579 582 self.quantities_to_be_monitored = None 580 583 self.monitor_polygon = None 581 self.monitor_time_interval = None 584 self.monitor_time_interval = None 585 self.monitor_indices = None 582 586 return 583 587 … … 596 600 apply_expression_to_dictionary(quantity_name, self.quantities) 597 601 598 # Initialise extrema 599 self.quantities_to_be_monitored[quantity_name] = [None, None] 602 # Initialise extrema information 603 info_block = {'min': None, # Min value 604 'max': None, # Max value 605 'min_location': None, # Argmin (x, y) 606 'max_location': None, # Argmax (x, y) 607 'min_time': None, # Argmin (t) 608 'max_time': None} # Argmax (t) 600 609 610 self.quantities_to_be_monitored[quantity_name] = info_block 611 612 601 613 602 614 if polygon is not None: 603 # FIXME Check input 604 pass 615 # Check input 616 if isinstance(polygon, basestring): 617 618 # Check if multiple quantities were accidentally 619 # given as separate argument rather than a list. 620 msg = 'Multiple quantities must be specified in a list. ' 621 msg += 'Not as multiple arguments. ' 622 msg += 'I got "%s" as a second argument' %polygon 623 624 if polygon in self.quantities: 625 raise Exception, msg 626 627 try: 628 apply_expression_to_dictionary(polygon, self.quantities) 629 except: 630 # At least polygon wasn't an expression involving quantitites 631 pass 632 else: 633 raise Exception, msg 634 635 # In any case, we don't allow polygon to be a string 636 msg = 'argument "polygon" must not be a string: ' 637 msg += 'I got polygon=\'%s\' ' %polygon 638 raise Exception, msg 639 640 641 # Get indices for centroids that are inside polygon 642 points = self.get_centroid_coordinates(absolute=True) 643 self.monitor_indices = inside_polygon(points, polygon) 644 605 645 606 646 if time_interval is not None: 607 # FIXME Check input 608 pass 609 647 assert len(time_interval) == 2 610 648 611 649 … … 758 796 """ 759 797 760 # Input checks798 # Input checks 761 799 import types, string 762 800 … … 780 818 assert type(tags) == types.ListType, msg 781 819 782 # Determine width of longest quantity name (for cosmetic purposes)820 # Determine width of longest quantity name (for cosmetic purposes) 783 821 maxwidth = 0 784 822 for name in quantities: … … 787 825 maxwidth = w 788 826 789 # Output stats827 # Output stats 790 828 msg = 'Boundary values at time %.4f:\n' %self.time 791 829 for tag in tags: … … 795 833 q = self.quantities[name] 796 834 797 # Find range of boundary values for tag and q835 # Find range of boundary values for tag and q 798 836 maxval = minval = None 799 837 for i, ((vol_id, edge_id), B) in\ … … 815 853 816 854 817 818 def quantity_statistics(self): 855 def update_extrema(self): 856 """Update extrema if requested by set_quantities_to_be_monitored. 857 This data is used for reporting e.g. by running 858 print domain.quantity_statistics() 859 and may also stored in output files (see data_manager in shallow_water) 860 """ 861 862 if self.quantities_to_be_monitored is None: 863 return 864 865 # Observe time interval restriction if any 866 if self.monitor_time_interval is not None and\ 867 (self.time < self.monitor_time_interval[0] or\ 868 self.time > self.monitor_time_interval[1]): 869 return 870 871 872 # Update extrema for each specified quantity subject to 873 # polygon restriction (via monitor_indices). 874 for quantity_name in self.quantities_to_be_monitored: 875 876 if quantity_name in self.quantities: 877 Q = self.get_quantity(quantity_name) 878 else: 879 Q = self.create_quantity_from_expression(quantity_name) 880 881 info_block = self.quantities_to_be_monitored[quantity_name] 882 883 # Update maximum (n > None is always True) 884 maxval = Q.get_maximum_value(self.monitor_indices) 885 if maxval > info_block['max']: 886 info_block['max'] = maxval 887 maxloc = Q.get_maximum_location() 888 info_block['max_location'] = maxloc 889 info_block['max_time'] = self.time 890 891 892 # Update minimum (n < None is always False) 893 minval = Q.get_minimum_value(self.monitor_indices) 894 if info_block['min'] is None or\ 895 minval < info_block['min']: 896 info_block['min'] = minval 897 minloc = Q.get_minimum_location() 898 info_block['min_location'] = minloc 899 info_block['min_time'] = self.time 900 901 902 903 def quantity_statistics(self, precision = '%.4f'): 819 904 """Return string with statistics about quantities for printing or logging 820 905 … … 825 910 """ 826 911 827 pass 828 829 912 maxlen = 128 # Max length of polygon string representation 913 914 # Output stats 915 msg = 'Monitored quantities at time %.4f:\n' %self.time 916 if self.monitor_polygon is not None: 917 p_str = str(self.monitor_polygon) 918 msg += '- Restricted by polygon: %s' %p_str[:maxlen] 919 if len(p_str) >= maxlen: 920 msg += '...\n' 921 else: 922 msg += '\n' 923 924 925 if self.monitor_time_interval is not None: 926 msg += '- Restricted by time interval: %s\n' %str(self.monitor_time_interval) 927 time_interval_start = self.monitor_time_interval[0] 928 else: 929 time_interval_start = 0.0 930 931 932 for quantity_name, info in self.quantities_to_be_monitored.items(): 933 msg += ' %s:\n' %quantity_name 934 935 msg += ' values since time = %.2f in [%s, %s]\n'\ 936 %(time_interval_start, 937 get_textual_float(info['min'], precision), 938 get_textual_float(info['max'], precision)) 939 940 msg += ' minimum attained at time = %s, location = %s\n'\ 941 %(get_textual_float(info['min_time'], precision), 942 get_textual_float(info['min_location'], precision)) 943 944 945 msg += ' maximum attained at time = %s, location = %s\n'\ 946 %(get_textual_float(info['max_time'], precision), 947 get_textual_float(info['max_location'], precision)) 948 949 950 return msg 830 951 831 952 … … 902 1023 from anuga.config import min_timestep, max_timestep, epsilon 903 1024 904 # FIXME: Maybe lump into a larger check prior to evolving1025 # FIXME: Maybe lump into a larger check prior to evolving 905 1026 msg = 'Boundary tags must be bound to boundary objects before ' 906 1027 msg += 'evolving system, ' … … 920 1041 921 1042 if finaltime is not None and duration is not None: 922 # print 'F', finaltime, duration1043 # print 'F', finaltime, duration 923 1044 msg = 'Only one of finaltime and duration may be specified' 924 1045 raise msg … … 932 1053 933 1054 934 self.yieldtime = 0.0 # Time between 'yields'935 936 # Initialise interval of timestep sizes (for reporting only)1055 self.yieldtime = 0.0 # Track time between 'yields' 1056 1057 # Initialise interval of timestep sizes (for reporting only) 937 1058 self.min_timestep = max_timestep 938 1059 self.max_timestep = min_timestep … … 940 1061 self.number_of_first_order_steps = 0 941 1062 942 # update ghosts1063 # Update ghosts 943 1064 self.update_ghosts() 944 1065 945 # Initial update of vertex and edge values1066 # Initial update of vertex and edge values 946 1067 self.distribute_to_vertices_and_edges() 947 1068 948 #Initial update boundary values 1069 # Update extrema if necessary (for reporting) 1070 self.update_extrema() 1071 1072 # Initial update boundary values 949 1073 self.update_boundary() 950 1074 951 # Or maybe restore from latest checkpoint1075 # Or maybe restore from latest checkpoint 952 1076 if self.checkpoint is True: 953 1077 self.goto_latest_checkpoint() 954 1078 955 1079 if skip_initial_step is False: 956 yield(self.time) # Yield initial values1080 yield(self.time) # Yield initial values 957 1081 958 1082 while True: 959 # Compute fluxes across each element edge1083 # Compute fluxes across each element edge 960 1084 self.compute_fluxes() 961 1085 962 # Update timestep to fit yieldstep and finaltime1086 # Update timestep to fit yieldstep and finaltime 963 1087 self.update_timestep(yieldstep, finaltime) 964 1088 965 # Update conserved quantities1089 # Update conserved quantities 966 1090 self.update_conserved_quantities() 967 1091 968 # update ghosts1092 # Update ghosts 969 1093 self.update_ghosts() 970 1094 971 # Update vertex and edge values1095 # Update vertex and edge values 972 1096 self.distribute_to_vertices_and_edges() 973 1097 974 #Update boundary values 1098 # Update extrema if necessary (for reporting) 1099 self.update_extrema() 1100 1101 # Update boundary values 975 1102 self.update_boundary() 976 1103 977 # Update time1104 # Update time 978 1105 self.time += self.timestep 979 1106 self.yieldtime += self.timestep … … 982 1109 self.number_of_first_order_steps += 1 983 1110 984 # Yield results1111 # Yield results 985 1112 if finaltime is not None and self.time >= finaltime-epsilon: 986 1113 987 1114 if self.time > finaltime: 988 # FIXME (Ole, 30 April 2006): Do we need this check?1115 # FIXME (Ole, 30 April 2006): Do we need this check? 989 1116 print 'WARNING (domain.py): time overshot finaltime. Contact Ole.Nielsen@ga.gov.au' 990 1117 self.time = finaltime -
anuga_core/source/anuga/abstract_2d_finite_volumes/quantity.py
r4679 r4704 16 16 17 17 from Numeric import array, zeros, Float, less, concatenate, NewAxis,\ 18 argmax, a llclose, take, reshape18 argmax, argmin, allclose, take, reshape 19 19 20 20 from anuga.utilities.numerical_tools import ensure_numeric, is_scalar … … 799 799 800 800 801 def get_maximum_index(self, indices=None): 802 """Return index for maximum value of quantity (on centroids) 803 804 Optional argument: 801 def get_extremum_index(self, mode=None, indices=None): 802 """Return index for maximum or minimum value of quantity (on centroids) 803 804 Optional arguments: 805 mode is either 'max'(default) or 'min'. 805 806 indices is the set of element ids that the operation applies to. 806 807 807 808 Usage: 808 i = get_ maximum_index()809 i = get_extreme_index() 809 810 810 811 Notes: 811 We do not seek the maximum at vertices as each vertex can812 We do not seek the extremum at vertices as each vertex can 812 813 have multiple values - one for each triangle sharing it. 813 814 … … 819 820 820 821 # Always return absolute indices 821 i = argmax(V) 822 822 if mode is None or mode == 'max': 823 i = argmax(V) 824 elif mode == 'min': 825 i = argmin(V) 826 827 823 828 if indices is None: 824 829 return i … … 826 831 return indices[i] 827 832 833 834 def get_maximum_index(self, indices=None): 835 """See get extreme index for details 836 """ 837 838 return self.get_extremum_index(mode='max', 839 indices=indices) 840 841 828 842 829 843 def get_maximum_value(self, indices=None): … … 866 880 867 881 i = self.get_maximum_index(indices) 882 x, y = self.domain.get_centroid_coordinates()[i] 883 884 return x, y 885 886 887 def get_minimum_index(self, indices=None): 888 """See get extreme index for details 889 """ 890 891 return self.get_extremum_index(mode='min', 892 indices=indices) 893 894 895 def get_minimum_value(self, indices=None): 896 """Return minimum value of quantity (on centroids) 897 898 Optional argument: 899 indices is the set of element ids that the operation applies to. 900 901 Usage: 902 v = get_minimum_value() 903 904 See get_maximum_value for more details. 905 """ 906 907 908 i = self.get_minimum_index(indices) 909 V = self.get_values(location='centroids') 910 911 return V[i] 912 913 914 def get_minimum_location(self, indices=None): 915 """Return location of minimum value of quantity (on centroids) 916 917 Optional argument: 918 indices is the set of element ids that the operation applies to. 919 920 Usage: 921 x, y = get_minimum_location() 922 923 924 Notes: 925 We do not seek the maximum at vertices as each vertex can 926 have multiple values - one for each triangle sharing it. 927 928 If there are multiple cells with same maximum value, the 929 first cell encountered in the triangle array is returned. 930 """ 931 932 i = self.get_minimum_index(indices) 868 933 x, y = self.domain.get_centroid_coordinates()[i] 869 934 -
anuga_core/source/anuga/abstract_2d_finite_volumes/test_domain.py
r4702 r4704 219 219 assert domain.quantities_to_be_monitored.has_key('stage') 220 220 assert domain.quantities_to_be_monitored.has_key('stage-elevation') 221 assert domain.quantities_to_be_monitored['stage'][0] == None222 assert domain.quantities_to_be_monitored['stage'][1] == None223 224 225 # Check that invalid request are dealt with221 for key in domain.quantities_to_be_monitored['stage'].keys(): 222 assert domain.quantities_to_be_monitored['stage'][key] is None 223 224 225 # Check that invalid requests are dealt with 226 226 try: 227 227 domain.set_quantities_to_be_monitored(['yyyyy']) … … 238 238 else: 239 239 msg = 'Should have caught illegal quantity' 240 raise Exception, msg 241 242 try: 243 domain.set_quantities_to_be_monitored('stage', 'stage-elevation') 244 except: 245 pass 246 else: 247 msg = 'Should have caught too many arguments' 248 raise Exception, msg 249 250 try: 251 domain.set_quantities_to_be_monitored('stage', 'blablabla') 252 except: 253 pass 254 else: 255 msg = 'Should have caught polygon as a string' 240 256 raise Exception, msg 257 258 259 260 # Now try with a polygon restriction 261 domain.set_quantities_to_be_monitored('xmomentum', 262 polygon=[[1,1], [1,3], [3,3], [3,1]], 263 time_interval = [0,3]) 264 assert domain.monitor_indices[0] == 1 265 assert domain.monitor_time_interval[0] == 0 266 assert domain.monitor_time_interval[1] == 3 267 241 268 242 269 def test_set_quantity_from_expression(self): -
anuga_core/source/anuga/abstract_2d_finite_volumes/test_quantity.py
r4592 r4704 122 122 [3.0, -1.5, -1.5]]) 123 123 124 def test_get_ maximum_1(self):124 def test_get_extrema_1(self): 125 125 quantity = Conserved_quantity(self.mesh4, 126 126 [[1,2,3], [5,5,5], [0,0,9], [-6, 3, 3]]) … … 130 130 assert v == 5 131 131 132 v = quantity.get_minimum_value() 133 assert v == 0 134 132 135 i = quantity.get_maximum_index() 133 136 assert i == 1 137 138 i = quantity.get_minimum_index() 139 assert i == 3 134 140 135 141 x,y = quantity.get_maximum_location() … … 140 146 v = quantity.get_values(interpolation_points = [[x,y]]) 141 147 assert allclose(v, 5) 148 149 150 x,y = quantity.get_minimum_location() 151 v = quantity.get_values(interpolation_points = [[x,y]]) 152 assert allclose(v, 0) 153 142 154 143 155 def test_get_maximum_2(self): … … 162 174 assert v == 6 163 175 176 v = quantity.get_minimum_value() 177 assert v == 2 178 164 179 i = quantity.get_maximum_index() 165 180 assert i == 3 181 182 i = quantity.get_minimum_index() 183 assert i == 0 166 184 167 185 x,y = quantity.get_maximum_location() … … 173 191 assert allclose(v, 6) 174 192 193 x,y = quantity.get_minimum_location() 194 v = quantity.get_values(interpolation_points = [[x,y]]) 195 assert allclose(v, 2) 175 196 176 197 #Multiple locations for maximum - -
anuga_core/source/anuga/abstract_2d_finite_volumes/util.py
r4663 r4704 431 431 raise ValueError, msg 432 432 433 434 def get_textual_float(value, format = '%.2f'): 435 """Get textual representation of floating point numbers 436 and accept None as valid entry 437 438 format is a string - default = '%.2f' 439 """ 440 441 if value is None: 442 return 'None' 443 else: 444 try: 445 float(value) 446 except: 447 # May this is a vector 448 if len(value) > 1: 449 s = '(' 450 for v in value: 451 s += get_textual_float(v, format) + ', ' 452 453 s = s[:-2] + ')' # Strip trailing comma and close 454 return s 455 else: 456 raise 'Illegal input to get_textual_float:', value 457 else: 458 return format %float(value) 433 459 434 460 -
anuga_core/source/anuga/shallow_water/data_manager.py
r4699 r4704 321 321 322 322 if hasattr(domain, 'minimum_storable_height'): 323 self.minimum_storable_height = 323 self.minimum_storable_height = domain.minimum_storable_height 324 324 else: 325 325 self.minimum_storable_height = default_minimum_storable_height … … 331 331 description = 'Output from anuga.abstract_2d_finite_volumes suitable for plotting' 332 332 self.writer = Write_sww() 333 self.writer.header(fid, domain.starttime, 334 self.number_of_volumes, 335 self.domain.number_of_full_nodes, 336 description=description, 337 smoothing=domain.smooth, 338 order=domain.default_order) 333 self.writer.store_header(fid, 334 domain.starttime, 335 self.number_of_volumes, 336 self.domain.number_of_full_nodes, 337 description=description, 338 smoothing=domain.smooth, 339 order=domain.default_order) 340 341 # Extra optional information 339 342 if hasattr(domain, 'texture'): 340 fid.texture = domain.texture 341 # if domain.geo_reference is not None: 342 # domain.geo_reference.write_NetCDF(fid) 343 344 # fid.institution = 'Geoscience Australia' 345 # fid.description = 'Output from anuga.abstract_2d_finite_volumes suitable for plotting' 346 347 # if domain.smooth: 348 # fid.smoothing = 'Yes' 349 # else: 350 # fid.smoothing = 'No' 351 352 # fid.order = domain.default_order 353 354 # #Reference point 355 # #Start time in seconds since the epoch (midnight 1/1/1970) 356 # #FIXME: Use Georef 357 # fid.starttime = domain.starttime 358 359 # # dimension definitions 360 # fid.createDimension('number_of_volumes', self.number_of_volumes) 361 # fid.createDimension('number_of_vertices', 3) 362 363 # if domain.smooth is True: 364 # #fid.createDimension('number_of_points', len(domain.vertexlist)) 365 # fid.createDimension('number_of_points', self.domain.number_of_full_nodes) 366 367 # # FIXME(Ole): This will cause sww files for paralle domains to 368 # # have ghost nodes stored (but not used by triangles). 369 # # To clean this up, we have to change get_vertex_values and friends in 370 # # quantity.py (but I can't be bothered right now) 371 # else: 372 # fid.createDimension('number_of_points', 3*self.number_of_volumes) 373 374 # fid.createDimension('number_of_timesteps', None) #extensible 375 376 # # variable definitions 377 # fid.createVariable('x', self.precision, ('number_of_points',)) 378 # fid.createVariable('y', self.precision, ('number_of_points',)) 379 # fid.createVariable('elevation', self.precision, ('number_of_points',)) 380 # if domain.geo_reference is not None: 381 # domain.geo_reference.write_NetCDF(fid) 382 383 # #FIXME: Backwards compatibility 384 # fid.createVariable('z', self.precision, ('number_of_points',)) 385 # ################################# 386 387 # fid.createVariable('volumes', Int, ('number_of_volumes', 388 # 'number_of_vertices')) 389 390 # fid.createVariable('time', Float, # Always use full precision lest two timesteps 391 # # close to each other may appear as the same step 392 # ('number_of_timesteps',)) 393 394 # fid.createVariable('stage', self.precision, 395 # ('number_of_timesteps', 396 # 'number_of_points')) 397 398 # fid.createVariable('xmomentum', self.precision, 399 # ('number_of_timesteps', 400 # 'number_of_points')) 401 402 # fid.createVariable('ymomentum', self.precision, 403 # ('number_of_timesteps', 404 # 'number_of_points')) 405 406 #Close 343 fid.texture = domain.texture 344 345 if domain.quantities_to_be_monitored is not None: 346 fid.createDimension('singleton', 1) 347 for q in domain.quantities_to_be_monitored: 348 #print 'doing', q 349 fid.createVariable(q+':extrema', self.precision, 350 ('numbers_in_range',)) 351 fid.createVariable(q+':min_location', self.precision, 352 ('numbers_in_range',)) 353 fid.createVariable(q+':max_location', self.precision, 354 ('numbers_in_range',)) 355 fid.createVariable(q+':min_time', self.precision, 356 ('singleton',)) 357 fid.createVariable(q+':max_time', self.precision, 358 ('singleton',)) 359 360 407 361 fid.close() 408 362 … … 438 392 # 439 393 points = concatenate( (X[:,NewAxis],Y[:,NewAxis]), axis=1 ) 440 self.writer.triangulation(fid, points, 441 V.astype(volumes.typecode()), 442 Z, 443 points_georeference= \ 444 domain.geo_reference) 445 # 446 447 # volumes[:] = V.astype(volumes.typecode()) 448 # x[:] = X 449 # y[:] = Y 450 # z[:] = Z 451 452 # #FIXME: Backwards compatibility 453 # z = fid.variables['z'] 454 # z[:] = Z 455 ################################ 456 457 458 459 #Close 394 self.writer.store_triangulation(fid, 395 points, 396 V.astype(volumes.typecode()), 397 Z, 398 points_georeference= \ 399 domain.geo_reference) 400 401 # Close 460 402 fid.close() 403 461 404 462 405 def store_timestep(self, names): … … 470 413 from Numeric import choose 471 414 472 # Get NetCDF415 # Get NetCDF 473 416 retries = 0 474 417 file_open = False 475 418 while not file_open and retries < 10: 476 419 try: 477 fid = NetCDFFile(self.filename, 'a') # Open existing file420 fid = NetCDFFile(self.filename, 'a') # Open existing file 478 421 except IOError: 479 # This could happen if someone was reading the file.480 # In that case, wait a while and try again422 # This could happen if someone was reading the file. 423 # In that case, wait a while and try again 481 424 msg = 'Warning (store_timestep): File %s could not be opened'\ 482 425 %self.filename … … 494 437 495 438 496 # Check to see if the file is already too big:439 # Check to see if the file is already too big: 497 440 time = fid.variables['time'] 498 441 i = len(time)+1 … … 500 443 file_size_increase = file_size/i 501 444 if file_size + file_size_increase > self.max_size*(2**self.recursion): 502 # in order to get the file name and start time correct,503 # I change the domian.filename and domain.starttime.504 # This is the only way to do this without changing505 # other modules (I think).506 507 # write a filename addon that won't break swollens reader508 # (10.sww is bad)445 # In order to get the file name and start time correct, 446 # I change the domain.filename and domain.starttime. 447 # This is the only way to do this without changing 448 # other modules (I think). 449 450 # Write a filename addon that won't break swollens reader 451 # (10.sww is bad) 509 452 filename_ext = '_time_%s'%self.domain.time 510 453 filename_ext = filename_ext.replace('.', '_') 511 #remember the old filename, then give domain a 512 #name with the extension 454 455 # Remember the old filename, then give domain a 456 # name with the extension 513 457 old_domain_filename = self.domain.get_name() 514 458 if not self.recursion: … … 516 460 517 461 518 # change the domain starttime to the current time462 # Change the domain starttime to the current time 519 463 old_domain_starttime = self.domain.starttime 520 464 self.domain.starttime = self.domain.time 521 465 522 # build a new data_structure.466 # Build a new data_structure. 523 467 next_data_structure=\ 524 468 Data_format_sww(self.domain, mode=self.mode,\ … … 554 498 555 499 if 'stage' in names and 'xmomentum' in names and \ 556 500 'ymomentum' in names: 557 501 558 502 # Get stage … … 573 517 ymomentum, _ = Q.get_vertex_values(xy = False, 574 518 precision = self.precision) 575 self.writer.quantities(fid, 576 time=self.domain.time, 577 precision=self.precision, 578 stage=stage, 579 xmomentum=xmomentum, 580 ymomentum=ymomentum) 519 520 # Write quantities to NetCDF 521 self.writer.store_quantities(fid, 522 time=self.domain.time, 523 precision=self.precision, 524 stage=stage, 525 xmomentum=xmomentum, 526 ymomentum=ymomentum) 581 527 else: 582 528 # This is producing a sww that is not standard. 583 # Store time529 # Store time 584 530 time[i] = self.domain.time 585 531 … … 588 534 Q = domain.quantities[name] 589 535 A,V = Q.get_vertex_values(xy = False, 590 precision = self.precision)591 592 # FIXME: Make this general (see below)536 precision = self.precision) 537 538 # FIXME: Make this general (see below) 593 539 if name == 'stage': 594 540 z = fid.variables['elevation'] … … 603 549 #As in.... 604 550 #eval( name + '[i,:] = A.astype(self.precision)' ) 605 #FIXME : But we need a UNIT test for that before551 #FIXME (Ole): But we need a UNIT test for that before 606 552 # refactoring 607 553 608 554 555 556 # Update extrema if requested 557 domain = self.domain 558 if domain.quantities_to_be_monitored is not None: 559 for q, info in domain.quantities_to_be_monitored.items(): 560 561 if info['min'] is not None: 562 fid.variables[q + ':extrema'][0] = info['min'] 563 fid.variables[q + ':min_location'][:] =\ 564 info['min_location'] 565 fid.variables[q + ':min_time'][0] = info['min_time'] 566 567 if info['max'] is not None: 568 fid.variables[q + ':extrema'][1] = info['max'] 569 fid.variables[q + ':max_location'][:] =\ 570 info['max_location'] 571 fid.variables[q + ':max_time'][0] = info['max_time'] 572 573 609 574 610 575 #Flush and close … … 614 579 615 580 616 # Class for handling checkpoints data581 # Class for handling checkpoints data 617 582 class Data_format_cpt(Data_format): 618 583 """Interface to native NetCDF format (.cpt) … … 752 717 Q = domain.quantities[name] 753 718 A,V = Q.get_vertex_values(xy=False, 754 precision = self.precision)719 precision = self.precision) 755 720 756 721 stage[i,:] = A.astype(self.precision) … … 2863 2828 2864 2829 2865 # print number_of_latitudes, number_of_longitudes2830 # print number_of_latitudes, number_of_longitudes 2866 2831 number_of_points = number_of_latitudes*number_of_longitudes 2867 2832 number_of_volumes = (number_of_latitudes-1)*(number_of_longitudes-1)*2 … … 2883 2848 basename_in + '_e.nc') 2884 2849 2885 # Create new file2850 # Create new file 2886 2851 starttime = times[0] 2887 2852 sww = Write_sww() 2888 sww. header(outfile, times, number_of_volumes,2889 2890 2891 2892 # Store2853 sww.store_header(outfile, times, number_of_volumes, 2854 number_of_points, description=description, 2855 verbose=verbose) 2856 2857 # Store 2893 2858 from anuga.coordinate_transforms.redfearn import redfearn 2894 2859 x = zeros(number_of_points, Float) #Easting … … 2897 2862 2898 2863 if verbose: print 'Making triangular grid' 2899 #Check zone boundaries 2864 2865 # Check zone boundaries 2900 2866 refzone, _, _ = redfearn(latitudes[0],longitudes[0]) 2901 2867 … … 4727 4693 # work out sww_times and the index range this covers 4728 4694 sww = Write_sww() 4729 sww. header(outfile, times, len(volumes), len(points_utm),4730 4695 sww.store_header(outfile, times, len(volumes), len(points_utm), 4696 verbose=verbose) 4731 4697 outfile.mean_stage = mean_stage 4732 4698 outfile.zscale = zscale 4733 4699 4734 sww. triangulation(outfile, points_utm, volumes,4700 sww.store_triangulation(outfile, points_utm, volumes, 4735 4701 elevation, zone, new_origin=origin, 4736 4702 verbose=verbose) … … 4745 4711 xmomentum = ua*h 4746 4712 ymomentum = -1*va*h # -1 since in mux files south is positive. 4747 sww. quantities(outfile,4748 4749 4750 4751 4752 4713 sww.store_quantities(outfile, 4714 slice_index=j - mux_times_start_i, 4715 verbose=verbose, 4716 stage=stage, 4717 xmomentum=xmomentum, 4718 ymomentum=ymomentum) 4753 4719 j += 1 4754 4720 if verbose: sww.verbose_quantities(outfile) … … 4778 4744 4779 4745 class Write_sww: 4780 from anuga.shallow_water.shallow_water_domain import Domain 4746 from anuga.shallow_water.shallow_water_domain import Domain 4747 4748 # FIXME (Ole): Hardwiring the conserved quantities like 4749 # this could be a problem. I would prefer taking them from 4750 # the instantiation of Domain. 4781 4751 sww_quantities = Domain.conserved_quantities 4752 4753 4782 4754 RANGE = '_range' 4755 EXTREMA = ':extrema' 4783 4756 4784 4757 def __init__(self): 4785 4758 pass 4786 4759 4787 def header(self,outfile, times, number_of_volumes, 4788 number_of_points, 4789 description='Converted from XXX', 4790 smoothing=True, 4791 order=1, verbose=False): 4760 def store_header(self, 4761 outfile, 4762 times, 4763 number_of_volumes, 4764 number_of_points, 4765 description='Converted from XXX', 4766 smoothing=True, 4767 order=1, verbose=False): 4792 4768 """ 4793 4769 outfile - the name of the file that will be written … … 4863 4839 ('numbers_in_range',)) 4864 4840 4841 4865 4842 # Initialise ranges with small and large sentinels. 4866 4843 # If this was in pure Python we could have used None sensibly … … 4868 4845 outfile.variables[q+Write_sww.RANGE][1] = -max_float # Max 4869 4846 4870 # FIXME: Backwards compatibility4847 # FIXME: Backwards compatibility 4871 4848 outfile.createVariable('z', precision, ('number_of_points',)) 4872 4849 ################################# … … 4900 4877 4901 4878 4902 def triangulation(self,outfile, points_utm, volumes, 4903 elevation, zone=None, new_origin=None, 4904 points_georeference=None, verbose=False): 4879 def store_triangulation(self, 4880 outfile, 4881 points_utm, 4882 volumes, 4883 elevation, zone=None, new_origin=None, 4884 points_georeference=None, verbose=False): 4905 4885 """ 4906 4886 … … 4994 4974 outfile.variables[q+Write_sww.RANGE][1] = max(elevation) 4995 4975 4996 def quantities(self, outfile, precision=Float, 4997 slice_index=None, time=None, 4998 verbose=False, **quant): 4976 4977 def store_quantities(self, outfile, precision=Float, 4978 slice_index=None, time=None, 4979 verbose=False, **quant): 4999 4980 """ 5000 4981 Write the quantity info. … … 5021 5002 file_time[slice_index] = time 5022 5003 5023 # write the conserved quantities from Do amin.5004 # write the conserved quantities from Domain. 5024 5005 # Typically stage, xmomentum, ymomentum 5025 5006 # other quantities will be ignored, silently. … … 5049 5030 outfile.variables[q+Write_sww.RANGE][1]) 5050 5031 print '------------------------------------------------' 5032 5051 5033 5052 5034 -
anuga_core/source/anuga/shallow_water/test_data_manager.py
r4701 r4704 256 256 os.remove(sww.filename) 257 257 258 def NOtest_sww_extrema(self):258 def test_sww_extrema(self): 259 259 """Test that extrema of quantities can be retrieved at every vertex 260 260 Extrema are updated at every *internal* timestep … … 263 263 domain = self.domain 264 264 265 domain.set_name(' datatest' + str(id(self)))265 domain.set_name('extrema_test' + str(id(self))) 266 266 domain.format = 'sww' 267 267 domain.smooth = True … … 271 271 assert domain.monitor_time_interval is None 272 272 273 domain.set_quantities_to_be_monitored(['stage', 'ymomentum']) 274 275 assert len(domain.quantities_to_be_monitored) == 2 276 assert domain.quantities_to_be_monitored[0] == 'stage' 277 assert domain.quantities_to_be_monitored[1] == 'ymomentum' 273 domain.set_quantities_to_be_monitored(['xmomentum', 274 'ymomentum', 275 'stage-elevation']) 276 277 assert len(domain.quantities_to_be_monitored) == 3 278 assert domain.quantities_to_be_monitored.has_key('stage-elevation') 279 assert domain.quantities_to_be_monitored.has_key('xmomentum') 280 assert domain.quantities_to_be_monitored.has_key('ymomentum') 278 281 assert domain.monitor_polygon is None 279 282 assert domain.monitor_time_interval is None … … 282 285 283 286 for t in domain.evolve(yieldstep = 1, finaltime = 1): 284 print domain.timestepping_statistics() 285 print domain.quantity_statistics() 287 pass 288 #print domain.timestepping_statistics() 289 #print domain.quantity_statistics(precision = '%.8f') 286 290 287 291 … … 290 294 291 295 # Get the variables 292 extrema = fid.variables['stage_extrema'][:] 293 assert allclose(range, []) 294 295 extrema = fid.variables['xmomentum_extrema'][:] 296 assert allclose(range,[]) 297 298 extrema = fid.variables['ymomentum_extrema'][:] 299 assert allclose(range,[]) 296 extrema = fid.variables['stage-elevation:extrema'][:] 297 assert allclose(extrema, [0.00, 0.30]) 298 299 loc = fid.variables['stage-elevation:min_location'][:] 300 assert allclose(loc, [0.16666667, 0.33333333]) 301 302 loc = fid.variables['stage-elevation:max_location'][:] 303 assert allclose(loc, [0.8333333, 0.16666667]) 304 305 time = fid.variables['stage-elevation:max_time'][:] 306 assert allclose(time, 0.0) 307 308 extrema = fid.variables['xmomentum:extrema'][:] 309 assert allclose(extrema,[-0.06062178, 0.47886313]) 310 311 extrema = fid.variables['ymomentum:extrema'][:] 312 assert allclose(extrema,[0.00, 0.06241221]) 300 313 301 314 … … 6723 6736 number_of_points = len(points_utm) 6724 6737 sww = Write_sww() 6725 sww. header(outfile, times, number_of_volumes,6738 sww.store_header(outfile, times, number_of_volumes, 6726 6739 number_of_points, description='fully sick testing', 6727 6728 sww. triangulation(outfile, points_utm, volumes,6729 6730 6740 verbose=self.verbose) 6741 sww.store_triangulation(outfile, points_utm, volumes, 6742 elevation, new_origin=new_origin, 6743 verbose=self.verbose) 6731 6744 outfile.close() 6732 6745 fid = NetCDFFile(filename) … … 6755 6768 number_of_points = len(points_utm) 6756 6769 sww = Write_sww() 6757 sww. header(outfile, times, number_of_volumes,6770 sww.store_header(outfile, times, number_of_volumes, 6758 6771 number_of_points, description='fully sick testing', 6759 6772 verbose=self.verbose) 6760 sww. triangulation(outfile, points_utm, volumes,6761 6762 6773 sww.store_triangulation(outfile, points_utm, volumes, 6774 elevation, new_origin=new_origin, 6775 verbose=self.verbose) 6763 6776 outfile.close() 6764 6777 fid = NetCDFFile(filename) … … 6791 6804 number_of_points = len(points_utm) 6792 6805 sww = Write_sww() 6793 sww. header(outfile, times, number_of_volumes,6806 sww.store_header(outfile, times, number_of_volumes, 6794 6807 number_of_points, description='fully sick testing', 6795 6808 verbose=self.verbose) 6796 sww. triangulation(outfile, points_utm, volumes,6797 6798 6809 sww.store_triangulation(outfile, points_utm, volumes, 6810 elevation, new_origin=new_origin, 6811 verbose=self.verbose) 6799 6812 outfile.close() 6800 6813 fid = NetCDFFile(filename) … … 6830 6843 number_of_points = len(points_utm) 6831 6844 sww = Write_sww() 6832 sww. header(outfile, times, number_of_volumes,6845 sww.store_header(outfile, times, number_of_volumes, 6833 6846 number_of_points, description='fully sick testing', 6834 6847 verbose=self.verbose) 6835 sww. triangulation(outfile, points_utm, volumes,6836 6837 6838 6848 sww.store_triangulation(outfile, points_utm, volumes, 6849 elevation, new_origin=new_origin, 6850 points_georeference=points_georeference, 6851 verbose=self.verbose) 6839 6852 outfile.close() 6840 6853 fid = NetCDFFile(filename) … … 6866 6879 number_of_points = len(points_utm) 6867 6880 sww = Write_sww() 6868 sww. header(outfile, times, number_of_volumes,6881 sww.store_header(outfile, times, number_of_volumes, 6869 6882 number_of_points, description='fully sick testing', 6870 6883 verbose=self.verbose) 6871 sww. triangulation(outfile, points_utm, volumes,6872 6873 6874 6884 sww.store_triangulation(outfile, points_utm, volumes, 6885 elevation, new_origin=new_origin, 6886 points_georeference=points_georeference, 6887 verbose=self.verbose) 6875 6888 outfile.close() 6876 6889 fid = NetCDFFile(filename) … … 7281 7294 #suite = unittest.makeSuite(Test_Data_Manager,'test_sww_header') 7282 7295 #suite = unittest.makeSuite(Test_Data_Manager,'test_export_grid_parallel') 7283 #suite = unittest.makeSuite(Test_Data_Manager,'t')7284 7296 suite = unittest.makeSuite(Test_Data_Manager,'test') 7297 #suite = unittest.makeSuite(Test_Data_Manager,'test_sww_extrema') 7285 7298 7286 7299 -
anuga_core/source/anuga/shallow_water/test_shallow_water_domain.py
r4686 r4704 4635 4635 4636 4636 4637 4638 def test_extrema(self): 4639 """Test that extrema of quantities are computed correctly 4640 Extrema are updated at every *internal* timestep 4641 """ 4642 4643 from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross 4644 4645 initial_runup_height = -0.4 4646 final_runup_height = -0.3 4647 4648 4649 #-------------------------------------------------------------- 4650 # Setup computational domain 4651 #-------------------------------------------------------------- 4652 N = 5 4653 points, vertices, boundary = rectangular_cross(N, N) 4654 domain = Domain(points, vertices, boundary) 4655 domain.set_name('extrema_test') 4656 4657 #-------------------------------------------------------------- 4658 # Setup initial conditions 4659 #-------------------------------------------------------------- 4660 def topography(x,y): 4661 return -x/2 # linear bed slope 4662 4663 4664 domain.set_quantity('elevation', topography) # Use function for elevation 4665 domain.set_quantity('friction', 0.) # Zero friction 4666 domain.set_quantity('stage', initial_runup_height) # Constant negative initial stage 4667 domain.set_quantities_to_be_monitored(['stage', 'stage-elevation'], 4668 time_interval = [0.5, 2.7], 4669 polygon = [[0,0], [0,1], [1,1], [1,0]]) 4670 4671 assert len(domain.quantities_to_be_monitored) == 2 4672 assert domain.quantities_to_be_monitored.has_key('stage') 4673 assert domain.quantities_to_be_monitored.has_key('stage-elevation') 4674 for key in domain.quantities_to_be_monitored['stage'].keys(): 4675 assert domain.quantities_to_be_monitored['stage'][key] is None 4676 4677 4678 #-------------------------------------------------------------- 4679 # Setup boundary conditions 4680 #-------------------------------------------------------------- 4681 Br = Reflective_boundary(domain) # Reflective wall 4682 Bd = Dirichlet_boundary([final_runup_height, # Constant inflow 4683 0, 4684 0]) 4685 4686 # All reflective to begin with (still water) 4687 domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br}) 4688 4689 4690 #-------------------------------------------------------------- 4691 # Let triangles adjust and check extrema 4692 #-------------------------------------------------------------- 4693 for t in domain.evolve(yieldstep = 0.1, finaltime = 1.0): 4694 domain.quantity_statistics() # Run it silently 4695 4696 4697 4698 #-------------------------------------------------------------- 4699 # Test extrema 4700 #-------------------------------------------------------------- 4701 4702 stage = domain.quantities_to_be_monitored['stage'] 4703 assert stage['min'] <= stage['max'] 4704 4705 #print stage['min'], stage['max'] 4706 assert allclose(stage['min'], initial_runup_height, 4707 rtol = 1.0/N) # First order accuracy 4708 4709 4710 depth = domain.quantities_to_be_monitored['stage-elevation'] 4711 assert depth['min'] <= depth['max'] 4712 assert depth['min'] >= 0.0 4713 assert depth['max'] >= 0.0 4714 ##assert depth[1] <= ?? initial_runup_height 4715 4716 4717 #-------------------------------------------------------------- 4718 # Update boundary to allow inflow 4719 #-------------------------------------------------------------- 4720 domain.set_boundary({'right': Bd}) 4721 4722 4723 #-------------------------------------------------------------- 4724 # Evolve system through time 4725 #-------------------------------------------------------------- 4726 for t in domain.evolve(yieldstep = 0.1, finaltime = 3.0): 4727 #domain.write_time() 4728 domain.quantity_statistics() # Run it silently 4729 4730 4731 #-------------------------------------------------------------- 4732 # Test extrema again 4733 #-------------------------------------------------------------- 4734 4735 stage = domain.quantities_to_be_monitored['stage'] 4736 assert stage['min'] <= stage['max'] 4737 4738 assert allclose(stage['min'], initial_runup_height, 4739 rtol = 1.0/N) # First order accuracy 4740 4741 depth = domain.quantities_to_be_monitored['stage-elevation'] 4742 assert depth['min'] <= depth['max'] 4743 assert depth['min'] >= 0.0 4744 assert depth['max'] >= 0.0 4745 4746 4747 4637 4748 def test_tight_slope_limiters(self): 4638 4749 """Test that new slope limiters (Feb 2007) don't induce extremely … … 4872 4983 if __name__ == "__main__": 4873 4984 4874 suite = unittest.makeSuite(Test_Shallow_Water,'test') 4985 #suite = unittest.makeSuite(Test_Shallow_Water,'test') 4986 suite = unittest.makeSuite(Test_Shallow_Water,'test_extrema') 4875 4987 #suite = unittest.makeSuite(Test_Shallow_Water,'test_tight_slope_limiters') 4876 4988 #suite = unittest.makeSuite(Test_Shallow_Water,'test_get_maximum_inundation_from_sww')
Note: See TracChangeset
for help on using the changeset viewer.