The GimmeMCK integrator is one of my more useful contributions to OpenSees. This integrator allows you to extract the individual mass, damping, and stiffness matrices, or some linear combination therein, in order to see what’s assembled in an OpenSees model or to bootstrap new functionality.

While getting the mass and stiffness matrices seems to work, GimmeMCK only worked for Rayleigh and viscous damping (you know, actual damper elements), but not modal damping. I initially thought the issue was how modal damping is computed, but it turns out a simple function, getCFactor(), was not defined in the GimmeMCK class. The fix was so easy I did a web edit on GitHub instead of a branch and pull request.

Before figuring out the issue was a simple fix, I wrote the Python script below to construct the modal damping matrix from eigenvectors, assuming only nodal mass. Try the script on your modal damping models and verify that you get the same result as ops.integrator('GimmeMCK',0,1,0).

import openseespy.opensees as ops
import numpy as np
#
# Define your model
#
modalDamping = [0.05,0.1,0.1] ;# Or whatever
Nmodes = len(modalDamping)
w2 = ops.eigen(Nmodes)
N = ops.systemSize()
C = np.zeros((N,N))
for n in range(Nmodes):
zeta = modalDamping[n]
wn = w2[n]**0.5
phin = np.zeros(N)
for nd in ops.getNodeTags():
mass = ops.nodeMass(nd)
for i,dof in enumerate(ops.nodeDOFs(nd)):
if dof < 0:
continue
phin[dof] = mass[i]*ops.nodeEigenvector(nd,n+1)[i]
C = C + 2*zeta*wn*np.outer(phin,phin)

I have been involved in the development, maintenance, and growth of OpenSees since its early days. I am interested in learning Python and improving my academic writing.
View all posts by Michael H. Scott

Published

5 thoughts on “Gimme All Your Modal Damping”

Hello Professor Michael Scott,
With the application of ops.integrator(‘GimmeMCK’,0,1,0) I got an array of zeros, with the script showing if I got an array with non-zero values. I’m not sure what I’m doing wrong, I show you part of the code:
import numpy as np
from openseespy.opensees import *
#
# three-storey frame model
#
w2 = eigen(‘-fullGenLapack’,3)
modalDamping(0.05)
wipeAnalysis()
constraints(‘Transformation’)
numberer(‘Plain’)

system(‘FullGeneral’)
analysis(‘Transient’)
integrator(‘GimmeMCK’,0.0,1.0,0.0)
analyze(1,0.0)
Ngdl = systemSize()
C = printA(‘-ret’)
C = np.array(C)
C.shape = (Ngdl,Ngdl)

Hello, I too am having the same issue when attempting to pull the damping matrix for modal damping. C is a matrix of zeros.

I can run my script perfectly with Rayliegh damping, I am able to call the damping matrix – which is diagonally banded as expected. There seems to still be an issue with Modal Damping only.

Hello Professor Michael Scott,

With the application of ops.integrator(‘GimmeMCK’,0,1,0) I got an array of zeros, with the script showing if I got an array with non-zero values. I’m not sure what I’m doing wrong, I show you part of the code:

import numpy as np

from openseespy.opensees import *

#

# three-storey frame model

#

w2 = eigen(‘-fullGenLapack’,3)

modalDamping(0.05)

wipeAnalysis()

constraints(‘Transformation’)

numberer(‘Plain’)

system(‘FullGeneral’)

analysis(‘Transient’)

integrator(‘GimmeMCK’,0.0,1.0,0.0)

analyze(1,0.0)

Ngdl = systemSize()

C = printA(‘-ret’)

C = np.array(C)

C.shape = (Ngdl,Ngdl)

LikeLike

I don’t know. Could be an error in your model. Check that you are able to perform a successful analysis with the model you’ve defined.

LikeLiked by 1 person

Hello, I too am having the same issue when attempting to pull the damping matrix for modal damping. C is a matrix of zeros.

I can run my script perfectly with Rayliegh damping, I am able to call the damping matrix – which is diagonally banded as expected. There seems to still be an issue with Modal Damping only.

LikeLike

Please start an issue on GitHub and provide a MWE that shows the issue.

LikeLike

Make sure you’re using the latest version of OpenSeesPy.

https://github.com/OpenSees/OpenSees/commit/d2250047f74ab47fe7136e22769fcfb2e8b7c5a3

LikeLike