# -*- coding: utf-8 -*- """Untitled1.ipynb Automatically generated by Colab. Original file is located at https://colab.research.google.com/drive/11Qva5ddomzIbz6DxYcTc0-amujuGqXAM """ import math import gradio as gr import pandas as pd from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline # Load LLM 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 ) # Beam Calculation (I-beam) def ibeam_calc(L_m, bf_m, tf_m, tw_m, h_m, P_kN, E_GPa=200, Sy_MPa=250): E = E_GPa * 1e9 Sy = Sy_MPa * 1e6 P = P_kN * 1e3 # Inertia I = (bf_m*h_m**3)/12 - ((bf_m - tw_m)*(h_m - 2*tf_m)**3)/12 S = I / (h_m/2) # Stress M = P*L_m/4 sigma = M/S sigma_MPa = sigma/1e6 # Deflection delta = (P*L_m**3)/(48*E*I) delta_mm = delta*1e3 # Limits delta_allow = L_m/360 fos_yield = Sy/sigma if sigma > 0 else math.inf fos_defl = delta_allow/delta if delta > 0 else math.inf return dict( results={ "σ_max [MPa]": sigma_MPa, "FoS_yield": fos_yield, "δ [mm]": delta_mm, "FoS_defl": fos_defl, }, verdict={ "passes_yield": sigma <= Sy, "passes_serviceability": delta <= delta_allow, } ) # LLM Explanation def llm_explain(results, inputs): L, bf, tf, tw, h, P = inputs r = results["results"] v = results["verdict"] system_prompt = "You are a structural engineer. Explain results concisely in one professional sentence." user_prompt = ( f"I-beam length {L} m, load {P} kN, bf={bf} m, tf={tf} m, tw={tw} m, h={h} m.\n" f"σ_max={r['σ_max [MPa]']:.2f} MPa, FoS_yield={r['FoS_yield']:.2f}, " f"δ={r['δ [mm]']:.2f} mm, FoS_defl={r['FoS_defl']:.2f}. " f"Yield check={'OK' if v['passes_yield'] else 'FAIL'}, " f"Deflection check={'OK' if v['passes_serviceability'] else 'FAIL'}.\n" "Explain verdict." ) messages = [{"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}] prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) out = pipe(prompt, max_new_tokens=128, temperature=0.5, return_full_text=False) return out[0]["generated_text"] # Run once def run_once(L, bf, tf, tw, h, P): d = ibeam_calc(L, bf, tf, tw, h, P) df = pd.DataFrame([d["results"]]) narrative = llm_explain(d, [L, bf, tf, tw, h, P]) return df, narrative # Gradio UI with gr.Blocks() as demo: gr.Markdown("# I-beam Stress & Deflection Calculator") with gr.Row(): L = gr.Number(value=6.0, label="Beam length L [m]") P = gr.Number(value=50.0, label="Central load P [kN]") with gr.Row(): bf = gr.Number(value=0.2, label="Flange width bf [m]") tf = gr.Number(value=0.02, label="Flange thickness tf [m]") tw = gr.Number(value=0.01, label="Web thickness tw [m]") h = gr.Number(value=0.3, label="Beam height h [m]") run_btn = gr.Button("Compute") results_df = gr.Dataframe(label="Results", interactive=False) explain_md = gr.Markdown(label="Explanation") run_btn.click(fn=run_once, inputs=[L, bf, tf, tw, h, P], outputs=[results_df, explain_md]) gr.Examples( examples=[ [6.0, 0.2, 0.02, 0.01, 0.3, 50.0], [4.0, 0.15, 0.015, 0.008, 0.25, 30.0], [8.0, 0.25, 0.02, 0.012, 0.35, 80.0], ], inputs=[L, bf, tf, tw, h, P], ) if __name__ == "__main__": demo.launch(debug=True)