stormwater-management
Skill for integrated stormwater management and green infrastructure design with SWMM modeling, hydrologic analysis, BMP sizing, and MS4 permit compliance.
Best use case
stormwater-management is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Skill for integrated stormwater management and green infrastructure design with SWMM modeling, hydrologic analysis, BMP sizing, and MS4 permit compliance.
Teams using stormwater-management should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/stormwater-management/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How stormwater-management Compares
| Feature / Agent | stormwater-management | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Skill for integrated stormwater management and green infrastructure design with SWMM modeling, hydrologic analysis, BMP sizing, and MS4 permit compliance.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Stormwater Management Skill
Integrated stormwater management and green infrastructure design for sustainable urban drainage.
## Purpose
This skill provides comprehensive capabilities for stormwater management planning, including hydrologic analysis, green infrastructure design, BMP selection and sizing, SWMM modeling, and MS4 permit compliance analysis.
## Capabilities
### SWMM Modeling and Simulation
- EPA SWMM model setup and configuration
- Subcatchment delineation and parameterization
- Drainage network modeling
- Long-term continuous simulation
- Design storm analysis
- LID representation and modeling
### Hydrologic Analysis
- TR-55 methodology implementation
- Rational method calculations
- SCS Curve Number determination
- Time of concentration estimation
- Unit hydrograph development
- Rainfall-runoff modeling
### Green Infrastructure Sizing
- Bioretention facility design
- Permeable pavement sizing
- Rain garden design
- Green roof specifications
- Tree box filters
- Vegetated swales
### Detention/Retention Pond Design
- Storage volume calculations
- Stage-storage-discharge relationships
- Outlet structure design
- Emergency spillway sizing
- Sediment forebay design
- Maintenance access planning
### Water Quality BMP Selection
- Pollutant removal efficiency analysis
- BMP selection matrix
- Treatment train design
- Sizing for TSS removal
- Nutrient removal considerations
- Cost-effectiveness analysis
### Pollutant Load Modeling
- Event Mean Concentration (EMC) analysis
- Annual pollutant load estimation
- Source area contribution analysis
- Loading rate calculations
- Reduction target setting
### Low Impact Development Integration
- Site-level LID planning
- Watershed-scale LID analysis
- LID retrofit opportunities
- Performance monitoring design
- Adaptive management frameworks
### MS4 Permit Compliance Analysis
- NPDES requirements interpretation
- MCM implementation tracking
- TMDL compliance assessment
- Monitoring program design
- Annual report preparation
## Prerequisites
### Installation
```bash
pip install numpy scipy pandas matplotlib
```
### Optional Dependencies
```bash
# For SWMM integration
pip install swmm-api pyswmm
# For GIS analysis
pip install geopandas shapely
# For visualization
pip install plotly folium
```
## Usage Patterns
### Rational Method Calculations
```python
import numpy as np
from dataclasses import dataclass
from typing import Dict, List, Tuple
@dataclass
class CatchmentData:
"""Catchment characteristics"""
area_acres: float
runoff_coefficient: float
time_of_concentration_min: float
description: str = ""
class RationalMethod:
"""Rational method for peak runoff calculation"""
def __init__(self):
# IDF curve coefficients (example for generic location)
# Q = C * I * A, where I from 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:
"""Calculate rainfall intensity from IDF curve (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:
"""Calculate peak runoff using Rational Method (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:
"""Calculate composite C for mixed land uses
subareas: list of (area, C) tuples
"""
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 equation for Tc (minutes)"""
tc = 0.0078 * (length_ft ** 0.77) * (slope_pct ** -0.385)
return tc
# Example runoff coefficients
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
}
# Example usage
rational = RationalMethod()
# Calculate composite C for mixed use area
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="Mixed use development"
)
for rp in [2, 10, 25, 100]:
Q = rational.peak_runoff(catchment, rp)
print(f"{rp}-year storm: Q = {Q:.1f} cfs")
```
### SCS Curve Number Method
```python
class SCSMethod:
"""SCS Curve Number method for runoff calculation"""
def __init__(self, curve_number: float):
self.cn = curve_number
self.S = (1000 / curve_number) - 10 # Potential retention (inches)
self.Ia = 0.2 * self.S # Initial abstraction
def runoff_depth(self, rainfall_inches: float) -> float:
"""Calculate runoff depth (inches)"""
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:
"""Calculate runoff volume (acre-feet)"""
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:
"""Calculate area-weighted composite CN
subareas: list of (area, CN) tuples
"""
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:
"""Adjust CN for antecedent moisture condition
condition: 'dry' (AMC-I), 'normal' (AMC-II), or '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
# Standard curve numbers (AMC-II, Hydrologic Soil Group 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
}
# Example usage
# Pre-development condition
pre_cn = SCSMethod.composite_cn([
(20, CURVE_NUMBERS['forest_good']),
(80, CURVE_NUMBERS['pasture_good'])
])
pre_scs = SCSMethod(pre_cn)
# Post-development condition
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 # inches (design storm)
pre_runoff = pre_scs.runoff_volume(rainfall, area_acres=100)
post_runoff = post_scs.runoff_volume(rainfall, area_acres=100)
print(f"Pre-development CN: {pre_cn:.0f}")
print(f"Post-development CN: {post_cn:.0f}")
print(f"Pre-development runoff: {pre_runoff:.2f} acre-feet")
print(f"Post-development runoff: {post_runoff:.2f} acre-feet")
print(f"Required detention: {post_runoff - pre_runoff:.2f} acre-feet")
```
### Bioretention Sizing
```python
class BioretentionDesign:
"""Bioretention facility design"""
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:
"""Size bioretention for water quality treatment"""
# Calculate water quality volume (WQv)
# Using simplified volumetric approach
Rv = 0.05 + 0.009 * (impervious_fraction * 100) # Runoff coefficient
wqv_cf = Rv * design_rainfall_in / 12 * drainage_area_sf
# Bioretention area sizing
# Based on 6" ponding depth and filter media depth
ponding_depth_ft = 0.5 # 6 inches
drain_time_hr = 24 # Maximum drain time
# Area based on infiltration during storm
storm_duration_hr = 2 # Assume 2-hour storm
infiltrated_depth = self.infiltration_rate * storm_duration_hr / 12 # feet
# Minimum surface area
min_area_sf = wqv_cf / (ponding_depth_ft + infiltrated_depth)
# Typical sizing: 5-10% of impervious area
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:
"""Generate design details for bioretention"""
return {
'surface_area_sf': surface_area_sf,
'filter_media': {
'depth_in': 24,
'composition': '50% sand, 30% comite, 20% mulch (top)',
'permeability_in_hr': self.infiltration_rate
},
'underdrain': {
'diameter_in': 4,
'material': 'Perforated PVC',
'slope_pct': 0.5,
'gravel_depth_in': 12
},
'overflow': {
'type': 'Standpipe or weir',
'elevation': '6 inches above media surface'
},
'plants': {
'density': '1 per 3 sq ft',
'recommended': ['Switchgrass', 'Black-eyed Susan', 'Sedges']
},
'maintenance': {
'mulch_replacement': 'Annual',
'vegetation_maintenance': 'Biannual',
'sediment_removal': 'As needed, typically 5-year'
}
}
# Example usage
bio = BioretentionDesign(infiltration_rate_in_hr=1.5)
sizing = bio.size_for_water_quality(
drainage_area_sf=43560, # 1 acre
impervious_fraction=0.6,
design_rainfall_in=1.0
)
print(f"Water quality volume: {sizing['water_quality_volume_cf']:.0f} cf")
print(f"Recommended area: {sizing['recommended_area_sf']:.0f} sf")
print(f"Drain time: {sizing['drain_time_hr']:.1f} hours")
details = bio.design_details(sizing['recommended_area_sf'])
print(f"\nFilter media depth: {details['filter_media']['depth_in']} inches")
```
### Pollutant Load Analysis
```python
class PollutantLoading:
"""Stormwater pollutant load estimation"""
# Event Mean Concentrations (mg/L) by land use
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 removal efficiencies (%)
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:
"""Calculate annual pollutant load (lbs/year)"""
emc = self.EMC.get(land_use, self.EMC['residential']).get(pollutant, 0)
# Load = EMC * Volume
# Volume (L) = runoff (in) * area (acres) * 43560 sf/ac * 0.0254 m/in * 1000 L/m3
volume_l = annual_runoff_in * 0.0254 * area_acres * 43560 * 0.0929 * 1000
# Load in mg, convert to lbs
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:
"""Calculate load reduction from 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
}
# Example usage
loading = PollutantLoading()
# Calculate loads for a 50-acre commercial development
area = 50 # acres
annual_runoff = 30 # inches
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} lbs/yr -> {reduction['remaining_load_lbs']:.1f} lbs/yr "
f"({reduction['removal_efficiency_pct']:.0f}% removal)")
```
## Usage Guidelines
### When to Use This Skill
- Stormwater management plan development
- Green infrastructure design
- BMP selection and sizing
- MS4 permit compliance analysis
- Watershed planning and TMDL implementation
### Best Practices
1. **Match design storm** to local requirements
2. **Consider treatment train approaches** for multiple benefits
3. **Plan for maintenance access** in design
4. **Verify infiltration rates** with field testing
5. **Include pre-treatment** for high pollutant areas
6. **Monitor performance** for adaptive management
### Process Integration
- WW-004: Stormwater Management Planning (all phases)
## Dependencies
- numpy, scipy: Numerical calculations
- pandas: Data analysis
- pyswmm: SWMM model interaction (optional)
## References
- EPA SWMM Reference Manual
- ASCE Manual of Practice No. 77
- State-specific stormwater design manuals
- NCHRP Report 565 BMP SelectionRelated Skills
translation-management
Integration with translation management systems and i18n workflows. Connect with Crowdin, Transifex, Weblate, manage translation memory, synchronize glossaries, and automate localization pipelines.
key-management-orchestrator
Cryptographic key lifecycle management orchestration including generation, rotation, and destruction across key management systems
ip-core-management
Vendor IP core configuration and integration expertise for FPGA designs
donor-relationship-management
Cultivate and steward donor relationships including prospect research, personalized engagement strategies, gift acknowledgment, and impact reporting
change-management
Skill for engineering change request and order processing through PLM systems
thermal-management
Vehicle and powertrain thermal management system design
influencer-kol-management
Industry influencer and key opinion leader relationship management
crisis-management-platform
Crisis response platform integration and real-time monitoring
social-media-management
Cross-platform social media operations and analytics
marketing-project-management
Marketing workflow and project management integration
content-management
CMS operations and content optimization tools
brand-asset-management
Digital asset management and brand guideline enforcement tools