T15: Angle, Bolted One Leg
from Designer import makePart, DesignNotes, SST
%figure bolted-single-angle.svg
Note: The figure shows 2 rows of 4 bolts through one leg. The logic below works for 1 or 2 rows and almost any number of bolts per row. It also works for 1 or 2 angles, back-to-back.
import pint # setup to use the module for computing with units
ureg = pint.UnitRegistry()
mm = ureg['mm']
inch = ureg['inch']
kN = ureg['kN']
MPa = ureg['MPa']
ureg.default_format = '~P'
notes = DesignNotes('Tr',units=kN,title='Angle bolted through single leg')
REQUIRE = notes.require # useful abbreviations
CHECK = notes.check
USEVARS = notes.usevars
@makePart
class Bolts:
'Bolts'
grade = 'ASTM A325'
size = '3/4"'
d = (3/4*inch).to(mm)
Fu = 825*MPa
Ab = 3.14159*d**2/4
Dsg = 'L178x102x13'
Ag,d,b,t = SST.section(Dsg,'A,D,B,T')
@makePart
class Angle:
'Angle'
grade = "CSA G40.21 350W",
Fy = 350*MPa
Fu = 450*MPa
dsg = Dsg # copy dimensions from SST
Ag = Ag*mm*mm
d = d*mm # normally the long leg
b = b*mm # normally the short leg
t = t*mm # always the thickness :-)
bolted_leg = 'long' # 'long' (usually) or 'short'
n = 1 # number of angles (may be 1 or 2)
threads_intercepted = True
hole_type = 'punched' # 'punched' or 'drilled'
Nrows = 2 # a row is parallel to the load
Nlines = 4 # a line is perpendicular to the load
pitch = 75*mm # spacing measured parallel to load (along length of angle)
end_distance = 35*mm # from end of angle to center of closest hole
# for one row of bolts:
g = 100*mm
# for two rows of bolts:
g1 = 65*mm # gauge to first row of bolts, CISC HB-11 p. 6-173
g2 = 80*mm # gauge to second row of bolts, or 0 if only 1 row
# ha = hole allowance by CSA S16-14 12.3.2:
ha = 22*mm + (0*mm if hole_type == 'drilled' else 2*mm)
if bolted_leg == 'short':
d,b = b,d # d will always be dimension of bolted leg
if Nrows == 1: # below we will use only g1, g2, g3
g1 = g
g2 = 0*mm
elif Nrows == 2:
g = 0*mm
REQUIRE(Angle.hole_type in ['punched','drilled'],
"Value of 'Angle.hole_type' must be punched or drilled")
REQUIRE(Angle.threads_intercepted in [False,True],
"Value of 'Angle.threads_intercepted' must be True or False")
REQUIRE(Angle.n in [1,2],
'Number of angles, Angle.n, must be 1 or 2')
REQUIRE(Angle.bolted_leg in ['short','long'],
"Value of 'Angle.bolted_leg' must be short or long")
REQUIRE(Angle.Nrows in [1,2],
"Angle.Nrows must be 1 or 2")
REQUIRE(Angle.Nlines >= 2 and Angle.Nlines <= 10,
"Angle.Nlines must be in range of 2 to 10")
# data derived from input data: pitch, end_distance, gauges, etc.
with USEVARS(('Ag,d,b,t,pitch,g1,g2,end_distance,Nrows,Nlines',Angle),
('bolt_diameter=d',Bolts),
locals='g3'):
minimum_pitch = 2.7*bolt_diameter # CSA S16-14 22.3.1
min_edge_distance = 25*mm # CSA S16-14 22.3.2, Table 6, 3/4", rolled edge
min_end_distance = min_edge_distance # CSA S16-14 22.3.3
if Nlines <= 2:
min_end_distance = 1.5*bolt_diameter # CSA S16-01 22.3.4
max_edge_distance = min(150*mm,12*t)
g3 = edge_distance = d-(g1+g2)
Angle.g3 = g3
Angle.edge_distance = g3
REQUIRE(edge_distance > bolt_diameter/2.,
'Angle leg of {0} does not allow {1} lines of bolts.'.format(d,Nrows))
CHECK(pitch >= minimum_pitch,
'Pitch greater than minimum','pitch,minimum_pitch')
if Nrows > 1:
CHECK(g2 >= minimum_pitch,
'Gauge g2 greater than minimum pitch','g2,minimum_pitch')
CHECK(edge_distance >= min_edge_distance,
'Edge distance greater than minimum','edge_distance,min_edge_distance')
CHECK(edge_distance <= max_edge_distance,
'Edge distance less than maximum','edge_distance,max_edge_distance')
CHECK(end_distance >= min_end_distance,
'End distance greater than minimum','end_distance,min_end_distance')
# CSA S16-14 13.1
phi = 0.90
phiu = 0.75
phib = 0.80
phibr = 0.80
# CSA S16-14 13.2 (a) (i):
with USEVARS(('Ag,Fy,n',Angle), label='Gross area yield'):
Tr = phi*Ag*Fy*n
# CSA S16-14 13.2 (a) (iii):
with USEVARS(('Nrows,Nlines,ha,Ag,t,Fu,n',Angle),
locals='An,Ane', label='Net area fracture'):
An = Ag - Nrows*ha*t # CSA S16-14 12.3.1 a)
if Nlines >= 4: # CSA S16-14 12.3.3.2 (b)
Ane = 0.80*An
else:
Ane = 0.60*An
Tr = phiu*Ane*Fu*n
%figure "bolted-single-angle-shear-blocks.svg"
# CSA S16-14 13.11
with USEVARS(('Nrows,Nlines,ha,e=end_distance,s=pitch,g1,d,t,Fy,Fu,n',Angle),
locals='An,Agv,Ut', globals='phiu, Fv, L', label='Block shear (case 1)'):
L = (Nlines-1.)*s
# Case 1 - one shear area, tension failure from furthest bolt to edge
An = (d - g1 - (Nrows-0.5)*ha)*t
Agv = (e+L)*t
Ut = 0.6
Fv = (Fy+Fu)/2.
if Fy > 460*MPa: # CSA S16-14 13.11 (foot note)
Fv = Fy
Tr = n*phiu*(Ut*An*Fu + 0.6*Agv*Fv)
# Case 2 - for 2 or more rows of bolts CSA S16-14 13.11
with USEVARS(('Nrows',Angle),showvars=False):
if Nrows > 1:
with USEVARS(('n,g2,ha,t,e=end_distance,Fu',Angle),
locals='An,Agv,Ut', globals='Nrows,L,phiu', label='Block shear (case 2)'):
An = (g2 - ha)*t
Agv = 2.*(e+L)*t
Ut = 0.6
Tr = n*phiu*(Ut*An*Fu + 0.6*Agv*Fv)
# Case 3 - tearout CSA S16-14 13.11
with USEVARS(('n,Nrows,t,e=end_distance,Fu',Angle),
locals='An,Agv,Ut', globals='L,phiu', label='Block shear (tearout)'):
An = 0.*mm*mm
Agv = 2.*(e+L)*t*Nrows
Ut = 0.
Tr = n*phiu*(Ut*An*Fu + 0.6*Agv*Fv)
with USEVARS(('m=n,threads_intercepted,s=pitch,Nrows,Nlines,n',Angle),
('Ab,Fu,bd=d',Bolts),
locals='L,multiplier', globals='nbolts,phib', record='Vr', label='Bolt Shear'):
nbolts = Nrows*Nlines
L = (Nlines-1.)*s # length of connection
# CSA S16-14 13.12.1.2 (c)
multiplier = 1.0
if L >= 760.*mm:
multiplier *= 0.5/0.6
if threads_intercepted:
multiplier *= 0.70
Vr = multiplier*0.6*phib*nbolts*m*Ab*Fu
# CSA S16-14 13.12.1.2 a):
with USEVARS(('Fu,t,n,nbolts=Nrows*Nlines',Angle),
('d',Bolts), globals='phibr', record='Br', label='Bolt Bearing' ):
Br = 3.*phibr*nbolts*t*d*Fu * n
# combine tearout of bolts closest to end with bearing of remainder
with USEVARS(('t,e=end_distance,Nlines,Nrows,nangles=n,Fu',Angle),
('db=d',Bolts),
locals='Agv,nbolts,Tr2,Br', globals='phiu,phibr,Fv', label='Bolt bearing + end tearout'):
Agv = 2.*e*t*Nrows
nbolts = Nrows*(Nlines-1)
Tr2 = nangles*(phiu*(0.6*Agv*Fv)).to(kN) # S16-14 13.11
Br = nangles*(3.*phibr*nbolts*t*db*Fu).to(kN) # S16-14 13.12.1.2 b)
Tr = Tr2+Br
# combine block shear of bolts closes to end with bearing of remainder (CSA S16-14: 13.12.1.2 b))
with USEVARS(('Nrows',Angle),showvars=False):
if Nrows > 1:
with USEVARS(('e=end_distance,t,g2,ha,Fu,nangles=n,Nlines',Angle),
('db=d',Bolts),
locals='Agv,Tr2,Br,Ut,n', globals='Nrows,phiu,phibr,Fv', label='Bolt bearing + end block shear (case 2)' ):
An = (g2 - ha)*t
Agv = 2.*e*t
Ut = 0.6
Tr2 = nangles*(phiu*(Ut*An*Fu + 0.6*Agv*Fv)).to(kN) # S16-14 13.11
n = Nrows*(Nlines-1)
Br = nangles*(3.*phibr*n*t*db*Fu).to(kN) # S16-14 13.12.1.2 b)
Tr = Tr2+Br
notes.summary()