In this part we cover welding a flat plate to a flange.
Firstly, a couple of housekeeping issues…..
Most people (and commercial software) approach the calculation of properties for built-up shapes by slapping a plate hard against the section resulting in intimate contact between the plate and section. Effectively the strengthening element becomes part of the flange of the section. They then read off the properties, job done….
But I propose this is incorrect with respect to the calculation of torsion properties. In reality the plate won’t ‘be one’ with the flange. The reality is the two elements are only joined at the location of any welds, not across the full surface of contact. This matters when it comes to the calculation of torsion properties as you’ll see.
Additionally, it hopefully goes without saying, for any strengthening of this nature that you will be wanting to weld, not bolt. Bolting allows for slip so the composite section you are hoping to make is no longer composite.
The mesh size and number of points around curves (such as root radii) have the most impact on accuracy, and also the time to run the code.
Use a consistent set of units for the inputs (millimetres usually or inches if you’re imperially challenged) and our properties will be in those units.
Lastly, be aware that the sectionproperties package output is based mostly on New Zealand & Australian nomenclature, the main difference from other international standards is the following: –
- Z is the elastic section properties
- S is the plastic section properties
- In other international standards the above is reversed … don’t get caught out.
You can check at the sectionproperties docs for other definitions if you’re struggling to figure out what some property is.
The code…
import copy
import sectionproperties.pre.sections as sections
from sectionproperties.analysis.cross_section import CrossSection
# -------------------------------------------------------------
# Inputs
# -------------------------------------------------------------
num_plates = 2 # number strengthening plates, 1 for single flange, 2 for both flanges
d = 612 # I section depth
b_f = 229 # I-section flange width
t_f = 19.6 # I-section flange thickness
t_w = 11.9 # I-section web thickness
r_1 = 14 # I-section root radii
n_r = 50 # number of points considered around root radii
d_p = 10 # strengthening plate thickness
b_p = 250 # strengthening plate width
gap = 0.5 # gap between plate and section
weld_size = 6 # weld size
mesh_area = 1 # max mesh size
# -------------------------------------------------------------
# Calculations
# -------------------------------------------------------------
# create constituent geometry
# weld base geometry
weld = sections.CustomSection(
points=[[0, 0], [weld_size, 0], [0, weld_size]], facets=[[0, 1], [1, 2], [2, 0]], holes=[], control_points=[[weld_size / 3, weld_size / 3]]
)
if b_p > b_f and not gap == 0:
weld_vert_move = -gap
else:
weld_vert_move = 0
# I-Section beam
geometry1 = sections.ISection(d=d, b=b_f, t_f=t_f, t_w=t_w, r=r_1, n_r=n_r, shift=[-b_f / 2, 0])
# strengthening plate 1
geometry2 = sections.RectangularSection(d=d_p, b=b_p, shift=[-b_p / 2, -d_p - gap])
# weld 1 & 2
geometry3 = copy.deepcopy(weld)
geometry3.mirror_section(axis='y', mirror_point=[0, 0])
geometry3.shift = [-min(b_f, b_p) / 2, weld_vert_move]
geometry3.shift_section()
geometry4 = copy.deepcopy(weld)
geometry4.shift = [min(b_f, b_p) / 2, weld_vert_move]
geometry4.shift_section()
# mirror welds depending on wider plate
if b_f > b_p:
geometry3.mirror_section(axis='x', mirror_point=[0, 0])
geometry4.mirror_section(axis='x', mirror_point=[0, 0])
# create second plate and welds if specified
if num_plates == 2:
# strengthening plate 2
geometry5 = copy.deepcopy(geometry2)
geometry5.mirror_section(axis='x', mirror_point=[0, d / 2])
# weld 3 & 4
geometry6 = copy.deepcopy(geometry3)
geometry6.mirror_section(axis='x', mirror_point=[0, d / 2])
geometry7 = copy.deepcopy(geometry4)
geometry7.mirror_section(axis='x', mirror_point=[0, d / 2])
# total number of individual geometry elements
geo_number = 7
else:
# total number of individual geometry elements
geo_number = 4
# assemble geometry list
geo_list = [globals()[f'geometry{i}'] for i in range(1, geo_number + 1)]
# create merged section
geometry = sections.MergedSection(geo_list)
# add holes for gaps between I-Section and strengthening plates
if not gap == 0:
if num_plates == 2:
geometry.add_hole([0, d + gap / 2])
geometry.add_hole([0, -gap / 2])
# clean geometry
geometry.clean_geometry(verbose=True)
# create mesh
mesh = geometry.create_mesh(mesh_sizes=[mesh_area] * geo_number)
# create section
section = CrossSection(geometry, mesh)
# calculate results
section.calculate_geometric_properties()
section.calculate_plastic_properties()
section.calculate_warping_properties()
# -------------------------------------------------------------
# Display results
# -------------------------------------------------------------
# plot results
section.plot_mesh()
section.plot_centroids()
# display all results
# check https://sectionproperties.readthedocs.io/en/latest/rst/post.html for definitions
section.display_results(fmt='.3f')
Just change the variables in the input section of the script, it should be self-explanatory.
The code will correctly orientate the welds based on whether the plate(s) are wider or narrower than your beam flange as demonstrated below.
Results are returned in your terminal as follows, cut and paste and use elsewhere.
Section Properties:
A = 20193.473
Perim. = 0.000
Qx = 6179202.829
Qy = 0.000
cx = 0.000
cy = 306.000
Ixx_g = 3296963464.803
Iyy_g = 45506857.933
Ixy_g = 0.000
Ixx_c = 1406127399.071
Iyy_c = 45506857.933
Ixy_c = 0.000
Zxx+ = 4360084.958
Zxx- = 4360084.958
Zyy+ = 397439.807
Zyy- = 397439.807
rx = 263.880
ry = 47.471
phi = 0.000
I11_c = 1406127399.071
I22_c = 45506857.933
Z11+ = 4360084.958
Z11- = 4360084.958
Z22+ = 397439.807
Z22- = 397439.807
r11 = 263.880
r22 = 47.471
J = 4499264.297
Iw = 4213150905708.065
x_se = 0.001
y_se = 306.000
x_st = 0.001
y_st = 306.000
x1_se = 0.001
y2_se = -0.000
A_sx = 11851.214
A_sy = 7218.252
A_s11 = 11851.214
A_s22 = 7218.252
betax+ = -0.000
betax- = 0.000
betay+ = 0.001
betay- = -0.001
beta11+ = -0.000
beta11- = 0.000
beta22+ = 0.001
beta22- = -0.001
x_pc = 0.000
y_pc = 306.000
Sxx = 5013210.893
Syy = 675752.706
SF_xx+ = 1.150
SF_xx- = 1.150
SF_yy+ = 1.700
SF_yy- = 1.700
x11_pc = 0.000
y22_pc = 306.000
S11 = 5013210.893
S22 = 675752.706
SF_11+ = 1.150
SF_11- = 1.150
SF_22+ = 1.700
SF_22- = 1.700
Demo
To demonstrate the unconservative estimate of section properties with full contact vs a discrete gap being provided, the following comparison of no gap vs gap for the two plate arrangement above should convince you to change your ways.
Basically all the other properties are within a fraction of a percent, however J is overestimated by 4.4% for the no gap condition. Bad J.
| PROPERTY | NO GAP PROVIDED | GAP PROVIDED | RATIO OF NO GAP PROVIDED TO GAP PROVIDED PROPERTIES |
|---|---|---|---|
| A | 20193.47 | 20193.47 | 1.000 |
| Perim. | 0 | 0 | – |
| Qx | 6179203 | 6179203 | 1.000 |
| Qy | 0 | 0 | – |
| cx | 0 | 0 | – |
| cy | 306 | 306 | 1.000 |
| Ixx_g | 3.3E+09 | 3.3E+09 | 1.000 |
| Iyy_g | 45506858 | 45506858 | 1.000 |
| Ixy_g | 0 | 0 | – |
| Ixx_c | 1.4E+09 | 1.41E+09 | 0.999 |
| Iyy_c | 45506858 | 45506858 | 1.000 |
| Ixy_c | 0 | 0 | – |
| Zxx+ | 4362795 | 4360085 | 1.001 |
| Zxx- | 4362795 | 4360085 | 1.001 |
| Zyy+ | 397439.8 | 397439.8 | 1.000 |
| Zyy- | 397439.8 | 397439.8 | 1.000 |
| rx | 263.758 | 263.88 | 1.000 |
| ry | 47.471 | 47.471 | 1.000 |
| phi | 0 | 0 | – |
| I11_c | 1.4E+09 | 1.41E+09 | 0.999 |
| I22_c | 45506858 | 45506858 | 1.000 |
| Z11+ | 4362795 | 4360085 | 1.001 |
| Z11- | 4362795 | 4360085 | 1.001 |
| Z22+ | 397439.8 | 397439.8 | 1.000 |
| Z22- | 397439.8 | 397439.8 | 1.000 |
| r11 | 263.758 | 263.88 | 1.000 |
| r22 | 47.471 | 47.471 | 1.000 |
| J | 4697209 | 4499264 | 1.044 |
| Iw | 4.22E+12 | 4.21E+12 | 1.003 |
| x_se | 0 | 0.001 | 0.000 |
| y_se | 306 | 306 | 1.000 |
| x_st | 0 | 0.001 | 0.000 |
| y_st | 306 | 306 | 1.000 |
| x1_se | 0 | 0.001 | 0.000 |
| y2_se | 0 | 0 | – |
| A_sx | 12040.91 | 11851.21 | 1.016 |
| A_sy | 7350.099 | 7218.252 | 1.018 |
| A_s11 | 12040.91 | 11851.21 | 1.016 |
| A_s22 | 7350.099 | 7218.252 | 1.018 |
| betax+ | 0 | 0 | – |
| betax- | 0 | 0 | – |
| betay+ | 0 | 0.001 | 0.000 |
| betay- | 0 | -0.001 | 0.000 |
| beta11+ | 0 | 0 | – |
| beta11- | 0 | 0 | – |
| beta22+ | 0 | 0.001 | 0.000 |
| beta22- | 0 | -0.001 | 0.000 |
| x_pc | 0 | 0 | – |
| y_pc | 306 | 306 | 1.000 |
| Sxx | 5011131 | 5013211 | 1.000 |
| Syy | 675752.7 | 675752.7 | 1.000 |
| SF_xx+ | 1.149 | 1.15 | 0.999 |
| SF_xx- | 1.149 | 1.15 | 0.999 |
| SF_yy+ | 1.7 | 1.7 | 1.000 |
| SF_yy- | 1.7 | 1.7 | 1.000 |
| x11_pc | 0 | 0 | – |
| y22_pc | 306 | 306 | 1.000 |
| S11 | 5011131 | 5013211 | 1.000 |
| S22 | 675752.7 | 675752.7 | 1.000 |
| SF_11+ | 1.149 | 1.15 | 0.999 |
| SF_11- | 1.149 | 1.15 | 0.999 |
| SF_22+ | 1.7 | 1.7 | 1.000 |
| SF_22- | 1.7 | 1.7 | 1.000 |
Does it really matter in terms of the end result of capacity, I’ll leave that to you to prove. But take away from this assessment that two separate plates should be treated as two separate plates and not magically fused together by poor judgement.
Until part 3, plate everything in sight.
This is some really good insight and an excellent analysis. I haven’t heard anyone really deal with this aspect before (though I’m mostly a concrete guy), and leveraging section-properties this way is cool!