Eccentrically Loaded Bolt Groups with Bolt Hole Clearance

Standard bolt holes punched in steel elements are either 1/16 inch or 1/8 inch wider than the bolt diameter. Oversized bolt holes can have larger clearances in order to make fit-up easier.

While the bolt hole clearance can affect the available strength of an eccentrically loaded bolt group, Tables 7-6 to 7-13 of the AISC Steel Manual list bolt group resistance coefficients, C, based on the instantaneous center of rotation (IC) method assuming each bolt hole has zero clearance relative to its bolt.

Reynolds et al (2021) showed that not accounting for bolt hole clearance can lead to unconservative estimates of the group resistance. In other words, accounting for bolt hole clearance leads to lower C values compared to not accounting for bolt hole clearance.

A previous post showed how to use OpenSees to compute C values via the IC method, but was limited to cases with zero clearance. Accounting for bolt hole clearance is a straightforward extension and will be shown in this post.

First, the bolt load-deformation relationship is modified to account for slip distance. Table 1 of Reynolds et al (2021) gives a range of slip distances, \Delta_{sd}, for standard holes and oversized holes with one or two plies.

In this post, bolt pre-tensioning is not taken into account as Reynolds et al found pre-tensioning to have little effect on bolt group resistance coefficients. With no pre-tensioning, bolt slip occurs immediately and the bolt load-deformation relationship is

R=0 when \Delta \leq \Delta_{sd}

R=R_{ult}(1-e^{-10(\Delta-\Delta_{sd})})^{0.55} when \Delta > \Delta_{sd}

The load-deformation relationship for a single bolt is shown below for an ultimate strength of 1 kip and slip distance of 1/8 inch. A bolt is assumed to fail when its deformation exceeds \Delta_{sd} + 0.34 inch.

The definition of the bolt load-deformation relationship as a MultiLinear material in OpenSees is shown below. Because the assumed bolt load-deformation relationship has zero stiffness prior to engagement, a small elastic force is added to each point on the load-deformation curve.

Rult = 1.0 # Bolt strength
dmax = 0.34 # Maximum bolt deformation
dsd = 0.125 # Slip distance

N = 20 # Number of points
uf = [] # Array of deformation and force values
for i in range(1,N+1):
    d = i*(dmax+dsd)/N
    uf.append(d)
    if d <= dsd:
        R = 0
    else:
        R = Rult*(1-math.exp(-10*(d-dsd)))**0.55
    R = R + 0.001*d # small elastic force
    uf.append(R)

ops.uniaxialMaterial('MultiLinear',1,*uf)

Next, we define the bolt group as a collection of CoupledZeroLength elements, then constrain the bolt nodes to move as a rigid diaphragm with the node at the loading point as the primary node.

# Bolt group 2 from Reynolds et al (2021)
#
n = 5 # bolts per row
Nrows = 4 # number of rows
ex = 12 # load eccentricity
s = 3 # bolt spacing
srow = 3 # row spacing

theta = 0*math.pi/180 # load direction

ndTags = []
for r in range(Nrows):
    for i in range(n):
        ndTag = r*n + i + 1
        ndTags.append(ndTag)
        ops.node(-ndTag,-r*srow,i*s)
        ops.fix(-ndTag,1,1,1)
        ops.node(ndTag,-r*srow,i*s)
    
        ops.element('CoupledZeroLength',ndTag,-ndTag,ndTag,1,2,1)

ops.node(0,ex-srow*(Nrows-1)/2,s*(n-1)/2)
ops.rigidDiaphragm(3,0,*ndTags)

Note that in the time between the previous post on bolt groups and now, 2D rigid diaphragm functionality was added to OpenSees (PR #1092), greatly simplifying the model definition.

Although load control should be fine with the small elastic force added to the bolt load-deformation relationship, in the analysis I opted for displacement control on the primary node (tag=0). I also used the KrylovNewton algorithm because the CoupledZeroLength element does not return a consistent tangent.

ops.timeSeries('Linear',1)
ops.pattern('Plain',1,1)
ops.load(0,-math.sin(theta),-math.cos(theta),0)

ops.test('NormDispIncr',1e-3,10,0)
ops.algorithm('KrylovNewton')
ops.system('UmfPack')
ops.constraints('Transformation')

Umax = 3.0
dU = 0.001
Nsteps = int(Umax/dU)
ops.integrator('DisplacementControl',0,2,-dU)

ops.analysis('Static')

for i in range(Nsteps):
    ok = ops.analyze(1)
    if ok < 0:
        break
    
    stopAnalysis = False
    for j in ops.getEleTags():
        eps = ops.eleResponse(j,'material','strain')
        if abs(eps[0]) >= (dmax+dsd):
            stopAnalysis = True
            break
    if stopAnalysis:
        break

C = ops.getLoadFactor(1)/Rult

The load-deformation responses for various uniform slip distances of Bolt group 2 from Reynolds et al (2021), computed using OpenSees, are shown below.

The group resistance coefficients are slightly different from the 7.06, 6.81, 6.53, 6.06, and 5.39 shown in Figure 5 of Reynolds et al (2021), but I’m not going to lose any sleep over such small discrepancies.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.