def test_inlet_variable_Q(self): """test_inlet_Q This tests that the inlet operator adds the correct amount of water """ stage_0 = 11.0 stage_1 = 10.0 elevation_0 = 10.0 elevation_1 = 10.0 domain_length = 200.0 domain_width = 200.0 domain = self._create_domain(d_length=domain_length, d_width=domain_width, dx=10.0, dy=10.0, elevation_0=elevation_0, elevation_1=elevation_1, stage_0=stage_0, stage_1=stage_1) vol0 = domain.compute_total_volume() finaltime = 3.0 #Make sure we are inthe right directory to find the #time series data for the inlets import os path = get_pathname_from_package('anuga.structures') filename1 = os.path.join(path, 'tests', 'data', 'inlet_operator_test1.tms') filename2 = os.path.join(path, 'tests', 'data', 'inlet_operator_test2.tms') line1 = [[95.0, 10.0], [105.0, 10.0]] Q1 = file_function(filename=filename1, quantities=['hydrograph']) line2 = [[10.0, 90.0], [20.0, 90.0]] Q2 = file_function(filename=filename2, quantities=['hydrograph']) Inlet_operator(domain, line1, Q1) Inlet_operator(domain, line2, Q2) for t in domain.evolve(yieldstep=1.0, finaltime=finaltime): #domain.write_time() #print domain.volumetric_balance_statistics() pass vol1 = domain.compute_total_volume() #print vol1-vol0 assert numpy.allclose(13.5, vol1 - vol0, rtol=1.0e-8) assert numpy.allclose(vol1 - vol0, domain.fractional_step_volume_integral, rtol=1.0e-8)
def test_inlet_variable_Q(self): """test_inlet_Q This tests that the inlet operator adds the correct amount of water """ stage_0 = 11.0 stage_1 = 10.0 elevation_0 = 10.0 elevation_1 = 10.0 domain_length = 200.0 domain_width = 200.0 domain = self._create_domain(d_length=domain_length, d_width=domain_width, dx = 10.0, dy = 10.0, elevation_0 = elevation_0, elevation_1 = elevation_1, stage_0 = stage_0, stage_1 = stage_1) vol0 = domain.compute_total_volume() finaltime = 3.0 #Make sure we are inthe right directory to find the #time series data for the inlets import os path = get_pathname_from_package('anuga.structures') filename1 = os.path.join(path, 'tests', 'data', 'inlet_operator_test1.tms') filename2 = os.path.join(path, 'tests', 'data', 'inlet_operator_test2.tms') line1 = [[95.0, 10.0], [105.0, 10.0]] Q1 = file_function(filename=filename1, quantities=['hydrograph']) line2 = [[10.0, 90.0], [20.0, 90.0]] Q2 = file_function(filename=filename2, quantities=['hydrograph']) Inlet_operator(domain, line1, Q1) Inlet_operator(domain, line2, Q2) for t in domain.evolve(yieldstep = 1.0, finaltime = finaltime): #domain.write_time() #print domain.volumetric_balance_statistics() pass vol1 = domain.compute_total_volume() #print vol1-vol0 assert numpy.allclose(13.5, vol1-vol0, rtol=1.0e-8) assert numpy.allclose(vol1-vol0, domain.fractional_step_volume_integral, rtol=1.0e-8)
def get_timeseries(sww_filename, gauges): """Generate time series for sww file based on gauges """ gauge_locations = gauges.values() gauge_names = gauges.keys() tempfile = 'xyz1234tempfile.sww' # Has to end with sww os.system('cp %s %s' % (sww_filename, tempfile)) f = file_function(tempfile, quantities='stage', interpolation_points=gauge_locations, use_cache=True, verbose=True) timevector = f.get_time() timeseries = {} for k, name in enumerate(gauge_names): model = timeseries[name] = [] for t in timevector: model.append(f(t, point_id=k)[0]) return num.array(timevector), timeseries
def get_timeseries(sww_filename, gauges): """Generate time series for sww file based on gauges """ gauge_locations = gauges.values() gauge_names = gauges.keys() tempfile = 'xyz1234tempfile.sww' # Has to end with sww os.system('cp %s %s' % (sww_filename, tempfile)) f = file_function(tempfile, quantities='stage', interpolation_points=gauge_locations, use_cache=True, verbose=True) timevector = f.get_time() timeseries = {} for k, name in enumerate(gauge_names): model = timeseries[name] = [] for t in timevector: model.append(f(t, point_id=k)[0]) return num.array(timevector), timeseries
def test_get_energy_through_cross_section(self): """test_get_energy_through_cross_section(self): Test that the specific and total energy through a cross section can be correctly obtained from an sww file. This test creates a flat bed with a known flow through it and tests that the function correctly returns the expected energies. The specifics are u = 2 m/s h = 1 m w = 3 m (width of channel) q = u*h*w = 6 m^3/s Es = h + 0.5*v*v/g # Specific energy head [m] Et = w + 0.5*v*v/g # Total energy head [m] This test uses georeferencing """ import time, os from anuga.file.netcdf import NetCDFFile # Setup #from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular # Create basic mesh (20m x 3m) width = 3 length = 20 t_end = 1 points, vertices, boundary = rectangular(length, width, length, width) # Create shallow water domain domain = Domain(points, vertices, boundary, geo_reference = Geo_reference(56,308500,6189000)) domain.default_order = 2 domain.set_minimum_storable_height(0.01) domain.set_name('flowtest') swwfile = domain.get_name() + '.sww' domain.set_datadir('.') domain.format = 'sww' domain.smooth = True e = -1.0 w = 1.0 h = w-e u = 2.0 uh = u*h Br = Reflective_boundary(domain) # Side walls Bd = Dirichlet_boundary([w, uh, 0]) # 2 m/s across the 3 m inlet: domain.set_quantity('elevation', e) domain.set_quantity('stage', w) domain.set_quantity('xmomentum', uh) domain.set_boundary( {'left': Bd, 'right': Bd, 'top': Br, 'bottom': Br}) for t in domain.evolve(yieldstep=1, finaltime = t_end): pass # Check that momentum is as it should be in the interior I = [[0, width/2.], [length/2., width/2.], [length, width/2.]] I = domain.geo_reference.get_absolute(I) f = file_function(swwfile, quantities=['stage', 'xmomentum', 'ymomentum'], interpolation_points=I, verbose=False) for t in range(t_end+1): for i in range(3): #print i, t, f(t, i) assert num.allclose(f(t, i), [w, uh, 0], atol=1.0e-6) # Check energies through the middle for i in range(5): x = length/2. + i*0.23674563 # Arbitrary cross_section = [[x, 0], [x, width]] cross_section = domain.geo_reference.get_absolute(cross_section) time, Es = get_energy_through_cross_section(swwfile, cross_section, kind='specific', verbose=False) assert num.allclose(Es, h + 0.5*u*u/g) time, Et = get_energy_through_cross_section(swwfile, cross_section, kind='total', verbose=False) assert num.allclose(Et, w + 0.5*u*u/g)
def test_get_flow_through_cross_section_stored_uniquely(self): """test_get_flow_through_cross_section_stored_uniquely(self): Test that the total flow through a cross section can be correctly obtained from an sww file. This test creates a flat bed with a known flow through it and tests that the function correctly returns the expected flow. The specifics are u = 2 m/s h = 1 m w = 3 m (width of channel) q = u*h*w = 6 m^3/s """ import time, os from anuga.file.netcdf import NetCDFFile # Setup #from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular # Create basic mesh (20m x 3m) width = 3 length = 20 t_end = 3 points, vertices, boundary = rectangular(length, width, length, width) # Create shallow water domain domain = Domain(points, vertices, boundary) domain.default_order = 2 domain.set_minimum_storable_height(0.01) domain.set_name('flowtest_uniquely') swwfile = domain.get_name() + '.sww' domain.set_store_vertices_uniquely() domain.set_datadir('.') domain.format = 'sww' domain.smooth = True h = 1.0 u = 2.0 uh = u*h Br = Reflective_boundary(domain) # Side walls Bd = Dirichlet_boundary([h, uh, 0]) # 2 m/s across the 3 m inlet: domain.set_quantity('elevation', 0.0) domain.set_quantity('stage', h) domain.set_quantity('xmomentum', uh) domain.set_boundary( {'left': Bd, 'right': Bd, 'top': Br, 'bottom': Br}) for t in domain.evolve(yieldstep=1, finaltime = t_end): pass # Check that momentum is as it should be in the interior I = [[0, width/2.], [length/2., width/2.], [length, width/2.]] f = file_function(swwfile, quantities=['stage', 'xmomentum', 'ymomentum'], interpolation_points=I, verbose=False) for t in range(t_end+1): for i in range(3): assert num.allclose(f(t, i), [1, 2, 0], atol=1.0e-6) # Check flows through the middle for i in range(5): x = length/2. + i*0.23674563 # Arbitrary cross_section = [[x, 0], [x, width]] time, Q = get_flow_through_cross_section(swwfile, cross_section, verbose=False) assert num.allclose(Q, uh*width) # Try the same with partial lines x = length/2. for i in range(5): start_point = [length/2., i*width/5.] #print start_point cross_section = [start_point, [length/2., width]] time, Q = get_flow_through_cross_section(swwfile, cross_section, verbose=False) #print i, Q, (width-start_point[1]) assert num.allclose(Q, uh*(width-start_point[1])) # Verify no flow when line is parallel to flow cross_section = [[length/2.-10, width/2.], [length/2.+10, width/2.]] time, Q = get_flow_through_cross_section(swwfile, cross_section, verbose=False) #print i, Q assert num.allclose(Q, 0, atol=1.0e-5) # Try with lines on an angle (all flow still runs through here) cross_section = [[length/2., 0], [length/2.+width, width]] time, Q = get_flow_through_cross_section(swwfile, cross_section, verbose=False) assert num.allclose(Q, uh*width)
for key in gauge_names: validation_data[key] = ensure_numeric(validation_data[key]) #-------------------------------------------------- # Read and interpolate model output #-------------------------------------------------- #if len(sys.argv) > 1: # sww_filename = sys.argv[1] #else: sww_filename = project.output_filename f = file_function(sww_filename, quantities='stage', interpolation_points=gauge_locations, use_cache=False, verbose=verbose) def report_difference(name, computed_value, reference_value, rtol, atol): if abs(reference_value) > 0: msg = '%s (expected, computed):\n (%.18e, %.18e):\n Relative error=%.18e'\ %(name, reference_value, computed_value, abs(reference_value-computed_value)/reference_value) print msg msg = ' Absolute error=%.18e'\ %(abs(reference_value-computed_value))
def __init__(self, filename, domain, time_thinning=1, use_cache=False, verbose=False): import time from anuga.config import time_format from anuga.abstract_2d_finite_volumes.util import file_function Boundary.__init__(self) # Get x,y vertex coordinates for all triangles V = domain.vertex_coordinates # Compute midpoint coordinates for all boundary elements # Only a subset may be invoked when boundary is evaluated but # we don't know which ones at this stage since this object can # be attached to # any tagged boundary later on. if verbose: log.critical('Find midpoint coordinates of entire boundary') self.midpoint_coordinates = num.zeros((len(domain.boundary), 2), num.float) boundary_keys = list(domain.boundary.keys()) xllcorner = domain.geo_reference.get_xllcorner() yllcorner = domain.geo_reference.get_yllcorner() # Make ordering unique #FIXME: should this happen in domain.py? boundary_keys.sort() # Record ordering #FIXME: should this also happen in domain.py? self.boundary_indices = {} for i, (vol_id, edge_id) in enumerate(boundary_keys): base_index = 3 * vol_id x0, y0 = V[base_index, :] x1, y1 = V[base_index + 1, :] x2, y2 = V[base_index + 2, :] # Compute midpoints if edge_id == 0: m = num.array([old_div((x1 + x2), 2), old_div((y1 + y2), 2)]) if edge_id == 1: m = num.array([old_div((x0 + x2), 2), old_div((y0 + y2), 2)]) if edge_id == 2: m = num.array([old_div((x1 + x0), 2), old_div((y1 + y0), 2)]) # Convert to absolute UTM coordinates m[0] += xllcorner m[1] += yllcorner # Register point and index self.midpoint_coordinates[i, :] = m # Register index of this boundary edge for use with evaluate self.boundary_indices[(vol_id, edge_id)] = i if verbose: log.critical('Initialise file_function') self.F = file_function(filename, domain, interpolation_points=self.midpoint_coordinates, time_thinning=time_thinning, use_cache=use_cache, verbose=verbose) self.domain = domain # Test # Here we'll flag indices outside the mesh as a warning # as suggested by Joaquim Luis in sourceforge posting # November 2007 # We won't make it an error as it is conceivable that # only part of mesh boundary is actually used with a given # file boundary sww file. if (hasattr(self.F, 'indices_outside_mesh') and len(self.F.indices_outside_mesh)) > 0: msg = 'WARNING: File_boundary has points outside the mesh ' msg += 'given in %s. ' % filename msg += 'See warning message issued by Interpolation_function ' msg += 'for details (should appear above somewhere if ' msg += 'verbose is True).\n' msg += 'This is perfectly OK as long as the points that are ' msg += 'outside aren\'t used on the actual boundary segment.' if verbose is True: log.critical(msg) #raise Exception(msg) q = self.F(0, point_id=0) d = len(domain.conserved_quantities) msg = 'Values specified in file %s must be ' % filename msg += 'a list or an array of length %d' % d assert len(q) == d, msg
def calc_max_depth_and_momentum(sww_base_name, points, ground_floor_height=0.0, verbose=True, use_cache = True): """ Calculate the maximum inundation height above ground floor for a list of locations. The inundation value is in the range -ground_floor_height to overflow errors. These calculations are done over all the sww files with the sww_base_name in the specified directory. """ quantities = ['stage', 'elevation', 'xmomentum', 'ymomentum'] points = ensure_absolute(points) point_count = len(points) # initialise the max lists max_depths = [-ground_floor_height]*point_count max_momentums = [-ground_floor_height]*point_count # How many sww files are there? dir, base = os.path.split(sww_base_name) if base[-4:] == '.sww': base = base[:-4] if dir == "": dir = "." # Unix compatibility dir_ls = os.listdir(dir) interate_over = [x for x in dir_ls if base in x and x[-4:] == '.sww'] if len(interate_over) == 0: msg = 'No files of the base name %s.'\ %(sww_base_name) raise IOError, msg from os import sep for this_sww_file in interate_over: callable_sww = file_function(dir+sep+this_sww_file, quantities=quantities, interpolation_points=points, verbose=verbose, use_cache=use_cache) for point_i, point in enumerate(points): for time in callable_sww.get_time(): quantity_values = callable_sww(time,point_i) w = quantity_values[0] z = quantity_values[1] uh = quantity_values[2] vh = quantity_values[3] #print w,z,uh,vh if w == NAN or z == NAN or uh == NAN or vh == NAN: continue # -ground_floor_height is the minimum value. depth = w - z - ground_floor_height if depth > max_depths[point_i]: max_depths[point_i] = depth momentum = sqrt(uh*uh + vh*vh) if momentum > max_momentums[point_i]: max_momentums[point_i] = momentum return max_depths, max_momentums
def test_get_energy_through_cross_section(self): """test_get_energy_through_cross_section(self): Test that the specific and total energy through a cross section can be correctly obtained from an sww file. This test creates a flat bed with a known flow through it and tests that the function correctly returns the expected energies. The specifics are u = 2 m/s h = 1 m w = 3 m (width of channel) q = u*h*w = 6 m^3/s Es = h + 0.5*v*v/g # Specific energy head [m] Et = w + 0.5*v*v/g # Total energy head [m] This test uses georeferencing """ import time, os from anuga.file.netcdf import NetCDFFile # Setup #from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular # Create basic mesh (20m x 3m) width = 3 length = 20 t_end = 1 points, vertices, boundary = rectangular(length, width, length, width) # Create shallow water domain domain = Domain(points, vertices, boundary, geo_reference=Geo_reference(56, 308500, 6189000)) domain.default_order = 2 domain.set_minimum_storable_height(0.01) domain.set_name('flowtest') swwfile = domain.get_name() + '.sww' domain.set_datadir('.') domain.format = 'sww' domain.smooth = True e = -1.0 w = 1.0 h = w - e u = 2.0 uh = u * h Br = Reflective_boundary(domain) # Side walls Bd = Dirichlet_boundary([w, uh, 0]) # 2 m/s across the 3 m inlet: domain.set_quantity('elevation', e) domain.set_quantity('stage', w) domain.set_quantity('xmomentum', uh) domain.set_boundary({'left': Bd, 'right': Bd, 'top': Br, 'bottom': Br}) for t in domain.evolve(yieldstep=1, finaltime=t_end): pass # Check that momentum is as it should be in the interior I = [[0, width / 2.], [length / 2., width / 2.], [length, width / 2.]] I = domain.geo_reference.get_absolute(I) f = file_function(swwfile, quantities=['stage', 'xmomentum', 'ymomentum'], interpolation_points=I, verbose=False) for t in range(t_end + 1): for i in range(3): #print i, t, f(t, i) assert num.allclose(f(t, i), [w, uh, 0], atol=1.0e-6) # Check energies through the middle for i in range(5): x = length / 2. + i * 0.23674563 # Arbitrary cross_section = [[x, 0], [x, width]] cross_section = domain.geo_reference.get_absolute(cross_section) time, Es = get_energy_through_cross_section(swwfile, cross_section, kind='specific', verbose=False) assert num.allclose(Es, h + 0.5 * u * u / g) time, Et = get_energy_through_cross_section(swwfile, cross_section, kind='total', verbose=False) assert num.allclose(Et, w + 0.5 * u * u / g)
def test_get_flow_through_cross_section_stored_uniquely(self): """test_get_flow_through_cross_section_stored_uniquely(self): Test that the total flow through a cross section can be correctly obtained from an sww file. This test creates a flat bed with a known flow through it and tests that the function correctly returns the expected flow. The specifics are u = 2 m/s h = 1 m w = 3 m (width of channel) q = u*h*w = 6 m^3/s """ import time, os from anuga.file.netcdf import NetCDFFile # Setup #from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular # Create basic mesh (20m x 3m) width = 3 length = 20 t_end = 3 points, vertices, boundary = rectangular(length, width, length, width) # Create shallow water domain domain = Domain(points, vertices, boundary) domain.default_order = 2 domain.set_minimum_storable_height(0.01) domain.set_name('flowtest_uniquely') swwfile = domain.get_name() + '.sww' domain.set_store_vertices_uniquely() domain.set_datadir('.') domain.format = 'sww' domain.smooth = True h = 1.0 u = 2.0 uh = u * h Br = Reflective_boundary(domain) # Side walls Bd = Dirichlet_boundary([h, uh, 0]) # 2 m/s across the 3 m inlet: domain.set_quantity('elevation', 0.0) domain.set_quantity('stage', h) domain.set_quantity('xmomentum', uh) domain.set_boundary({'left': Bd, 'right': Bd, 'top': Br, 'bottom': Br}) for t in domain.evolve(yieldstep=1, finaltime=t_end): pass # Check that momentum is as it should be in the interior I = [[0, width / 2.], [length / 2., width / 2.], [length, width / 2.]] f = file_function(swwfile, quantities=['stage', 'xmomentum', 'ymomentum'], interpolation_points=I, verbose=False) for t in range(t_end + 1): for i in range(3): assert num.allclose(f(t, i), [1, 2, 0], atol=1.0e-6) # Check flows through the middle for i in range(5): x = length / 2. + i * 0.23674563 # Arbitrary cross_section = [[x, 0], [x, width]] time, Q = get_flow_through_cross_section(swwfile, cross_section, verbose=False) assert num.allclose(Q, uh * width) # Try the same with partial lines x = length / 2. for i in range(5): start_point = [length / 2., i * width / 5.] #print start_point cross_section = [start_point, [length / 2., width]] time, Q = get_flow_through_cross_section(swwfile, cross_section, verbose=False) #print i, Q, (width-start_point[1]) assert num.allclose(Q, uh * (width - start_point[1])) # Verify no flow when line is parallel to flow cross_section = [[length / 2. - 10, width / 2.], [length / 2. + 10, width / 2.]] time, Q = get_flow_through_cross_section(swwfile, cross_section, verbose=False) #print i, Q assert num.allclose(Q, 0, atol=1.0e-5) # Try with lines on an angle (all flow still runs through here) cross_section = [[length / 2., 0], [length / 2. + width, width]] time, Q = get_flow_through_cross_section(swwfile, cross_section, verbose=False) assert num.allclose(Q, uh * width)
def __init__(self, filename, domain, time_thinning=1, use_cache=False, verbose=False): import time from anuga.config import time_format from anuga.abstract_2d_finite_volumes.util import file_function Boundary.__init__(self) # Get x,y vertex coordinates for all triangles V = domain.vertex_coordinates # Compute midpoint coordinates for all boundary elements # Only a subset may be invoked when boundary is evaluated but # we don't know which ones at this stage since this object can # be attached to # any tagged boundary later on. if verbose: log.critical('Find midpoint coordinates of entire boundary') self.midpoint_coordinates = num.zeros((len(domain.boundary), 2), num.float) boundary_keys = domain.boundary.keys() xllcorner = domain.geo_reference.get_xllcorner() yllcorner = domain.geo_reference.get_yllcorner() # Make ordering unique #FIXME: should this happen in domain.py? boundary_keys.sort() # Record ordering #FIXME: should this also happen in domain.py? self.boundary_indices = {} for i, (vol_id, edge_id) in enumerate(boundary_keys): base_index = 3*vol_id x0, y0 = V[base_index, :] x1, y1 = V[base_index+1, :] x2, y2 = V[base_index+2, :] # Compute midpoints if edge_id == 0: m = num.array([(x1 + x2)/2, (y1 + y2)/2]) if edge_id == 1: m = num.array([(x0 + x2)/2, (y0 + y2)/2]) if edge_id == 2: m = num.array([(x1 + x0)/2, (y1 + y0)/2]) # Convert to absolute UTM coordinates m[0] += xllcorner m[1] += yllcorner # Register point and index self.midpoint_coordinates[i,:] = m # Register index of this boundary edge for use with evaluate self.boundary_indices[(vol_id, edge_id)] = i if verbose: log.critical('Initialise file_function') self.F = file_function(filename, domain, interpolation_points=self.midpoint_coordinates, time_thinning=time_thinning, use_cache=use_cache, verbose=verbose) self.domain = domain # Test # Here we'll flag indices outside the mesh as a warning # as suggested by Joaquim Luis in sourceforge posting # November 2007 # We won't make it an error as it is conceivable that # only part of mesh boundary is actually used with a given # file boundary sww file. if (hasattr(self.F, 'indices_outside_mesh') and len(self.F.indices_outside_mesh)) > 0: msg = 'WARNING: File_boundary has points outside the mesh ' msg += 'given in %s. ' % filename msg += 'See warning message issued by Interpolation_function ' msg += 'for details (should appear above somewhere if ' msg += 'verbose is True).\n' msg += 'This is perfectly OK as long as the points that are ' msg += 'outside aren\'t used on the actual boundary segment.' if verbose is True: log.critical(msg) #raise Exception(msg) q = self.F(0, point_id=0) d = len(domain.conserved_quantities) msg = 'Values specified in file %s must be ' % filename msg += 'a list or an array of length %d' % d assert len(q) == d, msg
def __init__(self, filename, domain, time_thinning=1, time_limit=None, boundary_polygon=None, default_boundary=None, use_cache=False, verbose=False): import time from anuga.config import time_format from anuga.abstract_2d_finite_volumes.util import file_function Boundary.__init__(self) # Get x,y vertex coordinates for all triangles V = domain.vertex_coordinates # Compute midpoint coordinates for all boundary elements # Only a subset may be invoked when boundary is evaluated but # we don't know which ones at this stage since this object can # be attached to # any tagged boundary later on. if verbose: log.critical('Find midpoint coordinates of entire boundary') self.midpoint_coordinates = num.zeros((len(domain.boundary), 2), num.float) boundary_keys = domain.boundary.keys() xllcorner = domain.geo_reference.get_xllcorner() yllcorner = domain.geo_reference.get_yllcorner() # Make ordering unique #FIXME: should this happen in domain.py? boundary_keys.sort() # Record ordering #FIXME: should this also happen in domain.py or general_mesh.py? self.boundary_indices = {} for i, (vol_id, edge_id) in enumerate(boundary_keys): self.midpoint_coordinates[i,:] = domain.get_edge_midpoint_coordinate(vol_id, edge_id, absolute=True) # Register index of this boundary edge for use with evaluate self.boundary_indices[(vol_id, edge_id)] = i if verbose: log.critical('Initialise file_function') self.F = file_function(filename, domain, quantities=domain.conserved_quantities, interpolation_points=self.midpoint_coordinates, time_thinning=time_thinning, time_limit=time_limit, use_cache=use_cache, verbose=verbose, boundary_polygon=boundary_polygon) # Check and store default_boundary msg = 'Keyword argument default_boundary must be either None ' msg += 'or a boundary object.\n I got %s' %(str(default_boundary)) assert default_boundary is None or\ isinstance(default_boundary, Boundary), msg self.default_boundary = default_boundary self.default_boundary_invoked = False # Flag # Store pointer to domain and verbosity self.domain = domain self.verbose = verbose # Here we'll flag indices outside the mesh as a warning # as suggested by Joaquim Luis in sourceforge posting # November 2007 # We won't make it an error as it is conceivable that # only part of mesh boundary is actually used with a given # file boundary sww file. if hasattr(self.F, 'indices_outside_mesh') and\ len(self.F.indices_outside_mesh) > 0: msg = 'WARNING: File_boundary has points outside the mesh ' msg += 'given in %s. ' %filename msg += 'See warning message issued by Interpolation_function ' msg += 'for details (should appear above somewhere if ' msg += 'verbose is True).\n' msg += 'This is perfectly OK as long as the points that are ' msg += 'outside aren\'t used on the actual boundary segment.' if verbose is True: log.critical(msg) #raise Exception(msg) # Test that file function can be called q = self.F(0, point_id=0) d = len(domain.conserved_quantities) msg = 'Values specified in file %s must be ' %filename msg += ' a list or an array of length %d' %d assert len(q) == d, msg
# Boyd_box_operator(domain, # end_points=[[9.0, 2.5],[13.0, 2.5]], # losses=1.5, # width=1.5, # apron=5.0, # use_momentum_jet=True, # use_velocity_head=False, # manning=0.013, # verbose=False) line0 = [[0.0, 5.0], [0.0, 10.0]] Q = file_function("test_hydrograph.tms", quantities=["hydrograph"]) # inlet0 = Inlet_operator(domain, line0, Q, label='first inlet') line1 = [[1.0, 5.0], [2.0, 10.0]] poly1 = [[1.0, 5.0], [2.0, 5.0], [2.0, 10.0], [1.0, 10.0]] inlet1 = Inlet_operator(domain, poly1, 2.0) ##----------------------------------------------------------------------- ## Setup boundary conditions ##----------------------------------------------------------------------- ## Inflow based on Flow Depth and Approaching Momentum Bi = anuga.Dirichlet_boundary([2.0, 0.0, 0.0])
for key in gauge_names: validation_data[key] = ensure_numeric(validation_data[key]) #-------------------------------------------------- # Read and interpolate model output #-------------------------------------------------- #if len(sys.argv) > 1: # sww_filename = sys.argv[1] #else: sww_filename = project.output_filename f = file_function(sww_filename, quantities='stage', interpolation_points=gauge_locations, use_cache=False, verbose=verbose) def report_difference(name, computed_value, reference_value, rtol, atol): if abs(reference_value) > 0: msg = '%s (expected, computed):\n (%.18e, %.18e):\n Relative error=%.18e'\ %(name, reference_value, computed_value, abs(reference_value-computed_value)/reference_value) print msg msg = ' Absolute error=%.18e'\ %(abs(reference_value-computed_value))
#Boyd_box_operator(domain, # end_points=[[9.0, 2.5],[13.0, 2.5]], # losses=1.5, # width=1.5, # apron=5.0, # use_momentum_jet=True, # use_velocity_head=False, # manning=0.013, # verbose=False) line0 = [[0.0, 5.0], [0.0, 10.0]] Q = file_function('test_hydrograph.tms', quantities=['hydrograph']) #inlet0 = Inlet_operator(domain, line0, Q, label='first inlet') line1 = [[1.0, 5.0], [2.0, 10.0]] poly1 = [[1.0, 5.0], [2.0, 5.0], [2.0, 10.0], [1.0, 10.0]] inlet1 = Inlet_operator(domain, poly1, 2.0) ##----------------------------------------------------------------------- ## Setup boundary conditions ##----------------------------------------------------------------------- ## Inflow based on Flow Depth and Approaching Momentum
if 2.0-(x[i]-12.0)/2.5 < y[i] < 3.0 + (x[i]-12.0)/2.5: z[i]=z[i] else: z[i] += 2.5-1.0*(x[i] -12.0) # Sloping D/S Face return z #filename=os.path.join(path, 'example_rating_curve.csv') mod_path = get_pathname_from_package('anuga.parallel') line0 = [[10.0, 10.0], [30.0, 10.0]] #line0 = [[29.0, 10.0], [30.0, 10.0]] line1 = [[0.0, 10.0], [0.0, 15.0]] Q0 = file_function(os.path.join(mod_path,'data','test_hydrograph.tms'), quantities=['hydrograph']) Q1 = 5.0 samples = 50 def run_simulation(parallel = False, control_data = None, test_points = None, verbose = False): success = True ##----------------------------------------------------------------------- ## Setup domain ##----------------------------------------------------------------------- points, vertices, boundary = rectangular_cross(int(length/dx), int(width/dy), len1=length, len2=width)
# Cut Out Segment for Culvert face if 2.0 - (x[i] - 12.0) / 2.5 < y[i] < 3.0 + (x[i] - 12.0) / 2.5: z[i] = z[i] else: z[i] += 2.5 - 1.0 * (x[i] - 12.0) # Sloping D/S Face return z #filename=os.path.join(path, 'example_rating_curve.csv') mod_path = get_pathname_from_package('anuga.parallel') line0 = [[10.0, 10.0], [30.0, 10.0]] #line0 = [[29.0, 10.0], [30.0, 10.0]] line1 = [[0.0, 10.0], [0.0, 15.0]] Q0 = file_function(os.path.join(mod_path, 'data', 'test_hydrograph.tms'), quantities=['hydrograph']) Q1 = 5.0 samples = 50 def run_simulation(parallel=False, control_data=None, test_points=None, verbose=False): success = True ##----------------------------------------------------------------------- ## Setup domain ##-----------------------------------------------------------------------
filename = os.path.join(path, 'example_rating_curve.csv') #Boyd_box_operator(domain, # end_points=[[9.0, 2.5],[13.0, 2.5]], # losses=1.5, # width=1.5, # apron=5.0, # use_momentum_jet=True, # use_velocity_head=False, # manning=0.013, # verbose=False) line0 = [[0.0, 5.0], [0.0, 10.0]] Q = file_function( '/home/lixinhou/anuga_core/anuga/parallel/data/test_hydrograph.tms', quantities=['hydrograph']) #inlet0 = Inlet_operator(domain, line0, Q, label='first inlet') line1 = [[1.0, 5.0], [2.0, 10.0]] poly1 = [[1.0, 5.0], [2.0, 5.0], [2.0, 10.0], [1.0, 10.0]] inlet1 = Inlet_operator(domain, poly1, 2.0) ##----------------------------------------------------------------------- ## Setup boundary conditions ##----------------------------------------------------------------------- ## Inflow based on Flow Depth and Approaching Momentum Bi = anuga.Dirichlet_boundary([2.0, 0.0, 0.0]) Br = anuga.Reflective_boundary(domain) # Solid reflective wall
def __init__(self, filename, domain, time_thinning=1, time_limit=None, boundary_polygon=None, default_boundary=None, use_cache=False, verbose=False): import time from anuga.config import time_format from anuga.abstract_2d_finite_volumes.util import file_function Boundary.__init__(self) # Get x,y vertex coordinates for all triangles V = domain.vertex_coordinates # Compute midpoint coordinates for all boundary elements # Only a subset may be invoked when boundary is evaluated but # we don't know which ones at this stage since this object can # be attached to # any tagged boundary later on. if verbose: log.critical('Find midpoint coordinates of entire boundary') self.midpoint_coordinates = num.zeros((len(domain.boundary), 2), num.float) boundary_keys = list(domain.boundary.keys()) xllcorner = domain.geo_reference.get_xllcorner() yllcorner = domain.geo_reference.get_yllcorner() # Make ordering unique #FIXME: should this happen in domain.py? boundary_keys.sort() # Record ordering #FIXME: should this also happen in domain.py or general_mesh.py? self.boundary_indices = {} for i, (vol_id, edge_id) in enumerate(boundary_keys): self.midpoint_coordinates[ i, :] = domain.get_edge_midpoint_coordinate(vol_id, edge_id, absolute=True) # Register index of this boundary edge for use with evaluate self.boundary_indices[(vol_id, edge_id)] = i if verbose: log.critical('Initialise file_function') self.F = file_function(filename, domain, quantities=domain.conserved_quantities, interpolation_points=self.midpoint_coordinates, time_thinning=time_thinning, time_limit=time_limit, use_cache=use_cache, verbose=verbose, boundary_polygon=boundary_polygon) # Check and store default_boundary msg = 'Keyword argument default_boundary must be either None ' msg += 'or a boundary object.\n I got %s' % (str(default_boundary)) assert default_boundary is None or\ isinstance(default_boundary, Boundary), msg self.default_boundary = default_boundary self.default_boundary_invoked = False # Flag # Store pointer to domain and verbosity self.domain = domain self.verbose = verbose # Here we'll flag indices outside the mesh as a warning # as suggested by Joaquim Luis in sourceforge posting # November 2007 # We won't make it an error as it is conceivable that # only part of mesh boundary is actually used with a given # file boundary sww file. if hasattr(self.F, 'indices_outside_mesh') and\ len(self.F.indices_outside_mesh) > 0: msg = 'WARNING: File_boundary has points outside the mesh ' msg += 'given in %s. ' % filename msg += 'See warning message issued by Interpolation_function ' msg += 'for details (should appear above somewhere if ' msg += 'verbose is True).\n' msg += 'This is perfectly OK as long as the points that are ' msg += 'outside aren\'t used on the actual boundary segment.' if verbose is True: log.critical(msg) #raise Exception(msg) # Test that file function can be called q = self.F(0, point_id=0) d = len(domain.conserved_quantities) msg = 'Values specified in file %s must be ' % filename msg += ' a list or an array of length %d' % d assert len(q) == d, msg
def _sww2timeseries(swwfiles, gauge_filename, production_dirs, report = None, reportname = None, plot_quantity = None, generate_fig = False, surface = None, time_min = None, time_max = None, time_thinning = 1, time_unit = None, title_on = None, use_cache = False, verbose = False, output_centroids = False): # FIXME(Ole): Shouldn't print statements here be governed by verbose? assert type(gauge_filename) == type(''), 'Gauge filename must be a string' try: fid = open(gauge_filename) except Exception as e: msg = 'File "%s" could not be opened: Error="%s"' % (gauge_filename, e) raise Exception(msg) if report is None: report = False if plot_quantity is None: plot_quantity = ['depth', 'speed'] else: assert type(plot_quantity) == list, 'plot_quantity must be a list' check_list(plot_quantity) if surface is None: surface = False if time_unit is None: time_unit = 'hours' if title_on is None: title_on = True if verbose: log.critical('Gauges obtained from: %s' % gauge_filename) gauges, locations, elev = gauge_get_from_file(gauge_filename) sww_quantity = ['stage', 'elevation', 'xmomentum', 'ymomentum'] file_loc = [] f_list = [] label_id = [] leg_label = [] themaxT = 0.0 theminT = 0.0 for swwfile in list(swwfiles.keys()): try: fid = open(swwfile) except Exception as e: msg = 'File "%s" could not be opened: Error="%s"' % (swwfile, e) raise Exception(msg) if verbose: log.critical('swwfile = %s' % swwfile) # Extract parent dir name and use as label path, _ = os.path.split(swwfile) _, label = os.path.split(path) leg_label.append(label) f = file_function(swwfile, quantities = sww_quantity, interpolation_points = gauges, time_thinning = time_thinning, verbose = verbose, use_cache = use_cache, output_centroids = output_centroids) # determine which gauges are contained in sww file count = 0 gauge_index = [] for k, g in enumerate(gauges): if f(0.0, point_id = k)[2] > 1.0e6: count += 1 if count == 1: log.critical('Gauges not contained here:') log.critical(locations[k]) else: gauge_index.append(k) if len(gauge_index) > 0: log.critical('Gauges contained here:') else: log.critical('No gauges contained here.') for i in range(len(gauge_index)): log.critical(locations[gauge_index[i]]) index = swwfile.rfind(sep) file_loc.append(swwfile[:index+1]) label_id.append(swwfiles[swwfile]) f_list.append(f) maxT = max(f.get_time()) minT = min(f.get_time()) if maxT > themaxT: themaxT = maxT if minT > theminT: theminT = minT if time_min is None: time_min = theminT # min(T) else: if time_min < theminT: # min(T): msg = 'Minimum time entered not correct - please try again' raise Exception(msg) if time_max is None: time_max = themaxT # max(T) else: if time_max > themaxT: # max(T): msg = 'Maximum time entered not correct - please try again' raise Exception(msg) if verbose and len(gauge_index) > 0: log.critical('Inputs OK - going to generate figures') if len(gauge_index) != 0: texfile, elev_output = \ _generate_figures(plot_quantity, file_loc, report, reportname, surface, leg_label, f_list, gauges, locations, elev, gauge_index, production_dirs, time_min, time_max, time_unit, title_on, label_id, generate_fig, verbose) else: texfile = '' elev_output = [] return texfile, elev_output
def calc_max_depth_and_momentum(sww_base_name, points, ground_floor_height=0.0, verbose=True, use_cache=True): """ Calculate the maximum inundation height above ground floor for a list of locations. The inundation value is in the range -ground_floor_height to overflow errors. These calculations are done over all the sww files with the sww_base_name in the specified directory. """ quantities = ['stage', 'elevation', 'xmomentum', 'ymomentum'] points = ensure_absolute(points) point_count = len(points) # initialise the max lists max_depths = [-ground_floor_height] * point_count max_momentums = [-ground_floor_height] * point_count # How many sww files are there? dir, base = os.path.split(sww_base_name) if base[-4:] == '.sww': base = base[:-4] if dir == "": dir = "." # Unix compatibility dir_ls = os.listdir(dir) interate_over = [x for x in dir_ls if base in x and x[-4:] == '.sww'] if len(interate_over) == 0: msg = 'No files of the base name %s.'\ %(sww_base_name) raise IOError, msg from os import sep for this_sww_file in interate_over: callable_sww = file_function(dir + sep + this_sww_file, quantities=quantities, interpolation_points=points, verbose=verbose, use_cache=use_cache) for point_i, point in enumerate(points): for time in callable_sww.get_time(): quantity_values = callable_sww(time, point_i) w = quantity_values[0] z = quantity_values[1] uh = quantity_values[2] vh = quantity_values[3] #print w,z,uh,vh if w == NAN or z == NAN or uh == NAN or vh == NAN: continue # -ground_floor_height is the minimum value. depth = w - z - ground_floor_height if depth > max_depths[point_i]: max_depths[point_i] = depth momentum = sqrt(uh * uh + vh * vh) if momentum > max_momentums[point_i]: max_momentums[point_i] = momentum return max_depths, max_momentums
def sww2csv_gauges(sww_file, gauge_file, out_name='gauge_', quantities=['stage', 'depth', 'elevation', 'xmomentum', 'ymomentum'], verbose=False, use_cache=True, output_centroids=False): """ Inputs: NOTE: if using csv2timeseries_graphs after creating csv file, it is essential to export quantities 'depth' and 'elevation'. 'depth' is good to analyse gauges on land and elevation is used automatically by csv2timeseries_graphs in the legend. sww_file: path to any sww file gauge_file: Assumes that it follows this format name, easting, northing, elevation point1, 100.3, 50.2, 10.0 point2, 10.3, 70.3, 78.0 NOTE: order of column can change but names eg 'easting', 'elevation' must be the same! ALL lowercaps! out_name: prefix for output file name (default is 'gauge_') Outputs: one file for each gauge/point location in the points file. They will be named with this format in the same directory as the 'sww_file' <out_name><name>.csv eg gauge_point1.csv if <out_name> not supplied myfile_2_point1.csv if <out_name> ='myfile_2_' They will all have a header Usage: sww2csv_gauges(sww_file='test1.sww', quantities = ['stage', 'elevation','depth','bearing'], gauge_file='gauge.txt') Interpolate the quantities at a given set of locations, given an sww file. The results are written to a csv file. In the future let points be a points file. And the user choose the quantities. This is currently quite specific. If it needs to be more general, change things. This is really returning speed, not velocity. """ from csv import reader,writer from anuga.utilities.numerical_tools import ensure_numeric, mean, NAN import string from anuga.utilities.file_utils import get_all_swwfiles from anuga.abstract_2d_finite_volumes.util import file_function assert isinstance(gauge_file,string_types) or isinstance(gauge_file, str), 'Gauge filename must be a string or unicode' assert isinstance(out_name,string_types) or isinstance(out_name, str), 'Output filename prefix must be a string' try: gid = open(gauge_file) point_reader = reader(gid) gid.close() except Exception as e: msg = 'File "%s" could not be opened: Error="%s"' % (gauge_file, e) raise Exception(msg) if verbose: log.critical('Gauges obtained from: %s' % gauge_file) gid = open(gauge_file) point_reader = reader(gid) points = [] point_name = [] # read point info from file for i,row in enumerate(point_reader): # read header and determine the column numbers to read correctly. if i==0: for j,value in enumerate(row): if value.strip()=='easting':easting=j if value.strip()=='northing':northing=j if value.strip()=='name':name=j if value.strip()=='elevation':elevation=j else: #points.append([float(row[easting]),float(row[northing])]) points.append([float(row[easting]),float(row[northing])]) point_name.append(row[name]) gid.close() #convert to array for file_function points_array = num.array(points,num.float) points_array = ensure_absolute(points_array) #print 'points_array', points_array dir_name, base = os.path.split(sww_file) #need to get current directory so when path and file #are "joined" below the directory is correct if dir_name == '': dir_name =getcwd() if access(sww_file,R_OK): if verbose: log.critical('File %s exists' % sww_file) else: msg = 'File "%s" could not be opened: no read permission' % sww_file raise Exception(msg) sww_files = get_all_swwfiles(look_in_dir=dir_name, base_name=base, verbose=verbose) # fudge to get SWW files in 'correct' order, oldest on the left sww_files.sort() if verbose: log.critical('sww files=%s' % sww_files) #to make all the quantities lower case for file_function quantities = [quantity.lower() for quantity in quantities] # what is quantities are needed from sww file to calculate output quantities # also core_quantities = ['stage', 'elevation', 'xmomentum', 'ymomentum'] gauge_file = out_name heading = [quantity for quantity in quantities] heading.insert(0,'time') heading.insert(1,'hours') if verbose: log.critical('Writing csv files') quake_offset_time = None is_opened = [False]*len(points_array) for sww_file in sww_files: sww_file = join(dir_name, sww_file+'.sww') callable_sww = file_function(sww_file, quantities=core_quantities, interpolation_points=points_array, verbose=verbose, use_cache=use_cache, output_centroids = output_centroids) if quake_offset_time is None: quake_offset_time = callable_sww.starttime for point_i, point in enumerate(points_array): for time in callable_sww.get_time(): # add domain starttime to relative time. quake_time = time + quake_offset_time point_quantities = callable_sww(time, point_i) # __call__ is overridden if point_quantities[0] != NAN: if is_opened[point_i] == False: points_handle = open(dir_name + sep + gauge_file + point_name[point_i] + '.csv', 'w') points_writer = writer(points_handle) points_writer.writerow(heading) is_opened[point_i] = True else: points_handle = open(dir_name + sep + gauge_file + point_name[point_i] + '.csv', 'a') points_writer = writer(points_handle) points_list = [quake_time, quake_time/3600.] + _quantities2csv(quantities, point_quantities, callable_sww.centroids, point_i) points_writer.writerow(points_list) points_handle.close() else: if verbose: msg = 'gauge' + point_name[point_i] + 'falls off the mesh in file ' + sww_file + '.' log.warning(msg)