# app.py import gradio as gr import numpy as np import matplotlib.pyplot as plt from io import BytesIO from calculator import ( deflection_simply_supported_point_load, deflection_simply_supported_udl, deflection_cantilever_point_load, deflection_cantilever_udl, generate_deflection_curve, ) plt.switch_backend("Agg") # safe for non-interactive environments (Spaces) def plot_deflection(x, y, L): fig, ax = plt.subplots(figsize=(8, 3)) ax.plot(x, y) ax.axhline(0, linewidth=0.8) ax.set_xlabel("x (m)") ax.set_ylabel("Deflection (m)") ax.set_title("Beam Deflection Curve") ax.grid(True) ax.set_xlim(0, L) fig.tight_layout() buf = BytesIO() fig.savefig(buf, format="png") buf.seek(0) plt.close(fig) return buf def run(beam_type, L, load_type, load_value, load_pos, E, I, num_points): # convert inputs L = float(L) E = float(E) I = float(I) load_value = float(load_value) num_points = int(num_points) # For point load use load_pos (a). For UDL, load_pos ignored. a = float(load_pos) if load_type == "Point Load" else None x, y = generate_deflection_curve( beam_type=beam_type, load_type=load_type, L=L, load_value=load_value, a=a, E=E, I=I, num=num_points, ) # find maximum deflection magnitude and its x location # deflections are returned as signed values (downwards negative) abs_y = np.abs(y) idx = np.argmax(abs_y) max_defl = float(y[idx]) max_x = float(x[idx]) buf = plot_deflection(x, y, L) # Return nicely formatted outputs return ( f"{max_defl:.6e} m", f"{max_x:.4f} m", buf, f"x sample: {np.round(x[:6], 6).tolist()} ...", f"y sample: {np.round(y[:6], 9).tolist()} ...", ) title = "Beam Deflection Calculator" desc = "Calculate beam deflections for common beam/load cases and view the deflection curve." with gr.Blocks() as demo: gr.Markdown(f"# {title}\n\n{desc}") with gr.Row(): with gr.Column(): beam_type = gr.Radio( ["Simply Supported", "Cantilever"], label="Beam Type", value="Simply Supported", ) L = gr.Number(label="Length L (m)", value=1.0) load_type = gr.Radio( ["Point Load", "Uniformly Distributed Load"], label="Load Type", value="Point Load", ) load_value = gr.Number(label="Load (N or N/m)", value=100.0) load_pos = gr.Number( label="Load position a (m) — for point load (from left / fixed end)", value=0.5, ) E = gr.Number(label="Elastic modulus E (Pa)", value=2.1e11) I = gr.Number(label="Moment of inertia I (m^4)", value=1e-6) num_points = gr.Slider(50, 2000, value=400, step=10, label="Points for curve") run_btn = gr.Button("Calculate") with gr.Column(): max_defl_out = gr.Textbox(label="Max deflection", interactive=False) max_x_out = gr.Textbox(label="Location of max deflection", interactive=False) plot_out = gr.Image(label="Deflection curve") x_sample = gr.Textbox(label="x sample", interactive=False) y_sample = gr.Textbox(label="y sample", interactive=False) run_btn.click( run, inputs=[beam_type, L, load_type, load_value, load_pos, E, I, num_points], outputs=[max_defl_out, max_x_out, plot_out, x_sample, y_sample], ) if __name__ == "__main__": demo.launch()