A comprehensive Python library for open channel flow analysis and design. PyOpenChannel provides tools for hydraulic engineers, water resources professionals, and students to analyze and design open channel systems with ease and accuracy.
- Rectangular channels: Standard rectangular cross-sections
- Trapezoidal channels: Most common natural and constructed channels
- Triangular channels: V-shaped channels and ditches
- Circular channels: Pipes and culverts with free surface flow
- Parabolic channels: Efficient hydraulic sections
- Manning's equation: Uniform flow calculations
- Critical depth: Critical flow conditions and Froude number analysis
- Normal depth: Uniform flow depth calculations
- Energy equation: Specific energy and alternate depths
- Momentum equation: Hydraulic jump analysis
- Uniform flow: Complete flow state analysis
- Critical flow: Critical conditions and flow regime classification
- Gradually varied flow: Water surface profile calculations (basic implementation)
- Flow classification: Subcritical, critical, and supercritical flow identification
- Optimal sections: Hydraulically efficient channel design
- Economic sections: Cost-optimized channel design
- Channel sizing: Capacity-based channel dimensioning
- Design recommendations: Freeboard, velocity limits, and side slopes
git clone https://github.com/alexiusacademia/pyopenchannel.git
cd pyopenchannel
pip install -e .
- Python 3.12+
- No external dependencies for core functionality
import pyopenchannel as poc
# Create a rectangular channel
channel = poc.RectangularChannel(width=3.0)
# Calculate normal depth for given flow conditions
discharge = 5.0 # m³/s
slope = 0.001 # dimensionless
manning_n = 0.025
normal_depth = poc.NormalDepth.calculate(channel, discharge, slope, manning_n)
print(f"Normal depth: {normal_depth:.3f} m")
# Calculate critical depth
critical_depth = poc.CriticalDepth.calculate(channel, discharge)
print(f"Critical depth: {critical_depth:.3f} m")
# Analyze flow regime
if normal_depth > critical_depth:
print("Flow regime: Subcritical (mild slope)")
else:
print("Flow regime: Supercritical (steep slope)")
import pyopenchannel as poc
# Create a trapezoidal channel
channel = poc.TrapezoidalChannel(bottom_width=2.0, side_slope=1.5)
# Flow conditions
discharge = 10.0 # m³/s
slope = 0.002 # 0.2%
manning_n = 0.030 # earth channel
# Create uniform flow analyzer
uniform_flow = poc.UniformFlow(channel, slope, manning_n)
flow_state = uniform_flow.calculate_flow_state(discharge)
print(f"Flow depth: {flow_state.depth:.3f} m")
print(f"Flow velocity: {flow_state.velocity:.3f} m/s")
print(f"Froude number: {flow_state.froude_number:.3f}")
print(f"Flow type: {'Subcritical' if flow_state.is_subcritical else 'Supercritical'}")
import pyopenchannel as poc
# Design optimal rectangular channel
discharge = 15.0 # m³/s
slope = 0.001 # 0.1%
manning_n = 0.025 # concrete lining
result = poc.OptimalSections.rectangular(discharge, slope, manning_n)
print(f"Optimal width: {result.channel.width:.3f} m")
print(f"Flow depth: {result.depth:.3f} m")
print(f"Flow velocity: {result.velocity:.3f} m/s")
print(f"Recommended freeboard: {result.freeboard:.3f} m")
print(f"Total channel depth: {result.total_depth:.3f} m")
import pyopenchannel as poc
# Economic channel design considering costs
economic_designer = poc.EconomicSections(
excavation_cost_per_m3=25.0, # $/m³
lining_cost_per_m2=50.0, # $/m²
land_cost_per_m2=100.0 # $/m²
)
result = economic_designer.design_rectangular(
discharge=20.0, slope=0.001, manning_n=0.015
)
print(f"Economic width: {result.channel.width:.3f} m")
print(f"Flow depth: {result.depth:.3f} m")
print(f"Cost per meter: ${result.cost_per_meter:.2f}/m")
Rectangular channel cross-section.
Parameters:
width
(float): Channel bottom width in meters
Methods:
area(depth)
: Cross-sectional areawetted_perimeter(depth)
: Wetted perimetertop_width(depth)
: Top width (constant for rectangular)hydraulic_radius(depth)
: Hydraulic radius (A/P)
Trapezoidal channel cross-section.
Parameters:
bottom_width
(float): Channel bottom width in metersside_slope
(float): Side slope ratio (horizontal:vertical)
Triangular channel cross-section.
Parameters:
side_slope
(float): Side slope ratio (horizontal:vertical)
Circular channel cross-section (pipe with free surface).
Parameters:
diameter
(float): Pipe diameter in meters
Parabolic channel cross-section.
Parameters:
shape_parameter
(float): Shape parameter 'a' in y = ax²
Static methods for Manning's equation calculations.
Methods:
discharge(area, hydraulic_radius, slope, manning_n)
: Calculate dischargevelocity(hydraulic_radius, slope, manning_n)
: Calculate velocityrequired_slope(discharge, area, hydraulic_radius, manning_n)
: Calculate required slope
Critical depth and critical flow calculations.
Methods:
calculate(channel, discharge)
: Calculate critical depthfroude_number(velocity, hydraulic_depth)
: Calculate Froude number
Normal depth calculations for uniform flow.
Methods:
calculate(channel, discharge, slope, manning_n)
: Calculate normal depth
Uniform flow analysis.
Methods:
calculate_flow_state(discharge)
: Get complete flow statecalculate_discharge(depth)
: Calculate discharge for given depth
Energy equation applications.
Methods:
specific_energy(depth, velocity)
: Calculate specific energyminimum_specific_energy(channel, discharge)
: Minimum specific energyalternate_depths(channel, discharge, specific_energy)
: Calculate alternate depths
Hydraulically optimal channel design.
Methods:
rectangular(discharge, slope, manning_n)
: Optimal rectangular sectiontrapezoidal(discharge, slope, manning_n, side_slope)
: Optimal trapezoidal sectiontriangular(discharge, slope, manning_n)
: Optimal triangular section
Economic channel design.
Methods:
design_rectangular(discharge, slope, manning_n)
: Economic rectangular designdesign_trapezoidal(discharge, slope, manning_n, side_slope)
: Economic trapezoidal design
General design utilities.
Methods:
calculate_freeboard(discharge, depth, velocity)
: Recommended freeboardcheck_velocity_limits(velocity, channel_material)
: Velocity limit checksrecommend_side_slope(soil_type)
: Side slope recommendationssize_channel_for_capacity(discharge, slope, manning_n, channel_type)
: Size channel for capacity
GRAVITY
: 9.81 m/s²WATER_DENSITY
: 1000 kg/m³KINEMATIC_VISCOSITY
: 1.004×10⁻⁶ m²/s
Pre-defined roughness coefficients for common channel materials:
- Concrete (smooth): 0.012
- Concrete (rough): 0.017
- Earth channels: 0.025-0.040
- Natural channels: 0.030-0.040
Recommended side slopes for different soil types:
- Rock: 0.25:1 to 0.5:1
- Firm earth: 1:1
- Ordinary earth: 1.5:1
- Sandy earth: 2:1
- Loose earth: 3:1
PyOpenChannel includes comprehensive error handling with custom exceptions:
PyOpenChannelError
: Base exception classInvalidGeometryError
: Invalid channel geometry parametersConvergenceError
: Iterative calculations failed to convergeInvalidFlowConditionError
: Physically impossible flow conditionsInvalidRoughnessError
: Invalid Manning's roughness coefficientInvalidSlopeError
: Invalid channel slope
Run the test suite:
# Run all tests
pytest
# Run with coverage
pytest --cov=pyopenchannel
# Run specific test categories
pytest -m unit # Unit tests only
pytest -m integration # Integration tests only
pytest -m "not slow" # Skip slow tests
The examples/
directory contains comprehensive examples:
basic_calculations.py
: Fundamental hydraulic calculationschannel_design.py
: Channel design and optimization examples
Run examples:
python examples/basic_calculations.py
python examples/channel_design.py
PyOpenChannel is suitable for:
- River and stream analysis
- Flood control channel design
- Irrigation and drainage systems
- Culvert and bridge hydraulics
- Storm water management
- Highway drainage design
- Urban channel systems
- Infrastructure hydraulics
- Constructed wetlands
- Stream restoration
- Ecological channel design
- Natural channel analysis
- Hydraulic engineering coursework
- Research applications
- Design verification
- Parametric studies
PyOpenChannel implements fundamental open channel flow theory:
Q = (1/n) × A × R^(2/3) × S^(1/2)
Where:
- Q = discharge (m³/s)
- n = Manning's roughness coefficient
- A = cross-sectional area (m²)
- R = hydraulic radius (m)
- S = channel slope (dimensionless)
Q² = g × A³ / T
Where:
- g = gravitational acceleration (m/s²)
- T = top width (m)
Fr = V / √(g × D)
Where:
- V = average velocity (m/s)
- D = hydraulic depth (m)
Flow classification:
- Fr < 1: Subcritical flow
- Fr = 1: Critical flow
- Fr > 1: Supercritical flow
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
git clone https://github.com/alexiusacademia/pyopenchannel.git
cd pyopenchannel
pip install -e ".[dev]"
pytest
If using uv
uv run --with pytest pytest
This project uses:
- Black for code formatting
- isort for import sorting
- flake8 for linting
- mypy for type checking
This project is licensed under the MIT License - see the LICENSE file for details.
- Based on established open channel flow theory from hydraulic engineering literature
- Inspired by classic texts: "Open Channel Hydraulics" by Ven Te Chow
- Developed for educational and professional use in hydraulic engineering
For questions, issues, or contributions:
- Check the documentation and examples
- Search existing issues on GitHub
- Create a new issue with detailed information
- Consider contributing improvements
Future enhancements planned:
- Complete gradually varied flow implementation
- Hydraulic jump calculations
- Compound channel analysis
- Sediment transport basics
- Unsteady flow analysis
- Advanced optimization algorithms
- Integration with GIS data
- Visualization tools
- Additional channel shapes
- Performance optimizations
PyOpenChannel - Making open channel flow analysis accessible, accurate, and efficient.