def __init__(self): Section.__init__(self) self.start_date = "1/1/2002" """Date when the simulation begins""" self.start_time = "0:00" """Time of day on the starting date when the simulation begins""" self.end_date = "1/1/2002" """Date when the simulation is to end""" self.end_time = "24:00" """Time of day on the ending date when the simulation will end""" self.report_start_date = "1/1/2002" """Date when reporting of results is to begin""" self.report_start_time = "0:00" """Time of day on the report starting date when reporting is to begin""" self.sweep_start = "1/1" """Day of the year (month/day) when street sweeping operations begin""" self.sweep_end = "12/31" """Day of the year (month/day) when street sweeping operations end""" self.dry_days = 0 """Number of days with no rainfall prior to the start of the simulation"""
def __init__(self, new_text=None): if new_text: # if initialization text is provided, call set_text, which will call __init__ with no new_text self.set_text(new_text) else: Section.__init__(self) self.land_use_name = "" """land use name""" self.pollutant = '' """str: Pollutant name""" self.function = BuildupFunction.POW """BuildupFunction: Type of buildup function to use for the pollutant""" self.rate_constant = '0.0' """float: Time constant that governs the rate of pollutant buildup""" self.power_sat_constant = '0.0' """float: Exponent C3 used in the Power buildup formula, or the half-saturation constant C2 used in the Saturation buildup formula""" self.max_buildup = '0.0' """float: Maximum buildup that can occur""" self.scaling_factor = '1.0' """float: Multiplier used to adjust the buildup rates listed in the time series""" self.timeseries = '' """str: ID of Time Series that contains buildup rates""" self.normalizer = Normalizer.AREA """Variable to which buildup is normalized on a per unit basis"""
def __init__(self): Section.__init__(self) self.comment = ";;Interfacing Files" self.use_rainfall = None """Name of rainfall data file to use""" self.save_rainfall = None """Name of rainfall data file to save""" self.use_runoff = None """Name of runoff data file to use""" self.save_runoff = None """Name of runoff data file to save""" self.use_hotstart = None """Name of hot start data file to use""" self.save_hotstart = None """Name of hot start data file to save""" self.use_rdii = None """Name of RDII data file to use""" self.save_rdii = None """Name of RDII data file to save""" self.use_inflows = None """Name of inflows data file to use""" self.save_outflows = None """Name of outflows data file to save"""
def __init__(self, new_text=None): Section.__init__(self) self.land_use_name = "" """land use name""" self.pollutant = '' """Pollutant name""" self.function = WashoffFunction.EXP """Choice of washoff function to use for the pollutant""" self.coefficient = '0.0' """Value of C1 in the exponential and rating curve formulas""" self.exponent = '0.0' """Exponent used in the exponential and rating curve washoff formulas""" self.cleaning_efficiency = '0.0' """Street cleaning removal efficiency (percent) for the pollutant""" self.bmp_efficiency = '0.0' """Removal efficiency (percent) associated with any Best Management Practice that might have been implemented""" if new_text: self.set_text(new_text)
def set_text(self, new_text): self.value = [] item_lines = [] found_non_comment = False for line in new_text.splitlines(): if line.startswith(";;") or line.startswith('['): self.set_comment_check_section(line) elif line.startswith(';'): if found_non_comment: # This comment must be the start of the next one, so build the previous one try: make_one = self.list_type() make_one.set_text('\n'.join(item_lines)) self.value.append(make_one) item_lines = [] found_non_comment = False except Exception as e: print("Could not create object from: " + line + '\n' + str(e) + '\n' + str(traceback.print_exc())) item_lines.append(line) elif not line.strip(): # add blank row as a comment item in self.value list comment = Section() comment.name = "Comment" comment.value = '' self.value.append(comment) else: item_lines.append(line) found_non_comment = True if found_non_comment: # Found a final one that has not been built yet, build it now try: make_one = self.list_type() make_one.set_text('\n'.join(item_lines)) self.value.append(make_one) except Exception as e: print("Could not create object from: " + line + '\n' + str(e) + '\n' + str(traceback.print_exc()))
def __init__(self, new_text=None): if new_text: self.set_text(new_text) else: Section.__init__(self) self.name = '' """name assigned to junction node""" self.elevation = '' """Invert elevation of the Node (feet or meters)""" self.max_depth = '' """Maximum depth of junction (i.e., from ground surface to invert) (feet or meters). If zero, then the distance from the invert to the top of the highest connecting link will be used. (Ymax)""" self.initial_depth = '' """Depth of water at the junction at the start of the simulation (feet or meters) (Y0)""" self.surcharge_depth = '' """Additional depth of water beyond the maximum depth that is allowed before the junction floods (feet or meters). This parameter can be used to simulate bolted manhole covers or force main connections. (Ysur)""" self.ponded_area = '' """Area occupied by ponded water atop the junction after flooding
def __init__(self): Section.__init__(self) self.id = "Unnamed" """Link Identifier/Name""" self.inlet_node = '' """Node on the inlet end of the Link""" self.outlet_node = '' """Node on the outlet end of the Link""" self.description = '' """Optional description of the Link""" self.tag = '' """Optional label used to categorize or classify the Link""" self.vertices = [] # list of Vertex """Coordinates of interior vertex points """ self.report_flag = '' """Flag indicating whether an output report is desired for this link""" # TODO: sync this with STATUS section: self.initial_status = '' """initial status of a pipe, pump, or valve; can be a speed setting for a pump"""
def __init__(self, new_text=None): if new_text: self.set_text(new_text) # set_text will call __init__ without new_text to do the initialization below else: Section.__init__(self) self.link = '' """name of the conduit, orifice, or weir this is a cross-section of.""" self.shape = CrossSectionShape.NotSet """cross-section shape""" self.geometry1 = '' """float as str: full height of the cross-section (ft or m)""" self.geometry2 = '' """float as str: auxiliary parameters (width, side slopes, etc.)""" self.geometry3 = '' """float as str: auxiliary parameters (width, side slopes, etc.)""" self.geometry4 = '' """float as str: auxiliary parameters (width, side slopes, etc.)""" self.barrels = '' """float: number of barrels (i.e., number of parallel pipes of equal size, slope, and roughness) associated with a conduit (default is 1).""" self.culvert_code = '' """code number for the conduits inlet geometry if it is a culvert subject to possible inlet flow control""" self.curve = '' """str: associated Shape Curve ID that defines how width varies with depth."""
def __init__(self): Section.__init__(self) self.comment = ";;Reporting Options" self.input = False """Whether report includes a summary of the input data""" self.continuity = True """Whether to report continuity checks""" self.flow_stats = True """Whether to report summary flow statistics""" self.controls = False """Whether to list all control actions taken during a simulation""" self.subcatchments = Report.EMPTY_LIST """List of subcatchments whose results are to be reported, or ALL or NONE""" self.nodes = Report.EMPTY_LIST """List of nodes whose results are to be reported, or ALL or NONE""" self.links = Report.EMPTY_LIST """List of links whose results are to be reported, or ALL or NONE"""
def __init__(self, new_text=None): if new_text: self.set_text(new_text) # set_text will call __init__ without new_text to do the initialization below else: Section.__init__(self) self.node = '' """str: name of node where external inflow enters.""" self.timeseries = '' """str: Name of the time series describing how flow or constituent loading to this node varies with time.""" self.constituent = '' """str: Name of constituent (pollutant) or FLOW""" self.format = DirectInflowType.CONCENTRATION """DirectInflowType: Type of data contained in constituent_timeseries, concentration or mass flow rate""" self.conversion_factor = '1.0' """float: Numerical factor used to convert the units of pollutant mass flow rate in constituent_timeseries into project mass units per second as specified in [POLLUTANTS]""" self.scale_factor = '1.0' """float: Scaling factor that multiplies the recorded time series values.""" self.baseline = '0.0' """float: Constant baseline added to the time series values.""" self.baseline_pattern = '' """str: ID of Time Pattern whose factors adjust the baseline inflow on an hourly, daily, or monthly basis"""
def __init__(self): Section.__init__(self) self.duration = "0" # hours:minutes """duration of the simulation; the default of zero runs a single period snapshot analysis.""" self.hydraulic_timestep = "1:00" # hours:minutes """determines how often a new hydraulic state of the network is computed""" self.quality_timestep = "0:05" # hours:minutes """time step used to track changes in water quality throughout the network""" self.rule_timestep = "0:05" # hours:minutes """ime step used to check for changes in system status due to activation of rule-based controls""" self.pattern_timestep = "1:00" # hours:minutes """interval between time periods in all time patterns""" self.pattern_start = "0:00" # hours:minutes """time offset at which all patterns will start""" self.report_timestep = "1:00" # hours:minutes """time interval between which output results are reported""" self.report_start = "0:00" # hours:minutes """length of time into the simulation at which output results begin to be reported""" self.start_clocktime = "12 am" # hours:minutes AM/PM """time of day (e.g., 3:00 PM) at which the simulation begins""" self.statistic = StatisticOptions.NONE # NONE/AVERAGED/MINIMUM/MAXIMUM/RANGE """determines what kind of statistical post-processing to do on simulation results"""
def __init__(self, new_text=None): if new_text: self.set_text(new_text) # set_text will call __init__ without new_text to do the initialization below else: Section.__init__(self) self.subcatchment = '' """Subcatchment name""" self.aquifer = '' """Aquifer that supplies groundwater. None = no groundwater flow.""" self.receiving_node = '' """Node that receives groundwater from the aquifer.""" self.surface_elevation = '' """Elevation of ground surface for the subcatchment that lies above the aquifer (feet or meters).""" self.groundwater_flow_coefficient = '' """Value of A1 in the groundwater flow formula.""" self.groundwater_flow_exponent = '' """Value of B1 in the groundwater flow formula.""" self.surface_water_flow_coefficient = '' """Value of A2 in the groundwater flow formula.""" self.surface_water_flow_exponent = '' """Value of B2 in the groundwater flow formula.""" self.surface_gw_interaction_coefficient = '' """Value of A3 in the groundwater flow formula.""" self.fixed_surface_water_depth = '' """Fixed depth of surface water at the receiving node (feet or meters) (set to zero if surface water depth will vary as computed by flow routing). This value is used to compute HSW.""" self.threshold_groundwater_elevation = '' """Groundwater elevation that must be reached before any flow occurs (feet or meters). Leave blank to use the receiving node's invert elevation.""" self.bottom_elevation = '' """override bottom elevation aquifer parameter""" self.water_table_elevation = '' """override initial water table elevation aquifer parameter""" self.unsaturated_zone_moisture = '' """override initial upper moisture content aquifer parameter""" self.custom_lateral_flow_equation = '' """expression for lateral groundwater flow (to a node of the conveyance network)""" self.custom_deep_flow_equation = '' """expression for vertical loss to deep groundwater"""
def __init__(self, new_text=None): if new_text: self.set_text(new_text) # set_text will call __init__ without new_text to do the initialization below else: Section.__init__(self) self.name = '' """User-assigned name.""" self.porosity = '' """Volume of voids / total soil volume (volumetric fraction).""" self.wilting_point = '' """Soil moisture content at which plants cannot survive (volumetric fraction). """ self.field_capacity = '' """Soil moisture content after all free water has drained off (volumetric fraction).""" self.conductivity = '' """Soil's saturated hydraulic conductivity (in/hr or mm/hr).""" self.conductivity_slope = '' """Average slope of log(conductivity) versus soil moisture deficit (porosity minus moisture content) curve (unitless).""" self.tension_slope = '' """Average slope of soil tension versus soil moisture content curve (inches or mm).""" self.upper_evaporation_fraction = '' """Fraction of total evaporation available for evapotranspiration in the upper unsaturated zone.""" self.lower_evaporation_depth = '' """Maximum depth into the lower saturated zone over which evapotranspiration can occur (ft or m).""" self.lower_groundwater_loss_rate = '' """Rate of percolation from saturated zone to deep groundwater (in/hr or mm/hr).""" self.bottom_elevation = '' """Elevation of the bottom of the aquifer (ft or m).""" self.water_table_elevation = '' """Elevation of the water table in the aquifer at the start of the simulation (ft or m).""" self.unsaturated_zone_moisture = '' """Moisture content of the unsaturated upper zone of the aquifer at the start of the simulation (volumetric fraction) (cannot exceed soil porosity).""" self.upper_evaporation_pattern = '' """ID of monthly pattern of adjustments to upper evaporation fraction (optional)"""
def __init__(self): Section.__init__(self) self.hydraulics = HydraulicsOptions() """HydraulicsOptions: Hydraulics options""" self.quality = QualityOptions() """QualityOptions: Water quality options""" self.map = "" """str: Name of a file containing coordinates of the network's nodes, not written if not set"""
def __init__(self, new_text=None): if new_text: self.set_text(new_text) else: Section.__init__(self) self.id = '' """Identifier of link whose initial status is being specified""" self.status = '' """Initial status of link"""
def __init__(self, subcatchment_name = '', land_use_name = '', percent_subcatchment_area = ''): Section.__init__(self) self.subcatchment_name = subcatchment_name """Name of the Subcatchment defined in [SUBCATCHMENTS] where this coverage occurs""" self.land_use_name = land_use_name """land use name from [LANDUSE] of this coverage""" self.percent_subcatchment_area = percent_subcatchment_area """percent of subcatchment area covered by this land use"""
def __init__(self): Section.__init__(self) self.dimensions = (0.0, 0.0, 0.0, 0.0) # real """provides the X and Y coordinates of the lower-left and upper-right corners of the maps bounding rectangle""" self.file = "" # string """name of the file that contains the backdrop image""" self.units = "" # "None" # string self.offset = None # (0.0, 0.0) # real self.scaling = None # (0.0, 0.0) # real
def __init__(self): Section.__init__(self) self.flow_units = FlowUnits.GPM """FlowUnits: units in use for flow values""" self.head_loss = HeadLoss.H_W """HeadLoss: formula to use for computing head loss""" self.specific_gravity = 1.0 """Ratio of the density of the fluid being modeled to that of water at 4 deg. C""" self.viscosity = 1.0 """Kinematic viscosity of the fluid being modeled relative to that of water at 20 deg. C""" self.maximum_trials = 40 """Maximum number of trials used to solve network hydraulics at each hydraulic time step of a simulation""" self.accuracy = 0.001 """Prescribes the convergence criterion that determines when a hydraulic solution has been reached""" self.unbalanced = Unbalanced.STOP """Determines what happens if a hydraulic solution cannot be reached within the prescribed number of TRIALS""" self.unbalanced_continue = 10 """If continuing after n trials, continue this many more trials with links held fixed""" self.default_pattern = "1" """Default demand pattern to be applied to all junctions where no demand pattern was specified""" self.demand_multiplier = 1.0 """Used to adjust the values of baseline demands for all junctions and all demand categories""" self.emitter_exponent = 0.5 """Specifies the power to which the pressure is raised when computing the flow issuing from an emitter""" self.check_frequency = 2 """Undocumented""" self.max_check = 10 """Undocumented""" self.damp_limit = 0.0 """Undocumented""" self.hydraulics = Hydraulics.SAVE """Either SAVE the current hydraulics solution to a file or USE a previously saved hydraulics solution""" """By default do not write this line""" self.hydraulics_file = "" """Hydraulics file to either use or save""" """By default do not write this line"""
def __init__(self, new_text=None): if new_text: self.set_text(new_text) else: Section.__init__(self) self.subcatchment_name = '' """Name of the Subcatchment defined in [SUBCATCHMENTS] where this loading occurs""" self.pollutant_name = "" """name of a pollutant""" self.initial_buildup = 0 """initial buildup of pollutant (lbs/acre or kg/hectare)"""
def __init__(self): Section.__init__(self) self.dimensions = ("0.0", "0.0", "10000.0", "10000.0") # lst:X_Southwest, Y_Southwest, X_northeast, Y_northeast """X and Y coordinates of the lower-left and upper-right corners of the map's bounding rectangle""" self.units = BackdropUnits.NONE # FEET/METERS/DEGREES/NONE """specifies the units that the map's dimensions are given in""" self.file = '' # str """Name of the file that contains the backdrop image""" self.offset = ("0.0", "0.0") # lst of str (X_offset, Y_offset) """Distance the upper-left corner of the backdrop image is offset from the map's bounding rectangle (X, Y)"""
def __init__(self): Section.__init__(self) self.temperature = [] """monthly temperature adjustments as plus or minus degrees F (degrees C)""" self.evaporation = [] """monthly evaporation adjustments as plus or minus in/day (mm/day)""" self.rainfall = [] """monthly rain adjustments as multipliers applied to precipitation rate""" self.soil_conductivity = [] """monthly soil_conductivity adjustments as multipliers applied to soil hydraulic conductivity"""
def __init__(self): Section.__init__(self) self.dimensions = (0.0, 0.0, 10000.0, 10000.0) # real """X and Y coordinates of the lower-left and upper-right corners of the map's bounding rectangle""" self.units = BackdropUnits.NONE # FEET/METERS/DEGREES/NONE """specifies the units that the map's dimensions are given in""" self.file = "" # string """Name of the file that contains the backdrop image""" self.offset = (0.0, 0.0) # (real, real) """Distance the upper-left corner of the backdrop image is offset from the map's bounding rectangle (X, Y)"""
def __init__(self, new_text=None): Section.__init__(self) self.group_name = "Unnamed" """str: Name assigned to this Unit Hydrograph group""" self.rain_gage_id = '' """str: Name of the rain gage that supplies rainfall data to the unit hydrographs in the group""" self.value = [] """UnitHydrographEntry: each active combination of parameters for this unit hydrograph""" if new_text: self.set_text(new_text)
def __init__(self, new_text=None): if new_text: self.set_text(new_text) # set_text will call __init__ without new_text to do the initialization below else: Section.__init__(self) self.node = '' """str: name of node where external inflow enters.""" self.hydrograph_group = "" """str: name of an RDII unit hydrograph group specified in the [HYDROGRAPHS] section""" self.sewershed_area = '' """float: area of the sewershed which contributes RDII to the node (acres or hectares)"""
def __init__(self, new_text=None): Section.__init__(self) self.curve_id = '' # string """Curve ID Label""" self.curve_type = CurveType.PUMP1 """Curve type""" self.curve_xy = [] # list of (x, y) tuples """X, Y Values""" if new_text: self.set_text(new_text)
def __init__(self): Section.__init__(self) self.global_efficiency = "75" # treat as string to preserve formatting """global default value of pumping efficiency for all pumps or efficiency curve ID (percent)""" self.global_price = 0.0 # real """global default value of energy price for all pumps""" self.global_pattern = "" # string """id of global default value of price pattern for all pumps""" self.demand_charge = 0.0 # real """added cost per maximum kW usage during the simulation period"""
def __init__(self, new_text=None): if new_text: self.set_text(new_text) # set_text will call __init__ without new_text to do the initialization below else: Section.__init__(self) self.node = '' """str: name of node where external inflow enters.""" self.pollutant = '' """Name of pollutant receiving treatment""" self.function = '' """str: mathematical function expressing treatment result in terms of pollutant concentrations,
def __init__(self): Section.__init__(self) self.dimensions = (0.0, 0.0, 0.0, 0.0) # real """ Coordinates of the map extent: X1 lower-left X coordinate of full map extent Y1 lower-left Y coordinate of full map extent X2 upper-right X coordinate of full map extent Y2 upper-right Y coordinate of full map extent """ self.units = MapUnits.NONE """map units"""
def test_conduit_section(self): """Test CONDUIT section using Project class, data from Example 7""" from_text = Project() source_text = "[CONDUITS]\n" \ " ;; Inlet Outlet Manning Inlet Outlet Init. Max.\n" \ " ;;Name Node Node Length N Offset Offset Flow Flow\n" \ " ;;-------------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ----------\n" \ " C2a J2a J2 157.48 0.016 4 4 0 0\n" \ " C2 J2 J11 526.0 0.016 4 6 0 0\n" \ " C3 J3 J4 109.0 0.016 0 6 0 0\n" \ " C4 J4 J5 133.0 0.05 6 4 0 0\n" \ " C5 J5 J6 207.0 0.05 4 0 0 0\n" \ " C6 J7 J6 140.0 0.05 8 0 0 0\n" \ " C7 J6 J8 95.0 0.016 0 0 0 0\n" \ " C8 J8 J9 166.0 0.05 0 0 0 0\n" \ " C9 J9 J10 320.0 0.05 0 6 0 0\n" \ " C10 J10 J11 145.0 0.05 6 6 0 0\n" \ " C11 J11 O1 89.0 0.016 0 0 0 0\n" \ " C_Aux1 Aux1 J1 377.31 0.016 0 4 0 0\n" \ " C_Aux2 Aux2 J2a 239.41 0.016 0 4 0 0\n" \ " C_Aux1to2 J1 Aux2 286.06 0.016 4 0 0 0\n" \ " C_Aux3 Aux3 J3 444.75 0.05 6 0 0 0\n" \ " P1 J1 J5 185.39 0.016 0 0 0 0\n" \ " P2 J2a J2 157.48 0.016 0 0 0 0\n" \ " P3 J2 J11 529.22 0.016 0 0 0 0\n" \ " P4 Aux3 J4 567.19 0.016 0 0 0 0\n" \ " P5 J5 J4 125.98 0.016 0 0 0 0\n" \ " P6 J4 J7 360.39 0.016 0 0 0 0\n" \ " P7 J7 J10 507.76 0.016 0 0 0 0\n" \ " P8 J10 J11 144.50 0.016 0 0 0 0" from_text.set_text(source_text) project_section = from_text.conduits assert Section.match_omit(project_section.get_text(), source_text, " \t-;\n")
def __init__(self, new_text=None): Section.__init__(self) self.land_use_name = "" """Name assigned to the land use""" self.street_sweeping_interval = '' """Days between street sweeping within the land use""" self.street_sweeping_availability = '' """Fraction of the buildup of all pollutants that is available for removal by sweeping""" self.last_swept = '' """Number of days since last swept at the start of the simulation""" if new_text: self.set_text(new_text)
def test_dwf_section_example3(self): """Test DWF section from example 3""" from_text = Project() source_text = r""" [DWF] ;; Average Time ;;Node Parameter Value Patterns ;;----------------------------------------------------- KRO3001 FLOW 1 "" "" "DWF" "" "" "" "" KRO6015 FLOW 1 "" "" "DWF" "" "" "" "" KRO6016 FLOW 1 "" "" "DWF" "" "" "" "" KRO6017 FLOW 1 "" "" "DWF" "" "" "" "" KRO1002 FLOW 1 "" "" "DWF" "" "" "" "" KRO1003 FLOW 1 "" "" "DWF" "" "" "" "" KRO1004 FLOW 1 "" "" "DWF" "" "" "" "" KRO1005 FLOW 1 "" "" "DWF" "" "" "" "" KRO1006 FLOW 1 "" "" "DWF" "" "" "" "" KRO1007 FLOW 1 "" "" "DWF" "" "" "" "" KRO1008 FLOW 1 "" "" "DWF" "" "" "" "" KRO1009 FLOW 1 "" "" "DWF" "" "" "" "" KRO1010 FLOW 1 "" "" "DWF" "" "" "" "" KRO1012 FLOW 1 "" "" "DWF" "" "" "" "" KRO1013 FLOW 1 "" "" "DWF" "" "" "" "" KRO1015 FLOW 1 "" "" "DWF" "" "" "" "" KRO2001 FLOW 1 "" "" "DWF" "" "" "" "" KRO4004 FLOW 1 "" "" "DWF" "" "" "" "" KRO4008 FLOW 1 "" "" "DWF" "" "" "" "" KRO4009 FLOW 1 "" "" "DWF" "" "" "" "" KRO4010 FLOW 1 "" "" "DWF" "" "" "" "" KRO4011 FLOW 1 "" "" "DWF" "" "" "" "" KRO4012 FLOW 1 "" "" "DWF" "" "" "" "" KRO4013 FLOW 1 "" "" "DWF" "" "" "" "" KRO4014 FLOW 1 "" "" "DWF" "" "" "" "" KRO4015 FLOW 1 "" "" "DWF" "" "" "" "" KRO4017 FLOW 1 "" "" "DWF" "" "" "" "" KRO4018 FLOW 1 "" "" "DWF" "" "" "" "" KRO4019 FLOW 1 "" "" "DWF" "" "" "" "" SU1 FLOW 1 "" "" "DWF" "" "" "" "" """ from_text.set_text(source_text) project_section = from_text.dwf assert Section.match_omit(project_section.get_text(), source_text, " \t-;\n")
def test_subcatchments(self): """Test SUBCATCHMENTS section from Example 1""" test_text = """[SUBCATCHMENTS] ;; Total Pcnt. Pcnt. Curb Snow ;;Name Raingage Outlet Area Imperv Width Slope Length Pack ;;---------------------------------------------------------------------------------------------------- 1 RG1 9 10 50 500 0.01 0 2 RG1 10 10 50 500 0.01 0 3 RG1 13 5 50 500 0.01 0 4 RG1 22 5 50 500 0.01 0 5 RG1 15 15 50 500 0.01 0 6 RG1 23 12 10 500 0.01 0 7 RG1 19 4 10 500 0.01 0 8 RG1 18 10 10 500 0.01 0 """ from_text = Project() from_text.set_text(test_text) project_section = from_text.subcatchments assert Section.match_omit(project_section.get_text(), test_text, " \t-;\n")
def test_snowpacks_section(self): """Test SNOWPACKS section""" test_text = r""" [SNOWPACKS] ;;Name Surface Parameters ;;-------------- ---------- ---------- sno PLOWABLE 0.001 0.001 32.0 0.10 0.00 0.00 0.0 sno IMPERVIOUS 0.001 0.001 32.0 0.10 0.00 0.00 0.00 sno PERVIOUS 0.001 0.001 32.0 0.10 0.00 0.00 0.00 sno REMOVAL 1.0 0.0 0.0 0.0 0.0 0.0 s PLOWABLE 0.001 0.001 32.0 0.10 0.00 0.00 0.0 s IMPERVIOUS 0.001 0.001 32.0 0.10 0.00 0.00 0.00 s PERVIOUS 0.001 0.001 32.0 0.10 0.00 0.00 0.00 s REMOVAL 1.0 0.0 0.0 0.0 0.0 0.0 w """ from_text = Project() from_text.set_text(test_text) project_section = from_text.snowpacks assert Section.match_omit(project_section.get_text(), test_text, " \t-;\n")
def test_project_section(self): """Test EVAPORATION use project section""" test_text = ("[EVAPORATION]", ";;Type \tParameters", ";;----------\t----------", "CONSTANT \t0.2", "DRY_ONLY \tNO") from_text = Project() test_text = '\n'.join(test_text) from_text.set_text(test_text) project_section = from_text.evaporation assert Section.match_omit(project_section.get_text(), test_text, " \t-;\n") assert project_section.format == EvaporationFormat.CONSTANT assert project_section.constant == "0.2" assert project_section.monthly == () assert project_section.timeseries == '' assert project_section.monthly_pan_coefficients == () assert project_section.recovery_pattern == '' assert project_section.dry_only is False actual_text = project_section.get_text() msg = '\nSet:' + test_text + '\nGet:' + actual_text self.assertTrue(project_section.matches(test_text), msg)
def get_text(self): """Contents of this item formatted for writing to file""" # First, add the values in this section stored directly in this class # Omit COMPATIBILITY option if it is 5, this is assumed now and is no longer listed as an option in 5.1 text_list = [ Section.get_text(self).replace( self.field_format.format("COMPATIBILITY", "5"), '') ] if self.dates is not None: # Add the values stored in Dates class text_list.append(General.section_comments[0]) text_list.append(self.dates.get_text().replace( self.SECTION_NAME + '\n', '')) if self.time_steps is not None: # Add the values stored in TimeSteps class text_list.append(General.section_comments[1]) text_list.append(self.time_steps.get_text().replace( self.SECTION_NAME + '\n', '')) if self.dynamic_wave is not None: # Add the values stored in DynamicWave class text_list.append(General.section_comments[2]) text_list.append(self.dynamic_wave.get_text().replace( self.SECTION_NAME + '\n', '')) return '\n'.join(text_list)
def runTest(self): """Test set_text and get_text of demand options""" from_text = Project() source_text = '\n'.join(self.TEST_TEXT) from_text.set_text(source_text) project_demands = from_text.demands assert Section.match_omit(project_demands.get_text(), source_text, " \t-;\n") assert project_demands.value[0].junction_id == "JUNCTION-0" assert project_demands.value[0].base_demand == "0.0" assert project_demands.value[0].demand_pattern == "PATTERN-1" assert project_demands.value[0].category == '' assert project_demands.value[1].junction_id == "JUNCTION-1" assert project_demands.value[1].base_demand == "0.1" assert project_demands.value[1].demand_pattern == "PATTERN-2" assert project_demands.value[1].category == '' assert project_demands.value[2].junction_id == "JUNCTION-12" assert project_demands.value[2].base_demand == "0.2" assert project_demands.value[2].demand_pattern == "PATTERN-12" assert project_demands.value[2].category == "Category-12"
def __init__(self): Section.__init__(self) self.map = "" """Name of a file containing coordinates of the network's nodes""" """Don't write by default"""
def __init__(self): Section.__init__(self) self.inertial_damping = InertialDamping.NONE """ How the inertial terms in the Saint Venant momentum equation will be handled under dynamic wave flow routing """ self.normal_flow_limited = NormalFlowLimited.BOTH """ Which condition is checked to determine if flow in a conduit is supercritical and should thus be limited to the normal flow """ self.force_main_equation = ForceMainEquation.H_W """ Establishes whether the Hazen-Williams (H-W) or the Darcy-Weisbach (D-W) equation will be used to compute friction losses for pressurized flow in conduits that have been assigned a Circular Force Main cross-section shape. The default is H-W. """ self.lengthening_step = '' """ Time step, in seconds, used to lengthen conduits under dynamic wave routing, so that they meet the Courant stability criterion under full-flow conditions """ self.variable_step = '' """ Safety factor applied to a variable time step computed for each time period under dynamic wave flow routing """ self.min_surface_area = '' """ Minimum surface area used at nodes when computing changes in water depth under dynamic wave routing """ self.max_trials = '' """ The maximum number of trials allowed during a time step to reach convergence when updating hydraulic heads at the conveyance system’s nodes. The default value is 8. """ self.head_tolerance = '' """ Difference in computed head at each node between successive trials below which the flow solution for the current time step is assumed to have converged. The default tolerance is 0.005 ft (0.0015 m). """ self.minimum_step = '' """ Smallest time step allowed when variable time steps are used for dynamic wave flow routing. The default value is 0.5 seconds. """ self.threads = '' """
def __init__(self): Section.__init__(self) self.dates = Dates() self.time_steps = TimeSteps() self.dynamic_wave = DynamicWave() self.flow_units = FlowUnits.CFS """FlowUnits: units in use for flow values""" self.infiltration = "HORTON" """ Infiltration computation model of rainfall into the upper soil zone of subcatchments. Use one of the following: HORTON, MODIFIED_HORTON, GREEN_AMPT, MODIFIED_GREEN_AMPT, CURVE_NUMBER """ self.flow_routing = FlowRouting.KINWAVE """Method used to route flows through the drainage system""" self.link_offsets = LinkOffsets.DEPTH """ Convention used to specify the position of a link offset above the invert of its connecting node """ self.ignore_rainfall = False """True to ignore all rainfall data and runoff calculations""" self.ignore_rdii = False """True to ignore all rdii calculations""" self.ignore_snowmelt = False """ True to ignore snowmelt calculations even if a project contains snow pack objects """ self.ignore_groundwater = False """ True to ignored groundwater calculations even if the project contains aquifer objects """ self.ignore_routing = False """True to only compute runoff even if the project contains drainage system links and nodes""" self.ignore_quality = False """ True to ignore pollutant washoff, routing, and treatment even in a project that has pollutants defined """ self.allow_ponding = False """ True to allow excess water to collect atop nodes and be re-introduced into the system as conditions permit """ self.min_slope = "0.0" """Minimum value allowed for a conduit slope""" self.temp_dir = "" """Directory where model writes its temporary files""" self.compatibility = "5" """SWMM Version compatibility"""
def __init__(self, new_text=None): if new_text: self.set_text(new_text) else: Section.__init__(self) self.value = []
def __init__(self, new_text=None): if new_text: self.set_text(new_text) else: Section.__init__(self) self.name = "NewSubcatchment" """str: Unique user-assigned Subcatchment name.""" self.centroid = Coordinates(None, None) """Coordinates: Subcatchment's centroid on the Study Area Map. If not set, the subcatchment will not appear on the map.""" self.polygon_vertices = [] """List[Coordinates]:the Subcatchment's polygon.""" self.description = '' """str: Optional description of the Subcatchment.""" self.tag = '' """Optional label used to categorize or classify the Subcatchment.""" self.rain_gage = '' """str: The RainGage ID associated with the Subcatchment.""" self.outlet = '' """The Node or Subcatchment which receives Subcatchment's runoff.""" self.area = '' """float: Area of the subcatchment (acres or hectares).""" self.percent_impervious = '' """float: Percent of land area which is impervious.""" self.width = '' """Characteristic width of the overland flow path for sheet flow runoff (feet or meters). An initial estimate of the characteristic width is given by the subcatchment area divided by the average maximum overland flow length. The maximum overland flow length is the length of the flow path from the the furthest drainage point of the subcatchment before the flow becomes channelized. Maximum lengths from several different possible flow paths should be averaged. These paths should reflect slow flow, such as over pervious surfaces, more than rapid flow over pavement, for example. Adjustments should be made to the width parameter to produce good fits to measured runoff hydrographs.""" self.percent_slope = '' """float: Average percent slope of the subcatchment.""" self.n_imperv = '' """float: Manning's n for overland flow in impervious part of Subcatchment""" self.n_perv = '' """Manning's n for overland flow in pervious part of Subcatchment""" self.storage_depth_imperv = '' """float: Depth of depression storage on the impervious portion of the Subcatchment (inches or millimeters) """ self.storage_depth_perv = '' """float: Depth of depression storage on the pervious portion of the Subcatchment (inches or millimeters)""" self.percent_zero_impervious = '' """float: Percent of the impervious area with no depression storage.""" self.subarea_routing = Routing.OUTLET """Routing: Internal routing of runoff between pervious and impervious areas""" self.percent_routed = '' """float: Percent of runoff routed between subareas""" self.infiltration_parameters = HortonInfiltration() """infiltration parameters from horton, green-ampt, or scs classes""" self.groundwater = '' """Groundwater flow parameters for the subcatchment.""" self.snow_pack = '' """Snow pack parameter set (if any) of the subcatchment.""" self.curb_length = '' """ Total length of curbs in the subcatchment (any length units).
def __init__(self, new_text=None): Section.__init__(self) self.name = '' """User-assigned name for this snow pack""" self.has_plowable = False self.has_impervious = False self.has_pervious = False self.has_removal = False self.plowable_minimum_melt_coefficient = "0.0" """Degree-day snow melt coefficient that occurs on December 21""" self.plowable_maximum_melt_coefficient = "0.0" """Degree-day snow melt coefficient that occurs on June 21""" self.plowable_base_temperature = "0.0" """Temperature at which snow begins to melt""" self.plowable_fraction_free_water_capacity = "0.0" """Volume of a snow pack's pore space which must fill with melted snow before liquid runoff from the pack begins, expressed as a fraction of snow pack depth""" self.plowable_initial_snow_depth = "0.0" """Depth of snow at the start of the simulation""" self.plowable_initial_free_water = "0.0" """Depth of melted water held within the pack at the start of the simulation""" self.plowable_fraction_impervious_area = "0.0" """Fraction of impervious area that is plowable and therefore is not subject to areal depletion""" self.impervious_minimum_melt_coefficient = "0.0" """Degree-day snow melt coefficient that occurs on December 21""" self.impervious_maximum_melt_coefficient = "0.0" """Degree-day snow melt coefficient that occurs on June 21""" self.impervious_base_temperature = "0.0" """Temperature at which snow begins to melt""" self.impervious_fraction_free_water_capacity = "0.0" """Volume of a snow pack's pore space which must fill with melted snow before liquid runoff from the pack begins, expressed as a fraction of snow pack depth""" self.impervious_initial_snow_depth = "0.0" """Depth of snow at the start of the simulation""" self.impervious_initial_free_water = "0.0" """Depth of melted water held within the pack at the start of the simulation""" self.impervious_depth_100_cover = "0.0" """Depth of snow beyond which the entire area remains completely covered and is not subject to any areal depletion effect""" self.pervious_minimum_melt_coefficient = "0.0" """Degree-day snow melt coefficient that occurs on December 21""" self.pervious_maximum_melt_coefficient = "0.0" """Degree-day snow melt coefficient that occurs on June 21""" self.pervious_base_temperature = "0.0" """Temperature at which snow begins to melt""" self.pervious_fraction_free_water_capacity = "0.0" """Volume of a snow pack's pore space which must fill with melted snow before liquid runoff from the pack begins, expressed as a fraction of snow pack depth""" self.pervious_initial_snow_depth = "0.0" """Depth of snow at the start of the simulation""" self.pervious_initial_free_water = "0.0" """Depth of melted water held within the pack at the start of the simulation""" self.pervious_depth_100_cover = "0.0" """Depth of snow beyond which the entire area remains completely covered and is not subject to any areal depletion effect""" self.depth_snow_removal_begins = "0.0" """Depth which must be reached before any snow removal begins""" self.fraction_transferred_out_watershed = "0.0" """Fraction of snow depth that is removed from the system""" self.fraction_transferred_impervious_area = "0.0" """Fraction of snow depth that is added to snow accumulation on the pack's impervious area""" self.fraction_transferred_pervious_area = "0.0" """Fraction of snow depth that is added to snow accumulation on the pack's pervious area""" self.fraction_converted_immediate_melt = "0.0" """Fraction of snow depth that becomes liquid water, runs onto any subcatchment associated with the snow pack""" self.fraction_moved_another_subcatchment = "0.0" """Fraction of snow depth which is added to the snow accumulation on some other subcatchment""" self.subcatchment_transfer = "" """subcatchment receiving transfers of snow depth""" if new_text: self.set_text(new_text)
def __init__(self): Section.__init__(self) self.list_type = Transect
def __init__(self): Section.__init__(self) self.title = "" """str: Descriptive title"""
def test_pattern_section(self): """test PATTERNS section""" test_text = r""" [PATTERNS] ;;Name Type Multipliers ;;-------------- ---------- ----------- ;xx x MONTHLY 1.0 1.0 1.0 1.0 1.0 1.0 x 1.0 1.0 1.0 1.0 1.0 1.0""" from_text = Project() from_text.set_text(test_text) project_section = from_text.patterns assert Section.match_omit(project_section.get_text(), test_text, " \t-;\n") test_text = r"""[PATTERNS] ;;Name Type Multipliers ;;---------------------------------------------------------------------- DWF HOURLY .0151 .01373 .01812 .01098 .01098 .01922 DWF .02773 .03789 .03515 .03982 .02059 .02471 DWF .03021 .03789 .03350 .03158 .03954 .02114 DWF .02801 .03680 .02911 .02334 .02499 .02718""" test_text = """ [PATTERNS] ;ID Multipliers ;Demand Pattern 1 1.0 1.2 1.4 1.6 1.4 1.2 1 1.0 0.8 0.6 0.4 0.6 0.8 """ test_text = """[PATTERNS] ;ID Multipliers ;Demand Pattern 1 1.26 1.04 .97 .97 .89 1.19 1 1.28 .67 .67 1.34 2.46 .97 1 .92 .68 1.43 .61 .31 .78 1 .37 .67 1.26 1.56 1.19 1.26 1 .6 1.1 1.03 .73 .88 1.06 1 .99 1.72 1.12 1.34 1.12 .97 1 1.04 1.15 .91 .61 .68 .46 1 .51 .74 1.12 1.34 1.26 .97 1 .82 1.37 1.03 .81 .88 .81 1 .81 ;Pump Station Outflow Pattern 2 .96 .96 .96 .96 .96 .96 2 .62 0 0 0 0 0 2 .8 1 1 1 1 .15 2 0 0 0 0 0 0 2 .55 .92 .92 .92 .92 .9 2 .9 .45 0 0 0 0 2 0 .7 1 1 1 1 2 .2 0 0 0 0 0 2 0 .74 .92 .92 .92 .92 2 .92 ;Pump Station Fluoride Pattern 3 .98 1.02 1.05 .99 .64 .46 3 .35 .35 .35 .35 .35 .35 3 .17 .17 .13 .13 .13 .15 3 .15 .15 .15 .15 .15 .15 3 .15 .12 .1 .08 .11 .09 3 .09 .08 .08 .08 .08 .08 3 .08 .09 .07 .07 .09 .09 3 .09 .09 .09 .09 .09 .09 3 .09 .08 .35 .72 .82 .92 3 1 """ # Test Net 3 test_text = """[PATTERNS]
def test_hydrographs(self): """Test HYDROGRAPHS section""" TEST_TEXT = ( "[HYDROGRAPHS]", ";;Hydrograph\tMonth\tResponse\tR\tT\tK\tDmax\tDrecov\tDinit", "UH101 RG1", "UH101 ALL SHORT 0.033 1.0 2.0", "UH101 ALL MEDIUM 0.300 3.0 2.0\t1\t2\t3", "UH101 ALL LONG 0.033 10.0 2.0", "UH101 JUL SHORT 0.033 0.5 2.0", "UH101 JUL MEDIUM 0.011 2.0 2.0") from_text = Project() source_text = '\n'.join(TEST_TEXT) from_text.set_text(source_text) project_hydrographs = from_text.hydrographs assert Section.match_omit(project_hydrographs.get_text(), source_text, " \t-;\n") assert len(project_hydrographs.value) == 1 val = project_hydrographs.value[0] assert val.group_name == "UH101" assert val.rain_gage_id == "RG1" assert len(val.value) == 5 hydrograph_item = val.value[0] assert hydrograph_item.hydrograph_month == "ALL" assert hydrograph_item.term == "SHORT" assert hydrograph_item.response_ratio == "0.033" assert hydrograph_item.time_to_peak == "1.0" assert hydrograph_item.recession_limb_ratio == "2.0" assert hydrograph_item.initial_abstraction_depth == '' assert hydrograph_item.initial_abstraction_rate == '' assert hydrograph_item.initial_abstraction_amount == '' hydrograph_item = val.value[1] assert hydrograph_item.hydrograph_month == "ALL" assert hydrograph_item.term == "MEDIUM" assert hydrograph_item.response_ratio == "0.300" assert hydrograph_item.time_to_peak == "3.0" assert hydrograph_item.recession_limb_ratio == "2.0" assert hydrograph_item.initial_abstraction_depth == '1' assert hydrograph_item.initial_abstraction_rate == '2' assert hydrograph_item.initial_abstraction_amount == '3' hydrograph_item = val.value[2] assert hydrograph_item.hydrograph_month == "ALL" assert hydrograph_item.term == "LONG" assert hydrograph_item.response_ratio == "0.033" assert hydrograph_item.time_to_peak == "10.0" assert hydrograph_item.recession_limb_ratio == "2.0" assert hydrograph_item.initial_abstraction_depth == '' assert hydrograph_item.initial_abstraction_rate == '' assert hydrograph_item.initial_abstraction_amount == '' hydrograph_item = val.value[4] assert hydrograph_item.hydrograph_month == "JUL" assert hydrograph_item.term == "MEDIUM" assert hydrograph_item.response_ratio == "0.011" assert hydrograph_item.time_to_peak == "2.0" assert hydrograph_item.recession_limb_ratio == "2.0" assert hydrograph_item.initial_abstraction_depth == '' assert hydrograph_item.initial_abstraction_rate == '' assert hydrograph_item.initial_abstraction_amount == ''
def __init__(self, new_text=None): Section.__init__(self) self.control_name = '' """Name used to identify the particular LID control""" self.lid_type = LIDType.BC """Generic type of LID being defined""" self.has_surface_layer = False """does lid have surface layer""" self.has_pavement_layer = False """does lid have pavement layer""" self.has_soil_layer = False """does lid have soil layer""" self.has_storage_layer = False """does lid have storage layer""" self.has_underdrain_system = False """does lid have underdrain system""" self.has_drainmat_system = False """does lid have drainmat system""" self.surface_layer_storage_depth = "0.0" """When confining walls or berms are present this is the maximum depth to which water can pond above the surface of the unit before overflow occurs (in inches or mm). For LIDs that experience overland flow it is the height of any surface depression storage. For swales, it is the height of its trapezoidal cross section. """ self.surface_layer_vegetative_cover_fraction = "0.0" """Fraction of the storage area above the surface that is filled with vegetation""" self.surface_layer_surface_roughness = "0.0" """Manning's n for overland flow over the surface of porous pavement or a vegetative swale""" self.surface_layer_surface_slope = "0.0" """Slope of porous pavement surface or vegetative swale""" self.surface_layer_swale_side_slope = "0.0" """Slope (run over rise) of the side walls of a vegetative swale's cross section""" self.pavement_layer_thickness = "0.0" """Thickness of the pavement layer""" self.pavement_layer_void_ratio = "0.0" """Volume of void space relative to the volume of solids in the pavement""" self.pavement_layer_impervious_surface_fraction = "0.0" """Ratio of impervious paver material to total area for modular systems""" self.pavement_layer_permeability = "0.0" """Permeability of the concrete or asphalt used in continuous systems or hydraulic conductivity of the fill material (gravel or sand) used in modular systems """ self.pavement_layer_clogging_factor = "0.0" """Number of pavement layer void volumes of runoff treated it takes to completely clog the pavement""" self.soil_layer_thickness = "0.0" """Thickness of the soil layer""" self.soil_layer_porosity = "0.0" """Volume of pore space relative to total volume of soil""" self.soil_layer_field_capacity = "0.0" """Volume of pore water relative to total volume after the soil has been allowed to drain fully""" self.soil_layer_wilting_point = "0.0" """Volume of pore water relative to total volume for a well dried soil where only bound water remains""" self.soil_layer_conductivity = "0.0" """Hydraulic conductivity for the fully saturated soil""" self.soil_layer_conductivity_slope = "0.0" """Slope of the curve of log(conductivity) versus soil moisture content""" self.soil_layer_suction_head = "0.0" """Average value of soil capillary suction along the wetting front""" self.storage_layer_height = "0.0" """Height of a rain barrel or thickness of a gravel layer""" self.storage_layer_void_ratio = "0.0" """Volume of void space relative to the volume of solids in the layer""" self.storage_layer_filtration_rate = "0.0" """Maximum rate at which water can flow out the bottom of the layer after it is first constructed""" self.storage_layer_clogging_factor = "0.0" """Total volume of treated runoff it takes to completely clog the bottom of the layer divided by the void volume of the layer""" self.drain_coefficient = "0.0" """Coefficient that determines the rate of flow through the underdrain as a function of height of stored water above the drain height""" self.drain_exponent = "0.0" """Exponent that determines the rate of flow through the underdrain as a function of height of stored water above the drain height""" self.drain_offset_height = "0.0" """Height of any underdrain piping above the bottom of a storage layer or rain barrel""" self.drain_delay = "0.0" """Number of dry weather hours that must elapse before the drain line in a rain barrel is opened""" self.drainmat_thickness = "0.0" """Thickness of the drainage mat (inches or mm)""" self.drainmat_void_fraction = "0.5" """Ratio of void volume to total volume in the mat""" self.drainmat_roughness = "0.1" """Manning's n constant used to compute the horizontal flow rate of drained water through the mat""" if new_text: self.set_text(new_text)
def get_text(self): txt = Section.get_text(self) if self.parameters: txt += '\n' + '\n'.join(self.parameters) return txt