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.

Response history for free vibration

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.