def load_checkpoint_file(domain_name="domain", checkpoint_dir=".", time=None): from os.path import join if numprocs > 1: domain_name = domain_name + "_P{}_{}".format(numprocs, myid) if time is None: # will pull out the last available time times = _get_checkpoint_times(domain_name, checkpoint_dir) times = list(times) times.sort() # print times else: times = [float(time)] if len(times) == 0: raise Exception, "Unable to open checkpoint file" for time in reversed(times): pickle_name = join(checkpoint_dir, domain_name) + "_" + str(time) + ".pickle" # print pickle_name try: import cPickle domain = cPickle.load(open(pickle_name, "rb")) success = True except: success = False # print success overall = success for cpu in range(numprocs): if cpu != myid: send(success, cpu) for cpu in range(numprocs): if cpu != myid: overall = overall & receive(cpu) barrier() # print myid, overall, success, time if overall: break if not overall: raise Exception, "Unable to open checkpoint file" domain.last_walltime = walltime() domain.communication_time = 0.0 domain.communication_reduce_time = 0.0 domain.communication_broadcast_time = 0.0 return domain
def load_checkpoint_file(domain_name='domain', checkpoint_dir='.', time=None): from os.path import join if numprocs > 1: domain_name = domain_name + '_P{}_{}'.format(numprocs, myid) if time is None: # will pull out the last available time times = _get_checkpoint_times(domain_name, checkpoint_dir) times = list(times) times.sort() #print times else: times = [float(time)] if len(times) == 0: raise Exception("Unable to open checkpoint file") for time in reversed(times): pickle_name = join(checkpoint_dir, domain_name) + '_' + str(time) + '.pickle' #print pickle_name try: try: import dill as pickle except: import pickle domain = pickle.load(open(pickle_name, 'rb')) success = True except: success = False #print success overall = success for cpu in range(numprocs): if cpu != myid: send(success, cpu) for cpu in range(numprocs): if cpu != myid: overall = overall & receive(cpu) barrier() #print myid, overall, success, time if overall: break if not overall: raise Exception("Unable to open checkpoint file") domain.last_walltime = walltime() domain.communication_time = 0.0 domain.communication_reduce_time = 0.0 domain.communication_broadcast_time = 0.0 return domain
def _setup_original_domain(self, np=None): """ Create sequential domain and partition """ verbose = self.verbose outname = self.outname partition_dir = self.partition_dir if np is None: np = numprocs # Only create the sequential domain on processor 0 if myid == 0: if verbose: print 'CREATING PARTITIONED DOMAIN' # Let's see if we have already pickled this domain pickle_name = outname+'_P%g_%g.pickle'% (1,0) pickle_name = join(partition_dir,pickle_name) if os.path.exists(pickle_name): if verbose: print 'Saved domain seems to already exist' else: domain = self.setup_domain(self) if verbose: print 'Saving Domain' sequential_distribute_dump(domain, 1, partition_dir=partition_dir, verbose=verbose) # Now partition the domain if verbose: print 'Load in saved sequential pickled domain' domain = sequential_distribute_load_pickle_file(pickle_name, np=1, verbose = verbose) par_pickle_name = outname+'_P%g_%g.pickle'% (np,0) par_pickle_name = join(partition_dir,par_pickle_name) if os.path.exists(par_pickle_name): if verbose: print 'Saved partitioned domain seems to already exist' else: if verbose: print 'Dump partitioned domains' sequential_distribute_dump(domain, np, partition_dir=partition_dir, verbose=verbose) barrier() #=============================================================================== # Setup parallel domain #=============================================================================== if myid == 0 and verbose: print 'LOADING PARTITIONED DOMAIN' self.domain = sequential_distribute_load(filename=join(partition_dir,outname), verbose = self.verbose)
def run(self, yieldstep=None, finaltime=None): if yieldstep is None: yieldstep = self.args.yieldstep if finaltime is None: finaltime = self.args.finaltime if myid == 0 and self.verbose: print 'EVOLVE(yieldstep = {}, finaltime = {})'.format( yieldstep, finaltime) domain = self.domain #import time t0 = time.time() for t in domain.evolve(yieldstep=yieldstep, finaltime=finaltime): #= 83700.): if myid == 0 and self.verbose: domain.write_time() barrier() for p in range(numprocs): if myid == p: print 'Processor %g ' % myid print 'That took %.2f seconds' % (time.time() - t0) print 'Communication time %.2f seconds' % domain.communication_time print 'Reduction Communication time %.2f seconds' % domain.communication_reduce_time print 'Broadcast time %.2f seconds' % domain.communication_broadcast_time else: pass barrier() # if myid == 0 and self.verbose: # print 'Number of processors %g ' %numprocs # print 'That took %.2f seconds' %(time.time()-t0) # print 'Communication time %.2f seconds'%domain.communication_time # print 'Reduction Communication time %.2f seconds'%domain.communication_reduce_time # print 'Broadcast time %.2f seconds'%domain.communication_broadcast_time finalize()
def run(self, yieldstep = None, finaltime =None): if yieldstep is None: yieldstep = self.args.yieldstep if finaltime is None: finaltime = self.args.finaltime if myid == 0 and self.verbose: print 'EVOLVE(yieldstep = {}, finaltime = {})'.format(yieldstep,finaltime) domain = self.domain #import time t0 = time.time() for t in domain.evolve(yieldstep = yieldstep, finaltime = finaltime):#= 83700.): if myid == 0 and self.verbose: domain.write_time() barrier() for p in range(numprocs): if myid == p: print 'Processor %g ' %myid print 'That took %.2f seconds' %(time.time()-t0) print 'Communication time %.2f seconds'%domain.communication_time print 'Reduction Communication time %.2f seconds'%domain.communication_reduce_time print 'Broadcast time %.2f seconds'%domain.communication_broadcast_time else: pass barrier() # if myid == 0 and self.verbose: # print 'Number of processors %g ' %numprocs # print 'That took %.2f seconds' %(time.time()-t0) # print 'Communication time %.2f seconds'%domain.communication_time # print 'Reduction Communication time %.2f seconds'%domain.communication_reduce_time # print 'Broadcast time %.2f seconds'%domain.communication_broadcast_time finalize()
domain.set_quantity('KE', 0.5, location='centroids') domain.set_quantity('coeM', 0.5, location='centroids') domain.set_quantity('expM', 0.5, location='centroids') domain.set_quantity('coeR', 0.5, location='centroids') domain.set_quantity('coeS', 0.5, location='centroids') domain.set_quantity('KS', 0.5, location='centroids') domain.set_quantity('KI', 0.5, location='centroids') Br = anuga.Reflective_boundary(domain) Bt = anuga.Transmissive_boundary(domain) domain.set_boundary({'bottom': Bt, 'exterior': Br}) else: domain = None barrier() domain = distribute(domain) #domain.set_evap_dir('/hydros/MengyuChen/pet', pattern='cov_et17%m%d.asc', freq='D') #domain.set_precip_dir('/home/ZhiLi/CRESTHH/data/precip',pattern='imerg%Y%m%dS%H%M%S.tif', freq='H') #domain.set_timestamp('20170825180000', format='%Y%m%d%H%M%S') #domain.set_time_interval('1H') domain.set_evap_dir('/hydros/MengyuChen/pet', pattern='cov_et17%m%d.asc', freq='1D') # domain.set_precip_dir('/home/ZhiLi/CRESTHH/data/precip',pattern='nimerg%Y%m%dS%H%M%S.tif', freq='H') domain.set_precip_dir( '/hydros/MengyuChen/mrmsPrecRate', pattern='PrecipRate_00.00_%Y%m%d-%H%M00.grib2-var0-z0.tif',
def export_riverwalls_to_text(self, output_dir=None): """ Function for dumping riverwall outputs to text file (useful for QC) This will overwrite any existing files with the same location/name INPUT: output_dir = Directory where the outputs will be written OUTPUT: None, but writes files as a side effect """ if (output_dir is None): return if (myid == 0): # Make output directory try: os.mkdir(output_dir) except: pass # Make output files with empty contents for i, riverWallFile in enumerate(self.names): newFile = open( output_dir + '/' + os.path.splitext(os.path.basename(riverWallFile))[0] + '.txt', 'w') # Write hydraulic variable information hydraulicVars = self.hydraulic_properties[i, :] newFile.write('## Hydraulic Variable values below ## \n') newFile.write(str(self.hydraulic_variable_names) + '\n') newFile.write(str(hydraulicVars) + '\n') newFile.write('\n') newFile.write( '## xyElevation at edges below. Order may be erratic for parallel runs ##\n' ) newFile.close() else: pass domain = self.domain # The other processes might try to write into file # before process 0 has created file, so we need a # barrier if domain.parallel: barrier() # Now dump the required info to the files for i in range(numprocs): # Write 1 processor at a time if (myid == i): for j, riverWallname in enumerate(self.names): # Get xyz data for riverwall j riverWallInds = (self.hydraulic_properties_rowIndex == j ).nonzero()[0].tolist() riverWallDomainInds = self.riverwall_edges[ riverWallInds].tolist() myXCoords = domain.edge_coordinates[ riverWallDomainInds, 0] + domain.geo_reference.xllcorner myYCoords = domain.edge_coordinates[ riverWallDomainInds, 1] + domain.geo_reference.yllcorner myElev = self.riverwall_elevation[riverWallInds] # Open file for appending data theFile = open( output_dir + '/' + os.path.splitext(os.path.basename(riverWallname))[0] + '.txt', 'a') for k in range(len(myElev)): theFile.write( str(myXCoords[k]) + ',' + str(myYCoords[k]) + ',' + str(myElev[k]) + '\n') theFile.close() else: pass return
def create_riverwalls(self, riverwalls, riverwallPar={}, default_riverwallPar={}, tol=1.0e-4, verbose=True, output_dir=None): """Add riverwalls at chosen locations along the mesh As of 22/04/2014, these only work with DE algorithms [for which the concept is natural] The walls MUST EXACTLY COINCIDE with edges along the mesh You can force the mesh to do this by passing riverwalls.values() to the 'breaklines' argument in the function create_mesh_from_regions. You may also need to set the maximum_triangle_area for regions, if the breaklines split the region. Do this with the regionPtArea argument in create_mesh_from_regions. As of 22/04/2014, the computational method used here is very 'brute-force' For each segment on each riverwall, every point in the mesh is checked to see if it is on the segment. A possibly faster/less memory method would be to 'walk' through connected edges on the mesh. Inputs: riverwalls: Dictionary of '3D polygons', containing xyz locations of named riverwalls. exampleRiverWalls = { # Left bank n1 -- 'n1': [[1.0, 1000., 2.], [1.0, 50., 3.]], # Left bank n2 'n2': [[2.0, 30., 1.0], [3.0, 20., 2.], [2.5, 15., 1.5]] } riverwallPar: Dictionary containing a dictionary of named hydraulic parameters for each named riverwall If parameters are not provided, default values will be used. See the help for class 'RiverWall' for an explanation of these exampleRiverWallPar = {'n2': {'Qfactor':0.5} } This would use a Qfactor of 0.5 for riverwall 'n2', while the other riverwall would have the default values default_riverwallPar: Dictionary containing default values of the riverwall parameters, to be used if they are not explicitly set. If not provided, defaults from __init__ are used. See the help for class 'RiverWall' for more info example_default_riverwallPar = {'Qfactor':1.5, 's1': 0.9, 's2': 0.95, 'h1': 1.0, 'h2': 1.5 } example_default_riverwallPar = {'Qfactor':1.5, 's1': 10000., 's2': 20000. } # Here h1/h2 defaults will come from __init__ tol: Edges will be assigned a riverwall elevation if they are within 'tol' of a segment in riverwalls. Round-off error means this should not be too small. verbose: TRUE/FALSE Print lots of information output_dir: Text representation of riverwalls is written to output_dir, unless output_dir=None Outputs: None, but it sets domain.edge_flux_type = 1 for every edge on a riverwall Also, it adds a RiverWall object domain.riverwallData to the domain The latter contains the riverwall heights, names, and hydraulic properties for each edge, in a way we can pass in/out of C code. """ #if(verbose and myid==0): # print ' ' # print 'WARNING: Riverwall is an experimental feature' # print ' At each riverwall edge, we place a thin "wall" between' # print ' the 2 edges -- so each sees its neighbour edge as having' # print ' bed elevation = max(levee height, neighbour bed elevation)' # print ' We also force the discharge with a weir relation, blended with' # print ' the shallow water flux solution as the ratio (min_head)/(weir_height) becomes ' # print ' large, or the ratio (downstream_head)/(upstream_head) becomes large' # print ' ' # print ' It works in parallel, but you must use domain.riverwallData.create_riverwall AFTER distributing the mesh' # print ' ' # NOTE: domain.riverwallData is initialised in shallow_water_domain.py for DE algorithms domain = self.domain # Check flow algorithm if (not domain.get_using_discontinuous_elevation()): raise Exception, 'Riverwalls are currently only supported for discontinuous elevation flow algorithms' if (len(self.names) > 0): # Delete any existing riverwall data # The function cannot presently be used to partially edit riverwall data if (verbose): print 'Warning: There seems to be existing riverwall data' print 'It will be deleted and overwritten with this function call' domain.riverwallData.__init__(domain) # Store input parameters # FIXME: Is this worth it? self.input_riverwall_geo = riverwalls self.input_riverwallPar = riverwallPar # Update self.default_riverwallPar (defined in __init__) for i in self.default_riverwallPar.keys(): if (default_riverwallPar.has_key(i)): self.default_riverwallPar[i] = default_riverwallPar[i] # Check that all the keys in default_riverwallPar are allowed for i in default_riverwallPar.keys(): if (not self.default_riverwallPar.has_key(i)): msg = 'Key ', i + ' in default_riverwallPar not recognized' raise Exception, msg # Final default river-wall parameters default_riverwallPar = self.default_riverwallPar # Check that all named inputs in riverwallPar correspond to names in # riverwall for i in riverwallPar.keys(): if not riverwalls.has_key(i): msg = 'Key ', i, ' in riverwallPar has no corresponding key in riverwall' raise Exception, msg # # Check that all hydraulic parameter names in riverwallPar correspond # to names in default_riverwallPar # for j in riverwallPar[i].keys(): if not default_riverwallPar.has_key(j): msg = 'Hydraulic parameter named ', j ,\ ' not recognised in default_riverwallPar' raise Exception, msg if (verbose): print 'Setting riverwall elevations (P' + str(myid) + ')...' # Set up geometry exy = domain.edge_coordinates llx = domain.mesh.geo_reference.get_xllcorner() lly = domain.mesh.geo_reference.get_yllcorner() # Temporary variables from anuga.config import max_float riverwall_elevation = exy[:, 0] * 0. - max_float riverwall_Qfactor = exy[:, 0] * 0. riverwall_rowIndex = exy[:, 0] * 0 - 1. riverwall_rowIndex.astype(int) # Loop over all segments in each riverwall, and set its elevation nw = range(len(riverwalls)) nw_names = riverwalls.keys( ) # Not guarenteed to be in deterministic order if (verbose): # Use variable to record messages, allows cleaner parallel printing printInfo = '' for i in nw: # Name of riverwall riverwalli_name = nw_names[i] # Look at the ith riverwall riverwalli = riverwalls[riverwalli_name] ns = len(riverwalli) - 1 if (verbose): printInfo = printInfo + ' Wall ' + str(i) + ' ....\n' for j in range(ns): if (verbose): printInfo = printInfo + ' Segment ' + str(j) + ' ....\n' # Start and end xyz coordinates start = riverwalli[j] end = riverwalli[j + 1] if (len(start) != 3 | len(end) != 3): msg = 'Each riverwall coordinate must have at exactly 3 values [xyz]' raise Exception, msg # Find length segLen = ((start[0] - end[0])**2 + (start[1] - end[1])**2)**0.5 if (segLen < tol): if (verbose): printInfo = printInfo + ' Segment with length < tolerance ' + str( tol) + ' ignored\n' continue # Find edge indices which are within 'tol' of the segment # We use a simple, inefficient method [but likely ok in practice # except for very complex riverwalls] # Unit vector along segment se_0 = -(start[0] - end[0]) / segLen se_1 = -(start[1] - end[1]) / segLen # Vector from 'start' to every point on mesh # NOTE: We account for georeferencing pv_0 = exy[:, 0] - (start[0] - llx) pv_1 = exy[:, 1] - (start[1] - lly) pvLen = (pv_0**2 + pv_1**2)**0.5 # Dot product of pv and se == along-segment distance of projection # of each point onto segment pv_dot_se = pv_0 * se_0 + pv_1 * se_1 # Normal distance^2 of each point to segment perp_len_sq = pvLen**2. - pv_dot_se**2. # Point is on a levee if the perpendicular distance is < tol, # AND it is between start and end [within a tolerance] onLevee = (perp_len_sq < tol**2) * (pv_dot_se > 0. - tol) * ( pv_dot_se < segLen + tol) onLevee = onLevee.nonzero() onLevee = onLevee[0] if (len(onLevee) == 0): continue if (verbose): printInfo = printInfo + ' Finding ' + str( len(onLevee)) + ' edges on this segment\n' # Levee has Edge_flux_type=1 domain.edge_flux_type[onLevee] = 1 # Get edge elevations as weighted averages of start/end elevations w0 = pv_dot_se[onLevee] / segLen w0 = w0 * (w0 >= 0.0) # Enforce min of 0 w0 = w0 * (w0 <= 1.0) + 1.0 * (w0 > 1.0) # Max of 1 riverwall_elevation[onLevee] = start[2] * (1.0 - w0) + w0 * end[2] # Record row index riverwall_rowIndex[onLevee] = i # Now, condense riverwall_elevation to array with length = number of riverwall edges # # We do this to avoid storing a riverwall_elevation for every edge in the mesh # However, the data structure ends up being quite complex -- maybe there is a better way? # # The zeroth index in domain.edge_flux_type which = 1 will correspond to riverwall_elevation[0] # The first index will correspond to riverwall_elevation[1] # etc # riverwallInds = (domain.edge_flux_type == 1).nonzero()[0] # elevation self.riverwall_elevation=\ riverwall_elevation[riverwallInds] # corresponding row in the hydraulic properties table self.hydraulic_properties_rowIndex=\ riverwall_rowIndex[riverwallInds].astype(int) # index of edges which are riverwalls self.riverwall_edges = riverwallInds # Record the names of the riverwalls self.names = nw_names # Now create the hydraulic properties table # Temporary variable to hold hydraulic properties table # This will have as many rows are there are distinct riverwalls, # and as many columns as there are hydraulic variables hydraulicTmp = numpy.zeros( (len(riverwalls), len(default_riverwallPar))) * numpy.nan if (verbose): print ' ' # Loop over every riverwall / hydraulic parameter, and set its value for i in nw: # Get the riverwall's name and specified parameters name_riverwalli = nw_names[i] if (riverwallPar.has_key(name_riverwalli)): riverwalli_Par = riverwallPar[name_riverwalli] else: riverwalli_Par = None # Set the ith riverwall's hydraulic properties for j, hydraulicVar in enumerate(self.hydraulic_variable_names): if ((riverwalli_Par is not None) and (riverwalli_Par.has_key(hydraulicVar))): if (verbose): printInfo=printInfo+ ' Using provided '+ str(hydraulicVar)+' '+\ str(riverwalli_Par[hydraulicVar])+ ' for riverwall '+ str(name_riverwalli)+'\n' hydraulicTmp[i, j] = riverwalli_Par[hydraulicVar] else: if (verbose): printInfo=printInfo+ ' Using default '+ str(hydraulicVar)+' '+\ str(default_riverwallPar[hydraulicVar])+' for riverwall '+ str(name_riverwalli)+'\n' hydraulicTmp[i, j] = default_riverwallPar[hydraulicVar] if (verbose): print ' ' # Check that s1 < s2 for i in nw: if (hydraulicTmp[i, 1] >= hydraulicTmp[i, 2]): msg = 's1 >= s2 on riverwall ' + nw_names[ i] + '. This is not allowed' raise Exception, msg if ((hydraulicTmp[i, 1] < 0.) or (hydraulicTmp[i, 2] < 0.)): raise Exception, 's1 and s2 must be positive, with s1<s2' # Check that h1 < h2 for i in nw: if (hydraulicTmp[i, 3] >= hydraulicTmp[i, 4]): msg = 'h1 >= h2 on riverwall ' + nw_names[ i] + '. This is not allowed' raise Exception, msg if ((hydraulicTmp[i, 3] < 0.) or (hydraulicTmp[i, 4] < 0.)): raise Exception, 'h1 and h2 must be positive, with h1<h2' # Define the hydraulic properties self.hydraulic_properties = hydraulicTmp # Check for riverwall 'connectedness' errors (e.g. theoretically possible # to miss an edge due to round-off) connectedness = self.check_riverwall_connectedness(verbose=verbose) self.export_riverwalls_to_text(output_dir=output_dir) # Pretty printing of riverwall information in parallel if (verbose): if domain.parallel: barrier() for i in range(numprocs): if (myid == i): print 'Processor ' + str(myid) print printInfo print connectedness[0] msg='Riverwall discontinuity -- possible round-off error in'+\ 'finding edges on wall -- try increasing value of tol' if (not connectedness[1]): raise Exception, msg if domain.parallel: barrier() return
verbose=True ) #-------------------------------------------------------------------------- # Create the computational domain based on overall clipping polygon with # a tagged boundary and interior regions defined in project.py along with # resolutions (maximal area of per triangle) for each polygon #-------------------------------------------------------------------------- log.critical('Create computational domain') else: print 'Hello from processor ', myid barrier() # Read in boundary from ordered sts file event_sts = anuga.create_sts_boundary(project.event_sts) # Reading the landward defined points, this incorporates the original clipping # polygon minus the 100m contour landward_boundary = anuga.read_polygon(project.landward_boundary) # Combine sts polyline with landward points bounding_polygon_sts = event_sts + landward_boundary # Number of boundary segments num_ocean_segments = len(event_sts) - 1 # Number of landward_boundary points
def run_simulation(parallel=False, verbose=False): #-------------------------------------------------------------------------- # Setup computational domain and quantities #-------------------------------------------------------------------------- if myid == 0: anuga.create_mesh_from_regions(boundaryPolygon, boundary_tags={'left': [0], 'top': [1], 'right': [2], 'bottom': [3]}, maximum_triangle_area = 1.0e+20, minimum_triangle_angle = 28.0, filename = 'runup.msh', interior_regions = [ [higherResPolygon, 1.*1.*0.5], [midResPolygon, 3.0*3.0*0.5]], breaklines=riverWall.values(), use_cache=False, verbose=verbose, regionPtArea=regionPtAreas) sdomain=anuga.create_domain_from_file('runup.msh') sdomain.set_flow_algorithm(alg) sdomain.set_name('s_riverwall') sdomain.set_datadir('.') sdomain.set_store_vertices_uniquely() #------------------ # Define topography #------------------ def topography(x,y): return -x/150.*scale_me def stagefun(x,y): stg=-0.5*scale_me return stg sdomain.set_quantity('elevation',topography) # Use function for elevation sdomain.set_quantity('friction',0.03) # Constant friction sdomain.set_quantity('stage', stagefun) # Constant negative initial stage else: sdomain = None #-------------------------------------------------------------------------- # Create the parallel domains #-------------------------------------------------------------------------- if parallel: if myid == 0 and verbose : print 'DISTRIBUTING TO PARALLEL DOMAIN' pdomain = distribute(sdomain, verbose=verbose) pdomain.set_name('p_riverwall') pdomain.set_store_vertices_uniquely() if myid == 0 and verbose: print 60*'=' print 'EVOLVING pdomain' print 60*'=' setup_and_evolve(pdomain, verbose=verbose) barrier() if myid == 0: if verbose: print 60*'=' print 'EVOLVING sdomain' print 60*'=' setup_and_evolve(sdomain, verbose=verbose) barrier() #--------------------------------- # Now compare the merged sww files #--------------------------------- if myid == 0: if verbose: print 'COMPARING SWW FILES' sdomain_v = util.get_output('s_riverwall.sww') sdomain_c = util.get_centroids(sdomain_v) pdomain_v = util.get_output('p_riverwall.sww') pdomain_c = util.get_centroids(pdomain_v) # Test some values against the original ordering if verbose: order = 0 print 'PDOMAIN CENTROID VALUES' print num.linalg.norm(sdomain_c.x-pdomain_c.x,ord=order) print num.linalg.norm(sdomain_c.y-pdomain_c.y,ord=order) print num.linalg.norm(sdomain_c.stage[-1]-pdomain_c.stage[-1],ord=order) print num.linalg.norm(sdomain_c.xmom[-1]-pdomain_c.xmom[-1],ord=order) print num.linalg.norm(sdomain_c.ymom[-1]-pdomain_c.ymom[-1],ord=order) print num.linalg.norm(sdomain_c.xvel[-1]-pdomain_c.xvel[-1],ord=order) print num.linalg.norm(sdomain_c.yvel[-1]-pdomain_c.yvel[-1],ord=order) assert num.allclose(sdomain_c.stage,pdomain_c.stage) assert num.allclose(sdomain_c.xmom,pdomain_c.xmom) assert num.allclose(sdomain_c.ymom,pdomain_c.ymom) assert num.allclose(sdomain_c.xvel,pdomain_c.xvel) assert num.allclose(sdomain_c.yvel,pdomain_c.yvel) assert num.allclose(sdomain_v.x,pdomain_v.x) assert num.allclose(sdomain_v.y,pdomain_v.y) import os os.remove('s_riverwall.sww') os.remove('p_riverwall.sww') os.remove('runup.msh')
def export_riverwalls_to_text(self, output_dir=None): """ Function for dumping riverwall outputs to text file (useful for QC) This will overwrite any existing files with the same location/name INPUT: output_dir = Directory where the outputs will be written OUTPUT: None, but writes files as a side effect """ if(output_dir is None): return if(myid == 0): # Make output directory try: os.mkdir(output_dir) except: pass # Make output files with empty contents for i, riverWallFile in enumerate(self.names): newFile=open(output_dir + '/' + os.path.splitext(os.path.basename(riverWallFile))[0] + '.txt','w') # Write hydraulic variable information hydraulicVars=self.hydraulic_properties[i,:] newFile.write('## Hydraulic Variable values below ## \n') newFile.write(str(self.hydraulic_variable_names) + '\n') newFile.write(str(hydraulicVars) + '\n') newFile.write('\n') newFile.write('## xyElevation at edges below. Order may be erratic for parallel runs ##\n') newFile.close() else: pass domain = self.domain # The other processes might try to write into file # before process 0 has created file, so we need a # barrier if domain.parallel: barrier() # Now dump the required info to the files for i in range(numprocs): # Write 1 processor at a time if(myid == i): for j, riverWallname in enumerate(self.names): # Get xyz data for riverwall j riverWallInds = (self.hydraulic_properties_rowIndex==j).nonzero()[0].tolist() riverWallDomainInds = self.riverwall_edges[riverWallInds].tolist() myXCoords = domain.edge_coordinates[riverWallDomainInds,0] + domain.geo_reference.xllcorner myYCoords = domain.edge_coordinates[riverWallDomainInds,1] + domain.geo_reference.yllcorner myElev = self.riverwall_elevation[riverWallInds] # Open file for appending data theFile = open(output_dir + '/' + os.path.splitext(os.path.basename(riverWallname))[0] + '.txt','a') for k in range(len(myElev)): theFile.write(str(myXCoords[k]) + ',' + str(myYCoords[k]) + ',' + str(myElev[k]) + '\n') theFile.close() else: pass return
def create_riverwalls(self, riverwalls, riverwallPar={ }, default_riverwallPar={ }, tol=1.0e-4, verbose=True, output_dir=None): """Add riverwalls at chosen locations along the mesh As of 22/04/2014, these only work with DE algorithms [for which the concept is natural] The walls MUST EXACTLY COINCIDE with edges along the mesh You can force the mesh to do this by passing riverwalls.values() to the 'breaklines' argument in the function create_mesh_from_regions. You may also need to set the maximum_triangle_area for regions, if the breaklines split the region. Do this with the regionPtArea argument in create_mesh_from_regions. As of 22/04/2014, the computational method used here is very 'brute-force' For each segment on each riverwall, every point in the mesh is checked to see if it is on the segment. A possibly faster/less memory method would be to 'walk' through connected edges on the mesh. Inputs: riverwalls: Dictionary of '3D polygons', containing xyz locations of named riverwalls. exampleRiverWalls = { # Left bank n1 -- 'n1': [[1.0, 1000., 2.], [1.0, 50., 3.]], # Left bank n2 'n2': [[2.0, 30., 1.0], [3.0, 20., 2.], [2.5, 15., 1.5]] } riverwallPar: Dictionary containing a dictionary of named hydraulic parameters for each named riverwall If parameters are not provided, default values will be used. See the help for class 'RiverWall' for an explanation of these exampleRiverWallPar = {'n2': {'Qfactor':0.5} } This would use a Qfactor of 0.5 for riverwall 'n2', while the other riverwall would have the default values default_riverwallPar: Dictionary containing default values of the riverwall parameters, to be used if they are not explicitly set. If not provided, defaults from __init__ are used. See the help for class 'RiverWall' for more info example_default_riverwallPar = {'Qfactor':1.5, 's1': 0.9, 's2': 0.95, 'h1': 1.0, 'h2': 1.5 } example_default_riverwallPar = {'Qfactor':1.5, 's1': 10000., 's2': 20000. } # Here h1/h2 defaults will come from __init__ tol: Edges will be assigned a riverwall elevation if they are within 'tol' of a segment in riverwalls. Round-off error means this should not be too small. verbose: TRUE/FALSE Print lots of information output_dir: Text representation of riverwalls is written to output_dir, unless output_dir=None Outputs: None, but it sets domain.edge_flux_type = 1 for every edge on a riverwall Also, it adds a RiverWall object domain.riverwallData to the domain The latter contains the riverwall heights, names, and hydraulic properties for each edge, in a way we can pass in/out of C code. """ #if(verbose and myid==0): # print ' ' # print 'WARNING: Riverwall is an experimental feature' # print ' At each riverwall edge, we place a thin "wall" between' # print ' the 2 edges -- so each sees its neighbour edge as having' # print ' bed elevation = max(levee height, neighbour bed elevation)' # print ' We also force the discharge with a weir relation, blended with' # print ' the shallow water flux solution as the ratio (min_head)/(weir_height) becomes ' # print ' large, or the ratio (downstream_head)/(upstream_head) becomes large' # print ' ' # print ' It works in parallel, but you must use domain.riverwallData.create_riverwall AFTER distributing the mesh' # print ' ' # NOTE: domain.riverwallData is initialised in shallow_water_domain.py for DE algorithms domain=self.domain # Check flow algorithm if(not domain.get_using_discontinuous_elevation()): raise Exception, 'Riverwalls are currently only supported for discontinuous elevation flow algorithms' if(len(self.names)>0): # Delete any existing riverwall data # The function cannot presently be used to partially edit riverwall data if(verbose): print 'Warning: There seems to be existing riverwall data' print 'It will be deleted and overwritten with this function call' domain.riverwallData.__init__(domain) # Store input parameters # FIXME: Is this worth it? self.input_riverwall_geo=riverwalls self.input_riverwallPar=riverwallPar # Update self.default_riverwallPar (defined in __init__) for i in self.default_riverwallPar.keys(): if(default_riverwallPar.has_key(i)): self.default_riverwallPar[i]=default_riverwallPar[i] # Check that all the keys in default_riverwallPar are allowed for i in default_riverwallPar.keys(): if(not self.default_riverwallPar.has_key(i)): msg='Key ', i + ' in default_riverwallPar not recognized' raise Exception, msg # Final default river-wall parameters default_riverwallPar=self.default_riverwallPar # Check that all named inputs in riverwallPar correspond to names in # riverwall for i in riverwallPar.keys(): if not riverwalls.has_key(i): msg= 'Key ', i, ' in riverwallPar has no corresponding key in riverwall' raise Exception, msg # # Check that all hydraulic parameter names in riverwallPar correspond # to names in default_riverwallPar # for j in riverwallPar[i].keys(): if not default_riverwallPar.has_key(j): msg = 'Hydraulic parameter named ', j ,\ ' not recognised in default_riverwallPar' raise Exception, msg if(verbose): print 'Setting riverwall elevations (P'+str(myid)+')...' # Set up geometry exy=domain.edge_coordinates llx=domain.mesh.geo_reference.get_xllcorner() lly=domain.mesh.geo_reference.get_yllcorner() # Temporary variables from anuga.config import max_float riverwall_elevation=exy[:,0]*0. - max_float riverwall_Qfactor=exy[:,0]*0. riverwall_rowIndex=exy[:,0]*0 -1. riverwall_rowIndex.astype(int) # Loop over all segments in each riverwall, and set its elevation nw=range(len(riverwalls)) nw_names=riverwalls.keys() # Not guarenteed to be in deterministic order if(verbose): # Use variable to record messages, allows cleaner parallel printing printInfo='' for i in nw: # Name of riverwall riverwalli_name=nw_names[i] # Look at the ith riverwall riverwalli=riverwalls[riverwalli_name] ns=len(riverwalli)-1 if(verbose): printInfo=printInfo + ' Wall ' + str(i) +' ....\n' for j in range(ns): if(verbose): printInfo=printInfo + ' Segment ' + str(j) +' ....\n' # Start and end xyz coordinates start=riverwalli[j] end=riverwalli[j+1] if(len(start)!=3 | len(end)!=3): msg='Each riverwall coordinate must have at exactly 3 values [xyz]' raise Exception, msg # Find length segLen=( (start[0]-end[0])**2+(start[1]-end[1])**2)**0.5 if(segLen<tol): if(verbose): printInfo=printInfo+' Segment with length < tolerance ' + str(tol) +' ignored\n' continue # Find edge indices which are within 'tol' of the segment # We use a simple, inefficient method [but likely ok in practice # except for very complex riverwalls] # Unit vector along segment se_0=-(start[0]-end[0])/segLen se_1=-(start[1]-end[1])/segLen # Vector from 'start' to every point on mesh # NOTE: We account for georeferencing pv_0 = exy[:,0]-(start[0]-llx) pv_1 = exy[:,1]-(start[1]-lly) pvLen=( pv_0**2 + pv_1**2)**0.5 # Dot product of pv and se == along-segment distance of projection # of each point onto segment pv_dot_se = pv_0*se_0+pv_1*se_1 # Normal distance^2 of each point to segment perp_len_sq = pvLen**2.-pv_dot_se**2. # Point is on a levee if the perpendicular distance is < tol, # AND it is between start and end [within a tolerance] onLevee=(perp_len_sq<tol**2)*(pv_dot_se > 0.-tol)*(pv_dot_se<segLen+tol) onLevee=onLevee.nonzero() onLevee=onLevee[0] if(len(onLevee)==0): continue if(verbose): printInfo=printInfo+' Finding ' + str(len(onLevee)) + ' edges on this segment\n' # Levee has Edge_flux_type=1 domain.edge_flux_type[onLevee]=1 # Get edge elevations as weighted averages of start/end elevations w0=pv_dot_se[onLevee]/segLen w0=w0*(w0>=0.0) # Enforce min of 0 w0=w0*(w0<=1.0) + 1.0*(w0>1.0) # Max of 1 riverwall_elevation[onLevee]= start[2]*(1.0-w0)+w0*end[2] # Record row index riverwall_rowIndex[onLevee] = i # Now, condense riverwall_elevation to array with length = number of riverwall edges # # We do this to avoid storing a riverwall_elevation for every edge in the mesh # However, the data structure ends up being quite complex -- maybe there is a better way? # # The zeroth index in domain.edge_flux_type which = 1 will correspond to riverwall_elevation[0] # The first index will correspond to riverwall_elevation[1] # etc # riverwallInds=(domain.edge_flux_type==1).nonzero()[0] # elevation self.riverwall_elevation=\ riverwall_elevation[riverwallInds] # corresponding row in the hydraulic properties table self.hydraulic_properties_rowIndex=\ riverwall_rowIndex[riverwallInds].astype(int) # index of edges which are riverwalls self.riverwall_edges=riverwallInds # Record the names of the riverwalls self.names=nw_names # Now create the hydraulic properties table # Temporary variable to hold hydraulic properties table # This will have as many rows are there are distinct riverwalls, # and as many columns as there are hydraulic variables hydraulicTmp=numpy.zeros((len(riverwalls), len(default_riverwallPar)))*numpy.nan if(verbose): print ' ' # Loop over every riverwall / hydraulic parameter, and set its value for i in nw: # Get the riverwall's name and specified parameters name_riverwalli=nw_names[i] if(riverwallPar.has_key(name_riverwalli)): riverwalli_Par=riverwallPar[name_riverwalli] else: riverwalli_Par=None # Set the ith riverwall's hydraulic properties for j, hydraulicVar in enumerate(self.hydraulic_variable_names): if((riverwalli_Par is not None) and (riverwalli_Par.has_key(hydraulicVar))): if(verbose): printInfo=printInfo+ ' Using provided '+ str(hydraulicVar)+' '+\ str(riverwalli_Par[hydraulicVar])+ ' for riverwall '+ str(name_riverwalli)+'\n' hydraulicTmp[i,j]=riverwalli_Par[hydraulicVar] else: if(verbose): printInfo=printInfo+ ' Using default '+ str(hydraulicVar)+' '+\ str(default_riverwallPar[hydraulicVar])+' for riverwall '+ str(name_riverwalli)+'\n' hydraulicTmp[i,j]=default_riverwallPar[hydraulicVar] if(verbose): print ' ' # Check that s1 < s2 for i in nw: if(hydraulicTmp[i,1]>= hydraulicTmp[i,2]): msg = 's1 >= s2 on riverwall ' + nw_names[i] +'. This is not allowed' raise Exception, msg if( (hydraulicTmp[i,1]<0.) or (hydraulicTmp[i,2] < 0.)): raise Exception, 's1 and s2 must be positive, with s1<s2' # Check that h1 < h2 for i in nw: if(hydraulicTmp[i,3]>= hydraulicTmp[i,4]): msg = 'h1 >= h2 on riverwall ' + nw_names[i] +'. This is not allowed' raise Exception, msg if((hydraulicTmp[i,3]<0.) or (hydraulicTmp[i,4] < 0.)): raise Exception, 'h1 and h2 must be positive, with h1<h2' # Define the hydraulic properties self.hydraulic_properties=hydraulicTmp # Check for riverwall 'connectedness' errors (e.g. theoretically possible # to miss an edge due to round-off) connectedness=self.check_riverwall_connectedness(verbose=verbose) self.export_riverwalls_to_text(output_dir=output_dir) # Pretty printing of riverwall information in parallel if(verbose): if domain.parallel : barrier() for i in range(numprocs): if(myid==i): print 'Processor '+str(myid) print printInfo print connectedness[0] msg='Riverwall discontinuity -- possible round-off error in'+\ 'finding edges on wall -- try increasing value of tol' if(not connectedness[1]): raise Exception, msg if domain.parallel : barrier() return
def start_sim(run_id, Runs, scenario_name, Scenario, session, **kwargs): yieldstep = kwargs['yieldstep'] finaltime = kwargs['finaltime'] logger = logging.getLogger(run_id) max_triangle_area = kwargs['max_triangle_area'] logger.info('Starting hydrata_project') if run_id == 'local_run': base_dir = os.getcwd() else: base_dir = os.getcwd() + '/base_dir/%s/' % run_id outname = run_id meshname = base_dir + 'outputs/' + run_id + '.msh' def get_filename(data_type, file_type): files = os.listdir('%sinputs/%s' % (base_dir, data_type)) filename = '%sinputs/%s/%s' % ( base_dir, data_type, [f for f in files if f[-4:] == file_type][0]) return filename boundary_data_filename = get_filename('boundary_data', '.shp') elevation_data_filename = get_filename('elevation_data', '.tif') try: structures_filename = get_filename('structures', '.shp') except OSError as e: structures_filename = None try: rain_data_filename = get_filename('rain_data', '.shp') except OSError as e: rain_data_filename = None try: inflow_data_filename = get_filename('inflow_data', '.shp') except OSError as e: inflow_data_filename = None try: friction_data_filename = get_filename('friction_data', '.shp') except OSError as e: friction_data_filename = None logger.info('boundary_data_filename: %s' % boundary_data_filename) logger.info('structures_filename: %s' % structures_filename) logger.info('rain_data_filename: %s' % rain_data_filename) logger.info('inflow_data_filename: %s' % inflow_data_filename) logger.info('friction_data_filename: %s' % friction_data_filename) logger.info('elevation_data_filename: %s' % elevation_data_filename) # create a list of project files vector_filenames = [ boundary_data_filename, structures_filename, rain_data_filename, inflow_data_filename, friction_data_filename ] # set the projection system for ANUGA calculations from the geotiff elevation data elevation_data_gdal = gdal.Open(elevation_data_filename) project_spatial_ref = osr.SpatialReference() project_spatial_ref.ImportFromWkt(elevation_data_gdal.GetProjectionRef()) project_spatial_ref_epsg_code = int( project_spatial_ref.GetAttrValue("AUTHORITY", 1)) # check the spatial reference system of the project files matches that of the calculation for filename in vector_filenames: if filename: prj_text = open(filename[:-4] + '.prj').read() srs = osr.SpatialReference() srs.ImportFromESRI([prj_text]) srs.AutoIdentifyEPSG() logger.info('filename is: %s' % filename) logger.info('EPSG is: %s' % srs.GetAuthorityCode(None)) if str(srs.GetAuthorityCode(None)) != str( project_spatial_ref_epsg_code): logger.warning('warning spatial refs are not maching: %s, %s' % (srs.GetAuthorityCode(None), project_spatial_ref_epsg_code)) logger.info('Setting up structures...') if structures_filename: structures = [] logger.info('processing structures from :%s' % structures_filename) ogr_shapefile = ogr.Open(structures_filename) ogr_layer = ogr_shapefile.GetLayer(0) ogr_layer_feature = ogr_layer.GetNextFeature() while ogr_layer_feature: structure = json.loads(ogr_layer_feature.GetGeometryRef(). ExportToJson())['coordinates'][0] structures.append(structure) ogr_layer_feature = None ogr_layer_feature = ogr_layer.GetNextFeature() logger.info('structures: %s' % structures) else: logger.warning('warning: no structures found.') structures = None logger.info('Setting up friction...') frictions = [] if friction_data_filename: logger.info('processing frictions from :%s' % friction_data_filename) ogr_shapefile = ogr.Open(friction_data_filename) ogr_layer = ogr_shapefile.GetLayer(0) ogr_layer_feature = ogr_layer.GetNextFeature() while ogr_layer_feature: friction_poly = json.loads(ogr_layer_feature.GetGeometryRef(). ExportToJson())['coordinates'][0] friction_value = float(ogr_layer_feature.GetField('mannings')) friction_couple = [friction_poly, friction_value] frictions.append(friction_couple) ogr_layer_feature = None ogr_layer_feature = ogr_layer.GetNextFeature() frictions.append(['All', 0.04]) logger.info('frictions: %s' % frictions) else: frictions.append(['All', 0.04]) logger.info('warning: no frictions found.') logger.info('Setting up boundary conditions...') ogr_shapefile = ogr.Open(boundary_data_filename) ogr_layer = ogr_shapefile.GetLayer(0) ogr_layer_definition = ogr_layer.GetLayerDefn() logger.info('ogr_layer_definition.GetGeomType: %s' % ogr_layer_definition.GetGeomType()) boundary_tag_index = 0 bdy_tags = {} bdy = {} ogr_layer_feature = ogr_layer.GetNextFeature() while ogr_layer_feature: boundary_tag_key = ogr_layer_feature.GetField('bdy_tag_k') boundary_tag_value = ogr_layer_feature.GetField('bdy_tag_v') bdy_tags[boundary_tag_key] = [ boundary_tag_index * 2, boundary_tag_index * 2 + 1 ] bdy[boundary_tag_key] = boundary_tag_value geom = ogr_layer_feature.GetGeometryRef().GetPoints() ogr_layer_feature = None ogr_layer_feature = ogr_layer.GetNextFeature() boundary_tag_index = boundary_tag_index + 1 logger.info('bdy_tags: %s' % bdy_tags) logger.info('bdy: %s' % bdy) boundary_data = su.read_polygon(boundary_data_filename) create_mesh_from_regions(boundary_data, boundary_tags=bdy_tags, maximum_triangle_area=max_triangle_area, interior_regions=None, interior_holes=structures, filename=meshname, use_cache=False, verbose=True) domain = Domain(meshname, use_cache=False, verbose=True) domain.set_name(outname) domain.set_datadir(base_dir + '/outputs') logger.info(domain.statistics()) poly_fun_pairs = [['Extent', elevation_data_filename.encode("utf-8")]] topography_function = qs.composite_quantity_setting_function( poly_fun_pairs, domain, nan_treatment='exception', ) friction_function = qs.composite_quantity_setting_function( frictions, domain) domain.set_quantity('friction', friction_function, verbose=True) domain.set_quantity('stage', 0.0) domain.set_quantity('elevation', topography_function, verbose=True, alpha=0.99) domain.set_minimum_storable_height(0.005) logger.info('Applying rainfall...') if rain_data_filename: ogr_shapefile = ogr.Open(rain_data_filename) ogr_layer = ogr_shapefile.GetLayer(0) rainfall = 0 ogr_layer_feature = ogr_layer.GetNextFeature() while ogr_layer_feature: rainfall = float(ogr_layer_feature.GetField('rate_mm_hr')) polygon = su.read_polygon(rain_data_filename) logger.info("applying Polygonal_rate_operator with rate, polygon:") logger.info(rainfall) logger.info(polygon) Polygonal_rate_operator(domain, rate=rainfall, factor=1.0e-6, polygon=polygon, default_rate=0.0) ogr_layer_feature = None ogr_layer_feature = ogr_layer.GetNextFeature() logger.info('Applying surface inflows...') if inflow_data_filename: ogr_shapefile = ogr.Open(inflow_data_filename) ogr_layer = ogr_shapefile.GetLayer(0) ogr_layer_definition = ogr_layer.GetLayerDefn() ogr_layer_feature = ogr_layer.GetNextFeature() while ogr_layer_feature: in_fixed = float(ogr_layer_feature.GetField('in_fixed')) line = ogr_layer_feature.GetGeometryRef().GetPoints() logger.info("applying Inlet_operator with line, in_fixed:") logger.info(line) logger.info(in_fixed) Inlet_operator(domain, line, in_fixed, verbose=False) ogr_layer_feature = None ogr_layer_feature = ogr_layer.GetNextFeature() logger.info('Applying Boundary Conditions...') logger.info('Available boundary tags: %s' % domain.get_boundary_tags()) Br = anuga.Reflective_boundary(domain) Bd = anuga.Dirichlet_boundary([0.0, 0.0, 0.0]) Bt = anuga.Transmissive_boundary(domain) for key, value in bdy.iteritems(): if value == 'Br': bdy[key] = Br elif value == 'Bd': bdy[key] = Bd elif value == 'Bt': bdy[key] = Bt else: logger.info( 'No matching boundary condition exists - please check your shapefile attributes in: %s' % boundary_data_filename) # set a default value for exterior & interior boundary if it is not already set try: bdy['exterior'] except KeyError: bdy['exterior'] = Br try: bdy['interior'] except KeyError: bdy['interior'] = Br logger.info('bdy: %s' % bdy) domain.set_boundary(bdy) domain = distribute(domain) logger.info('Beginning evolve phase...') for t in domain.evolve(yieldstep, finaltime): domain.write_time() print domain.timestepping_statistics() logger.info(domain.timestepping_statistics(track_speeds=True)) percentage_complete = round(domain.time / domain.finaltime, 3) * 100 logger.info('%s percent complete' % percentage_complete) if run_id != 'local_run': write_percentage_complete(run_id, Runs, scenario_name, Scenario, session, percentage_complete) domain.sww_merge(delete_old=True) barrier() finalize() sww_file = base_dir + '/outputs/' + run_id + '.sww' sww_file = sww_file.encode( 'utf-8', 'ignore') # sometimes run_id gets turned to a unicode object by celery util.Make_Geotif(swwFile=sww_file, output_quantities=['depth', 'velocity'], myTimeStep='max', CellSize=max_triangle_area, lower_left=None, upper_right=None, EPSG_CODE=project_spatial_ref_epsg_code, proj4string=None, velocity_extrapolation=True, min_allowed_height=1.0e-05, output_dir=(base_dir + '/outputs/'), bounding_polygon=boundary_data, internal_holes=structures, verbose=False, k_nearest_neighbours=3, creation_options=[]) logger.info("Done. Nice work.")
def run_simulation(parallel=False, verbose=False): #-------------------------------------------------------------------------- # Setup computational domain and quantities #-------------------------------------------------------------------------- if myid == 0: anuga.create_mesh_from_regions( boundaryPolygon, boundary_tags={ 'left': [0], 'top': [1], 'right': [2], 'bottom': [3] }, maximum_triangle_area=1.0e+20, minimum_triangle_angle=28.0, filename='runup.msh', interior_regions=[[higherResPolygon, 1. * 1. * 0.5], [midResPolygon, 3.0 * 3.0 * 0.5]], breaklines=list(riverWall.values()), use_cache=False, verbose=verbose, regionPtArea=regionPtAreas) sdomain = anuga.create_domain_from_file('runup.msh') sdomain.set_flow_algorithm(alg) sdomain.set_name('s_riverwall') sdomain.set_datadir('.') sdomain.set_store_vertices_uniquely() #------------------ # Define topography #------------------ def topography(x, y): return -x / 150. * scale_me def stagefun(x, y): stg = -0.5 * scale_me return stg sdomain.set_quantity('elevation', topography) # Use function for elevation sdomain.set_quantity('friction', 0.03) # Constant friction sdomain.set_quantity('stage', stagefun) # Constant negative initial stage else: sdomain = None #-------------------------------------------------------------------------- # Create the parallel domains #-------------------------------------------------------------------------- if parallel: if myid == 0 and verbose: print('DISTRIBUTING TO PARALLEL DOMAIN') pdomain = distribute(sdomain, verbose=verbose) pdomain.set_name('p_riverwall') pdomain.set_store_vertices_uniquely() if myid == 0 and verbose: print(60 * '=') print('EVOLVING pdomain') print(60 * '=') setup_and_evolve(pdomain, verbose=verbose) barrier() if myid == 0: if verbose: print(60 * '=') print('EVOLVING sdomain') print(60 * '=') setup_and_evolve(sdomain, verbose=verbose) barrier() #--------------------------------- # Now compare the merged sww files #--------------------------------- if myid == 0: if verbose: print('COMPARING SWW FILES') sdomain_v = util.get_output('s_riverwall.sww') sdomain_c = util.get_centroids(sdomain_v) pdomain_v = util.get_output('p_riverwall.sww') pdomain_c = util.get_centroids(pdomain_v) # Test some values against the original ordering if verbose: order = 0 print('PDOMAIN CENTROID VALUES') print(num.linalg.norm(sdomain_c.x - pdomain_c.x, ord=order)) print(num.linalg.norm(sdomain_c.y - pdomain_c.y, ord=order)) print( num.linalg.norm(sdomain_c.stage[-1] - pdomain_c.stage[-1], ord=order)) print( num.linalg.norm(sdomain_c.xmom[-1] - pdomain_c.xmom[-1], ord=order)) print( num.linalg.norm(sdomain_c.ymom[-1] - pdomain_c.ymom[-1], ord=order)) print( num.linalg.norm(sdomain_c.xvel[-1] - pdomain_c.xvel[-1], ord=order)) print( num.linalg.norm(sdomain_c.yvel[-1] - pdomain_c.yvel[-1], ord=order)) assert num.allclose(sdomain_c.stage, pdomain_c.stage) assert num.allclose(sdomain_c.xmom, pdomain_c.xmom) assert num.allclose(sdomain_c.ymom, pdomain_c.ymom) assert num.allclose(sdomain_c.xvel, pdomain_c.xvel) assert num.allclose(sdomain_c.yvel, pdomain_c.yvel) assert num.allclose(sdomain_v.x, pdomain_v.x) assert num.allclose(sdomain_v.y, pdomain_v.y) import os os.remove('s_riverwall.sww') os.remove('p_riverwall.sww') os.remove('runup.msh')
# setup and create operator within polys setting the scour base elevations for each poly op0 = Sanddune_erosion_operator(domain, base=nsbase_elev_c, indices=indices_union, Ra=45) # both dunes # op1 = sanddune_erosion_operator(domain, base=nsbase_elev_c, polygon=polygon1) # first notched dune # op2 = sanddune_erosion_operator(domain, base=nsbase_elev_c, polygon=polygon2) # second plain dune # ------------------------------------------------------------------------------ # Evolve sanddune erosion simulation through time # ------------------------------------------------------------------------------ for t in domain.evolve(yieldstep=1, duration=600.0): if myid == 0: domain.print_timestepping_statistics() # run completed - tidy up barrier() if myid == 0: print " >>>>> Simulation completed succesfully " print " >>>>> Merging the individual cpu sww files and deleting the individual swws once merged" # Merge the individual parallel swws created by the n processors barrier() # wait foir all processors to complete domain.sww_merge(delete_old=False) if myid == 0: print " >>>>> Finalising the run -- all done" # Finaise the parallel code and this model run barrier() # wait for all processors to complete finalize()
def distibute_three_processors(): """ Do a parallel test of distributing a rectangle onto 3 processors """ # FIXME: Need to update expected values on macos if sys.platform == 'darwin': return # FIXME: Need to update expected values on macos #if sys.platform == 'win32': # return from anuga.utilities import parallel_abstraction as pypar myid = pypar.rank() numprocs = pypar.size() if not numprocs == 3: return try: import pymetis metis_version = 5 except: metis_version = 4 #print numprocs #barrier() if myid == 0: nodes_0, triangles_0, boundary_0 = rectangular_cross(2, 2) domain = Domain(nodes_0, triangles_0, boundary_0) domain.set_quantity('elevation', topography) # Use function for elevation domain.set_quantity('friction', 0.0) # Constant friction domain.set_quantity('stage', expression='elevation') # Dry initial stage domain.set_quantity('xmomentum', expression='friction + 2.0') domain.set_quantity('ymomentum', ycoord) #---------------------------------------------------------------------------------- # Test pmesh_divide_metis #---------------------------------------------------------------------------------- vertices, triangles, boundary, triangles_per_proc, quantities = pmesh_divide_metis( domain, numprocs) if False: print_seq_values(vertices, triangles, triangles_per_proc) true_seq_values = get_true_seq_values(metis_version=metis_version) if False: print("True Seq Values = \\") pprint(true_seq_values) assert_allclose(vertices, true_seq_values['vertices']) assert_allclose(triangles, true_seq_values['triangles']) assert_allclose(triangles_per_proc, true_seq_values['triangles_per_proc']) #---------------------------------------------------------------------------------- # Test build_submesh #---------------------------------------------------------------------------------- submesh = build_submesh(vertices, triangles, boundary, quantities, triangles_per_proc) if False: print('submesh_values = \\') print_submesh_values(submesh) true_values = get_true_submesh_values(metis_version) assert_allclose(submesh['full_nodes'][0], true_values['full_nodes_0']) assert_allclose(submesh['full_nodes'][1], true_values['full_nodes_1']) assert_allclose(submesh['full_nodes'][2], true_values['full_nodes_2']) assert_allclose(submesh['ghost_nodes'][0], true_values['ghost_nodes_0']) assert_allclose(submesh['ghost_nodes'][1], true_values['ghost_nodes_1']) assert_allclose(submesh['ghost_nodes'][2], true_values['ghost_nodes_2']) assert_allclose(submesh['full_triangles'][0], true_values['full_triangles_0']) assert_allclose(submesh['full_triangles'][1], true_values['full_triangles_1']) assert_allclose(submesh['full_triangles'][2], true_values['full_triangles_2']) assert_allclose(submesh['ghost_triangles'][0], true_values['ghost_triangles_0']) assert_allclose(submesh['ghost_triangles'][1], true_values['ghost_triangles_1']) assert_allclose(submesh['ghost_triangles'][2], true_values['ghost_triangles_2']) assert_allclose(submesh['ghost_commun'][0], true_values['ghost_commun_0']) assert_allclose(submesh['ghost_commun'][1], true_values['ghost_commun_1']) assert_allclose(submesh['ghost_commun'][2], true_values['ghost_commun_2']) assert_(submesh['full_commun'] == true_values['full_commun']) barrier() #-------------------------------- # Now do the comunnication part #-------------------------------- if myid == 0: points, vertices, boundary, quantities, \ ghost_recv_dict, full_send_dict, tri_map, node_map, tri_l2g, node_l2g, \ ghost_layer_width =\ extract_submesh(submesh, triangles_per_proc) #---------------------------------------------------------------------------------- # Test send_submesh #---------------------------------------------------------------------------------- for p in range(1, numprocs): send_submesh(submesh, triangles_per_proc, p, verbose=False) else: #---------------------------------------------------------------------------------- # Test rec_submesh #---------------------------------------------------------------------------------- points, triangles, boundary, quantities, \ ghost_recv_dict, full_send_dict, \ no_full_nodes, no_full_trigs, tri_map, node_map, tri_l2g, node_l2g, \ ghost_layer_width = \ rec_submesh(0, verbose=False) barrier() #-------------------------------- # Now do the test #-------------------------------- if myid == 0: if False: print('extract_values = \\') print_extract_submesh(points, triangles, ghost_recv_dict, \ full_send_dict, tri_map, node_map, ghost_layer_width) true_values = get_true_extract_submesh(metis_version) assert_allclose(points, true_values['points']) assert_allclose(triangles, true_values['triangles']) assert_allclose(ghost_recv_dict[1], true_values['ghost_recv_dict_1']) assert_allclose(ghost_recv_dict[2], true_values['ghost_recv_dict_2']) assert_allclose(full_send_dict[1], true_values['full_send_dict_1']) assert_allclose(full_send_dict[2], true_values['full_send_dict_2']) assert_allclose(tri_map, true_values['tri_map']) assert_allclose(node_map, true_values['node_map']) assert_allclose(ghost_layer_width, true_values['ghost_layer_width']) if myid == 1: if False: print("rec_submesh_1 = \\") print_rec_submesh_1(points, triangles, ghost_recv_dict, full_send_dict, \ tri_map, node_map, ghost_layer_width) true_values = get_true_rec_submesh_1(metis_version) if False: print('true_rec_values_1 = \\') pprint(true_values) assert_allclose(points, true_values['points']) assert_allclose(triangles, true_values['triangles']) assert_allclose(ghost_recv_dict[0], true_values['ghost_recv_dict_0']) assert_allclose(ghost_recv_dict[2], true_values['ghost_recv_dict_2']) assert_allclose(full_send_dict[0], true_values['full_send_dict_0']) assert_allclose(full_send_dict[2], true_values['full_send_dict_2']) assert_allclose(tri_map, true_values['tri_map']) assert_allclose(node_map, true_values['node_map']) assert_allclose(ghost_layer_width, true_values['ghost_layer_width']) if myid == 2: if False: print("rec_submesh_2 = \\") print_rec_submesh_2(points, triangles, ghost_recv_dict, full_send_dict, \ tri_map, node_map, ghost_layer_width) true_values = get_true_rec_submesh_2(metis_version) if False: print('true_rec_values_2 = \\') pprint(true_values) assert_allclose(points, true_values['points']) assert_allclose(triangles, true_values['triangles']) assert_allclose(ghost_recv_dict[0], true_values['ghost_recv_dict_0']) assert_allclose(ghost_recv_dict[1], true_values['ghost_recv_dict_1']) assert_allclose(full_send_dict[0], true_values['full_send_dict_0']) assert_allclose(full_send_dict[1], true_values['full_send_dict_1']) assert_allclose(tri_map, true_values['tri_map']) assert_allclose(node_map, true_values['node_map']) assert_allclose(ghost_layer_width, true_values['ghost_layer_width']) finalize()
# setup and create operator within polys setting the scour base elevations for each poly op0 = Sanddune_erosion_operator(domain, base=nsbase_elev_c, indices=indices_union, Ra=45) # both dunes #op1 = sanddune_erosion_operator(domain, base=nsbase_elev_c, polygon=polygon1) # first notched dune #op2 = sanddune_erosion_operator(domain, base=nsbase_elev_c, polygon=polygon2) # second plain dune #------------------------------------------------------------------------------ # Evolve sanddune erosion simulation through time #------------------------------------------------------------------------------ for t in domain.evolve(yieldstep=1, duration=600.0): if myid == 0: domain.print_timestepping_statistics() # run completed - tidy up barrier() if myid == 0: print ' >>>>> Simulation completed succesfully ' print ' >>>>> Merging the individual cpu sww files and deleting the individual swws once merged' # Merge the individual parallel swws created by the n processors barrier() # wait foir all processors to complete domain.sww_merge(delete_old=False) if myid == 0: print ' >>>>> Finalising the run -- all done' # Finaise the parallel code and this model run barrier() # wait for all processors to complete finalize()
len2=width) domain.set_quantity('elevation', -1.0) domain.set_quantity('stage', Set_Stage(h=2.0)) else: domain = None #-------------------------------------------------------------------------- # Distribute sequential domain on processor 0 to other processors #-------------------------------------------------------------------------- if myid == 0 and verbose: print('DISTRIBUTING DOMAIN') domain = distribute(domain) #domain.smooth = False barrier() for p in range(numprocs): if myid == p: print('Process ID %g' % myid) print('Number of triangles %g ' % domain.get_number_of_triangles()) sys.stdout.flush() barrier() domain.set_flow_algorithm(2.0) if myid == 0: domain.print_algorithm_parameters() sys.stdout.flush() barrier()