# -*- coding: utf-8 -*- """Untitled3.ipynb Automatically generated by Colab. Original file is located at https://colab.research.google.com/drive/11sS74P6WlrbXCzSh9_b8ELPTtcfdsz8s """ # -*- coding: utf-8 -*- # HW3: Deterministic calculator + LLM explanation (Gradio) # Topic: Simply supported beam with center point load (max bending stress & midspan deflection) # -*- coding: utf-8 -*- # HW3: Deterministic calculator + Gradio + LLM explanation # Simply Supported Beam with Center Load import gradio as gr import math import json from transformers import pipeline # ------------------------------- # 1. Deterministic backend function # ------------------------------- def beam_calculator(L, P, E, I, c, sigma_allow=250.0, fy=350.0, n=1.5): """ Deterministic first-principles calculation for a simply supported beam under a central point load. Inputs: L (m): span length P (kN): central load E (GPa): elastic modulus I (cm^4): second moment of area c (cm): extreme fiber distance sigma_allow (MPa): allowable stress fy (MPa): yield strength n (–): safety factor """ # --- Unit conversions --- P_N = P * 1000 # kN -> N E_Pa = E * 1e9 # GPa -> Pa I_m4 = I * 1e-8 # cm^4 -> m^4 c_m = c / 100.0 # cm -> m # --- Mechanics formulas --- M_max = P_N * L / 4.0 # Max bending moment (N·m) delta_max = (P_N * L**3) / (48 * E_Pa * I_m4) # Max deflection (m) sigma_max = M_max * c_m / I_m4 / 1e6 # Max stress (MPa) # --- Safety checks --- utilization_stress = sigma_max / sigma_allow utilization_yield = sigma_max / (fy / n) # Structured record record = { "inputs": { "L_m": L, "P_kN": P, "E_GPa": E, "I_cm4": I, "c_cm": c, "sigma_allow_MPa": sigma_allow, "fy_MPa": fy, "safety_factor": n }, "results": { "M_max_Nm": M_max, "delta_max_m": delta_max, "sigma_max_MPa": sigma_max, "utilization_vs_allow": utilization_stress, "utilization_vs_yield": utilization_yield } } return record # ------------------------------- # 2. LLM Explanation # ------------------------------- explainer = pipeline("text-generation", model="distilgpt2") def explain_results(record): """Use LLM to produce a clear explanation grounded in numbers.""" text = json.dumps(record, indent=2) prompt = f""" You are an engineering assistant. A beam calculation was performed. Here are the structured results: {text} Explain the results to a civil engineering student in plain English: - Report the maximum bending moment, stress, and deflection. - Compare stress with allowable stress and yield strength. - State clearly if the beam is safe or unsafe. Avoid speculation. Base explanation only on the provided numbers. """ explanation = explainer(prompt, max_new_tokens=200)[0]["generated_text"] return explanation # ------------------------------- # 3. Wrapper for Gradio # ------------------------------- def run_calculation(L, P, E, I, c, sigma_allow, fy, n): try: rec = beam_calculator(L, P, E, I, c, sigma_allow, fy, n) explanation = explain_results(rec) return json.dumps(rec["results"], indent=2), explanation except Exception as e: return {"error": str(e)}, "Error during calculation." # ------------------------------- # 4. Gradio UI # ------------------------------- with gr.Blocks() as demo: gr.Markdown("# Simply Supported Beam — Center Load") gr.Markdown("Deterministic calculator + LLM explanation (first principles).") with gr.Row(): with gr.Column(): L = gr.Slider(0.5, 30.0, value=2.0, label="Span L (m)") P = gr.Slider(0.1, 500.0, value=10.0, label="Center load P (kN)") E = gr.Slider(10, 300, value=200, label="Elastic modulus E (GPa)") I = gr.Number(value=8000, label="Second moment of area I (cm^4)") c = gr.Number(value=15, label="Extreme fiber distance c (cm)") with gr.Accordion("Optional: Allowables", open=False): sigma_allow = gr.Number(value=250, label="Allowable stress σ_allow (MPa)") fy = gr.Number(value=350, label="Yield strength fy (MPa)") n = gr.Number(value=1.5, label="Safety factor n") run_btn = gr.Button("Compute") with gr.Column(): results_out = gr.Textbox(label="Numerical Results") explain_out = gr.Textbox(label="LLM Explanation") run_btn.click( fn=run_calculation, inputs=[L, P, E, I, c, sigma_allow, fy, n], outputs=[results_out, explain_out], ) if __name__ == "__main__": demo.launch()