def give_ibound(line, number_of_layers, nx, ny, xmin, xmax, ymin, ymax): """ Function that finds if cells of a given grid are inside a given polygon. Returns an IBOUND - 2D array object, in which inner cells have values of '1' and outer have values of '0' Inner points defined using the matplotlib's mplPath function """ # Convert input to floats xmin = float(xmin) xmax = float(xmax) ymin = float(ymin) ymax = float(ymax) # Application of the 'line_area_intersect function to define cells intersected by the polygon area_line_cols, area_line_rows = intersector.line_area_intersect(line = line, xmax = xmax, xmin = xmin, ymax = ymax, ymin = ymin, nx = nx, ny = ny) # Domain definition ibound = np.zeros((int(number_of_layers), ny, nx), dtype=np.int32) x = np.linspace(xmin, xmax, nx) y = np.linspace(ymin, ymax, ny) bbPath = mplPath.Path(np.array(line[:-1])) for i in range(ny): for j in range(nx): cell_is_inside = bbPath.contains_point((x[j], y[i])) if cell_is_inside: ibound[:, i, j] = 1 for i in range(len(area_line_rows)): ibound[:, area_line_rows[i], area_line_cols[i]] = 1 # Rotete the array to 180 degrees to fit flopy IBOUND convention return np.rot90(ibound, 2)
def give_ibound(self, line, number_of_layers): """ """ self.line = line #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! self.line_cols, self.line_rows = intersector.line_area_intersect(line = self.line, xmax = self.xmax, xmin = self.xmin, ymax = self.ymax, ymin = self.ymin, nx = self.nx, ny = self.ny) #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! area_line_rows = np.ones(len(self.line_rows), dtype = np.int32) * (self.ny - 1) - np.array(self.line_rows) area_line_cols = np.array(self.line_cols) empty_rows = [] empty_cols = [] for i in range(self.ny): empty_cols += range(self.ny) empty_rows += [i] * self.nx #Lists of cols and rows to be removed from the entire list: rem_cols = [] rem_rows = [] for i in range(len(area_line_cols)): rem_cols.append(area_line_rows[i] * self.nx + area_line_cols[i]) rem_rows.append(area_line_rows[i] * self.nx + area_line_cols[i]) rem_rows = list(set(rem_rows)) rem_cols = list(set(rem_cols)) for i in sorted(rem_cols, reverse=True): del empty_cols[i] for i in sorted(rem_rows, reverse=True): del empty_rows[i] inner_cell_idx = [] for i in range(len(empty_rows)): x = (self.xmin + empty_cols[i] * self.dx) + self.dx/2 y = (self.ymax - empty_rows[i] * self.dy) - self.dy/2 crossed = 0 for j in range(len(self.line) - 1): bw1 = y < self.line[j][1] and y > self.line[j+1][1] bw2 = y > self.line[j][1] and y < self.line[j+1][1] if (bw1 or bw2) and x < self.line[j][0] - ((self.line[j][1] - y)/(self.line[j][1] - self.line[j+1][1]) * (self.line[j][0] - self.line[j+1][0])): crossed += 1 if crossed % 2 == 0: inner_cell_idx.append(0) else: inner_cell_idx.append(1) self.ibound = np.zeros((int(number_of_layers), self.nx, self.ny), dtype=np.int32) for i in range(len(empty_rows)): self.ibound[:, empty_rows[i], empty_cols[i]] = inner_cell_idx[i] for i in range(len(area_line_rows)): self.ibound[:, area_line_rows[i], area_line_cols[i]] = 1 return self.ibound
def give_ibound(line, number_of_layers, nx, ny, xmin, xmax, ymin, ymax, boundary_value=1): """ Function that finds if cells of a given grid are inside a given polygon. Returns an IBOUND - 2D array object, in which inner cells have values of '1' and outer have values of '0' Inner points defined using the matplotlib's mplPath function """ # Convert input to floats # print line xmin = float(xmin) xmax = float(xmax) ymin = float(ymin) ymax = float(ymax) # Application of the 'line_area_intersect function to define cells intersected by the polygon area_line_cols, area_line_rows = intersector.line_area_intersect(line=line, xmax=xmax, xmin=xmin, ymax=ymax, ymin=ymin, nx=nx, ny=ny) # Domain definition ibound = np.zeros((int(number_of_layers), ny, nx), dtype=np.int32) x = np.linspace(xmin, xmax, nx) y = np.linspace(ymin, ymax, ny) bbPath = mplPath.Path(np.array(line[:-1])) for i in range(ny): for j in range(nx): cell_is_inside = bbPath.contains_point((x[j], y[i])) if cell_is_inside: ibound[:, i, j] = 1 # print len(area_line_rows) for i in range(len(area_line_rows)): ibound[:, area_line_rows[i], area_line_cols[i]] = boundary_value # Rotete the array to 180 degrees to fit flopy IBOUND convention return np.rot90(ibound, 2)
def __init__(self, bo_ids, op, area): self.area = area self.bo = bo_ids self.op = op self.values_list = op.values_list self.line = [] for i in self.bo: cur.execute("""with dump as (select (st_dumppoints(geometry)).* from boundaries where id = %s) select st_x(geom) from dump;""", [i]) xlist = cur.fetchall() cur.execute("""with dump as (select (st_dumppoints(geometry)).* from boundaries where id = %s) select st_y(geom) from dump;""", [i]) ylist = cur.fetchall() for i in xlist: self.line.append(list(i)) for i in range(len(ylist)): self.line[i] += ylist[i] self.SPD_multi = {} #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! self.line_cols, self.line_rows = intersector.line_area_intersect(line = self.line, xmax = self.area.xmax, xmin = self.area.xmin, ymax = self.area.ymax, ymin = self.area.ymin, nx = self.area.nx, ny = self.area.ny) #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! self.vals = []
def give_SPD(points, point_vals, line, stress_period_list, interract_layers, xmax, xmin, ymax, ymin, nx, ny, layers_botm = None): """ Function interpolating given point values along on a grid along given line and returning Stress Period Data dictionary object """ # Definition of the cells intersected by a line boundary and by observation points line_cols, line_rows = intersector.line_area_intersect(line, xmax, xmin, ymax, ymin, nx, ny) point_cols, point_rows = [],[] # Columns and rows of the observation points for point in points: point_cols.append(int((point[0] - xmin)/(xmax - xmin) * nx) if point[0] < xmax else nx - 1) point_rows.append(int((point[1] - ymin)/(ymax - ymin) * ny) if point[1] < ymax else ny - 1) # Create a list of line cell values in which cells under points inherit their values and others beckome None list_of_values = [] for period in stress_period_list: list_of_values_single_timestep = [] for line_idx in range(len(line_cols)): for point_idx in range(len(point_cols)): if line_cols[line_idx] == point_cols[point_idx] and line_rows[line_idx] == point_rows[point_idx]: list_of_values_single_timestep.append(point_vals[period][point_idx]) else: list_of_values_single_timestep.append(None) # Fill the None values with distance - weighted average of closest not-None cells for i in range(len(list_of_values_single_timestep)): if list_of_values_single_timestep[i] is None: j = 1 l = 1 k = list_of_values_single_timestep[i] # Backward value m = list_of_values_single_timestep[i] # Forward value while m is None: m = list_of_values_single_timestep[i - l] l += 1 while k is None: k = list_of_values_single_timestep[i + j] if (i + j) < len(list_of_values_single_timestep) else list_of_values_single_timestep[(i + j - len(list_of_values_single_timestep))] j += 1 # Interpolating values using IDW method list_of_values_single_timestep[i] = (m * 1./(l-1) + k * 1./(j-1))/(1./(j-1) + 1./(l-1)) # Write resulting values lists for every time step list_of_values.append(list_of_values_single_timestep) # Reversing rows upside down due to flopy error line_rows_reversed = [(ny-1) - i for i in line_rows] # Checking if the boundary cells will become dry due to low specified head. If so, layer removed from the interracted layers list for idx, layer in enumerate(layers_botm): for period in stress_period_list: for i in range(len(line_cols)): cell_botm_elevation = layer[line_rows[i], line_cols[i]] if type(layer) == list else layer if list_of_values[period][i] <= cell_botm_elevation: del interract_layers[idx] break break # Writing CHD Stress Period Data dictionary CHD_stress_period_data = {} for period in stress_period_list: SPD_single = [] for lay in interract_layers: for i in range(len(line_cols)): # For periods except the last one head at begining and end vary if period != stress_period_list[-1]: SPD_single.append([lay, line_rows_reversed[i], line_cols[i], list_of_values[period][i], list_of_values[period + 1][i]]) else: SPD_single.append([lay, line_rows_reversed[i], line_cols[i], list_of_values[period][i], list_of_values[period][i]]) CHD_stress_period_data[period] = SPD_single return CHD_stress_period_data
def give_SPD(points, point_vals, line, stress_period_list, interract_layers, xmax, xmin, ymax, ymin, nx, ny, boundary_type, layers_botm=None, strt_head_mode='simple'): """ Function interpolating given point values along on a grid along given line and returning Stress Period Data dictionary object """ strt_head_mode_options = ['warmed_up', 'simple'] if strt_head_mode not in strt_head_mode_options: print 'given stress period data write mode option is not supported, should be either "warmed_up" or "simple"' return xmin = float(xmin) xmax = float(xmax) ymin = float(ymin) ymax = float(ymax) # Definition of the cells intersected by a line boundary and by observation points line_cols, line_rows = intersector.line_area_intersect( line, xmax, xmin, ymax, ymin, nx, ny) point_cols, point_rows = [], [] # Reversing rows upside down due to flopy error line_rows_reversed = [(ny - 1) - i for i in line_rows] # Columns and rows of the observation points for point in points: point_cols.append( int((point[0] - xmin) / (xmax - xmin) * nx) if point[0] < xmax else nx - 1) point_rows.append( int((point[1] - ymin) / (ymax - ymin) * ny) if point[1] < ymax else ny - 1) # Create a list of line cell values in which cells under points inherit their values and others beckome None def interpolate_property(stress_period_list, line_cols, line_rows, point_cols, point_rows, point_vals): list_of_values = [] for period in stress_period_list: list_of_values_single_timestep = [] for line_idx in range(len(line_cols)): for point_idx in range(len(point_cols)): if line_cols[line_idx] == point_cols[ point_idx] and line_rows[line_idx] == point_rows[ point_idx]: list_of_values_single_timestep.append( point_vals[point_idx][period]) else: list_of_values_single_timestep.append(None) # Fill the None values with distance - weighted average of closest not-None cells for i in range(len(list_of_values_single_timestep)): if list_of_values_single_timestep[i] is None: j = 1 l = 1 k = list_of_values_single_timestep[i] # Backward value m = list_of_values_single_timestep[i] # Forward value while m is None: m = list_of_values_single_timestep[i - l] l += 1 while k is None: k = list_of_values_single_timestep[i + j] if ( i + j) < len(list_of_values_single_timestep ) else list_of_values_single_timestep[( i + j - len(list_of_values_single_timestep))] j += 1 # Interpolating values using IDW method list_of_values_single_timestep[i] = ( m * 1. / (l - 1) + k * 1. / (j - 1)) / (1. / (j - 1) + 1. / (l - 1)) # Write resulting values lists for every time step list_of_values.append(list_of_values_single_timestep) return list_of_values if 'hh' in point_vals: point_head_vals = point_vals['hh'] list_of_head_values = interpolate_property(stress_period_list, line_cols, line_rows, point_cols, point_rows, point_head_vals) # Checking if the boundary head cells will become dry due to low specified head. # If so, layer removed from the interracted layers list n_removed_layers = 0 for idx, layer in enumerate(layers_botm): for period in stress_period_list: for i in range(len(line_cols)): cell_botm_elevation = layer[line_rows_reversed[i]][ line_cols[i]] if type(layer) == list else layer if list_of_head_values[period][i] <= cell_botm_elevation: del interract_layers[idx - n_removed_layers] n_removed_layers += 1 break break if 'rs' in point_vals: point_stage_vals = point_vals['rs'] list_of_stage_values = interpolate_property(stress_period_list, line_cols, line_rows, point_cols, point_rows, point_stage_vals) if 'rbc' in point_vals: point_conductance_vals = point_vals['rbc'] list_of_conductance_values = interpolate_property( stress_period_list, line_cols, line_rows, point_cols, point_rows, point_conductance_vals) if 'eb' in point_vals: point_elevation_vals = point_vals['eb'] list_of_elevation_values = interpolate_property( stress_period_list, line_cols, line_rows, point_cols, point_rows, point_elevation_vals) if boundary_type == 'CHB': # Writing CHD Stress Period Data dictionary if strt_head_mode == 'simple': CHD_stress_period_data = {} for period in stress_period_list: SPD_single = [] for lay in interract_layers: for i in range(len(line_cols)): # For periods except the last one head at begining and end vary if period != stress_period_list[-1]: SPD_single.append([ lay, line_rows_reversed[i], line_cols[i], list_of_head_values[period][i], list_of_head_values[period + 1][i] ]) else: SPD_single.append([ lay, line_rows_reversed[i], line_cols[i], list_of_head_values[period][i], list_of_head_values[period][i] ]) CHD_stress_period_data[period] = SPD_single elif strt_head_mode == 'warmed_up': CHD_stress_period_data = {} for period in stress_period_list: SPD_single = [] for lay in interract_layers: for i in range(len(line_cols)): # For periods except the last one head at begining and end vary if period != stress_period_list[-1]: SPD_single.append([ lay, line_rows_reversed[i], line_cols[i], list_of_head_values[period][i], list_of_head_values[period + 1][i] ]) else: SPD_single.append([ lay, line_rows_reversed[i], line_cols[i], list_of_head_values[period][i], list_of_head_values[period][i] ]) if len(CHD_stress_period_data) == 0: CHD_stress_period_data[period] = SPD_single CHD_stress_period_data[period + 1] = SPD_single else: print 'given strt_mode is not supported' return elif boundary_type == 'RIV': if strt_head_mode == 'simple': CHD_stress_period_data = {} for period in stress_period_list: SPD_single = [] for i in range(len(line_cols)): # For periods except the last one head at begining and end vary SPD_single.append([ 0, line_rows_reversed[i], line_cols[i], list_of_stage_values[period][i], list_of_conductance_values[period][i], list_of_elevation_values[period][i] ]) CHD_stress_period_data[period] = SPD_single elif strt_head_mode == 'warmed_up': CHD_stress_period_data = {} for period in stress_period_list: SPD_single = [] for i in range(len(line_cols)): # For periods except the last one head at begining and end vary SPD_single.append([ 0, line_rows_reversed[i], line_cols[i], list_of_stage_values[period][i], list_of_conductance_values[period][i], list_of_elevation_values[period][i] ]) if len(CHD_stress_period_data) == 0: CHD_stress_period_data[period] = SPD_single CHD_stress_period_data[period + 1] = SPD_single else: print 'given strt_mode is not supported' return # for i in CHD_stress_period_data: # print len(CHD_stress_period_data[i]) return CHD_stress_period_data
def give_SPD(points, point_vals, line, stress_period_list, interract_layers, xmax, xmin, ymax, ymin, nx, ny, boundary_type, layers_botm = None, strt_head_mode = 'simple'): """ Function interpolating given point values along on a grid along given line and returning Stress Period Data dictionary object """ strt_head_mode_options = ['warmed_up', 'simple'] if strt_head_mode not in strt_head_mode_options: print 'given stress period data write mode option is not supported, should be either "warmed_up" or "simple"' return xmin = float(xmin) xmax = float(xmax) ymin = float(ymin) ymax = float(ymax) # Definition of the cells intersected by a line boundary and by observation points line_cols, line_rows = intersector.line_area_intersect(line, xmax, xmin, ymax, ymin, nx, ny) point_cols, point_rows = [],[] # Reversing rows upside down due to flopy error line_rows_reversed = [(ny-1) - i for i in line_rows] # Columns and rows of the observation points for point in points: point_cols.append(int((point[0] - xmin)/(xmax - xmin) * nx) if point[0] < xmax else nx - 1) point_rows.append(int((point[1] - ymin)/(ymax - ymin) * ny) if point[1] < ymax else ny - 1) # Create a list of line cell values in which cells under points inherit their values and others beckome None def interpolate_property(stress_period_list,line_cols,line_rows,point_cols,point_rows,point_vals): list_of_values = [] for period in stress_period_list: list_of_values_single_timestep = [] for line_idx in range(len(line_cols)): for point_idx in range(len(point_cols)): if line_cols[line_idx] == point_cols[point_idx] and line_rows[line_idx] == point_rows[point_idx]: list_of_values_single_timestep.append(point_vals[point_idx][period]) else: list_of_values_single_timestep.append(None) # Fill the None values with distance - weighted average of closest not-None cells for i in range(len(list_of_values_single_timestep)): if list_of_values_single_timestep[i] is None: j = 1 l = 1 k = list_of_values_single_timestep[i] # Backward value m = list_of_values_single_timestep[i] # Forward value while m is None: m = list_of_values_single_timestep[i - l] l += 1 while k is None: k = list_of_values_single_timestep[i + j] if (i + j) < len(list_of_values_single_timestep) else list_of_values_single_timestep[(i + j - len(list_of_values_single_timestep))] j += 1 # Interpolating values using IDW method list_of_values_single_timestep[i] = (m * 1./(l-1) + k * 1./(j-1))/(1./(j-1) + 1./(l-1)) # Write resulting values lists for every time step list_of_values.append(list_of_values_single_timestep) return list_of_values if 'hh' in point_vals: point_head_vals = point_vals['hh'] list_of_head_values = interpolate_property(stress_period_list, line_cols,line_rows, point_cols,point_rows, point_head_vals) # Checking if the boundary head cells will become dry due to low specified head. # If so, layer removed from the interracted layers list n_removed_layers = 0 for idx, layer in enumerate(layers_botm): for period in stress_period_list: for i in range(len(line_cols)): cell_botm_elevation = layer[line_rows_reversed[i]][line_cols[i]] if type(layer) == list else layer if list_of_head_values[period][i] <= cell_botm_elevation: del interract_layers[idx - n_removed_layers] n_removed_layers += 1 break break if 'rs' in point_vals: point_stage_vals = point_vals['rs'] list_of_stage_values = interpolate_property(stress_period_list, line_cols,line_rows, point_cols,point_rows, point_stage_vals) if 'rbc' in point_vals: point_conductance_vals = point_vals['rbc'] list_of_conductance_values = interpolate_property(stress_period_list, line_cols,line_rows, point_cols,point_rows, point_conductance_vals) if 'eb' in point_vals: point_elevation_vals = point_vals['eb'] list_of_elevation_values = interpolate_property(stress_period_list, line_cols,line_rows, point_cols,point_rows, point_elevation_vals) if boundary_type == 'CHB': # Writing CHD Stress Period Data dictionary if strt_head_mode == 'simple': CHD_stress_period_data = {} for period in stress_period_list: SPD_single = [] for lay in interract_layers: for i in range(len(line_cols)): # For periods except the last one head at begining and end vary if period != stress_period_list[-1]: SPD_single.append([lay, line_rows_reversed[i], line_cols[i], list_of_head_values[period][i], list_of_head_values[period + 1][i]]) else: SPD_single.append([lay, line_rows_reversed[i], line_cols[i], list_of_head_values[period][i], list_of_head_values[period][i]]) CHD_stress_period_data[period] = SPD_single elif strt_head_mode == 'warmed_up': CHD_stress_period_data = {} for period in stress_period_list: SPD_single = [] for lay in interract_layers: for i in range(len(line_cols)): # For periods except the last one head at begining and end vary if period != stress_period_list[-1]: SPD_single.append([lay, line_rows_reversed[i], line_cols[i], list_of_head_values[period][i], list_of_head_values[period + 1][i]]) else: SPD_single.append([lay, line_rows_reversed[i], line_cols[i], list_of_head_values[period][i], list_of_head_values[period][i]]) if len(CHD_stress_period_data) == 0: CHD_stress_period_data[period] = SPD_single CHD_stress_period_data[period + 1] = SPD_single else: print 'given strt_mode is not supported' return elif boundary_type == 'RIV': if strt_head_mode == 'simple': CHD_stress_period_data = {} for period in stress_period_list: SPD_single = [] for i in range(len(line_cols)): # For periods except the last one head at begining and end vary SPD_single.append([0, line_rows_reversed[i], line_cols[i], list_of_stage_values[period][i], list_of_conductance_values[period][i], list_of_elevation_values[period][i]]) CHD_stress_period_data[period] = SPD_single elif strt_head_mode == 'warmed_up': CHD_stress_period_data = {} for period in stress_period_list: SPD_single = [] for i in range(len(line_cols)): # For periods except the last one head at begining and end vary SPD_single.append([0, line_rows_reversed[i], line_cols[i], list_of_stage_values[period][i], list_of_conductance_values[period][i], list_of_elevation_values[period][i]]) if len(CHD_stress_period_data) == 0: CHD_stress_period_data[period] = SPD_single CHD_stress_period_data[period + 1] = SPD_single else: print 'given strt_mode is not supported' return # for i in CHD_stress_period_data: # print len(CHD_stress_period_data[i]) return CHD_stress_period_data