def __init__(self, filename, domain, mean_stage=0.0, time_thinning=1, time_limit=None, boundary_polygon=None, default_boundary=None, use_cache=False, verbose=False): """Constructor filename: Name of sww file containing stage and x/ymomentum domain: pointer to shallow water domain for which the boundary applies mean_stage: The mean water level which will be added to stage derived from the boundary condition time_thinning: Will set how many time steps from the sww file read in will be interpolated to the boundary. For example if the sww file has 1 second time steps and is 24 hours in length it has 86400 time steps. If you set time_thinning to 1 it will read all these steps. If you set it to 100 it will read every 100th step eg only 864 step. This parameter is very useful to increase the speed of a model run that you are setting up and testing. default_boundary: Must be either None or an instance of a class descending from class Boundary. This will be used in case model time exceeds that available in the underlying data. Note that mean_stage will also be added to this. time_limit: boundary_polygon: use_cache: True if caching is to be used. verbose: True if this method is to be verbose. """ # Create generic file_boundary object self.file_boundary = File_boundary(filename, domain, time_thinning=time_thinning, time_limit=time_limit, boundary_polygon=boundary_polygon, default_boundary=default_boundary, use_cache=use_cache, verbose=verbose) # Record information from File_boundary self.F = self.file_boundary.F self.domain = self.file_boundary.domain # Record mean stage self.mean_stage = mean_stage
class Field_boundary(Boundary): """Set boundary from given field represented in an sww file containing values for stage, xmomentum and ymomentum. Optionally, the user can specify mean_stage to offset the stage provided in the sww file. This function is a thin wrapper around the generic File_boundary. The difference between the File_boundary and Field_boundary is only that the Field_boundary will allow you to change the level of the stage height when you read in the boundary condition. This is very useful when running different tide heights in the same area as you need only to convert one boundary condition to a SWW file, ideally for tide height of 0 m (saving disk space). Then you can use Field_boundary to read this SWW file and change the stage height (tide) on the fly depending on the scenario. """ def __init__(self, filename, domain, mean_stage=0.0, time_thinning=1, time_limit=None, boundary_polygon=None, default_boundary=None, use_cache=False, verbose=False): """Constructor filename: Name of sww file containing stage and x/ymomentum domain: pointer to shallow water domain for which the boundary applies mean_stage: The mean water level which will be added to stage derived from the boundary condition time_thinning: Will set how many time steps from the sww file read in will be interpolated to the boundary. For example if the sww file has 1 second time steps and is 24 hours in length it has 86400 time steps. If you set time_thinning to 1 it will read all these steps. If you set it to 100 it will read every 100th step eg only 864 step. This parameter is very useful to increase the speed of a model run that you are setting up and testing. default_boundary: Must be either None or an instance of a class descending from class Boundary. This will be used in case model time exceeds that available in the underlying data. Note that mean_stage will also be added to this. time_limit: boundary_polygon: use_cache: True if caching is to be used. verbose: True if this method is to be verbose. """ # Create generic file_boundary object self.file_boundary = File_boundary(filename, domain, time_thinning=time_thinning, time_limit=time_limit, boundary_polygon=boundary_polygon, default_boundary=default_boundary, use_cache=use_cache, verbose=verbose) # Record information from File_boundary self.F = self.file_boundary.F self.domain = self.file_boundary.domain # Record mean stage self.mean_stage = mean_stage def __repr__(self): """ Generate a string representation of this instance. """ return 'Field boundary' def evaluate(self, vol_id=None, edge_id=None): """ Calculate 'field' boundary results. vol_id and edge_id are ignored Return linearly interpolated values based on domain.time """ # Evaluate file boundary q = self.file_boundary.evaluate(vol_id, edge_id) # Adjust stage for j, name in enumerate(self.domain.conserved_quantities): if name == 'stage': q[j] += self.mean_stage return q
def test_file_boundary_stsIV_sinewave_ordering(self): """test_file_boundary_stsIV_sinewave_ordering(self): Read correct points from ordering file and apply sts to boundary This one uses a sine wave and compares to time boundary """ lat_long_points=[[6.01, 97.0], [6.02, 97.0], [6.05, 96.9], [6.0, 97.0]] bounding_polygon=[[6.0, 97.0], [6.01, 97.0], [6.02,97.0], \ [6.02,97.02], [6.00,97.02]] tide = 0.35 time_step_count = 50 time_step = 0.1 times_ref = num.arange(0, time_step_count*time_step, time_step) n=len(lat_long_points) first_tstep=num.ones(n,num.int) last_tstep=(time_step_count)*num.ones(n,num.int) gauge_depth=20*num.ones(n,num.float) ha1=num.ones((n,time_step_count),num.float) ua1=3.*num.ones((n,time_step_count),num.float) va1=2.*num.ones((n,time_step_count),num.float) for i in range(n): ha1[i]=num.sin(times_ref) base_name, files = self.write_mux2(lat_long_points, time_step_count, time_step, first_tstep, last_tstep, depth=gauge_depth, ha=ha1, ua=ua1, va=va1) # Write order file file_handle, order_base_name = tempfile.mkstemp("") os.close(file_handle) os.remove(order_base_name) d="," order_file=order_base_name+'order.txt' fid=open(order_file,'w') # Write Header header='index, longitude, latitude\n' fid.write(header) indices=[3,0,1] for i in indices: line=str(i)+d+str(lat_long_points[i][1])+d+\ str(lat_long_points[i][0])+"\n" fid.write(line) fid.close() sts_file=base_name urs2sts(base_name, basename_out=sts_file, ordering_filename=order_file, mean_stage=tide, verbose=False) self.delete_mux(files) # Now read the sts file and check that values have been stored correctly. fid = NetCDFFile(sts_file + '.sts') # Check the time vector times = fid.variables['time'][:] #print times # Check sts quantities stage = fid.variables['stage'][:] xmomentum = fid.variables['xmomentum'][:] ymomentum = fid.variables['ymomentum'][:] elevation = fid.variables['elevation'][:] # Create beginnings of boundary polygon based on sts_boundary boundary_polygon = create_sts_boundary(base_name) os.remove(order_file) # Append the remaining part of the boundary polygon to be defined by # the user bounding_polygon_utm=[] for point in bounding_polygon: zone,easting,northing=redfearn(point[0],point[1]) bounding_polygon_utm.append([easting,northing]) boundary_polygon.append(bounding_polygon_utm[3]) boundary_polygon.append(bounding_polygon_utm[4]) #print 'boundary_polygon', boundary_polygon plot=False if plot: from pylab import plot,show,axis boundary_polygon=ensure_numeric(boundary_polygon) bounding_polygon_utm=ensure_numeric(bounding_polygon_utm) #plot(lat_long_points[:,0],lat_long_points[:,1],'o') plot(boundary_polygon[:,0], boundary_polygon[:,1]) plot(bounding_polygon_utm[:,0],bounding_polygon_utm[:,1]) show() assert num.allclose(bounding_polygon_utm,boundary_polygon) extent_res=1000000 meshname = 'urs_test_mesh' + '.tsh' interior_regions=None boundary_tags={'ocean': [0,1], 'otherocean': [2,3,4]} # have to change boundary tags from last example because now bounding # polygon starts in different place. create_mesh_from_regions(boundary_polygon, boundary_tags=boundary_tags, maximum_triangle_area=extent_res, filename=meshname, interior_regions=interior_regions, verbose=False) domain_fbound = Domain(meshname) domain_fbound.set_quantity('stage', tide) Bf = File_boundary(sts_file+'.sts', domain_fbound, boundary_polygon=boundary_polygon) Br = Reflective_boundary(domain_fbound) domain_fbound.set_boundary({'ocean': Bf,'otherocean': Br}) finaltime=time_step*(time_step_count-1) yieldstep=time_step temp_fbound=num.zeros(int(finaltime/yieldstep)+1,num.float) for i, t in enumerate(domain_fbound.evolve(yieldstep=yieldstep, finaltime=finaltime, skip_initial_step=False)): temp_fbound[i]=domain_fbound.quantities['stage'].centroid_values[2] domain_time = Domain(meshname) domain_time.set_quantity('stage', tide) Br = Reflective_boundary(domain_time) Bw = Time_boundary(domain=domain_time, function=lambda t: [num.sin(t)+tide,3.*(20.+num.sin(t)+tide),2.*(20.+num.sin(t)+tide)]) domain_time.set_boundary({'ocean': Bw,'otherocean': Br}) temp_time=num.zeros(int(finaltime/yieldstep)+1,num.float) domain_time.set_starttime(domain_fbound.get_starttime()) for i, t in enumerate(domain_time.evolve(yieldstep=yieldstep, finaltime=finaltime, skip_initial_step=False)): temp_time[i]=domain_time.quantities['stage'].centroid_values[2] assert num.allclose(temp_fbound, temp_time) assert num.allclose(domain_fbound.quantities['stage'].vertex_values, domain_time.quantities['stage'].vertex_values) assert num.allclose(domain_fbound.quantities['xmomentum'].vertex_values, domain_time.quantities['xmomentum'].vertex_values) assert num.allclose(domain_fbound.quantities['ymomentum'].vertex_values, domain_time.quantities['ymomentum'].vertex_values) try: os.remove(sts_file+'.sts') except: # Windoze can't remove this file for some reason pass os.remove(meshname)