mohitk24 commited on
Commit
673832e
verified
1 Parent(s): 990173a

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +220 -0
app.py ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import math as m
3
+ import gradio as gr
4
+ import pandas as pd
5
+ import numpy as np
6
+ from math import log10, pi
7
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
8
+
9
+ # Assuming darcy_weisbach_calculation and explain_results functions are defined elsewhere or in this string
10
+ # For this example, I'll include them for completeness. In a real scenario,
11
+ # you might have these in separate files or ensure they are defined before this string.
12
+
13
+ def darcy_weisbach_calculation(
14
+ rho, # kg/m^3
15
+ mu, # Pa路s
16
+ D, # m
17
+ L, # m
18
+ Q, # m^3/s
19
+ eps=1.5e-6 # m, absolute roughness (default ~ smooth steel)
20
+ ):
21
+ """
22
+ Assumptions:
23
+ - Steady, incompressible, Newtonian fluid
24
+ - Fully developed internal flow in a straight, horizontal, circular pipe
25
+ - Single-phase, isothermal
26
+ - Darcy friction factor: laminar f=64/Re; turbulent via Swamee鈥揓ain explicit fit
27
+ Valid ranges (typical sanity):
28
+ - 500 <= rho <= 2000 kg/m^3
29
+ - 0.2e-3 <= mu <= 5e-3 Pa路s
30
+ - 0.005 <= D <= 1.0 m
31
+ - 0.5 <= L <= 1000 m
32
+ - 1e-5 <= Q <= 2.0 m^3/s
33
+ - 0 <= eps <= 5e-3 m
34
+ """
35
+ # Derived quantities
36
+ A = pi*(D**2)/4.0
37
+ v = Q / A
38
+ Re = rho * v * D / mu
39
+
40
+ # Friction factor
41
+ if Re < 2300:
42
+ f = 64.0 / max(Re, 1e-9) # protect division
43
+ regime = "laminar"
44
+ else:
45
+ # Swamee鈥揓ain explicit approximation for turbulent flow
46
+ # f = 0.25 / [log10( (eps/(3.7D)) + (5.74/Re^0.9) )]^2
47
+ term = (eps/(3.7*D)) + (5.74/(Re**0.9))
48
+ f = 0.25 / (log10(term)**2)
49
+ regime = "turbulent"
50
+
51
+ # Darcy鈥揥eisbach head loss: h_f = f*(L/D)*(v^2/(2g))
52
+ g = 9.80665 # m/s^2
53
+ hf = f * (L/D) * (v**2/(2*g))
54
+
55
+ # Pressure drop: 螖P = rho*g*h_f
56
+ dP = rho * g * hf
57
+
58
+ # Structured, human-readable message
59
+ message = {
60
+ "title": "Darcy鈥揥eisbach Head Loss Calculator",
61
+ "scope": [
62
+ "Steady, incompressible, fully developed flow in a straight circular pipe",
63
+ "Single-phase, isothermal, horizontal run"
64
+ ],
65
+ "assumptions": [
66
+ "Newtonian fluid",
67
+ "Darcy friction factor: laminar f=64/Re; turbulent via Swamee鈥揓ain explicit formula",
68
+ "No fittings/minor losses included"
69
+ ],
70
+ "inputs": {
71
+ "density_rho_kg_per_m3": rho,
72
+ "viscosity_mu_Pa_s": mu,
73
+ "diameter_D_m": D,
74
+ "length_L_m": L,
75
+ "flow_rate_Q_m3_per_s": Q,
76
+ "roughness_eps_m": eps
77
+ },
78
+ "derived": {
79
+ "area_A_m2": A,
80
+ "avg_velocity_v_m_per_s": v,
81
+ "Reynolds_Re": Re,
82
+ "friction_factor_f": f,
83
+ "flow_regime": regime
84
+ },
85
+ "outputs": {
86
+ "head_loss_hf_m": hf,
87
+ "pressure_drop_dP_Pa": dP
88
+ },
89
+ "formulas": [
90
+ "A = 蟺 D^2 / 4",
91
+ "v = Q / A",
92
+ "Re = 蟻 v D / 渭",
93
+ "Laminar: f = 64 / Re",
94
+ "Turbulent: f = 0.25 / [log10(蔚/(3.7D) + 5.74/Re^0.9)]^2",
95
+ "h_f = f (L/D) (v^2 / (2g))",
96
+ "螖P = 蟻 g h_f"
97
+ ],
98
+ "constants": {
99
+ "g_m_per_s2": g
100
+ },
101
+ "notes": [
102
+ "For turbulent flow with significant fittings, include minor losses separately.",
103
+ "Check cavitation or NPSH if near pumps; this tool reports line loss only."
104
+ ],
105
+ "valid_ranges": {
106
+ "rho_kg_per_m3": [500, 2000],
107
+ "mu_Pa_s": [0.0002, 0.005],
108
+ "D_m": [0.005, 1.0],
109
+ "L_m": [0.5, 1000],
110
+ "Q_m3_per_s": [1e-5, 2.0],
111
+ "eps_m": [0.0, 0.005]
112
+ }
113
+ }
114
+ return message
115
+
116
+ # Small instruction-tuned model for concise, low-latency explanations.
117
+ # Change model if desired; keep it tiny for Spaces CPU.
118
+ model_id = "hf-internal-testing/tiny-random-LlamaForCausalLM" # placeholder tiny model
119
+ # For practical explanations, replace with a small instruct model like:
120
+ # model_id = "HuggingFaceH4/zephyr-7b-alpha" # requires more resources
121
+ # or a tiny flan-t5: "google/flan-t5-small"
122
+
123
+ def load_llm_pipeline(model_name=model_id, task="text-generation"):
124
+ try:
125
+ pipe = pipeline(task, model=model_name, device_map="auto")
126
+ except Exception:
127
+ # Fallback small model available in most environments
128
+ pipe = pipeline(task, model="google/flan-t5-small")
129
+ return pipe
130
+
131
+ llm = load_llm_pipeline()
132
+
133
+ def explain_results(structured_message):
134
+ # Convert the structured dict into a readable block and prompt the LLM
135
+ import json
136
+ context = json.dumps(structured_message, indent=2)
137
+
138
+ prompt = (
139
+ "You are an engineering tutor. Read the structured calculation JSON and produce a clear, concise explanation for a non-expert.
140
+ "
141
+ "Goals:
142
+ "
143
+ "- Briefly restate the problem and assumptions.
144
+ "
145
+ "- Highlight the formulas and what they mean physically.
146
+ "
147
+ "- Interpret the Reynolds number and friction factor.
148
+ "
149
+ "- Explain head loss and pressure drop magnitudes and practical implications.
150
+ "
151
+ "- If inputs look out of typical ranges, gently flag them.
152
+ "
153
+ "Stay under 180 words. Avoid equations in LaTeX; use plain words.
154
+
155
+ "
156
+ f"JSON:
157
+ {context}
158
+
159
+ "
160
+ "Explanation:"
161
+ )
162
+ out = llm(prompt, max_new_tokens=220)
163
+ text = out[0]["generated_text"] if isinstance(out, list) else str(out)
164
+ # In case the model echoes the prompt, try to extract the tail
165
+ if "Explanation:" in text:
166
+ text = text.split("Explanation:", 1)[-1].strip()
167
+ return text
168
+
169
+
170
+ def run_calc(rho, mu, D, L, Q, eps):
171
+ msg = darcy_weisbach_calculation(rho, mu, D, L, Q, eps)
172
+ # Numeric panel summary
173
+ out_lines = []
174
+ out = msg["outputs"]
175
+ der = msg["derived"]
176
+ out_lines.append(f"Reynolds number: {der['Reynolds_Re']:.0f}")
177
+ out_lines.append(f"Friction factor: {der['friction_factor_f']:.5f} ({der['flow_regime']})")
178
+ out_lines.append(f"Head loss h_f: {out['head_loss_hf_m']:.4f} m")
179
+ out_lines.append(f"Pressure drop 螖P: {out['pressure_drop_dP_Pa']:.1f} Pa")
180
+ numeric_panel = "
181
+ ".join(out_lines)
182
+
183
+ # Explanation via LLM
184
+ explanation = explain_results(msg)
185
+ return numeric_panel, explanation
186
+
187
+ with gr.Blocks() as demo:
188
+ gr.Markdown("# Darcy鈥揥eisbach Pipe Loss (Deterministic)")
189
+
190
+ with gr.Row():
191
+ with gr.Column():
192
+ rho = gr.Slider(500, 2000, value=998.0, step=1.0, label="Density 蟻 (kg/m鲁)")
193
+ mu = gr.Slider(0.0002, 0.005, value=0.0010, step=0.0001, label="Viscosity 渭 (Pa路s)")
194
+ D = gr.Slider(0.005, 1.0, value=0.05, step=0.001, label="Diameter D (m)")
195
+ L = gr.Slider(0.5, 1000.0, value=50.0, step=0.5, label="Length L (m)")
196
+ Q = gr.Slider(1e-5, 2.0, value=0.005, step=1e-4, label="Flow rate Q (m鲁/s)")
197
+ eps= gr.Slider(0.0, 0.005, value=1.5e-6, step=1e-6, label="Roughness 蔚 (m)")
198
+
199
+ run_btn = gr.Button("Compute")
200
+
201
+ with gr.Column():
202
+ numeric = gr.Textbox(label="Numerical results", lines=6)
203
+ # Assuming 'explain' is defined elsewhere, e.g., as a gr.Textbox
204
+ # If not, you might need to define it here:
205
+ explain = gr.Textbox(label="Explanation", lines=10)
206
+
207
+
208
+ examples = gr.Examples(
209
+ examples=[
210
+ [998.0, 0.0010, 0.05, 50.0, 0.005, 1.5e-6], # Water, smooth steel
211
+ [870.0, 0.0015, 0.10, 200.0, 0.03, 4.5e-5], # Light oil, commercial steel
212
+ [1000.0, 0.0008, 0.02, 10.0, 0.0002, 1.0e-6] # Small tube, low flow
213
+ ],
214
+ inputs=[rho, mu, D, L, Q, eps]
215
+ )
216
+
217
+ run_btn.click(run_calc, inputs=[rho, mu, D, L, Q, eps], outputs=[numeric, explain])
218
+
219
+ # Comment out the demo.launch() call as it will be handled by the Hugging Face Space
220
+ # demo.launch(share=True)