111 / calculator.py
affanraz's picture
Create calculator.py
480c725 verified
# calculator.py
import numpy as np
def _safe_float(v, default=0.0):
try:
return float(v)
except Exception:
return default
# -----------------------------
# Simply supported: Point load
# -----------------------------
# L: beam length
# P: point load magnitude
# a: distance from left support to load
# x: array of positions where deflection is requested
#
# Formula (standard):
# b = L - a
# for 0 <= x <= a:
# y = P*b*x*(L**2 - b**2 - x**2) / (6*E*I*L)
# for a <= x <= L:
# y = P*a*(L-x)*(L**2 - a**2 - (L-x)**2) / (6*E*I*L)
#
def deflection_simply_supported_point_load(L, P, a, E, I, x):
L = _safe_float(L)
P = _safe_float(P)
a = _safe_float(a)
E = _safe_float(E)
I = _safe_float(I)
x = np.array(x, dtype=float)
b = L - a
y = np.zeros_like(x, dtype=float)
mask1 = x <= a
if np.any(mask1):
xx = x[mask1]
y[mask1] = P * b * xx * (L**2 - b**2 - xx**2) / (6.0 * E * I * L)
mask2 = x > a
if np.any(mask2):
xx = x[mask2]
y[mask2] = P * a * (L - xx) * (L**2 - a**2 - (L - xx) ** 2) / (6.0 * E * I * L)
# convention: downward deflection negative
return -y
# -----------------------------
# Simply supported: UDL (w = N/m)
# y(x) = (w * x * (L^3 - 2 L x^2 + x^3)) / (24 E I)
# -----------------------------
def deflection_simply_supported_udl(L, w, E, I, x):
L = _safe_float(L)
w = _safe_float(w)
E = _safe_float(E)
I = _safe_float(I)
x = np.array(x, dtype=float)
y = (w * x * (L**3 - 2.0 * L * x**2 + x**3)) / (24.0 * E * I)
return -y
# -----------------------------
# Cantilever: Point load at free end P
# y(x) = P * x^2 * (3L - x) / (6 E I)
# (x measured from fixed support at 0)
# -----------------------------
def deflection_cantilever_point_load(L, P, E, I, x):
L = _safe_float(L)
P = _safe_float(P)
E = _safe_float(E)
I = _safe_float(I)
x = np.array(x, dtype=float)
y = P * x**2 * (3.0 * L - x) / (6.0 * E * I)
return -y
# -----------------------------
# Cantilever: UDL over full length w
# y(x) = w * x^2 * (6 L^2 - 4 L x + x^2) / (24 E I)
# -----------------------------
def deflection_cantilever_udl(L, w, E, I, x):
L = _safe_float(L)
w = _safe_float(w)
E = _safe_float(E)
I = _safe_float(I)
x = np.array(x, dtype=float)
y = w * x**2 * (6.0 * L**2 - 4.0 * L * x + x**2) / (24.0 * E * I)
return -y
# -----------------------------
# Generate deflection curve helper
# -----------------------------
def generate_deflection_curve(beam_type, load_type, L, load_value, a, E, I, num=400):
"""
beam_type: 'Simply Supported' or 'Cantilever'
load_type: 'Point Load' or 'Uniformly Distributed Load'
L: length (m)
load_value: P (N) for point load, w (N/m) for UDL
a: point load position (m) for simply supported; ignored for cantilever here
E, I: material & section properties
num: number of points across the beam
"""
L = float(L)
E = float(E)
I = float(I)
x = np.linspace(0.0, L, int(num))
if beam_type == "Simply Supported":
if load_type == "Point Load":
if a is None:
a = L / 2.0
y = deflection_simply_supported_point_load(L, load_value, a, E, I, x)
else: # UDL
y = deflection_simply_supported_udl(L, load_value, E, I, x)
elif beam_type == "Cantilever":
if load_type == "Point Load":
# interpretation: point load at free end (common case)
y = deflection_cantilever_point_load(L, load_value, E, I, x)
else:
y = deflection_cantilever_udl(L, load_value, E, I, x)
else:
raise ValueError("Unsupported beam type")
return x, y
# quick demo if run directly
if __name__ == "__main__":
L = 2.0
P = 100.0
E = 2.1e11
I = 1e-6
x, y = generate_deflection_curve("Simply Supported", "Point Load", L, P, a=1.0, E=E, I=I)
print("sample x:", x[:5])
print("sample y:", y[:5])