File size: 7,050 Bytes
61ad070
f808308
d1b50c2
 
 
61ad070
 
 
 
 
 
 
 
 
 
 
 
d1b50c2
61ad070
 
 
f808308
61ad070
f808308
61ad070
f808308
61ad070
f808308
61ad070
f808308
61ad070
f808308
61ad070
f808308
61ad070
 
d1b50c2
61ad070
f808308
61ad070
f808308
61ad070
f808308
61ad070
 
d1b50c2
61ad070
f808308
 
 
 
 
 
 
 
 
 
d1b50c2
 
 
 
f808308
 
 
 
d1b50c2
 
 
 
f808308
d1b50c2
 
 
 
 
 
 
f808308
d1b50c2
 
f808308
d1b50c2
 
f808308
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
"""
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)