122 lines
No EOL
3.7 KiB
Python
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) |