reynolds_number / app.py
aedupuga's picture
Update app.py
f5967d2 verified
import math
import gradio
import pandas
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
# Instantiate the model that we'll be calling. This is a tiny one!
MODEL_ID = "HuggingFaceTB/SmolLM2-135M-Instruct"
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
pipe = pipeline(
task="text-generation",
model=AutoModelForCausalLM.from_pretrained(
MODEL_ID,
),
tokenizer=tokenizer
)
# This helper function applies a chat format to help the LLM understand what
# is going on
def _format_chat(system_prompt: str, user_prompt: str) -> str:
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt},
]
template = getattr(tokenizer, "chat_template", None)
return tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
# This functoin uses hte LLM to generate a response.
def _llm_generate(prompt: str, max_tokens: int) -> str:
out = pipe(
prompt,
max_new_tokens=max_tokens,
do_sample=True,
temperature=0.5,
return_full_text=False,
)
return out[0]["generated_text"]
# Create a function to do the Reynolds number calculation
def reynolds_number_calc(rho: float, v: float, D: float, mu: float) -> dict:
"""
Calculates the Reynolds number for flow in a circular pipe.
Determines the flow regime (laminar, transitional, or turbulent).
Inputs:
rho: fluid density [kg/m^3]
v: fluid velocity [m/s]
D: pipe diameter [m]
mu: dynamic viscosity [Pa*s] or [kg/(m*s)]
Returns:
reynolds_number: The calculated Reynolds number
flow_regime: The determined flow regime
"""
# Input validation
if rho <= 0 or v < 0 or D <= 0 or mu <= 0:
return {
"reynolds_number": None,
"flow_regime": "Invalid input: Density, velocity, diameter, and viscosity must be positive (velocity can be zero).",
}
reynolds_number = (rho * v * D) / mu
if reynolds_number < 2100:
flow_regime = "Laminar"
elif 2100 <= reynolds_number <= 4000:
flow_regime = "Transitional"
else:
flow_regime = "Turbulent"
return {
"reynolds_number": reynolds_number,
"flow_regime": flow_regime,
}
# This function generates an explanation of the results for Reynolds number
def llm_explain_reynolds(results: dict, inputs: list) -> str:
rho, v, D, mu = inputs
reynolds_number = results.get("reynolds_number")
flow_regime = results.get("flow_regime")
if reynolds_number is None:
return flow_regime # Return the error message from the calculation
system_prompt = (
"You explain fluid mechanics to a smart 5-year-old. "
"Use food-based analogies to support the explanation."
"You always return CONCISE responses, only one sentence."
)
user_prompt = (
f"For a fluid with density {rho:g} kg/m³ and viscosity {mu:g} Pa*s, "
f"flowing at {v:g} m/s through a pipe with diameter {D:g} m, "
f"the Reynolds number is {reynolds_number:.2f}. "
f"The flow regime is {flow_regime}. "
"Explain the Reynolds number and the flow regime in ONE friendly sentence for a non-expert."
)
formatted = _format_chat(system_prompt, user_prompt)
return _llm_generate(formatted, max_tokens=128)
# This function ties everything together for the Reynolds number calculator
def run_reynolds_once(rho, v, D, mu):
inputs = [rho, v, D, mu]
d = reynolds_number_calc(
rho=float(rho),
v=float(v),
D=float(D),
mu=float(mu)
)
if d.get("reynolds_number") is None:
return pandas.DataFrame(), d["flow_regime"]
df = pandas.DataFrame([{
"Reynolds Number [-]": round(d["reynolds_number"], 3),
"Flow Regime": d["flow_regime"],
}])
narrative = llm_explain_reynolds(d, inputs).split("\n")[0]
return df, narrative
# Define the Gradio interface directly
with gradio.Blocks() as demo:
gradio.Markdown(
"# Reynolds Number Calculator"
)
gradio.Markdown(
"This app calculates the Reynolds number for flow in a circular pipe and determines the flow regime (laminar, transitional, or turbulent)."
)
with gradio.Row():
rho = gradio.Number(value=1000.0, label="Fluid density [kg/m³]")
v = gradio.Number(value=1.0, label="Fluid velocity [m/s]")
D = gradio.Number(value=0.1, label="Pipe diameter [m]")
mu = gradio.Number(value=0.001, label="Dynamic viscosity [Pa*s]")
run_btn_reynolds = gradio.Button("Compute Reynolds Number")
results_df_reynolds = gradio.Dataframe(label="Calculation Results", interactive=False)
# Add an explicit title for the explanation panel
gradio.Markdown("## Explanation")
explain_md_reynolds = gradio.Markdown(label="Explanation")
run_btn_reynolds.click(fn=run_reynolds_once, inputs=[rho, v, D, mu], outputs=[results_df_reynolds, explain_md_reynolds])
gradio.Examples(
examples=[
[1000.0, 0.1, 0.05, 0.001], # Laminar example
[1000.0, 0.5, 0.1, 0.001], # Transitional example
[1000.0, 2.0, 0.1, 0.001], # Turbulent example
],
inputs=[rho, v, D, mu],
label="Representative cases",
examples_per_page=3,
cache_examples=False,
)
# Launch the Gradio interface for Hugging Face Spaces
demo.launch()