Changeset 4554


Ignore:
Timestamp:
Jun 21, 2007, 3:04:42 PM (17 years ago)
Author:
ole
Message:

Implemented get_maximum_inundation_elevation and
get_maximum_inundation_location for use with sww files, added tests and
updated user manual.

Location:
anuga_core
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • anuga_core/documentation/user_manual/anuga_user_manual.tex

    r4543 r4554  
    22382238
    22392239\subsection{Diagnostics}
     2240\label{sec:diagnostics}
    22402241
    22412242
     
    23692370
    23702371
     2372\section{Queries of SWW model output files} 
     2373After a model has been run, it is often useful to extract various information from the sww
     2374output file (see Section \ref{sec:sww format}). This is typically more convenient than using the
     2375diagnostics described in Section \ref{sec:diagnostics} which rely on the model running - something
     2376that can be very time consuming. The sww files are easy and quick to read and offer much information
     2377about the model results such as runup heights, time histories of selected quantities,
     2378flow through cross sections and much more.
     2379
     2380\begin{funcdesc}{get\_maximum\_inundation\_elevation}{filename, polygon=None,
     2381    time_interval=None, verbose=False}
     2382  Module: \module{shallow\_water.data\_manager}
     2383
     2384  Return highest elevation where depth ($h$) > 0
     2385
     2386  Example to find maximum runup elevation:\\   
     2387  max_runup = get_maximum_inundation_elevation(filename,
     2388  polygon=None,
     2389  time_interval=None,
     2390  verbose=False)
     2391
     2392   
     2393  filename is a NetCDF sww file containing ANUGA model output.                                                       
     2394  Optional arguments polygon and time_interval restricts the maximum runup calculation
     2395  to a points that lie within the specified polygon and time interval.
     2396
     2397  If no inundation is found within polygon and time_interval the return value
     2398  is None signifying "No Runup" or "Everything is dry".
     2399
     2400  See doc string for general function get_maximum_inundation_data for details.
     2401\end{funcdesc}
     2402
     2403
     2404\begin{funcdesc}{get\_maximum\_inundation\_location}{filename, polygon=None,
     2405    time_interval=None, verbose=False}
     2406  Module: \module{shallow\_water.data\_manager}
     2407
     2408  Return location (x,y) of highest elevation where depth ($h$) > 0
     2409
     2410  Example to find maximum runup location:\\   
     2411  max_runup_location = get_maximum_inundation_location(filename,
     2412  polygon=None,
     2413  time_interval=None,
     2414  verbose=False)
     2415
     2416   
     2417  filename is a NetCDF sww file containing ANUGA model output.                                                       
     2418  Optional arguments polygon and time_interval restricts the maximum runup calculation
     2419  to a points that lie within the specified polygon and time interval.
     2420
     2421  If no inundation is found within polygon and time_interval the return value
     2422  is None signifying "No Runup" or "Everything is dry".
     2423
     2424  See doc string for general function get_maximum_inundation_data for details.
     2425\end{funcdesc}
     2426
     2427
     2428\begin{funcdesc}{sww2time\_series}{}
     2429To appear
     2430\end{funcdesc}
     2431 
     2432 
    23712433
    23722434\section{Other}
     
    24912553
    24922554\subsection{SWW and TMS Formats}
     2555\label{sec:sww format}
    24932556
    24942557The SWW and TMS formats are both NetCDF formats, and are of key
  • anuga_core/source/anuga/shallow_water/data_manager.py

    r4551 r4554  
    6969from Numeric import concatenate, array, Float, Int, Int32, resize, sometrue, \
    7070     searchsorted, zeros, allclose, around, reshape, transpose, sort, \
    71      NewAxis, ArrayType, compress, take, arange, argmax
     71     NewAxis, ArrayType, compress, take, arange, argmax, alltrue
    7272from Scientific.IO.NetCDF import NetCDFFile
    7373#from shutil import copy
     
    53825382
    53835383
    5384 def get_maximum_inundation_elevation(sww_filename, region=None, timesteps=None, verbose=False):
     5384def get_maximum_inundation_elevation(filename,
     5385                                     polygon=None,
     5386                                     time_interval=None,
     5387                                     verbose=False):
     5388   
     5389    """Return highest elevation where depth > 0
     5390   
     5391    Usage:
     5392    max_runup = get_maximum_inundation_elevation(filename,
     5393                                                 polygon=None,
     5394                                                 time_interval=None,
     5395                                                 verbose=False)
     5396
     5397    filename is a NetCDF sww file containing ANUGA model output.                                                       
     5398    Optional arguments polygon and time_interval restricts the maximum runup calculation
     5399    to a points that lie within the specified polygon and time interval.
     5400
     5401    If no inundation is found within polygon and time_interval the return value
     5402    is None signifying "No Runup" or "Everything is dry".
     5403
     5404    See general function get_maximum_inundation_data for details.
     5405   
     5406    """
     5407   
     5408    runup, _ = get_maximum_inundation_data(filename,
     5409                                           polygon=polygon,
     5410                                           time_interval=time_interval,
     5411                                           verbose=verbose)
     5412    return runup
     5413
     5414
     5415
     5416
     5417def get_maximum_inundation_location(filename,
     5418                                    polygon=None,
     5419                                    time_interval=None,
     5420                                    verbose=False):
     5421    """Return location of highest elevation where h > 0
     5422   
     5423   
     5424    Usage:
     5425    max_runup_location = get_maximum_inundation_location(filename,
     5426                                                         polygon=None,
     5427                                                         time_interval=None,
     5428                                                         verbose=False)
     5429
     5430    filename is a NetCDF sww file containing ANUGA model output.
     5431    Optional arguments polygon and time_interval restricts the maximum runup calculation
     5432    to a points that lie within the specified polygon and time interval.
     5433
     5434    If no inundation is found within polygon and time_interval the return value
     5435    is None signifying "No Runup" or "Everything is dry".
     5436
     5437    See general function get_maximum_inundation_data for details.
     5438    """
     5439   
     5440    _, max_loc = get_maximum_inundation_data(filename,
     5441                                             polygon=polygon,
     5442                                             time_interval=time_interval,
     5443                                             verbose=verbose)
     5444    return max_loc
     5445   
     5446
     5447
     5448def get_maximum_inundation_data(filename, polygon=None, time_interval=None,
     5449                                verbose=False):
    53855450    """Compute maximum run up height from sww file.
     5451
     5452
     5453    Usage:
     5454    runup, location = get_maximum_inundation_data(filename,
     5455                                                  polygon=None,
     5456                                                  time_interval=None,
     5457                                                  verbose=False)
     5458   
    53865459
    53875460    Algorithm is as in get_maximum_inundation_elevation from shallow_water_domain
     
    53895462    runup height over multiple timesteps.
    53905463   
    5391     Optional argument region restricts this to specified polygon.
    5392     Optional argument timesteps restricts this to a specified time step (an index)
    5393     or time interval (a list of indices).
     5464    Optional arguments polygon and time_interval restricts the maximum runup calculation
     5465    to a points that lie within the specified polygon and time interval.
     5466
     5467    If no inundation is found within polygon and time_interval the return value
     5468    is None signifying "No Runup" or "Everything is dry".
    53945469    """
    53955470
     
    53985473    # Water depth below which it is considered to be 0 in the model
    53995474    # FIXME (Ole): Allow this to be specified as a keyword argument as well
    5400    
     5475
     5476    from anuga.utilities.polygon import inside_polygon   
    54015477    from anuga.config import minimum_allowed_height
    54025478
    5403     if region is not None:
    5404         msg = 'region not yet implemented in get_maximum_inundation_elevation'
    5405         raise Exception, msg
    5406 
    5407 
    5408     root, extension = os.path.splitext(sww_filename)
     5479
     5480    root, extension = os.path.splitext(filename)
    54095481    if extension == '':
    5410         sww_filename += '.sww'
     5482        filename += '.sww'
    54115483   
    54125484    # Read sww file
    54135485    if verbose:
    5414         print 'Reading from %s' %sww_filename
     5486        print 'Reading from %s' %filename
    54155487   
    54165488    from Scientific.IO.NetCDF import NetCDFFile
    5417     fid = NetCDFFile(sww_filename)
     5489    fid = NetCDFFile(filename)
    54185490
    54195491    # Get extent and reference
     5492    volumes = fid.variables['volumes'][:]   
    54205493    x = fid.variables['x'][:]
    54215494    y = fid.variables['y'][:]
    5422     volumes = fid.variables['volumes'][:]
    5423 
    5424 
    5425     time = fid.variables['time'][:]
    5426     if timesteps is not None:
    5427         if type(timesteps) is list or type(timesteps) is ArrayType: 
    5428             timesteps = ensure_numeric(timesteps, Int)
    5429         elif type(timesteps) is type(0):
    5430             timesteps = [timesteps]
    5431         else:
    5432             msg = 'timesteps must be either an integer or a sequence of integers. '
    5433             msg += 'I got timesteps==%s, %s' %(timesteps, type(timesteps))
    5434             raise Exception, msg
    5435     else:
    5436         # Take them all
    5437         timesteps = arange(len(time))   
    5438    
    54395495
    54405496    # Get the relevant quantities
     
    54435499
    54445500
     5501    # Spatial restriction
     5502    if polygon is not None:
     5503        msg = 'polygon must be a sequence of points.'
     5504        assert len(polygon[0]) == 2, msg
     5505        # FIXME (Ole): Make a generic polygon input check in polygon.py and call it here
     5506       
     5507        points = concatenate((x[:,NewAxis], y[:,NewAxis]), axis=1)
     5508
     5509        point_indices = inside_polygon(points, polygon)
     5510
     5511        # Restrict quantities to polygon
     5512        elevation = take(elevation, point_indices)
     5513        stage = take(stage, point_indices, axis=1)
     5514
     5515        # Get info for location of maximal runup
     5516        points_in_polygon = take(points, point_indices)
     5517        x = points_in_polygon[:,0]
     5518        y = points_in_polygon[:,1]       
     5519    else:
     5520        # Take all points
     5521        point_indices = arange(len(x))
     5522       
     5523
     5524    # Temporal restriction
     5525    time = fid.variables['time'][:]
     5526    all_timeindices = arange(len(time))       
     5527    if time_interval is not None:
     5528       
     5529        msg = 'time_interval must be a sequence of length 2.'
     5530        assert len(time_interval) == 2, msg
     5531        msg = 'time_interval %s must not be decreasing.' %(time_interval)       
     5532        assert time_interval[1] >= time_interval[0], msg
     5533       
     5534        msg = 'Specified time interval [%.8f:%.8f]' %tuple(time_interval)
     5535        msg += ' must does not match model time interval: [%.8f, %.8f]\n'\
     5536               %(time[0], time[-1])
     5537        if time_interval[1] < time[0]: raise ValueError(msg)
     5538        if time_interval[0] > time[-1]: raise ValueError(msg)
     5539
     5540        # Take time indices corresponding to interval (& is bitwise AND)
     5541        timesteps = compress((time_interval[0] <= time) & (time <= time_interval[1]),
     5542                             all_timeindices)
     5543
     5544
     5545        msg = 'time_interval %s did not include any model timesteps.' %(time_interval)       
     5546        assert not alltrue(timesteps == 0), msg
     5547
     5548
     5549    else:
     5550        # Take them all
     5551        timesteps = all_timeindices
     5552   
     5553
     5554    fid.close()
     5555
    54455556    # Compute maximal runup for each timestep
    54465557    maximal_runup = None
     5558    maximal_runup_location = None
    54475559    for i in timesteps:
    5448         #print 'time', time[i]
    5449         depth = stage[i,:] - elevation[:]
     5560        depth = stage[i,:] - elevation
    54505561   
    54515562        # Get wet nodes i.e. nodes with depth>0 within given region and timesteps
    54525563        wet_nodes = compress(depth > minimum_allowed_height, arange(len(depth)))
    54535564
    5454         # Find maximum elevation among wet nodes and return
    5455         #runup_index = argmax(take(elevation, wet_nodes)) #FIXME Maybe get loc as well
    5456         runup = max(take(elevation, wet_nodes))
     5565        if alltrue(wet_nodes == 0):
     5566            runup = None
     5567        else:   
     5568            # Find maximum elevation among wet nodes
     5569            wet_elevation = take(elevation, wet_nodes)
     5570
     5571            runup_index = argmax(wet_elevation)
     5572            runup = max(wet_elevation)
     5573            assert wet_elevation[runup_index] == runup # Must always be True
    54575574
    54585575        if runup > maximal_runup:
    5459             maximal_runup = runup  # This works even if maximal_runup is None
    5460                
    5461 
    5462     return maximal_runup
     5576            maximal_runup = runup      # This works even if maximal_runup is None
     5577
     5578            # Record location
     5579            wet_x = take(x, wet_nodes)
     5580            wet_y = take(y, wet_nodes)           
     5581            maximal_runup_location = [wet_x[runup_index], wet_y[runup_index]]               
     5582
     5583    return maximal_runup, maximal_runup_location
    54635584
    54645585
  • anuga_core/source/anuga/shallow_water/shallow_water_domain.py

    r4530 r4554  
    342342
    343343    def get_maximum_inundation_location(self, indices=None):
    344         """Return highest elevation where h > 0
     344        """Return location of highest elevation where h > 0
    345345
    346346        Optional argument:
     
    348348
    349349        Usage:
    350             q = get_maximum_inundation_elevation()
     350            q = get_maximum_inundation_location()
    351351
    352352        Note, centroid values are used for this operation           
  • anuga_core/source/anuga/shallow_water/test_shallow_water_domain.py

    r4553 r4554  
    77from Numeric import allclose, alltrue, array, zeros, ones, Float, take
    88from anuga.utilities.numerical_tools import mean
     9from anuga.utilities.polygon import is_inside_polygon
    910
    1011from shallow_water_domain import *
     
    951952        """test_get_maximum_inundation_from_sww(self)
    952953
    953         Test of get_maximum_inundation_elevation(sww_filename) from data_manager.py
     954        Test of get_maximum_inundation_elevation()
     955        and get_maximum_inundation_location() from data_manager.py
    954956       
    955957        This is based on test_get_maximum_inundation_3(self) but works with the
    956958        stored results instead of with the internal data structure.
    957        
     959
     960        This test uses the underlying get_maximum_inundation_data for tests
    958961        """
    959962
    960963        from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross
    961         from data_manager import get_maximum_inundation_elevation
     964        from data_manager import get_maximum_inundation_elevation, get_maximum_inundation_location, get_maximum_inundation_data
    962965       
    963966
     
    10331036        assert allclose(q, initial_runup_height, rtol = 1.0/N), msg
    10341037
    1035        
    1036 
     1038
     1039        # Test error condition if time interval is out
     1040        try:
     1041            q = get_maximum_inundation_elevation('runup_test.sww',
     1042                                                 time_interval=[2.0, 3.0])
     1043        except ValueError:
     1044            pass
     1045        else:
     1046            msg = 'should have caught wrong time interval'
     1047            raise Exception, msg
     1048
     1049        # Check correct time interval
     1050        q, loc = get_maximum_inundation_data('runup_test.sww',
     1051                                             time_interval=[0.0, 3.0])       
     1052        msg = 'We got %f, should have been %f' %(q, initial_runup_height)
     1053        assert allclose(q, initial_runup_height, rtol = 1.0/N), msg
     1054        assert allclose(-loc[0]/2, q) # From topography formula         
     1055       
    10371056
    10381057        #--------------------------------------------------------------
     
    10461065        #--------------------------------------------------------------
    10471066        q_max = None
    1048         for t in domain.evolve(yieldstep = 0.1, finaltime = 3.0):
     1067        for t in domain.evolve(yieldstep = 0.1, finaltime = 3.0,
     1068                               skip_initial_step = True):
    10491069            q = domain.get_maximum_inundation_elevation()
    10501070            if q > q_max: q_max = q
     
    10641084        assert allclose(q, final_runup_height, rtol = 1.0/N) # First order accuracy
    10651085
    1066         q = get_maximum_inundation_elevation('runup_test.sww', timesteps=31)
     1086        q, loc = get_maximum_inundation_data('runup_test.sww', time_interval=[3.0, 3.0])
    10671087        msg = 'We got %f, should have been %f' %(q, final_runup_height)
    1068         assert allclose(q, final_runup_height, rtol=1.0/N), msg       
    1069 
     1088        assert allclose(q, final_runup_height, rtol=1.0/N), msg
     1089        #print 'loc', loc, q       
     1090        assert allclose(-loc[0]/2, q) # From topography formula         
    10701091
    10711092        q = get_maximum_inundation_elevation('runup_test.sww')
     1093        loc = get_maximum_inundation_location('runup_test.sww')       
    10721094        msg = 'We got %f, should have been %f' %(q, q_max)
    10731095        assert allclose(q, q_max, rtol=1.0/N), msg
    1074 
    1075         q = get_maximum_inundation_elevation('runup_test.sww', timesteps=range(32))
     1096        #print 'loc', loc, q
     1097        assert allclose(-loc[0]/2, q) # From topography formula
     1098
     1099       
     1100
     1101        q = get_maximum_inundation_elevation('runup_test.sww', time_interval=[0, 3])
    10761102        msg = 'We got %f, should have been %f' %(q, q_max)
    1077         assert allclose(q, q_max, rtol=1.0/N), msg               
    1078 
    1079 
    1080 
     1103        assert allclose(q, q_max, rtol=1.0/N), msg
     1104
     1105
     1106        # Check polygon mode
     1107        polygon = [[0.3, 0.0], [0.9, 0.0], [0.9, 1.0], [0.3, 1.0]] # Runup region
     1108        q = get_maximum_inundation_elevation('runup_test.sww',
     1109                                             polygon = polygon,
     1110                                             time_interval=[0, 3])
     1111        msg = 'We got %f, should have been %f' %(q, q_max)
     1112        assert allclose(q, q_max, rtol=1.0/N), msg
     1113
     1114       
     1115        polygon = [[0.9, 0.0], [1.0, 0.0], [1.0, 1.0], [0.9, 1.0]] # Offshore region
     1116        q, loc = get_maximum_inundation_data('runup_test.sww',
     1117                                             polygon = polygon,
     1118                                             time_interval=[0, 3])
     1119        msg = 'We got %f, should have been %f' %(q, -0.475)
     1120        assert allclose(q, -0.475, rtol=1.0/N), msg
     1121        assert is_inside_polygon(loc, polygon)
     1122        assert allclose(-loc[0]/2, q) # From topography formula         
     1123
     1124
     1125        polygon = [[0.0, 0.0], [0.4, 0.0], [0.4, 1.0], [0.0, 1.0]] # Dry region
     1126        q, loc = get_maximum_inundation_data('runup_test.sww',
     1127                                             polygon = polygon,
     1128                                             time_interval=[0, 3])
     1129        msg = 'We got %s, should have been None' %(q)
     1130        assert q is None, msg
     1131        msg = 'We got %s, should have been None' %(loc)
     1132        assert loc is None, msg       
     1133
     1134        # Check what happens if no time point is within interval
     1135        try:
     1136            q = get_maximum_inundation_elevation('runup_test.sww', time_interval=[2.8, 2.8])
     1137        except AssertionError:
     1138            pass
     1139        else:
     1140            msg = 'Time interval should have raised an exception'
     1141            raise msg
     1142           
    10811143
    10821144    def test_another_runup_example(self):
Note: See TracChangeset for help on using the changeset viewer.