@@ -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