OpenSees Cloud

OpenSees AMI

Damping Is a Sensitive Subject

Original Post - 09 Feb 2025 - Michael H. Scott

Visit Structural Analysis Is Simple on Substack.


Dynamic response sensitivity analysis by the direct differentiation method (DDM) works pretty well in OpenSees, minus a couple limitations.

First, not all element and material models implement the methods necessary to compute response sensitivity with respect to model parameters.

And second, even fewer element and material models implement the methods necessary to compute the sensitivity of damping forces with respect to element mass and stiffness.

So, not only is damping a sensitive subject, damping is also a subject of sensitivity.

Consider a two-story EPP shear frame model with story stiffness k=600 kip/inch, yield strength Fy=450 kip, and mass m=400 kip/g. Rayleigh damping is defined at 2% in each mode (there’s only two) using the initial stiffness throughout the analysis.

Two-story shear frame model

The OpenSees Python code is straightforward using ZeroLength elements and the Hardening uniaxial material.

import openseespy.opensees as ops
import numpy as np

k = 600
Fy = 450
g = 386.4
m = 400/g
zeta = 0.02

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

ops.node(1,0); ops.fix(1,1)
ops.node(2,0); ops.mass(2,m)
ops.node(3,0); ops.mass(3,m/2)

ops.uniaxialMaterial('Hardening',1,k,Fy,0,0)

ops.element('zeroLength',1,1,2,'-mat',1,'-dir',1,'-doRayleigh')
ops.element('zeroLength',2,2,3,'-mat',1,'-dir',1,'-doRayleigh')

ops.parameter(1,'element',1,'E')
ops.parameter(2,'element',1,'Fy')

ops.timeSeries('Path',1,'-dt',0.02,'-filePath','tabasFN.txt','-factor',g)
ops.pattern('UniformExcitation',1,1,'-accel',1)

w2 = ops.eigen('-fullGenLapack',2)

wi = w2[0]**0.5; zetai = zeta
wj = w2[1]**0.5; zetaj = zeta

A = np.array([[1/wi, wi],[1/wj, wj]])
b = np.array([zetai,zetaj])
x = np.linalg.solve(A,2*b)

#             M  KT  KI  Kn
ops.rayleigh(x[0],0,x[1],0)

ops.analysis('Transient','-noWarnings')

ops.sensitivityAlgorithm('-computeAtEachStep')

To keep the code block short, details of the analysis, recording the DDM response sensitivity, and running finite differences are omitted.

The history of roof displacement response is shown below. There is a permanent displacement, indicating the frame yielded due to the earthquake loading.

Displacement response history

The history of roof displacement sensitivity with respect to k of the first story, computed via the DDM and FDM with forward perturbation equal to 1e-5 times the nominal parameter value, is shown below. Although to the naked eye the DDM and FDM appear to be the same, the mean absolute error (MAE) between the two response histories is 0.0001185 while the root mean squared error (RMSE) is 0.0001474.

Displacement response history

These errors are high relative to the 1e-5 parameter perturbation.

For comparison, the plot below shows the history of roof displacement response sensitivity with respect to Fy of the first story. Between the DDM and FDM, the MAE is 5.394e-13 and the RMSE is 6.846e-13. The errors in this case are very small compared to the 1e-5 parameter perturbation. The difference maker is the damping forces do not depend on yield strength.

Displacement response history

The HardeningMaterial class had the correct implementation for getInitialTangentSensitivity(), so the culprit was the ZeroLength element did not implement getInitialStiffSensitivity(), which allows the FE_Element class to assemble the sensitivity of stiffness-proportional Rayleigh damping forces.

Anyway, after adding the necessary code in ZeroLength.h/.cpp via PR #1571, I re-ran the analyses and the MAE and MRSE between DDM and FDM for roof displacement response sensitivity with respect to the first story stiffness reduced to 8.007e-7 and 1.099e-6, respectively.

This post covered one small detail of damping forces in nonlinear dynamic response sensitivity analysis. For more details and examples for both Rayleigh and modal damping, see Haukaas (2024).