def get_cir(radius=None, center=None, domain=None, size=None, polygons=None): if polygons is not None: polygon1 = polygons[0] # the larger one polygon2 = polygons[1] opp1 = Rate_operator(domain, polygon=polygon1) opp2 = Rate_operator(domain, polygon=polygon2) if isinstance(polygon1, Region): opp1.region = polygon1 else: opp1.region = Region(domain, poly=polygon1, expand_polygon=True) if isinstance(polygon2, Region): opp2.region = polygon2 else: opp2.region = Region(domain, poly=polygon2, expand_polygon=True) if radius is not None and center is not None: region1 = Region(domain, radius=radius, center=center) region2 = Region(domain, radius=radius - size, center=center) if radius is None and center is None: indices = [x for x in opp1.region.indices if x not in opp2.region.indices] else: indices = [x for x in region1.indices if x not in region2.indices] return indices
def __init__(self, domain, friction=lambda h: 0.03, indices=None, polygon=None, center=None, radius=None, description=None, label=None, logging=False, verbose=False): Operator.__init__(self, domain, description, label, logging, verbose) Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, verbose=verbose) #------------------------------------------ # Local variables #------------------------------------------ self.friction = friction self.friction_c = self.domain.get_quantity('friction').centroid_values
def __init__(self, domain, indices=None, polygon=None, center=None, radius=None, description=None, label=None, logging=False, verbose=False): Operator.__init__(self, domain, description, label, logging, verbose) Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, verbose=verbose) # set some alaises self.stage = self.domain.quantities['stage'].centroid_values self.conc = self.domain.quantities['concentration'].centroid_values self.depth = self.domain.quantities['height'].centroid_values self.elev = self.domain.quantities['elevation'].centroid_values self.xmom = self.domain.quantities['xmomentum'].centroid_values self.ymom = self.domain.quantities['ymomentum'].centroid_values
def get_cir(radius=None, center=None, domain=None, size=None, polygons=None): if polygons is not None: polygon1 = polygons[0] # the larger one polygon2 = polygons[1] opp1 = Rate_operator(domain, polygon=polygon1) opp2 = Rate_operator(domain, polygon=polygon2) if isinstance(polygon1, Region): opp1.region = polygon1 else: opp1.region = Region(domain, poly=polygon1, expand_polygon=True) if isinstance(polygon2, Region): opp2.region = polygon2 else: opp2.region = Region(domain, poly=polygon2, expand_polygon=True) if radius is not None and center is not None: region1 = Region(domain, radius=radius, center=center) if size < 0.03: #if the size of triangle is too small then this method cannot get the boundary indices. region2 = Region(domain, radius=radius - size * 4, center=center) else: region2 = Region(domain, radius=radius - size, center=center) if radius is None and center is None: indices = [ x for x in opp1.region.indices if x not in opp2.region.indices ] else: indices = [x for x in region1.indices if x not in region2.indices] return indices
def __init__(self, domain, friction=lambda h: 0.03, indices=None, polygon=None, center=None, radius=None, description = None, label = None, logging = False, verbose = False): Operator.__init__(self, domain, description, label, logging, verbose) Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, verbose=verbose) #------------------------------------------ # Local variables #------------------------------------------ self.friction = friction self.friction_c = self.domain.get_quantity('friction').centroid_values
def __init__(self, domain, poly, master_proc = 0, procs = None, verbose=False): self.domain = domain self.verbose = verbose # poly can be either a line, polygon or a regions if isinstance(poly,Region): self.region = poly else: self.region = Region(domain,poly=poly,expand_polygon=True) if self.region.get_type() == 'line': self.line = True else: self.line = False self.master_proc = master_proc if procs is None: self.procs = [self.master_proc] else: self.procs = procs from anuga.utilities import parallel_abstraction as pypar self.myid = pypar.rank() self.triangle_indices = self.region.get_indices(full_only=True) self.compute_area()
def __init__(self, domain, threshold=0.0, base=0.0, indices=None, polygon=None, center=None, radius=None, Ra=34.0, description=None, label=None, logging=False, verbose=False): Operator.__init__(self, domain, description, label, logging, verbose) Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, verbose=verbose) #------------------------------------------- # set some sand and water properties #------------------------------------------- self.Wd = 1000 # water mass density kg/m3 self.Sd = 1800 # sediment mass density kg/m3 self.G = 9.8 # acceleration due to gravity m/sec/sec self.n = 0.030 # sand mannings n - mostly bare with undulations self.Tau_crit = 2.1 # critical (detachment) bed shear stress Pa self.Kd = 0.025 # detachment factor Froelich Table 2 Kg/sec/m2/Pa self.Ra = Ra # Repose angle in degrees for dry sand (note wet varies 30-45) #------------------------------------------ # Local variables #------------------------------------------ self.base = base if self.indices is not []: ind = self.indices neighbours = self.domain.surrogate_neighbours self.neighbourindices = neighbours[ ind] # get the neighbour Indices for each triangle in the erosion zone(s) self.n0 = self.neighbourindices[:, 0] # separate into three lists self.n1 = self.neighbourindices[:, 1] self.n2 = self.neighbourindices[:, 2] k = self.n0.shape[0] # Erosion poly lEN - num of triangles in poly self.e = num.zeros( (k, 3)) # create elev array k triangles, 3 neighbour elev self.ident = num.arange(k) # ident is array 0.. k-1, step 1
def __init__(self, domain, threshold= 0.0, base=0.0, indices=None, polygon=None, center=None, radius=None, description = None, label = None, logging = False, verbose = False): Operator.__init__(self, domain, description, label, logging, verbose) Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, verbose=verbose) #------------------------------------------ # Local variables #------------------------------------------ self.threshold = threshold self.base = base #------------------------------------------ # Extra aliases for changing elevation at # vertices and edges #------------------------------------------ self.elev_v = self.domain.quantities['elevation'].vertex_values self.elev_e = self.domain.quantities['elevation'].edge_values #------------------------------------------ # Need to turn off this optimization as it # doesn't fixup the relationship between # bed and stage vertex values in dry region #------------------------------------------ if not self.domain.get_using_discontinuous_elevation(): self.domain.optimise_dry_cells = 0 #----------------------------------------- # Extra structures to support maintaining # continuity of elevation #----------------------------------------- if not self.domain.get_using_discontinuous_elevation(): self.setup_node_structures() #----------------------------------------- # Some extras for reporting #----------------------------------------- self.max_change = 0
def __init__(self, domain, threshold=0.0, base=0.0, indices=None, polygon=None, center=None, radius=None, description=None, label=None, logging=False, verbose=False): Operator.__init__(self, domain, description, label, logging, verbose) Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, verbose=verbose) #------------------------------------------ # Local variables #------------------------------------------ self.threshold = threshold self.base = base #------------------------------------------ # Extra aliases for changing elevation at # vertices and edges #------------------------------------------ self.elev_v = self.domain.quantities['elevation'].vertex_values self.elev_e = self.domain.quantities['elevation'].edge_values #------------------------------------------ # Need to turn off this optimization as it # doesn't fixup the relationship between # bed and stage vertex values in dry region #------------------------------------------ if not self.domain.get_using_discontinuous_elevation(): self.domain.optimise_dry_cells = 0 #----------------------------------------- # Extra structures to support maintaining # continuity of elevation #----------------------------------------- if not self.domain.get_using_discontinuous_elevation(): self.setup_node_structures() #----------------------------------------- # Some extras for reporting #----------------------------------------- self.max_change = 0
def __init__( self, domain, threshold=0.0, base=0.0, indices=None, polygon=None, center=None, radius=None, Ra=34.0, description=None, label=None, logging=False, verbose=False, ): Operator.__init__(self, domain, description, label, logging, verbose) Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, verbose=verbose) # ------------------------------------------- # set some sand and water properties # ------------------------------------------- self.Wd = 1000 # water mass density kg/m3 self.Sd = 1800 # sediment mass density kg/m3 self.G = 9.8 # acceleration due to gravity m/sec/sec self.n = 0.030 # sand mannings n - mostly bare with undulations self.Tau_crit = 2.1 # critical (detachment) bed shear stress Pa self.Kd = 0.025 # detachment factor Froelich Table 2 Kg/sec/m2/Pa self.Ra = Ra # Repose angle in degrees for dry sand (note wet varies 30-45) # ------------------------------------------ # Local variables # ------------------------------------------ self.base = base if self.indices is not []: ind = self.indices neighbours = self.domain.surrogate_neighbours self.neighbourindices = neighbours[ ind ] # get the neighbour Indices for each triangle in the erosion zone(s) self.n0 = self.neighbourindices[:, 0] # separate into three lists self.n1 = self.neighbourindices[:, 1] self.n2 = self.neighbourindices[:, 2] k = self.n0.shape[0] # Erosion poly lEN - num of triangles in poly self.e = num.zeros((k, 3)) # create elev array k triangles, 3 neighbour elev self.ident = num.arange(k) # ident is array 0.. k-1, step 1
def __init__(self, domain, rate=0.0, factor=1.0, indices=None, polygon=None, center=None, radius=None, relative_time=True, default_rate=0.0, description = None, label = None, logging = False, verbose = False, monitor = False): Operator.__init__(self, domain, description, label, logging, verbose) Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, verbose=verbose) #------------------------------------------ # Local variables #------------------------------------------ self.monitor = monitor self.factor = factor self.relative_time = relative_time self.rate_callable = False self.rate_spatial = False self.set_rate(rate) self.set_default_rate(default_rate) self.default_rate_invoked = False # Flag self.set_areas() self.set_full_indices() # Mass tracking self.local_influx=0.
def __init__(self, domain, poly, verbose=False): self.domain = domain self.domain_bounding_polygon = self.domain.get_boundary_polygon() self.verbose = verbose # poly can be either a line, polygon or a regions if isinstance(poly,Region): self.region = poly else: self.region = Region(domain,poly=poly,expand_polygon=True) #self.line = True #if len(self.poly) > 2: # self.line = False self.triangle_indices = self.region.indices #print self.triangle_indices #print poly #print self.triangle_indices #self.compute_triangle_indices() self.compute_area()
def __init__(self, domain, rate=0.0, factor=1.0, indices=None, polygon=None, center=None, radius=None, time_relative=True, default_rate=0.0, description = None, label = None, logging = False, verbose = False): Operator.__init__(self, domain, description, label, logging, verbose) Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, verbose=verbose) #------------------------------------------ # Local variables #------------------------------------------ self.factor = factor self.time_relative = time_relative self.rate_callable = False self.rate_spatial = False self.set_rate(rate) self.set_default_rate(default_rate) self.default_rate_invoked = False # Flag self.set_areas() self.set_full_indices() # Mass tracking self.local_influx=0.
def __init__(self, domain, quantity, value=None, indices=None, polygon=None, center=None, radius=None, line=None, verbose = False, test_elevation=True, test_stage=True): Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, line=line, verbose=verbose) self.set_value(value) #------------------------------------------- # Test quantity #------------------------------------------- self.quantity = quantity msg = 'quantity not found in domain' assert quantity in domain.quantities, msg if test_elevation: msg ='Use Set_elevation to maintain continuity' assert quantity is not 'elevation', msg if test_stage: msg ='Use Set_stage to maintain non-negative water depth' assert quantity is not 'stage', msg #------------------------------------------- # Useful quantity alias #------------------------------------------ self.quantity_c = self.domain.quantities[quantity].centroid_values self.coord_c = self.domain.centroid_coordinates self.areas = self.domain.areas
def __init__(self, domain, quantity, value=None, indices=None, polygon=None, center=None, radius=None, line=None, verbose=False, test_elevation=True, test_stage=True): Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, line=line, verbose=verbose) self.set_value(value) #------------------------------------------- # Test quantity #------------------------------------------- self.quantity = quantity msg = 'quantity not found in domain' assert quantity in domain.quantities, msg if test_elevation: msg = 'Use Set_elevation to maintain continuity' assert quantity is not 'elevation', msg if test_stage: msg = 'Use Set_stage to maintain non-negative water depth' assert quantity is not 'stage', msg #------------------------------------------- # Useful quantity alias #------------------------------------------ self.quantity_c = self.domain.quantities[quantity].centroid_values self.coord_c = self.domain.centroid_coordinates self.areas = self.domain.areas
def __init__(self, domain, indices=None, polygon=None, center=None, radius=None, description=None, label=None, logging=False, verbose=False): Operator.__init__(self, domain, description, label, logging, verbose) Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, verbose=verbose)
def __init__(self, domain, indices=None, polygon=None, center=None, radius=None, description=None, label=None, logging=False, verbose=False): Operator.__init__(self, domain, description, label, logging, verbose) Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, verbose=verbose) # set some alaises self.depth = self.domain.quantities['height'].centroid_values
def __init__(self, domain, w_uh_vh=None, indices=None, polygon=None, center=None, radius=None, description = None, label = None, logging = False, verbose = False): Operator.__init__(self, domain, description, label, logging, verbose) Region.__init__(self, domain, indices=indices, polygon=polygon, center=center, radius=radius, verbose=verbose) #print self.indices self.set_w_uh_vh(w_uh_vh)
print('Available boundary tags', domain.get_boundary_tags()) Br = anuga.Reflective_boundary(domain) Bd = anuga.Dirichlet_boundary([0, 0, 0]) #Bt = anuga.Flather_external_stage_zero_velocity_boundary() domain.set_boundary({'inflow': Br, 'bottom': Br, 'outflow': Bd, 'top': Br}) #domain.set_boundary({'exterior' : Bd}) # ------------------------------------------------------------------------------ # Setup inject water # ------------------------------------------------------------------------------ input_rate = 0.05 # 0.102 # i made inflow exactly the same as in DRAINS example input1_anuga_region = Region(domain, radius=1.0, center=(305694.91, 6188013.94)) input1_anuga_inlet_op = Inlet_operator(domain, input1_anuga_region, Q=input_rate) # ------------------------------------------------------------------------------ # Setup pipedream inlets # ------------------------------------------------------------------------------ radius = 0.25 inlet1_anuga_region = Region(domain, radius=radius, center=(305698.51, 6188004.63)) inlet2_anuga_region = Region(domain, radius=radius,
Br = anuga.Reflective_boundary(domain) Bd = anuga.Dirichlet_boundary([0, 0, 0]) domain.set_boundary({ 'interior': Br, 'exterior': Bd, 'west': Bd, 'south': Bd, 'north': Bd, 'east': Bd }) # ------------------------------------------------------------------------------ # Setup inject water # ------------------------------------------------------------------------------ input1_anuga_region = Region(domain, radius=1.0, center=(305694.91, 6188013.94)) input1_anuga_inlet_op = Inlet_operator( domain, input1_anuga_region, Q=0.102) # i made flow exactly the same as in DRAINS example dt = 0.25 # yield step ft = 400 # final timestep for t in domain.evolve(yieldstep=dt, finaltime=ft): print('\n') domain.print_timestepping_statistics()
#op1 = Rate_operator(domain, rate=lambda t: 10.0 if (t>=0.0) else 0.0, polygon=polygon2) op2 = Rate_operator(domain, rate=lambda t: 10.0 if (t>=0.0) else 0.0, radius=1.0, center=(10.0, 3.0)) def dyn_t(t): return t+0.5 op1 = Rate_operator(domain, polygon=polygon1) domain.set_starttime(-0.1) boundary_tags={'bottom': [0], 'right': [1], 'top': [2], 'left': [3]} dodm = anuga.create_domain_from_regions(polygon2,boundary_tags, maximum_triangle_area = 0.5, ) from anuga import Region region1 = Region(domain,radius = 1.0, center = (10.0, 3.0)) if isinstance(region1, Region): op2.region = region1 else: op2.region = Region(domain, poly=region1, expand_polygon=True) if isinstance(polygon1, Region): op1.region = polygon1 else: op1.region = Region(domain, poly=polygon1, expand_polygon=True) from self_try import get_circumference_indices polygon11 = [ [10.0, 0.2], [11.0, 0.2], [11.0, 4.8], [10.0, 4.8] ] for t in domain.evolve(yieldstep=0.3, finaltime=1.0):
from scipy import interpolate h = [0.0, 0.2, 0.4, 0.8, 2.0, 99.0] n = [0.250, 0.060, 0.045, 0.035, 0.025, 0.025] friction = interpolate.interp1d(h, n, fill_value=0.025) op1 = Depth_friction_operator(domain,friction=friction) #p1 = [ [12.0, 2.5], [13.5, 2.5], [13.5, 4.0], [12.0, 4.0] ] #op2 = Depth_friction_operator(domain, # friction = lambda h :10, # polygon=p1) # Setup region for integrating quantities p2 = [ [8.0, 2.5], [9.5, 2.5], [9.5, 4.0], [8.0, 4.0] ] reg = Region(domain, polygon=p2) # Some useful aliases stage = domain.quantities['stage'] elev = domain.quantities['elevation'] #------------------------------------------------------------------------------ # Evolve system through time #------------------------------------------------------------------------------ for t in domain.evolve(yieldstep=0.1, finaltime=10.0): domain.print_timestepping_statistics() domain.print_operator_timestepping_statistics() # let calculate the integral of height over a region height = stage-elev print indent+'Int_p2(h) = '+str(height.get_integral(region=reg))
# polygon2 = [ [10.0, 0.2], [11.0, 0.2], [11.0, 4.8], [10.0, 4.8] ] # ------------------------------------------------------------------------------ # Setup boundaries # ------------------------------------------------------------------------------ Bi = Dirichlet_boundary([-2.75, 0, 0]) # Inflow Br = Reflective_boundary(domain) # Solid reflective wall Bo = Dirichlet_boundary([-5, 0, 0]) # Outflow domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br}) # ------------------------------------------------------------------------------ # Setup inject water # ------------------------------------------------------------------------------ region_inlet = Region(domain, radius=1.0, center=(7., 2.)) region_outlet = Region(domain, radius=1.0, center=(17., 2.)) region_input = Region(domain, radius=1.0, center=(2., 2.)) op_input = Inlet_operator(domain, region_input, Q=0.25) op_inlet = Inlet_operator(domain, region_inlet, Q=0.0, zero_velocity=True) op_outlet = Inlet_operator(domain, region_outlet, Q=0.0, zero_velocity=False) # x = domain.centroid_coordinates[:, 0] indices = num.where(x < 10) anuga.Set_stage(domain, stage=-2.75, indices=indices)() from pyswmm import Simulation, Nodes, Links
class Parallel_Inlet(Inlet): """Contains information associated with each inlet """ """ Parallel inlet: master_proc - coordinates all processors associated with this inlet usually the processors with domains which contains parts of this inlet. procs - is the list of all processors associated with this inlet. (We assume that the above arguments are determined correctly by the parallel_operator_factory) """ def __init__(self, domain, poly, master_proc = 0, procs = None, verbose=False): self.domain = domain self.verbose = verbose # poly can be either a line, polygon or a regions if isinstance(poly,Region): self.region = poly else: self.region = Region(domain,poly=poly,expand_polygon=True) if self.region.get_type() == 'line': self.line = True else: self.line = False self.master_proc = master_proc if procs is None: self.procs = [self.master_proc] else: self.procs = procs from anuga.utilities import parallel_abstraction as pypar self.myid = pypar.rank() self.triangle_indices = self.region.get_indices(full_only=True) self.compute_area() #self.compute_inlet_length() def compute_area(self): # Compute inlet area as the sum of areas of triangles identified # by line. Must be called after compute_inlet_triangle_indices(). if len(self.triangle_indices) == 0: region = 'Inlet line=%s' % (self.line) msg = 'No triangles have been identified in region ' print("WARNING: " + msg) self.area = 0.0 for j in self.triangle_indices: self.area += self.domain.areas[j] msg = 'Inlet exchange area has area = %f' % self.area assert self.area >= 0.0 def compute_inlet_length(self): """ Compute the length of the inlet within this domain (as defined by the input line """ point0 = self.line[0] point1 = self.line[1] self.inlet_length = anuga.geometry.polygon.line_length(self.line) def get_inlet_length(self): # LOCAL msg = "Warning: compute_inlet_length not implemented" warnings.warn(msg) return self.inlet_length def get_line(self): return self.line def get_area(self): # LOCAL return self.area def get_global_area(self): # GLOBAL: Master processor gathers area from all child processors, and returns value # WARNING: requires synchronization, must be called by all procs associated # with this inlet from anuga.utilities import parallel_abstraction as pypar local_area = self.area area = local_area if self.myid == self.master_proc: for i in self.procs: if i == self.master_proc: continue val = pypar.receive(i) area = area + val else: pypar.send(area, self.master_proc) return area def get_areas(self): # Must be called after compute_inlet_triangle_indices(). # LOCAL return self.domain.areas.take(self.triangle_indices) def get_stages(self): # LOCAL return self.domain.quantities['stage'].centroid_values.take(self.triangle_indices) def get_average_stage(self): # LOCAL return old_div(num.sum(self.get_stages()*self.get_areas()),self.area) def get_global_average_stage(self): # GLOBAL: Master processor gathers stages from all child processors, and returns average # WARNING: requires synchronization, must be called by all procs associated # with this inlet from anuga.utilities import parallel_abstraction as pypar local_stage = num.sum(self.get_stages()*self.get_areas()) global_area = self.get_global_area() global_stage = local_stage if self.myid == self.master_proc: for i in self.procs: if i == self.master_proc: continue val = pypar.receive(i) global_stage = global_stage + val else: pypar.send(local_stage, self.master_proc) if global_area > 0.0: return old_div(global_stage,global_area) else: return 0.0 def get_elevations(self): # LOCAL return self.domain.quantities['elevation'].centroid_values.take(self.triangle_indices) def get_average_elevation(self): # LOCAL if self.area > 0: return old_div(num.sum(self.get_elevations()*self.get_areas()),self.area) else: return 0.0 def get_global_average_elevation(self): # GLOBAL: Master processor gathers elevations from all child processors, and returns average # WARNING: requires synchronization, must be called by all procs associated # with this inlet from anuga.utilities import parallel_abstraction as pypar local_elevation = num.sum(self.get_elevations()*self.get_areas()) global_area = self.get_global_area() global_elevation = local_elevation if self.myid == self.master_proc: for i in self.procs: if i == self.master_proc: continue val = pypar.receive(i) global_elevation = global_elevation + val else: pypar.send(local_elevation, self.master_proc) if global_area > 0.0: return old_div(global_elevation,global_area) else: return 0.0 def get_xmoms(self): # LOCAL return self.domain.quantities['xmomentum'].centroid_values.take(self.triangle_indices) def get_average_xmom(self): # LOCAL if self.area > 0: return old_div(num.sum(self.get_xmoms()*self.get_areas()),self.area) else: return 0.0 def get_global_average_xmom(self): # GLOBAL: master proc gathers all xmom values and returns average # WARNING: requires synchronization, must be called by all procs associated # with this inlet from anuga.utilities import parallel_abstraction as pypar global_area = self.get_global_area() local_xmoms = num.sum(self.get_xmoms()*self.get_areas()) global_xmoms = local_xmoms if self.myid == self.master_proc: for i in self.procs: if i == self.master_proc: continue val = pypar.receive(i) global_xmoms = global_xmoms + val else: pypar.send(local_xmoms, self.master_proc) if global_area > 0.0: return old_div(global_xmoms,global_area) else: return 0.0 def get_ymoms(self): # LOCAL return self.domain.quantities['ymomentum'].centroid_values.take(self.triangle_indices) def get_average_ymom(self): # LOCAL return old_div(num.sum(self.get_ymoms()*self.get_areas()),self.area) def get_global_average_ymom(self): # GLOBAL: master proc gathers all ymom values and returns average # WARNING: requires synchronization, must be called by all procs associated # with this inlet from anuga.utilities import parallel_abstraction as pypar global_area = self.get_global_area() local_ymoms = num.sum(self.get_ymoms()*self.get_areas()) global_ymoms = local_ymoms if self.myid == self.master_proc: for i in self.procs: if i == self.master_proc: continue val = pypar.receive(i) global_ymoms = global_ymoms + val else: pypar.send(local_ymoms, self.master_proc) if global_area > 0.0: return old_div(global_ymoms,global_area) else: return 0.0 def get_depths(self): # LOCAL return self.get_stages() - self.get_elevations() def get_total_water_volume(self): # LOCAL return num.sum(self.get_depths()*self.get_areas()) def get_global_total_water_volume(self): # GLOBAL: master proc gathers total water volumes from each proc and returns average # WARNING: requires synchronization, must be called by all procs associated # with this inlet from anuga.utilities import parallel_abstraction as pypar local_volume = num.sum(self.get_depths()*self.get_areas()) volume = local_volume if self.myid == self.master_proc: for i in self.procs: if i == self.master_proc: continue val = pypar.receive(i) volume = volume + val else: pypar.send(volume, self.master_proc) return volume def get_average_depth(self): # LOCAL if self.area > 0.0: return old_div(self.get_total_water_volume(),self.area) else: return 0.0 def get_global_average_depth(self): # GLOBAL: master proc gathers all depth values and returns average # WARNING: requires synchronization, must be called by all procs associated # with this inlet area = self.get_global_area() total_water_volume = self.get_global_total_water_volume() if area > 0.0: return old_div(total_water_volume, area) else: return 0.0 def get_velocities(self): #LOCAL depths = self.get_depths() u = old_div(depths*self.get_xmoms(),(depths**2 + velocity_protection)) v = old_div(depths*self.get_ymoms(),(depths**2 + velocity_protection)) return u, v def get_xvelocities(self): #LOCAL depths = self.get_depths() return old_div(depth*self.get_xmoms(),(depths**2 + velocity_protection)) def get_yvelocities(self): #LOCAL depths = self.get_depths() return old_div(depths*self.get_ymoms(),(depths**2 + velocity_protection)) def get_average_speed(self): #LOCAL u, v = self.get_velocities() average_u = old_div(num.sum(u*self.get_areas()),self.area) average_v = old_div(num.sum(v*self.get_areas()),self.area) return math.sqrt(average_u**2 + average_v**2) def get_average_velocity_head(self): #LOCAL return old_div(0.5*self.get_average_speed()**2,g) def get_average_total_energy(self): #LOCAL return self.get_average_velocity_head() + self.get_average_stage() def get_average_specific_energy(self): #LOCAL return self.get_average_velocity_head() + self.get_average_depth() # Set routines (ALL LOCAL) def set_depths(self,depth): self.domain.quantities['stage'].centroid_values.put(self.triangle_indices, self.get_elevations() + depth) def set_stages(self,stage): self.domain.quantities['stage'].centroid_values.put(self.triangle_indices, stage) def set_xmoms(self,xmom): self.domain.quantities['xmomentum'].centroid_values.put(self.triangle_indices, xmom) def set_ymoms(self,ymom): self.domain.quantities['ymomentum'].centroid_values.put(self.triangle_indices, ymom) def set_elevations(self,elevation): self.domain.quantities['elevation'].centroid_values.put(self.triangle_indices, elevation) def set_stages_evenly(self,volume): """ Distribute volume of water over inlet exchange region so that stage is level """ # WARNING: requires synchronization, must be called by all procs associated # with this inlet from anuga.utilities import parallel_abstraction as pypar centroid_coordinates = self.domain.get_full_centroid_coordinates(absolute=True) areas = self.get_areas() stages = self.get_stages() stages_order = stages.argsort() # PETE: send stages and areas, apply merging procedure s_areas = {} s_stages = {} s_stages_order = {} total_stages = len(stages) if self.myid == self.master_proc: s_areas[self.myid] = areas s_stages[self.myid] = stages s_stages_order[self.myid] = stages_order # Recieve areas, stages, and stages order for i in self.procs: if i != self.master_proc: s_areas[i] = pypar.receive(i) s_stages[i] = pypar.receive(i) s_stages_order[i] = pypar.receive(i) total_stages = total_stages + len(s_stages[i]) else: # Send areas, stages, and stages order to master proc of inlet pypar.send(areas, self.master_proc) pypar.send(stages, self.master_proc) pypar.send(stages_order, self.master_proc) # merge sorted stage order if self.myid == self.master_proc: pos = {} summed_volume = 0. summed_areas = 0. prev_stage = 0. num_stages = 0. first = True for i in self.procs: pos[i] = 0 while num_stages < total_stages: # Determine current minimum stage of all the processors in s_stages num_stages = num_stages + 1 current_stage = num.finfo(num.float32).max index = -1 for i in self.procs: if pos[i] >= len(s_stages[i]): continue if s_stages[i][s_stages_order[i][pos[i]]] < current_stage: current_stage = s_stages[i][s_stages_order[i][pos[i]]] index = i # If first iteration, then only update summed_areas, position, and prev|current stage if first: first = False summed_areas = s_areas[index][s_stages_order[index][pos[index]]] pos[index] = pos[index] + 1 prev_stage = current_stage continue assert index >= 0, "Index out of bounds" # Update summed volume and summed areas tmp_volume = summed_volume + (summed_areas * (current_stage - prev_stage)) # Terminate if volume exceeded if tmp_volume >= volume: break summed_areas = summed_areas + s_areas[index][s_stages_order[index][pos[index]]] pos[index] = pos[index] + 1 summed_volume = tmp_volume # Update position of index processor and current stage prev_stage = current_stage # Calculate new stage new_stage = prev_stage + old_div((volume - summed_volume), summed_areas) # Send postion and new stage to all processors for i in self.procs: if i != self.master_proc: pypar.send(pos[i], i) pypar.send(new_stage, i) # Update own depth stages[stages_order[0:pos[self.myid]]] = new_stage else: pos = pypar.receive(self.master_proc) new_stage = pypar.receive(self.master_proc) stages[stages_order[0:pos]] = new_stage self.set_stages(stages) stages = self.get_stages() stages_order = stages.argsort() def set_depths_evenly(self,volume): """ Distribute volume over all exchange cells with equal depth of water """ new_depth = self.get_average_depth() + (old_div(volume,self.get_area())) self.set_depths(new_depth) def get_master_proc(self): return self.master_proc def parallel_safe(self): return True def statistics(self): # WARNING: requires synchronization, must be called by all procs associated # with this inlet from anuga.utilities import parallel_abstraction as pypar message = '' tri_indices = {} if self.myid == self.master_proc: tri_indices[self.myid] = self.triangle_indices for proc in self.procs: if proc == self.master_proc: continue tri_indices[proc] = pypar.receive(proc) else: pypar.send(self.triangle_indices, self.master_proc) if self.myid == self.master_proc: message += '=====================================\n' message += 'Inlet\n' message += '=====================================\n' for proc in self.procs: message += '======> inlet triangle indices and centres and elevation at P%d\n' %(proc) message += '%s' % tri_indices[proc] message += '\n' message += '%s' % self.domain.get_centroid_coordinates()[tri_indices[proc]] message += '\n' elev = self.domain.quantities['elevation'].centroid_values[tri_indices[proc]] message += '%s' % elev message += '\n' try: elevation_difference = elev.max() - elev.min() except ValueError: elevation_difference = 0.0 if not num.allclose(elevation_difference, 0.): message += 'Elevation range of ' + str(elevation_difference) message += 'Warning: Non-constant inlet elevation can lead to well-balancing problems' try: # If the inlet does not have an enquiry point this will # fail gracefully message += '\n' message += 'Enquiry point:' message += '%s' % self.domain.get_centroid_coordinates()[self.enquiry_index] message += '\n' message += 'Enquiry Index:' message += '%s' % self.enquiry_index message += '\n' except: pass message += 'line\n' message += '%s' % self.line message += '\n' return message
domain.set_quantity('stage', expression='elevation', location='centroids') # Dry initial condition # ------------------------------------------------------------------------------ # Setup boundaries # ------------------------------------------------------------------------------ Bi = Dirichlet_boundary([-2.75, 0, 0]) # Inflow Br = Reflective_boundary(domain) # Solid reflective wall Bo = Dirichlet_boundary([-5, 0, 0]) # Outflow domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br}) # ------------------------------------------------------------------------------ # Setup inject water # ------------------------------------------------------------------------------ inlet1_anuga_region = Region(domain, radius=1.0, center=(7., 1.)) inlet2_anuga_region = Region(domain, radius=1.0, center=(7., 5.)) outlet_anuga_region = Region(domain, radius=1.0, center=(17., 3.)) input1_anuga_region = Region(domain, radius=1.0, center=(2., 1.)) # region_input2 = Region(domain, radius=1.0, center=(2., 5.)) inlet1_anuga_inlet_op = Inlet_operator(domain, inlet1_anuga_region, Q=0.0, zero_velocity=True) inlet2_anuga_inlet_op = Inlet_operator(domain, inlet2_anuga_region, Q=0.0, zero_velocity=True) outlet_anuga_inlet_op = Inlet_operator(domain,
verbose=True, alpha=0.1) #------------------------------------------------------------------------------ # SETUP BOUNDARY CONDITIONS #------------------------------------------------------------------------------ print('Available boundary tags', domain.get_boundary_tags()) Br = anuga.Reflective_boundary(domain) Bd = anuga.Dirichlet_boundary([0, 0, 0]) domain.set_boundary({'west': Bd, 'south': Br, 'north': Bd, 'east': Bd}) inlet1_anuga_region = Region(domain, radius=0.5, center=(296660.390, 6180017.186)) outlet_anuga_region = Region(domain, radius=0.5, center=(296649.976, 6180038.872)) inlet1_anuga_inlet_op = Inlet_operator(domain, inlet1_anuga_region, Q=0.0, zero_velocity=True) outlet_anuga_inlet_op = Inlet_operator(domain, outlet_anuga_region, Q=0.0, zero_velocity=False) line = [[296669.258, 6179974.191], [296677.321, 6179976.449]]
int(width / dy), len1=length, len2=width) domain = anuga.Domain(points, vertices, boundary) domain.set_flow_algorithm('DE0') domain.set_name('sanddune_testV2SR') # Output name domain.set_quantity('elevation', topography) # elevation is a function domain.set_quantity('friction', 0.01) # Constant friction domain.set_quantity('stage', expression='elevation') # Dry initial condition print domain.statistics() # get the indices of triangles in each erosion poly so can setup nsbase_ in domain poly1ind = (Region(domain, polygon=polygon1)).indices poly2ind = (Region(domain, polygon=polygon2)).indices print '>>>>> poly1ind is of length ', len( poly1ind), ' and contains triangles', poly1ind[0], ' to ', poly1ind[-1] print '>>>>> poly2ind is of length ', len( poly2ind), ' and contains triangles', poly2ind[0], ' to ', poly2ind[-1] # get the initial model surface elevation nsbase_elev_c = domain.get_quantity('elevation').get_values( location='centroids') print '>>>>> nsbase_elev_c is of length ', len(nsbase_elev_c) # build the no scour base surface by combining initial elev where < nsbase and nsbase in each scour poly nsbase_elev_c[poly1ind] = num.minimum(nsbase_elev_c[poly1ind], poly1nsbase) nsbase_elev_c[poly2ind] = num.minimum(nsbase_elev_c[poly2ind], poly2nsbase)
#Btds = anuga.Time_boundary(domain, \ #lambda t: [-5*(num.cos(2*pi*(t-4)/20)), 0.0, 0.0]) #domain.set_boundary({'left': Btus, 'right': Btds, 'top': Br, 'bottom': Br}) domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br}) ##----------------------------------------------------------------------- ## Evolve system through time ##----------------------------------------------------------------------- #min_delta_w = sys.maxint #max_delta_w = -min_delta_w from anuga import Region if isinstance(poly1, Region): inlet1.region = poly1 else: inlet1.region = Region(domain, poly=poly1, expand_polygon=True) for t in domain.evolve(yieldstep=1.0, finaltime=38): domain.write_time() #if domain.get_time() > 150.5 and domain.get_time() < 151.5 : #Bi = anuga.Dirichlet_boundary([0.0, 0.0, 0.0]) #domain.set_boundary({'left': Bi, 'right': Br, 'top': Br, 'bottom': Br}) #delta_w = culvert.inlet.stage - culvert.outlet.stage #if delta_w > max_delta_w: max_delta_w = delta_w #if delta_w < min_delta_w: min_delta_w = delta_w print(domain.volumetric_balance_statistics()) print("depth of inlet1:", inlet1.inlet.get_depths()) print(