Skip to content

Commit 6e556b4

Browse files
Add more composite plastic tests
1 parent d871119 commit 6e556b4

File tree

1 file changed

+150
-1
lines changed

1 file changed

+150
-1
lines changed

tests/analysis/test_plastic.py

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def test_plastic_centroid():
9393
# create a Section object
9494
section = Section(geometry=geometry)
9595

96-
# perform a geometric, warping and plastic analysis
96+
# perform a geometric and plastic analysis
9797
section.calculate_geometric_properties()
9898
section.calculate_plastic_properties()
9999

@@ -125,3 +125,152 @@ def test_plastic_centroid():
125125
x_pc, y_pc = nested_sec.get_pc()
126126
assert x_pc == pytest.approx(37.5)
127127
assert y_pc == pytest.approx(50)
128+
129+
130+
def test_plastic_composite_simple():
131+
"""Tests the plastic properties of a simple composite section."""
132+
mat1 = Material(
133+
name="mat1",
134+
elastic_modulus=10,
135+
poissons_ratio=0.3,
136+
density=1,
137+
yield_strength=50,
138+
color="grey",
139+
)
140+
141+
mat2 = Material(
142+
name="mat2",
143+
elastic_modulus=20,
144+
poissons_ratio=0.3,
145+
density=1,
146+
yield_strength=80,
147+
color="black",
148+
)
149+
150+
rect1 = sections.rectangular_section(d=100, b=50, material=mat1)
151+
rect2 = sections.rectangular_section(d=100, b=50, material=mat2).shift_section(
152+
x_offset=50
153+
)
154+
geom = rect1 + rect2
155+
geom.create_mesh(mesh_sizes=100)
156+
157+
sec = Section(geometry=geom)
158+
sec.calculate_geometric_properties()
159+
sec.calculate_plastic_properties()
160+
161+
x_pc, y_pc = sec.get_pc()
162+
assert y_pc == pytest.approx(50)
163+
164+
# calculate x_pc
165+
f_mat1 = 100 * 50 * 50 # force in mat1
166+
x_mat2 = f_mat1 / 80 / 100 # width of mat2 required to equal force in mat1
167+
x_left = (50 - x_mat2) / 2 # width of ma2 to left of pc
168+
assert x_pc == pytest.approx(x_left + 50)
169+
170+
mp_xx, mp_yy = sec.get_mp()
171+
mp_xx_calc = 50 * 100**2 / 4 * (80 + 50)
172+
assert mp_xx == pytest.approx(mp_xx_calc)
173+
174+
# calculate mp_yy
175+
mp_yy_calc = 0
176+
mp_yy_calc += f_mat1 * abs(25 - x_pc) # mat 1 contribution
177+
# left mat 2 contribution
178+
mp_yy_calc += x_left * 100 * 80 * abs(50 + x_left / 2 - x_pc)
179+
# right mat 2 contribution
180+
mp_yy_calc += (50 - x_left) * 100 * 80 * abs(100 - (50 - x_left) / 2 - x_pc)
181+
assert mp_yy == pytest.approx(mp_yy_calc)
182+
183+
# check principal calc with rotation 45 deg
184+
geom.rotate_section(angle=45)
185+
geom.create_mesh(mesh_sizes=100)
186+
sec = Section(geometry=geom)
187+
sec.calculate_geometric_properties()
188+
sec.calculate_plastic_properties()
189+
190+
mp_11, mp_22 = sec.get_mp_p()
191+
assert mp_11 == pytest.approx(mp_xx_calc)
192+
assert mp_22 == pytest.approx(mp_yy_calc)
193+
194+
195+
def test_plastic_composite_example():
196+
"""Tests the composite example on the sectionproperties docs, refer issue #460.
197+
198+
The steel section is simplified to have no root radii to allow hand calculation
199+
comparison.
200+
"""
201+
# create the steel material
202+
steel = Material(
203+
name="Steel",
204+
elastic_modulus=200e3,
205+
poissons_ratio=0.3,
206+
density=7.85e-6,
207+
yield_strength=500,
208+
color="grey",
209+
)
210+
211+
# create the timber material
212+
timber = Material(
213+
name="Timber",
214+
elastic_modulus=8e3,
215+
poissons_ratio=0.35,
216+
yield_strength=20,
217+
density=0.78e-6,
218+
color="burlywood",
219+
)
220+
221+
# universal steel beam
222+
ub = steel_sections.i_section(
223+
d=304, b=165, t_f=10.2, t_w=6.1, r=0, n_r=2, material=steel
224+
)
225+
226+
# timber floor panel
227+
panel = sections.rectangular_section(d=100, b=600, material=timber)
228+
panel = panel.align_center(align_to=ub).align_to(other=ub, on="top")
229+
230+
# combine geometry
231+
geom = ub + panel
232+
233+
geom.create_mesh(mesh_sizes=[50, 500])
234+
sec = Section(geometry=geom)
235+
sec.calculate_geometric_properties()
236+
sec.calculate_plastic_properties()
237+
238+
# get calculated values
239+
x_pc, y_pc = sec.get_pc()
240+
mp_xx, mp_yy = sec.get_mp()
241+
242+
# hand calcs
243+
# 1) x-axis bending
244+
# calculate y_pc -> assume centroid in top flange
245+
f_timber = 600 * 100 * 20
246+
f_web = (304 - 2 * 10.2) * 6.1 * 500
247+
f_flange = 165 * 10.2 * 500
248+
249+
# let y = distance from bottom of top flange to y_pc
250+
# A) bot = 165 * y * 500
251+
# B) top = 165 * (10.2 - y) * 500
252+
# C) (A) - (B) = f_timber - f_web - f_flange = f_diff
253+
# 165 * 500 (2y - 10.2) = f_diff
254+
# y = (f_diff / (165 * 500) + 10.2) / 2
255+
f_diff = f_timber - f_web - f_flange
256+
y = (f_diff / (165 * 500) + 10.2) / 2
257+
assert y_pc == pytest.approx(304 - 10.2 + y)
258+
259+
# calculate mp_xx
260+
mp_xx_calc = 0
261+
mp_xx_calc += f_timber * abs(304 + 50 - y_pc) # timber contribution
262+
mp_xx_calc += (10.2 - y) * 165 * 500 * abs((10.2 - y) / 2) # top flange p1
263+
mp_xx_calc += y * 165 * 500 * abs(y / 2) # top flange p2
264+
mp_xx_calc += f_web * abs(10.2 + (304 - 2 * 10.2) / 2 - y_pc) # web contribution
265+
mp_xx_calc += f_flange * abs(10.2 / 2 - y_pc) # bot flange contribution
266+
assert mp_xx == pytest.approx(mp_xx_calc)
267+
268+
# 2) y-axis bending
269+
assert x_pc == pytest.approx(165 / 2)
270+
271+
# calculate mp_yy
272+
mp_yy_calc = 0
273+
mp_yy_calc += 2 * (10.2 * 165**2 / 4) * 500 # 2 flanges
274+
mp_yy_calc += (304 - 10.2 * 2) * 6.1**2 / 4 * 500 # web
275+
mp_yy_calc += 100 * 600**2 / 4 * 20 # timber
276+
assert mp_yy == pytest.approx(mp_yy_calc)

0 commit comments

Comments
 (0)