A bolted joint is a classical engineering problem.
Joints are often very challenging in mechanical design, and a bolted joint is not an exception. The challenge requires particular care in lightweight design where composites and other lightweight materials are used. These materials do not permitt the bolts to be tightened such that the load is primarilly transferred through shear between the members. Rather, the bolted solution must rely on bearing between the bolt and the part(s).
The current example assumes the latter in an experimental configuration as illustrated below:
Symmetry about half the length of the plate is assumed, and the bolt is simplified to a discret rigid cylinder being infinitely stiff.
The problem is included as a case study in the course TMM4175 Lightweight Design and discussed further there.
from abaqus import *
from abaqusConstants import *
from part import EdgeArray
from customtools import isapprox, getByPO, getByR
def boltedJoint(modelname, L, b, d, r, dr, t, esize, ner, nec, net, Fx):
'''
L: total length of the plate
b: width of the plate
d: distance from center of hole to the end of the plate
r: radius of the hole
dr: additional radius for the cylindrical region surrounding the hole
t: thickness of the plate
esize: global element size of the plate
ner: number of elements radially for the cylindrical region
nec: number of elements along circular edges
net: number of elements through the thickness
Fx: applied force on the bolt
'''
mod = mdb.Model(name=modelname)
# --------------------
# The plate with hole
# --------------------
ske = mod.ConstrainedSketch(name='__profile__', sheetSize=200.0)
ske.rectangle(point1=(-d, -0.5*b), point2=(L-d, 0.5*b))
ske.CircleByCenterPerimeter(center=(0, 0), point1=(r, 0))
prt1 = mod.Part(name='Plate', dimensionality=THREE_D, type=DEFORMABLE_BODY)
prt1.BaseSolidExtrude(sketch=ske, depth=t)
del mod.sketches['__profile__']
prt1.DatumCsysByDefault(coordSysType=CARTESIAN)
# Partitions
prt1.WirePolyLine(points=(((r+dr,0.0,0.0), (r+dr,0.0,t)),), mergeType=IMPRINT, meshable=ON)
e1=getByPO(prt1.edges, x=r+dr)[0]
e2=getByR(prt1.edges)[0]
prt1.PartitionCellBySweepEdge(sweepPath=e2, cells=prt1.cells, edges=(e1,))
id1 = prt1.DatumPlaneByPrincipalPlane(principalPlane=YZPLANE, offset=0).id
id2 = prt1.DatumPlaneByPrincipalPlane(principalPlane=YZPLANE, offset=d).id
id3 = prt1.DatumPlaneByPrincipalPlane(principalPlane=XZPLANE, offset=0).id
prt1.PartitionCellByDatumPlane(cells=prt1.cells, datumPlane=prt1.datums[id1])
prt1.PartitionCellByDatumPlane(cells=prt1.cells, datumPlane=prt1.datums[id2])
prt1.PartitionCellByDatumPlane(cells=prt1.cells, datumPlane=prt1.datums[id3])
# Mesh
prt1.seedPart(size=esize, deviationFactor=0.1, minSizeFactor=0.1)
prt1.seedEdgeByNumber(edges=prt1.edges.findAt(coordinates=((r+0.5*dr,0,0),)),
number=ner, constraint=FINER)
prt1.seedEdgeByNumber(edges=getByR(prt1.edges), number=nec, constraint=FINER)
prt1.seedEdgeByNumber(edges=prt1.edges.findAt(coordinates=((r,0,0.5*t),)),
number=net, constraint=FINER)
prt1.generateMesh()
# Material and section
mat = mod.Material(name='Some polymer')
mat.Elastic(table=((2000.0, 0.35), ))
mod.HomogeneousSolidSection(name='Plate section', material='Some polymer', thickness=None)
prt1.SectionAssignment(region=prt1.Set(name='cells', cells=prt1.cells), sectionName='Plate section')
# ---------
# The bolt
# ---------
ske = mod.ConstrainedSketch(name='__profile__', sheetSize=200.0)
ske.CircleByCenterPerimeter(center=(0.0, 0.0), point1=(r, 0.0))
prt2 = mod.Part(name='Bolt', dimensionality=THREE_D, type=DISCRETE_RIGID_SURFACE)
prt2.BaseShellExtrude(sketch=ske, depth=t*1.1)
del mdb.models['M1'].sketches['__profile__']
# Partitions
id1 = prt2.DatumPlaneByPrincipalPlane(principalPlane=YZPLANE, offset=0.0).id
id2 = prt2.DatumPlaneByPrincipalPlane(principalPlane=XZPLANE, offset=0.0).id
prt2.PartitionFaceByDatumPlane(datumPlane=prt2.datums[id1], faces=prt2.faces)
prt2.PartitionFaceByDatumPlane(datumPlane=prt2.datums[id2], faces=prt2.faces)
# Mesh
prt2.setMeshControls(regions=prt2.faces, elemShape=QUAD, technique=STRUCTURED)
prt2.seedEdgeByNumber(edges=getByR(prt2.edges), number=nec, constraint=FINER)
e1 = EdgeArray([e for e in prt2.edges if e.pointOn[0][2] > 0 and e.pointOn[0][2]<t])
prt2.seedEdgeByNumber(edges=e1, number=net, constraint=FINER)
prt2.generateMesh()
# ---------
# Assembly
# ---------
ass = mod.rootAssembly
ass.DatumCsysByDefault(CARTESIAN)
ins1 = ass.Instance(name='Plate', part=prt1, dependent=ON)
ins2 = ass.Instance(name='Bolt', part=prt2, dependent=ON)
ass.translate(instanceList=('Bolt', ), vector=(0.0, 0.0, -t*0.05))
# Interactions
region1 = ass.Surface(name='hole', side1Faces=getByR(ins1.faces, r=r))
region2 = ass.Surface(name='bolt', side1Faces=getByR(ins2.faces))
cp = mod.ContactProperty('cp-1')
cp.TangentialBehavior(formulation=PENALTY, table=((0.2,),), fraction=0.005)
mod.SurfaceToSurfaceContactStd(name='contact', createStepName='Initial',
master=region2, slave=region1, sliding=FINITE, interactionProperty='cp-1')
rfid = ass.ReferencePoint(point=(0.0, 0.0, t/2.0)).id
reg_rf = ass.Set(name='rf rb', referencePoints = (ass.referencePoints[rfid],))
reg_rb = ass.Set(name='faces bolt', faces=ins2.faces)
mod.RigidBody(name='Constraint-1', refPointRegion=reg_rf, bodyRegion=reg_rb)
# Steps and loading:
mod.StaticStep(name='Step-1', previous='Initial', nlgeom=ON)
mod.DisplacementBC(name='bc bolt', createStepName='Step-1', region=reg_rf,
u2=0.0, u3=0.0, ur1=0.0, ur2=0.0, ur3=0.0)
reg_fix_ux = ass.Set(name='faces fix ux', faces=getByPO(ins1.faces, x=L-d))
mod.DisplacementBC(name='fix ux', createStepName='Step-1', region=reg_fix_ux, u1=0.0)
mod.ConcentratedForce(name='Fx', createStepName='Step-1', region=reg_rf, cf1=-Fx)
# Job and results
job = mdb.Job(name=modelname, model=modelname)
job.submit(consistencyChecking=OFF)
boltedJoint(modelname='M1', L=100.0, b=50.0, d=25.0, r=8.0, dr=4.0, t=6.0,
esize=1.5, ner=8, nec=20, net=6, Fx=1E4)