pump_power / app.py
zeeshan4801's picture
Update app.py
f808308 verified
"""
Pump Power Calculator — Gradio app (clean, fixed)
Calculates hydraulic, shaft and motor power for pumps. Supports multiple units,
optionally rounds motor to common standard kW sizes, shows a bar chart and lets
you download results as CSV.
"""
import tempfile
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import gradio as gr
# Constants
G = 9.80665 # m/s^2
HP_CONV = 745.699872 # W per mechanical horsepower
def flow_to_m3s(value: float, unit: str) -> float:
"""Convert various flow units to m^3/s"""
if unit == "m³/s":
return float(value)
if unit == "m³/h":
return float(value) / 3600.0
if unit == "L/s":
return float(value) / 1000.0
if unit == "L/min":
return float(value) / 60000.0
if unit == "m³/min":
return float(value) / 60.0
if unit == "ft³/s (cfs)":
return float(value) * 0.028316846592
if unit == "US gpm":
return float(value) * 0.003785411784
raise ValueError(f"Unsupported flow unit: {unit}")
def head_to_m(value: float, unit: str) -> float:
"""Convert head to meters"""
if unit == "m":
return float(value)
if unit == "ft":
return float(value) * 0.3048
raise ValueError(f"Unsupported head unit: {unit}")
def compute_pump_power(
flow_value,
flow_unit,
head_value,
head_unit,
density,
gravity,
pump_eff_pct,
motor_eff_pct,
service_factor,
round_motor_to_standard,
):
"""
Returns: (summary_text, results_dataframe, matplotlib_figure, csv_filepath)
"""
# Convert inputs
Q = flow_to_m3s(flow_value, flow_unit) # m^3/s
H = head_to_m(head_value, head_unit) # m
rho = float(density)
g = float(gravity)
# Efficiencies as decimals; protect against zero
pump_eff = max(float(pump_eff_pct) / 100.0, 1e-6)
motor_eff = max(float(motor_eff_pct) / 100.0, 1e-6)
sf = float(service_factor)
# Hydraulic power (W)
P_hyd_W = rho * g * Q * H
# Shaft power (W)
P_shaft_W = P_hyd_W / pump_eff
# Motor recommended power (W)
P_motor_W = (P_shaft_W * sf) / motor_eff
# Convert to kW and HP
P_hyd_kW = P_hyd_W / 1000.0
P_shaft_kW = P_shaft_W / 1000.0
P_motor_kW = P_motor_W / 1000.0
P_hyd_HP = P_hyd_W / HP_CONV
P_shaft_HP = P_shaft_W / HP_CONV
P_motor_HP = P_motor_W / HP_CONV
# Optionally round motor to next standard motor rating (kW)
rounded_kW = None
if round_motor_to_standard:
standard_kW = [
0.18, 0.25, 0.37, 0.55, 0.75, 1.1, 1.5, 2.2, 3.0, 3.7,
4.0, 4.5, 5.5, 7.5, 11, 15, 18.5, 22, 30, 37, 45, 55,
75, 90, 110,
]
required = P_motor_kW
# choose first standard >= required; if none, take last
rounded_kW = next((s for s in standard_kW if s >= required), standard_kW[-1])
# Build DataFrame for table output
rows = [
{
"Power type": "Hydraulic",
"W": P_hyd_W,
"kW": P_hyd_kW,
"HP": P_hyd_HP,
},
{
"Power type": "Shaft",
"W": P_shaft_W,
"kW": P_shaft_kW,
"HP": P_shaft_HP,
},
{
"Power type": "Motor (recommended)",
"W": P_motor_W,
"kW": P_motor_kW,
"HP": P_motor_HP,
},
]
if rounded_kW is not None:
rows.append(
{
"Power type": "Motor (rounded standard)",
"W": rounded_kW * 1000.0,
"kW": rounded_kW,
"HP": (rounded_kW * 1000.0) / HP_CONV,
}
)
df = pd.DataFrame(rows)
# Create a bar chart (kW)
fig, ax = plt.subplots(figsize=(6, 3.5))
ax.bar(df["Power type"], df["kW"].astype(float))
ax.set_ylabel("Power (kW)")
ax.set_title("Pump Power Summary")
ax.grid(axis="y", linestyle="--", linewidth=0.5)
plt.tight_layout()
# Summary text
summary_lines = [
f"Flow = {flow_value} {flow_unit} -> {Q:.6e} m³/s",
f"Head = {head_value} {head_unit} -> {H:.6f} m",
f"Density = {rho:.2f} kg/m³, g = {g:.5f} m/s²",
f"Pump eff = {pump_eff_pct}% | Motor eff = {motor_eff_pct}% | Service factor = {sf}",
"",
f"Hydraulic power: {P_hyd_kW:.4f} kW ({P_hyd_HP:.4f} HP)",
f"Shaft power: {P_shaft_kW:.4f} kW ({P_shaft_HP:.4f} HP)",
f"Motor recommended:{P_motor_kW:.4f} kW ({P_motor_HP:.4f} HP)",
]
if rounded_kW is not None:
summary_lines.append(f"Rounded motor (standard): {rounded_kW:.2f} kW")
summary = "\n".join(summary_lines)
# Write CSV to a temporary file for download
tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".csv")
df.to_csv(tmp.name, index=False)
tmp_path = tmp.name
tmp.close()
return summary, df, fig, tmp_path
# --- Build Gradio UI ---
with gr.Blocks(title="Pump Power Calculator") as demo:
gr.Markdown("## 🔧 Pump Power Calculator (Gradio)\nCalculate hydraulic, shaft and motor power for pumps.")
with gr.Row():
with gr.Column(scale=2):
flow_value = gr.Number(value=50.0, label="Flow value", info="Input flow magnitude")
flow_unit = gr.Dropdown(
choices=["m³/s", "m³/h", "L/s", "L/min", "m³/min", "ft³/s (cfs)", "US gpm"],
value="L/s",
label="Flow unit",
)
head_value = gr.Number(value=20.0, label="Head value")
head_unit = gr.Dropdown(choices=["m", "ft"], value="m", label="Head unit")
density = gr.Number(value=1000.0, label="Fluid density (kg/m³)")
gravity = gr.Number(value=G, label="Gravity (m/s²)")
with gr.Column(scale=1):
pump_eff = gr.Slider(1, 100, value=70, step=1, label="Pump efficiency (%)")
motor_eff = gr.Slider(1, 100, value=90, step=1, label="Motor efficiency (%)")
service_factor = gr.Number(value=1.1, label="Service factor")
round_standard = gr.Checkbox(value=True, label="Round motor to standard rating (common kW sizes)")
compute_btn = gr.Button("Compute")
summary_out = gr.Textbox(label="Summary", interactive=False)
table_out = gr.Dataframe(headers=["Power type", "W", "kW", "HP"], label="Power table")
plot_out = gr.Plot(label="Power chart (kW)")
download_file = gr.File(label="Download CSV (results table)")
compute_btn.click(
fn=compute_pump_power,
inputs=[flow_value, flow_unit, head_value, head_unit, density, gravity, pump_eff, motor_eff, service_factor, round_standard],
outputs=[summary_out, table_out, plot_out, download_file],
)
gr.Markdown(
"### Notes\n"
"- Hydraulic power is theoretical (no losses).\n"
"- Shaft power includes pump efficiency losses.\n"
"- Motor recommendation includes service factor and motor efficiency.\n"
)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)