Going Through Stages

Most structural earthquake engineering deals with staged analyses of built infrastructure in one way or another. In the most common scenario, we apply gravity loads to a structural model, get the model in equilibrium, then simulate the model response to earthquake loading.

Analysis of structural systems and components during construction is also important. Temporary construction loads can sometimes be the controlling load case.

A friend recently asked about staged analysis in OpenSees. As an aside, despite working in the Tickle College of Engineering (“Tcl”, get it?), this friend is a skilled Python and OpenSeesPy user.

I know that geotechnical engineers use OpenSees for staged analysis with the updateMaterialStage command, but I haven’t given much thought to staged analysis for structural models.

So, here’s a simple example with a beam and a truss element. In loading stage A, the beam is subjected to a dead load at midspan. Then, after finding equilibrium, a truss element is added to support the beam, and additional live load is applied in loading stage B.

Code for the staged analyses is shown below.

import openseespy.opensees as ops

# Units = kip, inch
L = 200
E = 29000
A = 25
I = 2000

PD = 50 # Dead load
PL = 30 # Live load

ops.wipe()
ops.model(‘basic’,’-ndm’,2,’-ndf’,3)

ops.node(1,0,0); ops.fix(1,1,1,0)
ops.node(2,L/2,0)
ops.node(3,L,0); ops.fix(3,1,1,0)

ops.geomTransf('Linear',1)

ops.section('Elastic',1,E,A,I)
ops.beamIntegration('Legendre',1,1,2)

ops.element('forceBeamColumn',1,1,2,1,1)
ops.element('forceBeamColumn',2,2,3,1,1)

# Loading stage A
ops.timeSeries('Constant',1)
ops.pattern('Plain',1,1)
ops.load(2,0,-PD,0)

ops.analysis('Static')
ops.analyze(1)

ops.node(4,L/2,-L/2); ops.fix(4,1,1,1)

# Using the same section as the beam
ops.element('truss',3,4,2,1)

# Loading stage B
ops.timeSeries('Constant',2)
ops.pattern('Plain',2,2)
ops.load(2,0,-PL,0)

ops.analyze(1)

# Axial force in truss element
print(ops.basicForce(3))

After loading stage B, the axial compression force in the truss element is 28.63 kip, i.e., the truss supports only its portion of the 30 kip live load, as intended. If the dead load and live load were applied all in one stage, the truss force would be 76.34 kip, i.e., most of the 80 kip total dead and live load. In both cases, the beam supports the remaining load through flexure.

A few lines of code in the Truss::setDomain() make this staged analysis example possible. The element length is computed not just from the nodal coordinates, but also from the current displacements at those nodes.

Most other elements are not implemented this way, but you can get similar results by setting initial strains in your materials, which can be kind of a pain.


2 thoughts on “Going Through Stages

  1. For the sake of precision, please add ahead these commands:
    ———
    import openseespy.opensees as ops
    ops.wipe()
    ops.model(‘basic’,’-ndm’,2,’-ndf’,3)
    ———
    Cheers

    Liked by 1 person

Leave a comment

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