pumpcalc/pumpcalc.py
2025-01-18 02:46:06 +00:00

122 lines
No EOL
3.7 KiB
Python

#!/usr/bin/env python3
from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
import math
import uvicorn
app = FastAPI()
templates = Jinja2Templates(directory="templates")
DEFAULTS = {
'temperature': 45, # °F
'distance': 5280, # feet
'pipe_diameter': 1.0, # inches
'suction_loss': 20, # feet
'static_head': 120, # feet
'flow_rate': 7.5, # gallons per minute
}
PIPE_MATERIALS = {
'PVC': {'roughness': 0.0000015},
'Steel (New)': {'roughness': 0.00015},
'Steel (Used)': {'roughness': 0.00060},
'Cast Iron (New)': {'roughness': 0.00085},
'Cast Iron (Used)': {'roughness': 0.00200},
'Galvanized Iron': {'roughness': 0.00050},
'Copper/Brass': {'roughness': 0.0000050},
'Concrete': {'roughness': 0.00100},
'Corrugated Steel': {'roughness': 0.00500},
'HDPE (New)': {'roughness': 0.0000070},
'HDPE (Used)': {'roughness': 0.0000150},
'PE (New)': {'roughness': 0.0000118},
'PE (Used)': {'roughness': 0.0000200},
}
def calculate_pump_power(
pipe_diameter: float,
distance: float,
suction_loss: float,
static_head: float,
flow_rate: float,
temperature: float = 50,
material: str = 'PVC'
):
# Temperature adjustments
# Approximate water density and viscosity based on temperature
temp_c = (temperature - 32) * 5/9
water_density = 62.4 * (1 - abs(temp_c - 4) / 1000) # lb/ft³
# Simplified viscosity calculation
kinematic_viscosity = (1.79 / (1 + 0.03368 * temp_c + 0.000221 * temp_c**2)) * 1e-6
# Constants
GRAVITY = 32.2 # ft/s²
EFFICIENCY = 0.65 # Typical pump efficiency
# Convert inputs to appropriate units
pipe_radius = (pipe_diameter / 2) / 12 # Convert to feet
flow_rate_cfs = flow_rate * 0.002228 # Convert GPM to ft³/s
# Calculate velocity
pipe_area = math.pi * (pipe_radius ** 2)
velocity = flow_rate_cfs / pipe_area
# Calculate Reynolds number
reynolds = (velocity * pipe_diameter/12) / kinematic_viscosity
# Calculate friction factor (Swamee-Jain equation)
roughness = PIPE_MATERIALS[material]['roughness']
relative_roughness = roughness / (pipe_diameter/12)
f = 0.25 / (math.log10(relative_roughness/3.7 + 5.74/(reynolds**0.9)))**2
# Calculate friction head loss (Darcy-Weisbach equation)
friction_head = f * (distance / (pipe_diameter/12)) * (velocity**2 / (2 * GRAVITY))
# Calculate total dynamic head
total_head = static_head + friction_head + suction_loss
# Calculate power requirement
power_ft_lbs = (flow_rate_cfs * water_density * total_head) / EFFICIENCY
horsepower = power_ft_lbs / 550 # Convert ft-lbs/s to HP
return {
'horsepower': round(horsepower, 2),
'total_head': round(total_head, 1),
'friction_head': round(friction_head, 1),
'velocity': round(velocity, 1),
'recommended_hp': round(horsepower * 1.3, 2),
}
@app.get("/")
async def home(request: Request):
return templates.TemplateResponse(
"index.html",
{
"request": request,
"defaults": DEFAULTS,
"pipe_materials": PIPE_MATERIALS
}
)
@app.get("/calculate")
async def calculate(
pipe_diameter: float,
distance: float,
suction_loss: float,
static_head: float,
flow_rate: float,
temperature: float = DEFAULTS['temperature'],
material: str = 'PVC'
):
return calculate_pump_power(
pipe_diameter,
distance,
suction_loss,
static_head,
flow_rate,
temperature,
material
)
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8901)