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.
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.