def test_2(self): #end_point0=[307138.813,6193474] #end_point1=[307150.563,6193469] end_point0=[10., 5.] end_point1=[10., 10.] width = 1 height = 3.5 number_of_barrels=1 P = create_culvert_polygons(end_point0, end_point1, width=width, height=height, number_of_barrels=number_of_barrels) # Compute area and check that it is greater than 0 for key1 in ['exchange_polygon0', 'exchange_polygon1']: polygon = P[key1] area = polygon_area(polygon) msg = 'Polygon %s ' % (polygon) msg += ' has area = %f' % area assert area > 0.0, msg for key2 in ['enquiry_point0', 'enquiry_point1']: point = P[key2] assert not inside_polygon(point, polygon)
def test_2(self): #end_point0=[307138.813,6193474] #end_point1=[307150.563,6193469] end_point0 = [10., 5.] end_point1 = [10., 10.] width = 1 height = 3.5 number_of_barrels = 1 P = create_culvert_polygons(end_point0, end_point1, width=width, height=height, number_of_barrels=number_of_barrels) # Compute area and check that it is greater than 0 for key1 in ['exchange_polygon0', 'exchange_polygon1']: polygon = P[key1] area = polygon_area(polygon) msg = 'Polygon %s ' % (polygon) msg += ' has area = %f' % area assert area > 0.0, msg for key2 in ['enquiry_point0', 'enquiry_point1']: point = P[key2] assert not inside_polygon(point, polygon)
def create_culvert_polygons(end_point0, end_point1, width, height=None, enquiry_gap_factor=0.2, number_of_barrels=1): """Create polygons at the end of a culvert inlet and outlet. At either end two polygons will be created; one for the actual flow to pass through and one a little further away for enquiring the total energy at both ends of the culvert and transferring flow. Input (mandatory): end_point0 - one end of the culvert (x,y) end_point1 - other end of the culvert (x,y) width - culvert width Input (optional): height - culvert height, defaults to width making a square culvert enquiry_gap_factor - sets the distance to the enquiry point as fraction of the height number_of_barrels - number of identical pipes. Output: Dictionary of four polygons. The dictionary keys are: 'exchange_polygon0' - polygon defining the flow area at end_point0 'exchange_polygon1' - polygon defining the flow area at end_point1 'enquiry_point0' - point beyond exchange_polygon0 'enquiry_point1' - point beyond exchange_polygon1 'vector' 'length' 'normal' """ # Input check if height is None: height = width # Dictionary for calculated polygons culvert_polygons = {} # Calculate geometry x0, y0 = end_point0 x1, y1 = end_point1 dx = x1-x0 dy = y1-y0 vector = num.array([dx, dy]) length = sqrt(num.sum(vector**2)) # Adjust polygon width to number of barrels in this culvert width *= number_of_barrels # Unit direction vector and normal vector /= length # Unit vector in culvert direction normal = num.array([-dy, dx])/length # Normal vector culvert_polygons['vector'] = vector culvert_polygons['length'] = length culvert_polygons['normal'] = normal # Short hands w = 0.5*width*normal # Perpendicular vector of 1/2 width h = height*vector # Vector of length=height in the # direction of the culvert gap = (1 + enquiry_gap_factor)*h # Build exchange polygon and enquiry point for opening 0 p0 = end_point0 + w p1 = end_point0 - w p2 = p1 - h p3 = p0 - h culvert_polygons['exchange_polygon0'] = num.array([p0,p1,p2,p3]) culvert_polygons['enquiry_point0'] = end_point0 - gap # Build exchange polygon and enquiry point for opening 1 p0 = end_point1 + w p1 = end_point1 - w p2 = p1 + h p3 = p0 + h culvert_polygons['exchange_polygon1'] = num.array([p0,p1,p2,p3]) culvert_polygons['enquiry_point1'] = end_point1 + gap # Check that enquiry polygons are outside exchange polygons for key1 in ['exchange_polygon0', 'exchange_polygon1']: polygon = culvert_polygons[key1] area = polygon_area(polygon) msg = 'Polygon %s ' %(polygon) msg += ' has area = %f' % area assert area > 0.0, msg for key2 in ['enquiry_point0', 'enquiry_point1']: point = culvert_polygons[key2] msg = 'Enquiry point falls inside an enquiry point.' msg += 'Email [email protected]' assert not inside_polygon(point, polygon), msg # Return results return culvert_polygons
def __init__(self, domain, quantity_name, rate=0.0, center=None, radius=None, polygon=None, default_rate=None, verbose=False): from math import pi, cos, sin if domain.numproc > 1: msg = 'Not implemented to run in parallel' assert self.parallel_safe(), msg if center is None: msg = 'I got radius but no center.' assert radius is None, msg if radius is None: msg += 'I got center but no radius.' assert center is None, msg self.domain = domain self.quantity_name = quantity_name self.rate = rate self.center = ensure_numeric(center) self.radius = radius self.polygon = polygon self.verbose = verbose self.value = 0.0 # Can be used to remember value at # previous timestep in order to obtain rate # Get boundary (in absolute coordinates) bounding_polygon = domain.get_boundary_polygon() # Update area if applicable if center is not None and radius is not None: assert len(center) == 2 msg = 'Polygon cannot be specified when center and radius are' assert polygon is None, msg # Check that circle center lies within the mesh. msg = 'Center %s specified for forcing term did not' % str(center) msg += 'fall within the domain boundary.' assert is_inside_polygon(center, bounding_polygon), msg # Check that circle periphery lies within the mesh. N = 100 periphery_points = [] for i in range(N): theta = 2*pi*i/100 x = center[0] + radius*cos(theta) y = center[1] + radius*sin(theta) periphery_points.append([x,y]) for point in periphery_points: msg = 'Point %s on periphery for forcing term' % str(point) msg += ' did not fall within the domain boundary.' assert is_inside_polygon(point, bounding_polygon), msg if polygon is not None: # Check that polygon lies within the mesh. for point in self.polygon: msg = 'Point %s in polygon for forcing term' % str(point) msg += ' did not fall within the domain boundary.' assert is_inside_polygon(point, bounding_polygon), msg # Pointer to update vector self.update = domain.quantities[self.quantity_name].explicit_update # Determine indices in flow area N = len(domain) points = domain.get_centroid_coordinates(absolute=True) # Calculate indices in exchange area for this forcing term self.exchange_indices = None if self.center is not None and self.radius is not None: # Inlet is circular inlet_region = 'center=%s, radius=%s' % (self.center, self.radius) self.exchange_indices = [] for k in range(N): x, y = points[k,:] # Centroid c = self.center if ((x-c[0])**2+(y-c[1])**2) < self.radius**2: self.exchange_indices.append(k) if self.polygon is not None: # Inlet is polygon self.exchange_indices = inside_polygon(points, self.polygon) if self.exchange_indices is None: self.exchange_area = polygon_area(bounding_polygon) else: if len(self.exchange_indices) == 0: msg = 'No triangles have been identified in ' msg += 'specified region: %s' % inlet_region raise Exception(msg) # Compute exchange area as the sum of areas of triangles identified # by circle or polygon self.exchange_area = 0.0 for i in self.exchange_indices: self.exchange_area += domain.areas[i] msg = 'Exchange area in forcing term' msg += ' has area = %f' %self.exchange_area assert self.exchange_area > 0.0 # Check and store default_rate msg = ('Keyword argument default_rate must be either None ' 'or a function of time.\nI got %s.' % str(default_rate)) assert (default_rate is None or isinstance(default_rate, (int, float)) or callable(default_rate)), msg if default_rate is not None: # If it is a constant, make it a function if not callable(default_rate): tmp = default_rate default_rate = lambda t: tmp # Check that default_rate is a function of one argument try: default_rate(0.0) except: raise Exception(msg) self.default_rate = default_rate self.default_rate_invoked = False # Flag