name: stormwater-management description: 技能整合了雨水管理和绿色基础设施设计,包括SWMM建模、水文分析、BMP尺寸确定和MS4许可证合规性分析。 allowed-tools: 阅读,搜索,写入,Bash,编辑,全局 category: 水和废水处理 backlog-id: SK-004 metadata: author: babysitter-sdk version: “1.0.0”
雨水管理技能
综合雨水管理和绿色基础设施设计,以实现可持续的城市排水。
目的
这项技能提供了全面的雨水管理规划能力,包括水文分析、绿色基础设施设计、BMP选择和尺寸确定、SWMM建模和MS4许可证合规性分析。
能力
SWMM建模和模拟
- EPA SWMM模型设置和配置
- 子流域划分和参数化
- 排水网络建模
- 长期连续模拟
- 设计风暴分析
- LID表示和建模
水文分析
- TR-55方法实施
- 合理方法计算
- SCS曲线数确定
- 集中时间估算
- 单位水文图开发
- 降雨径流建模
绿色基础设施尺寸确定
- 生物滞留设施设计
- 透水铺装尺寸确定
- 雨水花园设计
- 绿色屋顶规范
- 树池过滤器
- 植被沟渠
蓄/滞洪池设计
- 储存体积计算
- 阶段-储存-排放关系
- 出口结构设计
- 紧急溢洪道尺寸确定
- 沉沙池设计
- 维护通道规划
水质BMP选择
- 污染物去除效率分析
- BMP选择矩阵
- 处理链设计
- 尺寸确定TSS去除
- 营养物去除考虑
- 成本效益分析
污染物负荷建模
- 事件平均浓度(EMC)分析
- 年度污染物负荷估算
- 源区域贡献分析
- 负荷率计算
- 减排目标设定
低影响开发整合
- 现场级LID规划
- 水流域级LID分析
- LID改造机会
- 性能监测设计
- 适应性管理框架
MS4许可证合规性分析
- NPDES要求解释
- MCM实施跟踪
- TMDL合规性评估
- 监测程序设计
- 年度报告准备
先决条件
安装
pip install numpy scipy pandas matplotlib
可选依赖
# For SWMM integration
pip install swmm-api pyswmm
# For GIS analysis
pip install geopandas shapely
# For visualization
pip install plotly folium
使用模式
合理方法计算
import numpy as np
from dataclasses import dataclass
from typing import Dict, List, Tuple
@dataclass
class CatchmentData:
"""流域特征"""
area_acres: float
runoff_coefficient: float
time_of_concentration_min: float
description: str = ""
class RationalMethod:
"""合理方法用于洪峰径流计算"""
def __init__(self):
# IDF曲线系数(示例为通用位置)
# Q = C * I * A, 其中I来自IDF: I = a / (Tc + b)^c
self.idf_coefficients = {
2: {'a': 100, 'b': 10, 'c': 0.8},
5: {'a': 120, 'b': 10, 'c': 0.8},
10: {'a': 140, 'b': 10, 'c': 0.8},
25: {'a': 160, 'b': 10, 'c': 0.8},
50: {'a': 180, 'b': 10, 'c': 0.8},
100: {'a': 200, 'b': 10, 'c': 0.8}
}
def rainfall_intensity(self, tc_min: float, return_period: int) -> float:
"""从IDF曲线计算降雨强度(in/hr)"""
coef = self.idf_coefficients.get(return_period, self.idf_coefficients[10])
intensity = coef['a'] / (tc_min + coef['b']) ** coef['c']
return intensity
def peak_runoff(self, catchment: CatchmentData, return_period: int) -> float:
"""使用合理方法计算洪峰径流(cfs)"""
C = catchment.runoff_coefficient
I = self.rainfall_intensity(catchment.time_of_concentration_min, return_period)
A = catchment.area_acres
Q = C * I * A # cfs
return Q
def composite_runoff_coefficient(self, subareas: List[Tuple[float, float]]) -> float:
"""计算混合土地使用的复合C
subareas: 面积和C的列表元组
"""
total_area = sum(a for a, c in subareas)
weighted_c = sum(a * c for a, c in subareas) / total_area
return weighted_c
@staticmethod
def time_of_concentration_kirpich(length_ft: float, slope_pct: float) -> float:
"""Kirpich方程用于Tc(分钟)"""
tc = 0.0078 * (length_ft ** 0.77) * (slope_pct ** -0.385)
return tc
# 示例径流系数
RUNOFF_COEFFICIENTS = {
'commercial': 0.85,
'industrial': 0.75,
'residential_high_density': 0.65,
'residential_medium_density': 0.45,
'residential_low_density': 0.35,
'parks': 0.20,
'forest': 0.15,
'impervious': 0.95,
'lawn_steep': 0.30,
'lawn_flat': 0.20
}
# 示例用法
rational = RationalMethod()
# 计算混合用途区域的复合C
subareas = [
(5.0, RUNOFF_COEFFICIENTS['commercial']),
(10.0, RUNOFF_COEFFICIENTS['residential_medium_density']),
(3.0, RUNOFF_COEFFICIENTS['parks'])
]
composite_c = rational.composite_runoff_coefficient(subareas)
catchment = CatchmentData(
area_acres=18.0,
runoff_coefficient=composite_c,
time_of_concentration_min=15.0,
description="混合用途开发"
)
for rp in [2, 10, 25, 100]:
Q = rational.peak_runoff(catchment, rp)
print(f"{rp}年风暴:Q = {Q:.1f} cfs")
SCS曲线数方法
class SCSMethod:
"""SCS曲线数方法用于径流计算"""
def __init__(self, curve_number: float):
self.cn = curve_number
self.S = (1000 / curve_number) - 10 # 潜在保持(英寸)
self.Ia = 0.2 * self.S # 初始抽象
def runoff_depth(self, rainfall_inches: float) -> float:
"""计算径流深度(英寸)"""
P = rainfall_inches
if P <= self.Ia:
return 0.0
Q = (P - self.Ia) ** 2 / (P - self.Ia + self.S)
return Q
def runoff_volume(self, rainfall_inches: float, area_acres: float) -> float:
"""计算径流量(英亩-英尺)"""
Q_inches = self.runoff_depth(rainfall_inches)
volume_ac_ft = Q_inches / 12 * area_acres
return volume_ac_ft
@staticmethod
def composite_cn(subareas: List[Tuple[float, float]]) -> float:
"""计算面积加权复合CN
subareas: 面积和CN的列表元组
"""
total_area = sum(a for a, cn in subareas)
weighted_cn = sum(a * cn for a, cn in subareas) / total_area
return weighted_cn
@staticmethod
def adjust_cn_for_amc(cn_ii: float, condition: str) -> float:
"""根据前期湿度条件调整CN
condition: 'dry' (AMC-I), 'normal' (AMC-II), 或 'wet' (AMC-III)
"""
if condition == 'dry':
cn = cn_ii / (2.281 - 0.01281 * cn_ii)
elif condition == 'wet':
cn = cn_ii / (0.427 + 0.00573 * cn_ii)
else:
cn = cn_ii
return cn
# 标准曲线数(AMC-II,水文土壤组B)
CURVE_NUMBERS = {
'impervious': 98,
'commercial': 92,
'industrial': 88,
'residential_1_8_acre': 85,
'residential_1_4_acre': 80,
'residential_1_2_acre': 75,
'residential_1_acre': 68,
'open_space_good': 61,
'open_space_fair': 69,
'forest_good': 55,
'pasture_good': 61
}
# 示例用法
# 开发前条件
pre_cn = SCSMethod.composite_cn([
(20, CURVE_NUMBERS['forest_good']),
(80, CURVE_NUMBERS['pasture_good'])
])
pre_scs = SCSMethod(pre_cn)
# 开发后条件
post_cn = SCSMethod.composite_cn([
(30, CURVE_NUMBERS['impervious']),
(40, CURVE_NUMBERS['residential_1_4_acre']),
(30, CURVE_NUMBERS['open_space_good'])
])
post_scs = SCSMethod(post_cn)
rainfall = 3.5 # 英寸(设计风暴)
pre_runoff = pre_scs.runoff_volume(rainfall, area_acres=100)
post_runoff = post_scs.runoff_volume(rainfall, area_acres=100)
print(f"开发前CN: {pre_cn:.0f}")
print(f"开发后CN: {post_cn:.0f}")
print(f"开发前径流:{pre_runoff:.2f} 英亩-英尺")
print(f"开发后径流:{post_runoff:.2f} 英亩-英尺")
print(f"所需滞洪:{post_runoff - pre_runoff:.2f} 英亩-英尺")
生物滞留尺寸确定
class BioretentionDesign:
"""生物滞留设施设计"""
def __init__(self, infiltration_rate_in_hr: float = 1.0):
self.infiltration_rate = infiltration_rate_in_hr
def size_for_water_quality(self, drainage_area_sf: float,
impervious_fraction: float,
design_rainfall_in: float = 1.0) -> Dict:
"""为水质处理尺寸生物滞留"""
# 计算水质体积(WQv)
# 使用简化体积方法
Rv = 0.05 + 0.009 * (impervious_fraction * 100) # 径流系数
wqv_cf = Rv * design_rainfall_in / 12 * drainage_area_sf
# 生物滞留面积尺寸确定
# 基于6"积水深度和过滤介质深度
ponding_depth_ft = 0.5 # 6英寸
drain_time_hr = 24 # 最大排水时间
# 基于风暴期间渗透的面积
storm_duration_hr = 2 # 假设2小时风暴
infiltrated_depth = self.infiltration_rate * storm_duration_hr / 12 # 英尺
# 最小表面积
min_area_sf = wqv_cf / (ponding_depth_ft + infiltrated_depth)
# 典型尺寸:不透水面积的5-10%
recommended_area_sf = drainage_area_sf * impervious_fraction * 0.05
return {
'water_quality_volume_cf': wqv_cf,
'minimum_surface_area_sf': min_area_sf,
'recommended_area_sf': max(min_area_sf, recommended_area_sf),
'ponding_depth_in': 6,
'filter_media_depth_in': 24,
'drain_time_hr': ponding_depth_ft * 12 / self.infiltration_rate
}
def design_details(self, surface_area_sf: float) -> Dict:
"""为生物滞留生成设计细节"""
return {
'surface_area_sf': surface_area_sf,
'filter_media': {
'depth_in': 24,
'composition': '50%沙子,30%有机质,20%覆盖物(顶部)',
'permeability_in_hr': self.infiltration_rate
},
'underdrain': {
'diameter_in': 4,
'material': '穿孔PVC',
'slope_pct': 0.5,
'gravel_depth_in': 12
},
'overflow': {
'type': '立管或堰板',
'elevation': '介质表面以上6英寸'
},
'plants': {
'density': '每3平方英尺1株',
'recommended': ['柳枝稷', '黑眼苏珊', '莎草']
},
'maintenance': {
'mulch_replacement': '每年',
'vegetation_maintenance': '每半年',
'sediment_removal': '按需,通常5年'
}
}
# 示例用法
bio = BioretentionDesign(infiltration_rate_in_hr=1.5)
sizing = bio.size_for_water_quality(
drainage_area_sf=43560, # 1英亩
impervious_fraction=0.6,
design_rainfall_in=1.0
)
print(f"水质体积:{sizing['water_quality_volume_cf']:.0f} 立方英尺")
print(f"推荐面积:{sizing['recommended_area_sf']:.0f} 平方英尺")
print(f"排水时间:{sizing['drain_time_hr']:.1f} 小时")
details = bio.design_details(sizing['recommended_area_sf'])
print(f"
过滤介质深度:{details['filter_media']['depth_in']} 英寸")
污染物负荷分析
class PollutantLoading:
"""雨水污染物负荷估算"""
# 事件平均浓度(mg/L)按土地使用
EMC = {
'residential': {'TSS': 101, 'TP': 0.38, 'TN': 2.5, 'Zn': 0.14},
'commercial': {'TSS': 69, 'TP': 0.22, 'TN': 2.2, 'Zn': 0.22},
'industrial': {'TSS': 85, 'TP': 0.26, 'TN': 2.0, 'Zn': 0.32},
'highway': {'TSS': 142, 'TP': 0.34, 'TN': 3.2, 'Zn': 0.35},
'open_space': {'TSS': 40, 'TP': 0.10, 'TN': 1.0, 'Zn': 0.05}
}
# BMP去除效率(%)
BMP_REMOVAL = {
'bioretention': {'TSS': 85, 'TP': 60, 'TN': 50, 'Zn': 80},
'wet_pond': {'TSS': 80, 'TP': 50, 'TN': 30, 'Zn': 60},
'dry_pond': {'TSS': 60, 'TP': 20, 'TN': 15, 'Zn': 30},
'grass_swale': {'TSS': 70, 'TP': 25, 'TN': 20, 'Zn': 40},
'perm_pavement': {'TSS': 85, 'TP': 60, 'TN': 50, 'Zn': 70},
'sand_filter': {'TSS': 85, 'TP': 50, 'TN': 35, 'Zn': 80}
}
def annual_load(self, area_acres: float, land_use: str,
annual_runoff_in: float, pollutant: str) -> float:
"""计算年度污染物负荷(磅/年)"""
emc = self.EMC.get(land_use, self.EMC['residential']).get(pollutant, 0)
# 负荷 = EMC * 体积
# 体积(L)= 径流(英寸)* 面积(英亩)* 43560 平方英尺/英亩 * 0.0254 米/英寸 * 1000 L/立方米
volume_l = annual_runoff_in * 0.0254 * area_acres * 43560 * 0.0929 * 1000
# 负荷以毫克计,转换为磅
load_mg = emc * volume_l
load_lbs = load_mg / 453592
return load_lbs
def load_reduction(self, load_lbs: float, bmp_type: str,
pollutant: str) -> Dict:
"""计算BMP的负荷减少"""
efficiency = self.BMP_REMOVAL.get(bmp_type, {}).get(pollutant, 0) / 100
removed = load_lbs * efficiency
remaining = load_lbs - removed
return {
'initial_load_lbs': load_lbs,
'removal_efficiency_pct': efficiency * 100,
'load_removed_lbs': removed,
'remaining_load_lbs': remaining
}
# 示例用法
loading = PollutantLoading()
# 计算一个50英亩商业开发项目的负荷
area = 50 # 英亩
annual_runoff = 30 # 英寸
land_use = 'commercial'
for pollutant in ['TSS', 'TP', 'TN']:
load = loading.annual_load(area, land_use, annual_runoff, pollutant)
reduction = loading.load_reduction(load, 'bioretention', pollutant)
print(f"{pollutant}: {load:.1f} 磅/年 -> {reduction['remaining_load_lbs']:.1f} 磅/年 "
f"({reduction['removal_efficiency_pct']:.0f}% 去除)")
使用指南
何时使用此技能
- 雨水管理计划开发
- 绿色基础设施设计
- BMP选择和尺寸确定
- MS4许可证合规性分析
- 水流域规划和TMDL实施
最佳实践
- 将设计风暴与当地要求相匹配
- 考虑处理链方法以获得多重效益
- 在设计中规划维护通道
- 通过现场测试验证渗透率
- 为高污染区域包括预处理
- 监测性能以进行适应性管理
流程整合
- WW-004: 雨水管理规划(所有阶段)
依赖关系
- numpy, scipy: 数值计算
- pandas: 数据分析
- pyswmm: SWMM模型交互(可选)
参考资料
- EPA SWMM参考手册
- ASCE实践手册77
- 特定州的雨水设计手册
- NCHRP报告565 BMP选择