OpenSees Cloud

OpenSees AMI

One Way to Get Bad Eigenvalues

Original Post - 10 Nov 2022 - Michael H. Scott

Visit Structural Analysis Is Simple on Substack.


If one of the eigenvalues for your model is zero or negative, you likely made a modeling error. The error could be due to boundary conditions, element stiffness, or mass definition.

Let me show you how easy it is to make an error and get bad eigenvalues due to an error in mass definition.

Suppose you want to apply a 50 kip gravity load to a column. You plan to use a variable (always a good idea) and you remember that gravity acts “downward”, so you make the gravity load negative.

Pgrav = -50*kip

Then when you define the nodal mass, you divide that variable by gravitational acceleration to get mass.

m = Pgrav/g
ops.mass(2,m,m,0)

And because mass and weight require separate input, you define the gravity load in a constant time series. The definition of Pgrav accounted for the “downward” direction of the gravity load, so no negative sign required here.

ops.timeSeries('Constant',1)
ops.pattern('Plain',1,1)
ops.load(2,0,Pgrav,0)

Then, when you issue the eigen() command, the eigenvalues are negative!

w2 = ops.eigen('-fullGenLapack',2)
print('FullGenLapack Eigenvalue Solver',w2)

w2 = ops.eigen(2)
print('Default Eigenvalue Solver',w2)
FullGenLapack Eigenvalue Solver [-44822.40000000003, -941.2704000000004]
Default Eigenvalue Solver [1.1143657371044e-311, 1.114365737223e-311]

The FullGenLapack solver returns two negative eigenvalues (correct magnitudes, wrong signs) while the default eigenvalue solver returns two numbers that are basically zero.

Due to the negative sign in Pgrav, you ended up with negative mass–an easy mistake to make. I’ve made it before.

Generally, you want to define your variables using magnitude, then assign direction or sense in the subsequent command. In this example, make Pgrav positive and use a negative sign in the load() command. Same goes for Concrete23–define the compressive strength, fc, as positive, then use a negative sign to denote compression in the input command.

Here is the full script for a simple cantilever column. Try it out for yourself.

import openseespy.opensees as ops

kip = 1.0
sec = 1.0
ft = 1.0

inch = ft/12
g = 32.2*ft/sec**2

L = 100*inch
E = 29000*kip/inch**2
A = 20*inch**2
Iz = 1400*inch**4

Pgrav = -50*kip

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

ops.node(1,0,0); ops.fix(1,1,1,1)
m = Pgrav/g
ops.node(2,0,L); ops.mass(2,m,m,0)

ops.geomTransf('Linear',1)

ops.section('Elastic',1,E,A,Iz)
ops.beamIntegration('Lobatto',1,1,3)

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

ops.timeSeries('Constant',1)
ops.pattern('Plain',1,1)
ops.load(2,0,Pgrav,0)

ops.system('UmfPack')

w2 = ops.eigen('-fullGenLapack',2)
print('FullGenLapack Eigenvalue Solver',w2)

w2 = ops.eigen(2)
print('Default Eigenvalue Solver',w2)