"""Script for running a tsunami inundation scenario for Sydney, NSW, Australia. Source data such as elevation and boundary data is assumed to be available in directories specified by project.py The output sww file is stored in project.outputdir The scenario is defined by a triangular mesh created from project.polygon, the elevation data and a simulated submarine landslide. Ole Nielsen and Duncan Gray, GA - 2005 and Adrian Hitchman and Jane Sexton, GA - 2006 """ #-------------------------------------------------------------------------------# Import necessary modules #------------------------------------------------------------------------------- # Standard modules import os import time # Related major packages from pyvolution.shallow_water import Domain, Reflective_boundary, Dirichlet_boundary from pyvolution.data_manager import convert_dem_from_ascii2netcdf, dem2pts #from pyvolution.data_manager_old import convert_dem_from_ascii2netcdf, dem2pts from pyvolution.combine_pts import combine_rectangular_points_files from pyvolution.pmesh2domain import pmesh_to_domain_instance from pyvolution.quantity import Quantity from Numeric import allclose from utilities.polygon import inside_polygon # Application specific imports import project # Definition of file names and polygons from pyvolution.smf import slump_tsunami # Function for submarine mudslide #------------------------------------------------------------------------------- # Preparation of topographic data # # Convert ASC 2 DEM 2 PTS using source data and store result in source data # Do for coarse and fine data # Fine pts file to be clipped to area of interest #------------------------------------------------------------------------------- # filenames coarsedemname = project.coarsedemname finedemname = project.finedemname meshname = project.meshname+'.msh' # coarse data convert_dem_from_ascii2netcdf(coarsedemname, use_cache=True, verbose=True) dem2pts(coarsedemname, use_cache=True, verbose=True) # fine data (clipping the points file to smaller area) convert_dem_from_ascii2netcdf(finedemname, use_cache=True, verbose=True) dem2pts(finedemname, easting_min=project.eastingmin, easting_max=project.eastingmax, northing_min=project.northingmin, northing_max= project.northingmax, use_cache=True, verbose=True) # combining the coarse and fine data combine_rectangular_points_files(project.finedemname + '.pts', project.coarsedemname + '.pts', project.combineddemname + '.pts') #from pmesh.create_mesh import create_mesh_from_regions #new interface from pmesh.mesh_interface import create_mesh_from_regions # original issue to Benfield interior_res = 5000 interior_regions = [[project.harbour_polygon_2, interior_res], [project.botanybay_polygon_2, interior_res]] # used for finer mesh #interior_res1 = 5000 #interior_res2 = 315 #interior_regions = [[project.newpoly1, interior_res1], # [project.south1, interior_res1], # [project.finepolymanly, interior_res2], # [project.finepolyquay, interior_res2]] # used for coastal polygons constructed by GIS guys def get_polygon_from_file(filename): """ Function to read in output from GIS determined polygon """ fid = open(filename) lines = fid.readlines() fid.close() polygon = [] for line in lines[1:]: fields = line.split(',') x = float(fields[1]) y = float(fields[2]) polygon.append([x, y]) return polygon num_polygons = 9 fileext = '.csv' filename = project.polygonptsfile #interior_res = 1000 #interior_regions = [] #bounding_polygon = project.diffpolygonall#project.demopoly #count = 0 #for p in range(1, num_polygons+1): # thefilename = filename + str(p) + fileext # print 'reading in polygon points', thefilename # interior_polygon = get_polygon_from_file(thefilename) # interior_regions.append([interior_polygon, interior_res]) # n = len(interior_polygon) # # check interior polygon falls in bounding polygon # if len(inside_polygon(interior_polygon, bounding_polygon, # closed = True, verbose = False)) <> len(interior_polygon): # print 'WARNING: interior polygon %d is outside bounding polygon' %(p) # count += 1 # # check for duplicate points in interior polygon print 'number of interior polygons: ', len(interior_regions) #if count == 0: print 'interior polygons OK' #FIXME: Fix caching of this one once the mesh_interface is ready from caching import cache # original + refined region _ = cache(create_mesh_from_regions, #project.demopoly, project.diffpolygonall2, #{'boundary_tags': {'bottom': [0], # 'right1': [1], 'right0': [2], # 'right2': [3], 'top': [4], 'left1': [5], # 'left2': [6], 'left3': [7]}, {'boundary_tags': {'bottom': [0], 'bottom1': [1], 'right': [2], 'top1': [3], 'top': [4], 'left1': [5], 'left2': [6], 'left3': [7]}, #{'boundary_tags': {'bottom': [0], 'right': [1], # 'top': [2], 'left': [3]}, 'maximum_triangle_area': 100000, 'filename': meshname, 'interior_regions': interior_regions}, verbose = True) #------------------------------------------------------------------------------- # Setup computational domain #------------------------------------------------------------------------------- domain = pmesh_to_domain_instance(meshname, Domain, use_cache = True, verbose = True) print 'Number of triangles = ', len(domain) print 'The extent is ', domain.get_extent() print domain.statistics() domain.set_name(project.basename) domain.set_datadir(project.outputdir) domain.set_quantities_to_be_stored(['stage', 'xmomentum', 'ymomentum']) #------------------------------------------------------------------------------- # Set up scenario (tsunami_source is a callable object used with set_quantity) #------------------------------------------------------------------------------- tsunami_source = slump_tsunami(length=30000.0, depth=400.0, slope=6.0, thickness=176.0, radius=3330, dphi=0.23, x0=project.slump_origin2[0], y0=project.slump_origin2[1], alpha=0.0, domain=domain, verbose=True) #------------------------------------------------------------------------------- # Setup initial conditions #------------------------------------------------------------------------------- # apply slump after 30 mins, initialise to water level of tide = 0 domain.set_quantity('stage', 0.0) domain.set_quantity('friction', 0.04) domain.set_quantity('elevation', filename = project.combineddemname + '.pts', use_cache = True, verbose = True) #------------------------------------------------------------------------------- # Setup boundary conditions (all reflective) #------------------------------------------------------------------------------- print 'Available boundary tags', domain.get_boundary_tags() Br = Reflective_boundary(domain) Bd = Dirichlet_boundary([0, 0, 0]) # original + refined regions #domain.set_boundary( {'bottom': Br, 'right1': Br, 'right0': Br, # 'right2': Br, 'top': Br, 'left1': Br, # 'left2': Br, 'left3': Br} ) # for new tests 4 April 2006 #domain.set_boundary( {'bottom': Br, 'bottom1': Br, 'right': Br, # 'top1': Br, 'top': Br, 'left1': Br, # 'left2': Br, 'left3': Br} ) # enforce Dirichlet BC - from 30/03/06 Benfield visit domain.set_boundary( {'bottom': Bd, 'bottom1': Bd, 'right': Bd, 'top1': Bd, 'top': Bd, 'left1': Bd, 'left2': Bd, 'left3': Bd} ) # increasingly finer interior regions #domain.set_boundary( {'bottom': Bd, 'right': Bd, 'left': Bd, 'top': Bd} ) #------------------------------------------------------------------------------- # Evolve system through time #------------------------------------------------------------------------------- import time t0 = time.time() thisfile = project.integraltimeseries+'.csv' fid = open(thisfile, 'w') # save every 10 secs leading up to slump initiation for t in domain.evolve(yieldstep = 10, finaltime = 60): # 6 steps domain.write_time() domain.write_boundary_statistics(tags = 'bottom') # calculate integral thisstagestep = domain.get_quantity('stage') s = '%.2f, %.2f\n' %(t, thisstagestep.get_integral()) fid.write(s) # add slump after 30 secs if allclose(t, 30): slump = Quantity(domain) slump.set_values(tsunami_source) domain.set_quantity('stage', slump + thisstagestep) #test_stage = domain.get_quantity('stage') #test_elevation = domain.get_quantity('elevation') #test_depth = test_stage - test_elevation #test_max = max(test_depth.get_values()) #print 'testing', test_max import sys; sys.exit() # save every two minutes leading up to interesting period for t in domain.evolve(yieldstep = 120, finaltime = 660, # steps skip_initial_step = True): domain.write_time() domain.write_boundary_statistics(tags = 'bottom') # calculate integral thisstagestep = domain.get_quantity('stage') s = '%.2f, %.2f\n' %(t, thisstagestep.get_integral()) fid.write(s) # save every thirty secs during interesting period for t in domain.evolve(yieldstep = 60, finaltime = 5000, # steps skip_initial_step = True): domain.write_time() domain.write_boundary_statistics(tags = 'bottom') #quantities = 'stage') # calculate integral thisstagestep = domain.get_quantity('stage') s = '%.2f, %.2f\n' %(t, thisstagestep.get_integral()) fid.write(s) import sys; sys.exit() # save every two mins for next 5000 secs for t in domain.evolve(yieldstep = 120, finaltime = 10000, # about 42 steps skip_initial_step = True): domain.write_time() domain.write_boundary_statistics(tags = 'bottom') #quantities = 'stage') # calculate integral thisstagestep = domain.get_quantity('stage') s = '%.2f, %.2f\n' %(t, thisstagestep.get_integral()) fid.write(s) # save every half hour to end of simulation for t in domain.evolve(yieldstep = 1800, finaltime = 10*60*60, # 14 steps skip_initial_step = True): domain.write_time() domain.write_boundary_statistics(tags = 'bottom') #quantities = 'stage' # calculate integral thisstagestep = domain.get_quantity('stage') s = '%.2f, %.2f\n' %(t, thisstagestep.get_integral()) fid.write(s) print 'That took %.2f seconds' %(time.time()-t0)