Sensitivity of structural response with respect to modeling parameters provides search directions for gradient-based algorithms in reliability analysis, optimization, and system identification. In addition to these applications, stand-alone sensitivity analysis gives useful information about the effect of parameters on the structural response.
There are three methods to compute response sensitivity for nonlinear, path-dependent analysis of structural models: finite differences, complex perturbation, and direct differentiation.
The finite difference and complex perturbation methods require the analysis to be re-run for each model parameter of interest, making the computational burden high for response history analysis of large models with many parameters. Furthermore, even though it’s more accurate than finite differences, the complex perturbation method requires complex arithmetic through all computations in the finite element analysis. No one really wants to do that.
The direct differentiation method (DDM) computes accurate sensitivity concurrent with the response, but it requires significant derivation and implementation effort, i.e., there’s sport to the DDM. And by sport, I mean journal articles can be written about it–about a quarter to a third of my articles are on this subject.
OpenSees implements the DDM for nonlinear static and dynamic analyses. Sensitivity is computed based on parameter objects that point to the uncertain parameters of the model. I’ll demonstrate with the steel moment frame shown below.

Let’s define two parameters: Fy and E for the columns. I like to create blank parameters, then add model components with the addToParameter command. After assigning parameters, define the regular analysis options, then define a sensitivityAlgorithm, which tells OpenSees when to compute sensitivities, either at each step (shown below) or only when told (-computeByCommand).
#
# Define model
#
ops.parameter(1)
ops.parameter(2)
for ele in [1,2,3,4]: # Column elements
ops.addToParameter(1,'element',ele,'E')
ops.addToParameter(2,'element',ele,'Fy')
#
# Define regular analysis options
#
ops.sensitivityAlgorithm('-computeAtEachStep')
#
# Do the analysis
#
The parameters you can identify in a structural model depend on the element and constitutive models. Take a look at the setParameter method, which works a lot like the setResponse method with recorders. However, the implementation of the setParameter method does not mean the DDM is enabled, so also look for implementations of getResistingForceSensitivity in elements and getStressSensitivity in materials.
Load-controlled pushover analysis of the frame gives the base shear-roof displacement response shown below. Also plotted are the sensitivities of the roof displacement which you can record with node recorders (currently undocumented) as well as the sensNodeDisp command.

The results indicate that an increase in either E or Fy will lead to a decrease in roof displacement–increasing these parameters makes the structure stiffer and stronger, as expected. Furthermore, we see that the sensitivity with respect to Fy is zero prior to yield, i.e., Fy doesn’t matter at low load levels. Finite difference calculations confirm the DDM results.
Note that the sensitivities are scaled by the nominal parameter value so that the sensitivities have the same units as the response. Multiplying the ordinates by a % change in parameter value will approximate the change in displacement.
Now the pushover analysis is repeated using displacement control (on the roof displacement), giving the same base shear-roof displacement relationship (shown below) as obtained with load control. The sensitivity of the base shear (load factor) to the model parameters is obtained with the sensLambda command and scaled by the nominal parameter values.

We see that with displacement control, increases in Fy and E will lead to an increase in base shear, i.e., as these parameters increase, more load is required to reach a target displacement. The elastic modulus E has a significant effect on the base shear prior to yield–it’s a stiff system. After yield, the sensitivity with respect to E reduces while the sensitivity to Fy becomes significant. Again, finite difference calculations confirm the DDM results.
Although not shown here, we can also compute dynamic response sensitivity with the Newmark integrator. In most common cases, sensitivity of inertial and damping forces are computed at the structural level, so the elements don’t have to do anything extra for dynamic response sensitivity.
Currently, the DDM in OpenSees is limited to a handful of element and material models; however, I’m working on wrapper functions that use finite differences at the material level and DDM at the section, element, and higher levels of the analysis. With these wrappers, you’ll be able to use Concrete23 and Steel08 in your DDM-based analyses without having to go through the pain of differentiating the equations that govern the Concrete23 and Steel08 stress-strain response.
I struggled with the title for this post, but then thought about Michael G. Scott.

Dear P.D.,
Nice post! I like it. I look forward to reading your new posts.
Please provide more posts about sensitivity.
LikeLike
Thanks, MSB! Will do, sensitivity is one of my favorite subjects.
PD
LikeLike
Dear P.D.,
I am trying to build a background reading list in Sensitivity.
What books do you recommend?
LikeLike
Hello MSB,
The book “Parameter Sensitivity in Nonlinear Mechanics” by Kleiber et al is a good starting point.
Stay tuned to the blog though, I plan to make many more posts about sensitivity!
PDF
LikeLike
Hello,
Can I do sensitivity analysis on other quantity rather than displacement ”sensNodeDisp” or force ”sensLambda”. For example, if I need to see sensitivity of curvature of RC section to some parameters during M-C analysis
I found that there are limited command for sensitivity..
LikeLike
You can get moment and curvature sensitivity using sensLambda and sensNodeDisp in a moment-curvature analysis of a section in a zeroLengtSection element.
LikeLiked by 1 person
thanks for response
I tried that but failed thinking it is not possible
But now I will try again
LikeLike
Thanks for the interesting post,
I have a small question: how this becomes different when you have a first phase of load that is then maintained constant?
I have a beam with gravity load and then applied incremental load (4 point bending): I tried using sensLambda but the results become really strange with very high sensitivities… However, if I set the value of the gravity load equal to zero everything works as expected and I obtain meaningful sensitivities values (with in some cases 4-5 orders of magnitude of difference respect to the previous case)
What I am thinking is that the algorithm fails to work when part of the displacement is due to another (constant) load pattern. What is your idea?
LikeLike
Hello Diego,
Your description of the issue and the model is not clear, so I don’t know.
Michael
LikeLiked by 1 person
Hello professor,
thanks for your kind response. I am sorry If my question was not clear. I’ll try to explain better, providing a simple MWE.
We have a RC beam with rectangular section subjected to 4-point bending.
If we run the following code and evaluate the sensitivities for 3 parameters (E, fy and fc) we obtain respectively sensitivities of 2.01e-5 0.0 -0.0194 that make sense: the first one multiplied by the nominal value of E is 4.36 kN and indeed a variation of 10% of the parameter gives an increase on lambda of 0.436 kN. Same is for the third parameter (fc) that multiplied by its nominal value is 0.58 kN. The second parameter in this stage (I run for this example just one step) is still 0 since fy has no influence on the elastic response of the beam.
Now, I wanted to include the self-weight of the beam (decommenting the proper lines in the above MWE): I apply gravity load (modelled as eleLoad) in 10 steps with a Linear ramp and then I set it constant with loadConst.
Now the sensitivities for the three parameters become: -138.3494, -138.3494, -138.9883. I am not understanding exactly why this is happening.
I have tried to use a Constant time series instead of a Linear one for gravity load, of course applying it in one step. The sensitivities does not change. Curiously enough, with constant time series, if I comment the loadConst line (which is not needed actually) the sensitivities reduce by a factor 2 becoming: -69.1747, -69.1740, -69.4942.
Do you have any idea why this should happen to point me in the right search direction?
Diego
LikeLike