OpenSees Cloud
OpenSees AMI
Initial Conditions
Original Post - 20 Nov 2021 - Michael H. Scott
Visit Structural Analysis Is Simple on Substack.
There are a couple ways to set initial conditions for nodal displacements and velocities in OpenSees. If you look at the end of this post, you’ll see the hard way to do it: set initial displacements as single point (sp) constraints in a load pattern, do one analysis step, then remove the load pattern prior to the response history analysis. You could do the same shenanigans with velocity.
But, when something is that complicated, there should be an easier
way–use the setNodeDisp
and setNodeVel
commands. You just have to be
sure to use the -commit
option with these commands; otherwise, the
initial conditions are only trial values that get overwritten on the
first analysis step.
Below is a simple script for damped free vibration of an elastic SDF system.
import openseespy.opensees as ops
m = 1 # Mass
c = 0.1*m # Damping
# Period and stiffness
Tn = 2
k = m*(2*3.14159/Tn)**2
ops.wipe()
ops.model('basic','-ndm',1)
ops.node(1,0); ops.fix(1,1)
ops.node(2,0); ops.mass(2,m)
ops.uniaxialMaterial('Elastic',1,k,c)
ops.element('zeroLength',1,1,2,'-mat',1,'-dir',1)
# Initial displacement and velocity
u0 = 1
v0 = -5
ops.setNodeDisp(2,1,u0,'-commit')
ops.setNodeVel(2,1,v0,'-commit')
ops.analysis('Transient')
Tf = 10
dt = 0.01
Nsteps = int(Tf/dt)
for i in range(Nsteps):
ops.analyze(1,dt)
The resulting displacement response history shows the initial conditions are enforced.
You can also use the setNodeAccel
command to set initial acceleration
for masses subjected to step forces. To automate the calculation of
initial acceleration, first apply the force and
compute reactions.
The reactions
command forces OpenSees to compute unbalanced nodal
loads–prior to any analysis steps, the unbalance is equal to the
applied loads. Finally, compute the initial acceleration using the
nodeUnbalance
and nodeMass
commands, then set the nodal acceleration.
ops.timeSeries('Constant',1)
ops.pattern('Plain',1,1)
ops.load(2,F)
ops.reactions()
a0 = ops.nodeUnbalance(2,1)/ops.nodeMass(2,1)
ops.setNodeAccel(2,1,a0,'-commit')
for i in range(Nsteps):
ops.analyze(1,dt)
This post focused on an SDF model, but it is straightforward to scale initial conditions up to larger models. Note that the automated calculation of initial acceleration assumes a diagonal mass matrix for the model.
Thanks to Tuan Nguyen for asking about initial accelerations in this post on the OpenSees Facebook group.