Tube slenderness
During a pushover simulation last week, the jacket kept struggling at the set load increments. These had not changed from a previous such exercise, the difference being that a particular frame normal to the environmental attack direction had been revised.

When these braces, directly in the line of attack, continued to struggle — exhibiting excessive displacements in the revised model configuration causing negative matrix errors, I had to re-check their slenderness, even if they did not seem slender at all.
So back to basics. The criteria for a ductile design, recommended by §11.4, ISO 19902 is as follows:
$$ \frac{K L}{r} \leq 80 $$
$$ \lambda \leq \frac{80}{\pi} \sqrt{ \frac{f_{yc}}{E} } $$
$$ \frac{f_y D}{E t} \leq 0.069 $$
where,
- λ – column buckling parameter
- Cx – elastic critical buckling coefficient
- D, t, L – tube size
- E – modulus of steel elasticity
- fy – yield strength of steel
- fyc – representative local buckling strength of steel
- fxe – representative elastic local buckling strength of steel
From §13 of ISO 19902,
$$ \lambda = \frac{K L}{\pi r} \sqrt{ \frac{f_{yc}}{E} } $$
$$ \begin{aligned} f_{yc} &= f_y \;\;\; \text{for} \;\; \frac{fy}{f_{xe}} \leq 0.170 \cr &= \left( 1.047 - 0.274 \frac{f_y}{f_{xe}} \right) f_y \;\;\; \text{for} \;\; \frac{fy}{f_{xe}} > 0.170 \end{aligned} $$
$$ f_{xe} = \frac{2 C_x E t}{D} $$
Quick digression: While checking these above expressions for this note, I think I uncovered an error in the latest ISO 19902:2020 standard. Notice the conditional statements in equations 13.2-8 and 13.2-9 in the screenshot below.

The conditional statement in equation 13.2-9 should instead be (fy / fxe > 0.170), otherwise both conditionals (i.e., in 13.2-8 and 13.2-9) mean (about) the same. 🙃 It looks like an editorial mix-up.
Anyway, back to my braces. For a set of brace sizes (selecting one in each bay), the script lets me check their slenderness. And sure enough, three out of the four braces exceed the criteria for ductile design, resulting in premature buckling, as the figure above shows.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Determine tube slenderness
slenderness.py -- 2021 ckunte
"""
import numpy as np
# Tube section properties (A, I, r)
def secprop(D, t):
# Area of cross section
A = list(map(lambda x, y: np.round(np.pi * (x - y) * y, 1), D, t))
# Moment of Inertia
I = list(
map(
lambda x, y: np.round((np.pi / 64.0) * (x ** 4 - (x - 2 * y) ** 4), 1), D, t
)
)
# Radius of gyration
r = list(map(lambda x, y: np.round(np.sqrt(x / y), 3), I, A))
return A, I, r
# Representative elastic local buckling strength (fxe)
def rep_elastic_local_buckling_strength(Cx, D, E, t):
return list(map(lambda x, y: np.round((2.0 * Cx * E * y / x), 1), D, t))
# Representative local buckling strength (fyc)
def rep_local_buckling_strength(fy, fxe):
fyc_all = []
for i in fxe:
if (fy / i) <= 0.170:
fyc_all.append(fy)
elif (fy / i) > 0.170:
fyc_all.append(np.round((1.047 - 0.274 * fy / i) * fy), 1)
else:
print("Condition not satisfied.")
return fyc_all
# Slenderness parameters
def slenderness_param(fyc, fy, D, E, t, K, L, r):
# D/t
d_over_t = list(map(lambda x, y: (x / y), D, t))
# Get tube slenderness results
klr = list(map(lambda x, y: np.round((K * x / y), 1), L, r))
# Column buckling parameter lmbda, see 13.2.3.2, ISO 19902
lmbda = list(map(lambda x, y: np.round((x / np.pi) * np.sqrt(y / E), 3), klr, fyc))
# Limiting parameter 1 as per ISO 19902, Sec. 11.4
p1 = list(map(lambda x: np.round((80.0 / np.pi) * np.sqrt(x / E), 3), fyc))
# Limiting parameter 2 as per ISO 19902, Sec. 11.4
p2 = list(map(lambda x, y: np.round(fy * x / (E * y), 3), D, t))
return d_over_t, klr, lmbda, p1, p2
def main():
# -- BEGIN USER INPUTS --
# Yield strength of steel (S420) in MPa
fy = 400.0
# Modulus of elasticity (Young's modulus) for structural steel (N/mm^2)
E = 2.05e5
# Tube diameters (mm)
D = [1300.0, 900.0, 1000.0, 1200.0]
# Tube wall thicknesses (mm)
t = [50.0, 20.0, 20.0, 30.0]
# Tube lengths (mm)
L = [20518.0, 52151.0, 59685.0, 77500.0]
# Effective length factor (Table 13.5-1, ISO 19902)
K = 0.7
# Elastic critical buckling coefficient
Cx = 0.3 # Recommended value in Sec. 13.2.3.3, ISO 19902
# -- END of USER INPUTS --
A, I, r = secprop(D, t)
fxe = rep_elastic_local_buckling_strength(Cx, D, E, t)
fyc = rep_local_buckling_strength(fy, fxe)
sp = slenderness_param(fyc, fy, D, E, t, K, L, r)
# Labels list
labels = [
'D (mm) ',
't (mm) ',
'L (mm) ',
'A (mm^2) ',
'I (mm^4) ',
'r (mm) ',
'fy (MPa) ',
'fxe (MPa) ',
'fyc (MPa) ',
'D/t ',
'KL/r (NTE 80) ',
'lambda ',
'lambda (NTE) ',
'fyD/Et (NTE 0.069)',
]
# Data and results list
data_res = [D, t, L, A, I, r, fy, fxe, fyc, sp[0], sp[1], sp[2], sp[3], sp[4]]
# Print results
for i, j in zip(labels, data_res):
print(i + " =", j)
pass
pass
if __name__ == "__main__":
main()
Producing the following:
D (mm) = [1300.0, 900.0, 1000.0, 1200.0]
t (mm) = [50.0, 20.0, 20.0, 30.0]
L (mm) = [20518.0, 52151.0, 59685.0, 77500.0]
A (mm^2) = [196349.5, 55292.0, 61575.2, 110269.9]
I (mm^4) = [38410878928.7, 5355033173.6, 7395183442.8, 18880963994.1]
r (mm) = [442.295, 311.207, 346.555, 413.793]
fy (MPa) = 400.0
fxe (MPa) = [4730.8, 2733.3, 2460.0, 3075.0]
fyc (MPa) = [400.0, 400.0, 400.0, 400.0]
D/t = [26.0, 45.0, 50.0, 40.0]
KL/r (NTE 80) = [32.5, 117.3, 120.6, 131.1]
lambda = [0.457, 1.649, 1.696, 1.843]
lambda (NTE) = [1.125, 1.125, 1.125, 1.125]
fyD/Et (NTE 0.069) = [0.051, 0.088, 0.098, 0.078]
From above results, clearly the only member that is not considered slender is the one with size, 1,300×50×20518. The last three tubes exhibit some form of slenderness — mostly on account of length, and may warrant suitable resizing.
The lambda (in programming) is python’s built-in anonymous function I use to power through lists, which should not be confused with λ – the column buckling parameter, the latter corresponds to lmbda
in the script — note the intentional spelling change to avoid the built-in function clashing with the formula.