OpenSees Cloud
OpenSees AMI
Modal Participation Factors
Original Post - 01 Nov 2020 - Michael H. Scott
Visit Structural Analysis Is Simple on Substack.
Computing modal participation factors (yes, I know it’s a misnomer) from an OpenSees model is straightforward if you define only nodal mass with no element mass. Examples are available online showing how to compute the factors in OpenSees using Tcl, but let’s go over how to do it with OpenSeesPy.
After you define your model with nodal mass and do an eigenvalue analysis, you can write a simple loop with a couple utility functions to evaluate \(\Gamma_n = \phi_n^T m \iota / \phi_n^T m \phi_n\) for the \(n^{th}\) mode. In the code below, I’m wrapping that simple loop with another loop over N modes.
#
# Define your model
#
ndf = 6 # Nodal degrees of freedom
N = 3 # Or whatever
omega2 = ops.eigen(N)
for n in range(N):
Mn = 0.0
Ln = 0.0
for nd in ops.getNodeTags():
ndMass = ops.nodeMass(nd)
ndEigen = ops.nodeEigenvector(nd,n+1)
Ln += ndEigen[0]*ndMass[0] # 0 for X, 1 for Y, 2 for Z excitation
for dof in range(ndf):
Mn += (ndEigen[dof]**2)*ndMass[dof]
Gamman = Ln/Mn
Tn = 2*3.14159/omega2[n]**0.5
print(f'Mode {n+1}, Tn = {Tn}, Mn = {Mn}, Gamma = {Gamman}')
The default eigenvalue solver returns mass orthonormal eigenvectors, leading to unit values of modal mass. However, this solver will fail if you ask for as many modes as there are dynamic DOFs, e.g., asking for 4 modes from a model with 4 dynamic DOFs gives the following error:
To get all modes from the eigenvalue analysis, you can use the
'fullGenLapack'
option to the eigen
command.
omega2 = ops.eigen('fullGenLapack',Nmodes)
While this solver returns the same eigenvalues as the default solver, the eigenvectors are not normalized by mass. So, the modal masses will not be 1.0 and the modal participation factors you calculate will be different from the default solver. For example, asking for 3 modes using both solvers gives the following output. The periods are the same, but not the modal quantities.
Most of these differences come out in the wash. Except for modal damping. The non-mass-normalized eigenvectors can really mess up your modal damping. So, once again, be careful with modal damping.
Update: The issue with fullGenLapack
not returning mass orthonormal
eigenvectors was fixed in January 2022 with this commit.