Repository navigation
Expand file tree
/
Copy pathsection_modulus.py
More file actions
88 lines (77 loc) · 4.03 KB
/
Copy pathsection_modulus.py
File metadata and controls
88 lines (77 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
"""Section modulus of thin-walled Z, G and rotated-Z beam sections.
All lengths are in the same unit (for example mm); the result is in that unit cubed.
The same formulas are duplicated in JavaScript in index.html; keep both in step
(tests/test_js_parity.py checks that they agree).
"""
def _check_inputs(lengths, thick):
"""Reject inputs that have no physical meaning or would divide by zero."""
if thick <= 0:
raise ValueError("thickness must be greater than 0")
if any(length < 0 for length in lengths):
raise ValueError("lengths must not be negative")
if sum(lengths) == 0:
raise ValueError("at least one length must be greater than 0")
# (right) |
# (mid) ___| <- This is a Z-shaped beam
# (left) | The following function calculates its section modulus
def Z(left, mid, right, thick):
_check_inputs((left, mid, right), thick)
# solving the y-centroid integral by taking the origin at the center of the middle beam
# y0 = integral of y * dA / integral of dA
y0 = right * (right + thick) / 2 - left * (left + thick) / 2
y0 /= right + mid + left
# compute the integral of the second moment of area by each component
# Ix = integral of (y - y0)^2 * dA
Ix = mid * ((thick / 2 - y0) ** 3 - (-thick / 2 - y0) ** 3) / 3 # middle beam
Ix += thick * ((thick / 2 + right - y0) ** 3 - (thick / 2 - y0) ** 3) / 3 # right beam
Ix += thick * ((-thick / 2 - y0) ** 3 - (-thick / 2 - left - y0) ** 3) / 3 # left beam
# compute the section modulus
mod = Ix / max(right + thick / 2 - y0, left + thick / 2 + y0)
return mod
# (top)
# |‾‾
# (left) | | (right)
# |___| <- This is a G-shaped beam
# (bot) The following function calculates its section modulus
def G(top, right, bot, left, thick):
_check_inputs((top, right, bot, left), thick)
# solving the y-centroid integral by taking the origin at the center of the left beam
# y0 = integral of y * dA / integral of dA
y0 = top * (left + thick) / 2 - bot * (left + thick) / 2 - right * (left - right) / 2
y0 /= top + right + bot + left
# compute the integral of the second moment of area by each component
# Ix = integral of (y - y0)^2 * dA
Ix = top * ((left / 2 + thick - y0) ** 3 - (left / 2 - y0) ** 3) / 3 # top beam
Ix += bot * ((-left / 2 - y0) ** 3 - (-left / 2 - thick - y0) ** 3) / 3 # bottom beam
Ix += thick * ((right - left / 2 - y0) ** 3 - (-left / 2 - y0) ** 3) / 3 # right beam
Ix += thick * ((left / 2 - y0) ** 3 - (-left / 2 - y0) ** 3) / 3 # left beam
# extreme fibres: a flange only adds its thickness if it exists, and the right
# beam (which rises from the bottom flange) can stick out above the top edge
y_top = max(left / 2 + (thick if top > 0 else 0), right - left / 2)
y_bot = -left / 2 - (thick if bot > 0 else 0)
# compute the section modulus
mod = Ix / max(y_top - y0, y0 - y_bot)
return mod
# (top) __
# |
# (mid) | <- This is a Z-shaped beam rotated 90 degrees
# (bot) |__ The following function calculates its section modulus
def Z_rot90(top, mid, bot, thick):
_check_inputs((top, mid, bot), thick)
# solving the y-centroid integral by taking the origin at the center of the middle beam
# y0 = integral of y * dA / integral of dA
y0 = top * (mid + thick) / 2 - bot * (mid + thick) / 2
y0 /= top + mid + bot
# compute the integral of the second moment of area by each component
# Ix = integral of (y - y0)^2 * dA
Ix = thick * ((mid / 2 - y0) ** 3 - (-mid / 2 - y0) ** 3) / 3 # middle beam
Ix += top * ((mid / 2 + thick - y0) ** 3 - (mid / 2 - y0) ** 3) / 3 # top beam
Ix += bot * ((-mid / 2 - y0) ** 3 - (-mid / 2 - thick - y0) ** 3) / 3 # bottom beam
# compute the section modulus
mod = Ix / max(mid / 2 + thick * (bot > 0) + y0, mid / 2 + thick * (top > 0) - y0)
return mod
if __name__ == "__main__":
print(Z(0, 23, 67, 3)) # support arm
print(Z(30, 56.5, 15, 3)) # cross arm
print(G(14, 12, 50, 27, 3)) # bone
print(Z_rot90(10, 40, 20, 4))