apsora commited on
Commit
315fce5
·
verified ·
1 Parent(s): 84803cf

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +126 -0
app.py ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import gradio
3
+ import pandas as pd
4
+
5
+ # ---------------- Settings ----------------
6
+ TITLE = "Simply-Supported I-Beam"
7
+ DESC = "Point load @ midspan or uniform load (UDL). SI units. Euler–Bernoulli."
8
+
9
+ # ---------------- Deterministic backend ----------------
10
+ def _compute(load_type, L_m, E_GPa, Ix_m4, mode, Sx_m3, depth_m, P_kN, w_kNpm, sigma_allow_MPa, defl_ratio):
11
+ # validate
12
+ if L_m <= 0: raise ValueError("Span L must be > 0.")
13
+ if E_GPa <= 0: raise ValueError("E must be > 0.")
14
+ if Ix_m4 <= 0: raise ValueError("Ix must be > 0.")
15
+ has_Sx = (mode == "I have Sx")
16
+ if has_Sx and Sx_m3 <= 0: raise ValueError("Sx must be > 0.")
17
+ if (not has_Sx) and depth_m <= 0: raise ValueError("Depth must be > 0 when Sx not provided.")
18
+ if load_type == "Point @ midspan" and P_kN <= 0: raise ValueError("P must be > 0 for point load.")
19
+ if load_type == "Uniform (UDL)" and w_kNpm <= 0: raise ValueError("w must be > 0 for UDL.")
20
+
21
+ # units
22
+ E = E_GPa * 1e9 # Pa
23
+ P = P_kN * 1e3 # N
24
+ w = w_kNpm * 1e3 # N/m
25
+
26
+ # section modulus
27
+ if has_Sx:
28
+ Sx = Sx_m3
29
+ c = Ix_m4 / Sx
30
+ h = 2 * c
31
+ else:
32
+ h = depth_m
33
+ c = h / 2
34
+ Sx = Ix_m4 / c
35
+
36
+ # closed-form results
37
+ if load_type == "Point @ midspan":
38
+ Mmax = P * L_m / 4.0
39
+ dmax = P * (L_m**3) / (48.0 * E * Ix_m4)
40
+ else: # UDL
41
+ Mmax = w * (L_m**2) / 8.0
42
+ dmax = 5.0 * w * (L_m**4) / (384.0 * E * Ix_m4)
43
+
44
+ sigma = Mmax / Sx # Pa
45
+
46
+ # checks
47
+ stress_ok, SF = None, None
48
+ if sigma_allow_MPa and sigma_allow_MPa > 0:
49
+ sigma_MPa = sigma / 1e6
50
+ SF = sigma_allow_MPa / max(sigma_MPa, 1e-12)
51
+ stress_ok = sigma_MPa <= sigma_allow_MPa
52
+ defl_ok, defl_lim = None, None
53
+ if defl_ratio and defl_ratio > 0:
54
+ defl_lim = (L_m * 1e3) / defl_ratio
55
+ defl_ok = (dmax * 1e3) <= defl_lim
56
+
57
+ # compact dict result (easy to read in the UI)
58
+ return {
59
+ "inputs": {
60
+ "load_type": load_type,
61
+ "L_m": L_m, "E_GPa": E_GPa, "Ix_m4": Ix_m4,
62
+ "Sx_m3": Sx, "depth_m": h,
63
+ "P_kN": P_kN if load_type.startswith("Point") else 0.0,
64
+ "w_kN_per_m": w_kNpm if load_type.startswith("Uniform") else 0.0,
65
+ "sigma_allow_MPa": sigma_allow_MPa or None,
66
+ "deflection_ratio": defl_ratio or None,
67
+ },
68
+ "solution": {
69
+ "M_max_kN_m": Mmax / 1e3,
70
+ "sigma_max_MPa": sigma / 1e6,
71
+ "delta_max_mm": dmax * 1e3,
72
+ "delta_over_L": dmax / L_m,
73
+ },
74
+ "checks": {
75
+ "stress_ok": stress_ok, "SF_stress": SF,
76
+ "deflection_ok": defl_ok, "deflection_limit_mm": defl_lim, "deflection_ratio": defl_ratio or None,
77
+ },
78
+ }
79
+
80
+ # ---------------- Gradio UI (simple, like your example) ----------------
81
+ with gradio.Blocks() as demo:
82
+ gradio.Markdown(f"# {TITLE}")
83
+ gradio.Markdown(DESC)
84
+
85
+ with gradio.Row():
86
+ load_type = gradio.Radio(choices=["Point @ midspan", "Uniform (UDL)"], value="Point @ midspan", label="Load case")
87
+ L_m = gradio.Number(value=3.0, label="Span L [m]", precision=4)
88
+ E_GPa = gradio.Number(value=200.0, label="Young's modulus E [GPa]", precision=3)
89
+ Ix_m4 = gradio.Number(value=8.0e-6, label="Second moment Ix [m^4]", precision=10)
90
+
91
+ with gradio.Row():
92
+ mode = gradio.Radio(choices=["I have Sx", "I have depth (h) only"], value="I have Sx", label="Section input")
93
+ Sx_m3 = gradio.Number(value=4.0e-4, label="Section modulus Sx [m^3]", precision=8, visible=True)
94
+ depth_m = gradio.Number(value=0.30, label="Depth h [m]", precision=4, visible=False)
95
+
96
+ def _toggle(v):
97
+ return gradio.update(visible=(v=="I have Sx")), gradio.update(visible=(v!="I have Sx"))
98
+ mode.change(_toggle, inputs=mode, outputs=[Sx_m3, depth_m])
99
+
100
+ with gradio.Row():
101
+ P_kN = gradio.Number(value=20.0, label="Point load P [kN]", precision=3)
102
+ w_kNpm = gradio.Number(value=5.0, label="UDL w [kN/m]", precision=4)
103
+
104
+ with gradio.Row():
105
+ sigma_allow = gradio.Number(value=250.0, label="Allowable stress [MPa] (0=skip)", precision=3)
106
+ defl_ratio = gradio.Number(value=360, label="Deflection limit L/ratio (0=skip)", precision=0)
107
+
108
+ out = gradio.JSON(label="Results")
109
+
110
+ # Live updates on any input (like your example)
111
+ inputs = [load_type, L_m, E_GPa, Ix_m4, mode, Sx_m3, depth_m, P_kN, w_kNpm, sigma_allow, defl_ratio]
112
+ for comp in inputs:
113
+ comp.change(fn=_compute, inputs=inputs, outputs=out)
114
+
115
+ gradio.Examples(
116
+ examples=[
117
+ ["Point @ midspan", 3.0, 200.0, 8.0e-6, "I have Sx", 4.0e-4, 0.30, 20.0, 0.0, 250.0, 360],
118
+ ["Uniform (UDL)", 4.5, 200.0, 1.2e-5, "I have Sx", 6.0e-4, 0.35, 0.0, 8.0, 200.0, 360],
119
+ ["Uniform (UDL)", 2.5, 70.0, 3.5e-6, "I have depth (h) only", 0.0, 0.22, 0.0, 6.0, 160.0, 240],
120
+ ],
121
+ inputs=inputs,
122
+ label="Examples",
123
+ cache_examples=False,
124
+ )
125
+
126
+ demo.launch()