def run_storm_job(first_storm=0, last_storm=0, wind_model='holland80', amr_level=2): r""" Setup jobs to run at specific storm start and end. """ # Path to file containing log of storms run path = os.path.join(os.environ.get('DATA_PATH', os.getcwd()), "square_basin", "square-basin-storm-%i-%i" % (first_storm, last_storm), "run_log.txt") if not os.path.exists(path): os.makedirs(os.path.dirname(path)) # File to tracy synthetic storm in atcf format tracy_atcf_path = 'data/tracy_synthetic_atcf.storm' # Establish a control form of tracy control = Storm(path=tracy_atcf_path, file_format='ATCF') control.read_atcf(path=tracy_atcf_path) # Change tracy to piece wise constant wind curve u0 = control.max_wind_speed[1] control.max_wind_speed = piecewise_wind_curve(u0, control.max_wind_speed) control.write("data/tracy_geoclaw.storm", file_format="geoclaw") # Get a general storm path #data_path = os.path.join(os.getcwd(), "../../../data") #storms_path = os.path.join(data_path, "storms") #tracks = os.path.join(storms_path, "geoclaw-mumbai-tracks") tracks = os.path.join(os.getcwd(), "data", "synthetic_storm_files") num_storms = 1000 #storm_gauges = [(72.811790, 18.936508), (72.972316, 18.997762), # (72.819311, 18.818044)] #regions_data = [] #regions_data.append([2, 5, 70, 75, 17, 22]) ## Mumbai #regions_data.append([4, 7, 72.6, 73, 18.80, 19.15]) storm_gauges = None regions_data = None num_storms = 1000 with open(path, 'w') as run_log_file: jobs = [] for n in range(0, num_storms): storm = copy.copy(control) mws = copy.copy(control.max_wind_speed) mws = perturb_wind(mws) C0 = 218.3784 * numpy.ones(len(mws)) mwr = C0 - 1.2014 * mws + (mws / 10.9884)**2 - ( mws / 35.3052)**3 - 145.5090 * numpy.cos( control.eye_location[:, 1] * 0.0174533) storm.max_wind_speed = mws #storm.max_wind_radius = mwr # Name storm file and write to log storm_name = 'SquareBasin_%s.storm' % str(n) run_log_file.write("%s %s\n" % (n, '%s' % storm_name)) # Add job to queue jobs.append( StormJob(run_number=n, storm_directory=tracks, storm_object=storm, wind_model=wind_model, amr_level=amr_level, storm_ensemble_type="Synthetic", region="SquareBasin", gauges=storm_gauges, regions=regions_data)) #num_storms = 1 if n == num_storms - 1: #controller = StormHabaneroBatchController(jobs) controller = batch.HabaneroBatchController(jobs) controller.email = '*****@*****.**' print(controller) controller.run() jobs = [] break return jobs
directory = "data/synthetic_storm_files" if not os.path.exists(os.path.join(os.getcwd(), directory)): os.makedirs(directory) # File to tracy synthetic storm in atcf format tracy_atcf_path = 'data/tracy_synthetic_atcf.storm' # Establish a control form of tracy control = Storm(path=tracy_atcf_path, file_format='ATCF') control.read_atcf(path=tracy_atcf_path) # Change tracy to piece wise constant wind curve u0 = control.max_wind_speed[1] control.max_wind_speed = piecewise_wind_curve(u0, control.max_wind_speed) control.write("data/tracy_geoclaw.storm", file_format="geoclaw") perturbed_radii = [] perturbed_winds = [] # Create storm objects with perturbed wind data for i in range(0, 1000): storm = copy.copy(control) mws = copy.copy(control.max_wind_speed) mws = perturb_wind(mws) C0 = 218.3784 * numpy.ones(len(mws)) mwr = C0 - 1.2014 * mws + (mws / 10.9884)**2 - ( mws / 35.3052)**3 - 145.5090 * numpy.cos( control.eye_location[:, 1] * 0.0174533) storm.max_wind_speed = mws
def setgeo(rundata): #------------------- """ Set GeoClaw specific runtime parameters. For documentation see .... """ try: geo_data = rundata.geo_data except: print("*** Error, this rundata has no geo_data attribute") raise AttributeError("Missing geo_data attribute") # == Physics == geo_data.gravity = 9.81 geo_data.coordinate_system = 1 geo_data.earth_radius = 6367.5e3 geo_data.rho = [1025.0 * 0.9, 1025.0] geo_data.rho_air = 1.15 geo_data.ambient_pressure = 101.3e3 # == Forcing Options geo_data.coriolis_forcing = True geo_data.theta_0 = 25.0 # Beta-plane approximation center geo_data.friction_forcing = True geo_data.friction_depth = 1e10 # == Algorithm and Initial Conditions == geo_data.sea_level = 0.0 geo_data.dry_tolerance = 1.e-2 # Refinement settings refine_data = rundata.refinement_data refine_data.wave_tolerance = 1.0 refine_data.speed_tolerance = [1.0, 2.0, 3.0, 4.0] refine_data.deep_depth = 300.0 refine_data.max_level_deep = 4 refine_data.variable_dt_refinement_ratios = True # == settopo.data values == topo_data = rundata.topo_data # for topography, append lines of the form # [topotype, minlevel, maxlevel, t1, t2, fname] topo_data.topofiles.append([2, 1, 5, -RAMP_UP_TIME, 1e10, 'topo.tt2']) # == setdtopo.data values == dtopo_data = rundata.dtopo_data # for moving topography, append lines of the form : (<= 1 allowed for now!) # [topotype, minlevel,maxlevel,fname] # ================ # Set Surge Data # ================ data = rundata.surge_data # Source term controls data.wind_forcing = True data.drag_law = 1 data.pressure_forcing = True data.wind_index = 2 data.pressure_index = 4 data.display_landfall_time = True # AMR parameters, m/s and m respectively data.wind_refine = [20.0, 40.0, 60.0] data.R_refine = [60.0e3, 40e3, 20e3] # Storm parameters - Parameterized storm (Holland 1980) data.storm_specification_type = 'holland80' # (type 1) data.storm_file = os.path.expandvars( os.path.join(os.getcwd(), 'fake.storm')) # Contruct storm forward_velocity = units.convert(20, 'km/h', 'm/s') theta = 0.0 * numpy.pi / 180.0 # degrees from horizontal to radians my_storm = Storm() # Take seconds and time period of 30 minutes and turn them into datatimes t_ref = datetime.datetime.now() t_sec = numpy.arange(-RAMP_UP_TIME, rundata.clawdata.tfinal, 30.0 * 60.0) my_storm.t = [t_ref + datetime.timedelta(seconds=t) for t in t_sec] ramp_func = lambda t: (t + (2 * RAMP_UP_TIME)) * (t < 0) / (2 * RAMP_UP_TIME) \ + numpy.ones(t_sec.shape) * (t >= 0) my_storm.time_offset = t_ref my_storm.eye_location = numpy.empty((t_sec.shape[0], 2)) my_storm.eye_location[:, 0] = forward_velocity * t_sec * numpy.cos(theta) my_storm.eye_location[:, 1] = forward_velocity * t_sec * numpy.sin(theta) my_storm.max_wind_speed = units.convert(56, 'knots', 'm/s') * ramp_func(t_sec) my_storm.central_pressure = units.convert(1024, "mbar", "Pa") \ - (units.convert(1024, "mbar", "Pa") \ - units.convert(950, 'mbar', 'Pa')) \ * ramp_func(t_sec) my_storm.max_wind_radius = [units.convert(8, 'km', 'm')] * t_sec.shape[0] my_storm.storm_radius = [units.convert(100, 'km', 'm')] * t_sec.shape[0] my_storm.write(data.storm_file, file_format="geoclaw") # ====================== # Multi-layer settings # ====================== data = rundata.multilayer_data # Physics parameters data.num_layers = 2 data.eta = [0.0, -300.0] # Algorithm parameters data.eigen_method = 2 data.inundation_method = 2 data.richardson_tolerance = 1e10 data.wave_tolerance = [0.1, 0.5] data.layer_index = 1 # ======================= # Set Variable Friction # ======================= data = rundata.friction_data # Variable friction data.variable_friction = False data.friction_index = 1 return rundata
def setgeo(rundata): """ Set GeoClaw specific runtime parameters. For documentation see .... """ geo_data = rundata.geo_data # == Physics == geo_data.gravity = 9.81 geo_data.coordinate_system = 1 geo_data.earth_radius = 6367.5e3 geo_data.rho = 1025.0 geo_data.rho_air = 1.15 geo_data.ambient_pressure = 101.3e3 # == Forcing Options geo_data.coriolis_forcing = True geo_data.theta_0 = 25.0 # Beta-plane approximation center geo_data.friction_forcing = True geo_data.friction_depth = 1e10 # == Algorithm and Initial Conditions == # Due to seasonal swelling of gulf we set sea level higher geo_data.sea_level = 0.0 geo_data.dry_tolerance = 1.e-2 # Refinement Criteria refine_data = rundata.refinement_data refine_data.wave_tolerance = 1.0 refine_data.speed_tolerance = [1.0, 2.0, 3.0, 4.0] refine_data.variable_dt_refinement_ratios = True # == settopo.data values == topo_data = rundata.topo_data topo_data.topofiles = [] # for topography, append lines of the form # [topotype, fname] topo_data.topofiles.append([2, 'topo.tt2']) # == setfixedgrids.data values == rundata.fixed_grid_data.fixedgrids = [] # for fixed grids append lines of the form # [t1,t2,noutput,x1,x2,y1,y2,xpoints,ypoints,\ # ioutarrivaltimes,ioutsurfacemax] # ================ # Set Surge Data # ================ data = rundata.surge_data # Source term controls data.wind_forcing = True data.drag_law = 1 data.pressure_forcing = True data.wind_index = 2 data.pressure_index = 4 data.display_landfall_time = True # AMR parameters, m/s and m respectively data.wind_refine = [20.0, 40.0, 60.0] data.R_refine = [60.0e3, 40e3, 20e3] # Storm parameters - Parameterized storm (Holland 1980) data.storm_specification_type = 'holland80' # (type 1) data.storm_file = os.path.expandvars(os.path.join(os.getcwd(), 'fake.storm')) # Contruct storm forward_velocity = units.convert(20, 'km/h', 'm/s') theta = 0.0 * numpy.pi / 180.0 # degrees from horizontal to radians my_storm = Storm() # Take seconds and time period of 30 minutes and turn them into datatimes t_ref = datetime.datetime.now() t_sec = numpy.arange(-RAMP_UP_TIME, rundata.clawdata.tfinal, 30.0 * 60.0) my_storm.t = [t_ref + datetime.timedelta(seconds=t) for t in t_sec] ramp_func = lambda t: (t + (2 * RAMP_UP_TIME)) * (t < 0) / (2 * RAMP_UP_TIME) \ + numpy.ones(t_sec.shape) * (t >= 0) my_storm.time_offset = t_ref my_storm.eye_location = numpy.empty((t_sec.shape[0], 2)) my_storm.eye_location[:, 0] = forward_velocity * t_sec * numpy.cos(theta) my_storm.eye_location[:, 1] = forward_velocity * t_sec * numpy.sin(theta) my_storm.max_wind_speed = units.convert(56, 'knots', 'm/s') * ramp_func(t_sec) my_storm.central_pressure = units.convert(1024, "mbar", "Pa") \ - (units.convert(1024, "mbar", "Pa") \ - units.convert(950, 'mbar', 'Pa')) \ * ramp_func(t_sec) my_storm.max_wind_radius = [units.convert(8, 'km', 'm')] * t_sec.shape[0] my_storm.storm_radius = [units.convert(100, 'km', 'm')] * t_sec.shape[0] my_storm.write(data.storm_file, file_format="geoclaw") # ======================= # Set Variable Friction # ======================= data = rundata.friction_data # Variable friction data.variable_friction = False data.friction_index = 1 return rundata
def load_emanuel_storms(path, mask_distance=None, mask_coordinate=(0.0, 0.0), mask_category=None, categorization="NHC"): r"""Load storms from a Matlab file containing storms This format is based on the format Prof. Emmanuel uses to generate storms. :Input: - *path* (string) Path to the file to be read in - *mask_distance* (float) Distance from *mask_coordinate* at which a storm needs to in order to be returned in the list of storms. If *mask_distance* is *None* then no masking is used. Default is to use no *mask_distance*. - *mask_coordinate* (tuple) Longitude and latitude coordinates to measure the distance from. Default is *(0.0, 0.0)*. - *mask_category* (int) Category or highter a storm needs to be to be included in the returned list of storms. If *mask_category* is *None* then no masking occurs. The categorization used is controlled by *categorization*. Default is to use no *mask_category*. - *categorization* (string) Categorization to be used for the *mask_category* filter. Default is "NHC". :Output: - (list) List of Storm objects that have been read in and were not filtered out. """ # Load the mat file and extract pertinent data import scipy.io mat = scipy.io.loadmat(path) lon = mat['longstore'] lat = mat['latstore'] hour = mat['hourstore'] day = mat['daystore'] month = mat['monthstore'] year = mat['yearstore'] max_wind_radius = mat['rmstore'] max_wind_speed = mat['vstore'] central_pressure = mat['pstore'] # Convert into storms and truncate zeros storms = [] for n in range(lon.shape[0]): m = len(lon[n].nonzero()[0]) storm = Storm() storm.ID = n storm.t = [ datetime.datetime(year[0, n], month[n, i], day[n, i], hour[n, i]) for i in range(m) ] storm.time_offset = storm.t[0] storm.eye_location = numpy.empty((m, 2)) storm.max_wind_speed = numpy.empty(m) storm.max_wind_radius = numpy.empty(m) storm.central_pressure = numpy.empty(m) storm.eye_location[:, 0] = lon[n, :m] storm.eye_location[:, 1] = lat[n, :m] storm.max_wind_speed = max_wind_speed[n, :m] storm.max_wind_speed = units.convert(max_wind_speed[n, :m], 'knots', 'm/s') storm.max_wind_radius = units.convert(max_wind_radius[n, :m], 'km', 'm') storm.central_pressure = units.convert(central_pressure[n, :m], 'hPa', 'Pa') storm.storm_radius = numpy.ones(m) * 300e3 include_storm = True if mask_distance is not None: distance = numpy.sqrt((storm.eye_location[:, 0] - \ mask_coordinate[0])**2 + (storm.eye_location[:, 1] - \ mask_coordinate[1])**2) inlcude_storm = numpy.any(distance < mask_distance) if mask_category is not None: category = storm.category(categorization=categorization) include_storm = numpy.any(category > mask_category) if include_storm: storms.append(storm) #print("Length of storms:", len(storms)) return storms