Sensitivity Training

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.

13 thoughts on “Sensitivity Training

  1. 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..

    Like

      1. thanks for response
        I tried that but failed thinking it is not possible
        But now I will try again

        Like

  2. 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?

    Like

      1. 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.

        wipe
        model basic -ndm 3 -ndf 6
        reliability
        timeSeries Linear
        timeSeries Linear 1
        timeSeries Constant 2
        Materials
        uniaxialMaterial Concrete01 1 -29.89 -0.002 -0.3 -0.006
        uniaxialMaterial Steel01 2 381.98 216722.0 0.0023
        uniaxialMaterial Steel01 3 310.8 216722.0 0.002256
        set As [expr 28 * 28 * 3.14159 / 4]
        Section
        section Fiber 1 -GJ 1e14 {
        patch rect 1 5 1200 -200 -600 200 600
        layer straight 3 8 $As -160 -560 160 -560
        layer straight 3 3 $As -160 560 160 560
        }
        Create nodes
        tag x y z
        node 1 0 0 0
        node 2 7675 0 0
        node 3 5675 0 0
        node 4 3675 0 0
        node 5 11350 0 0
        Boundary conditions
        fix 1 0 1 1 1 0 1
        fix 5 1 1 1 1 0 1
        Create elements
        geomTransf Linear 1 0.0 0.0 1.0
        element forceBeamColumn 1 1 2 1 Lobatto 1 5
        element forceBeamColumn 2 2 3 1 Lobatto 1 5
        element forceBeamColumn 3 3 4 1 Lobatto 1 5
        element forceBeamColumn 4 4 5 1 Lobatto 1 5
        Parameters
        parameter 1
        parameter 2
        parameter 3
        foreach ele [getEleTags] {
        addToParameter 1 element $ele E
        addToParameter 2 element $ele fy
        addToParameter 3 element $ele fc
        }
        # Self weight
        #pattern Plain 1 1 {
        # eleLoad -ele 1 2 3 4 -type -beamUniform 0.0 -12.0
        #}
        #test NormDispIncr 1e-12 100 2
        #integrator LoadControl 0.1
        #analysis Static
        #analyze 10
        #loadConst -time 0.0
        print node 3
        foreach p [getParamTags] {
        set fileid fid_$p
        set $fileid [open “sensLambda_$p.out” “w+”]
        }
        recorder Node -file nodeDisp3.out -time -node 3 -dof 3 “disp”
        4 point bending
        pattern Plain 2 1 {
        load 2 0.0 0.0 -500.0 0.0 0.0 0.0
        load 4 0.0 0.0 -500.0 0.0 0.0 0.0
        }
        integrator DisplacementControl 3 3 -1.0
        analysis Static
        sensitivityAlgorithm -computeAtEachStep
        analyze 1
        Save sensitivity
        foreach p [getParamTags] {
        puts “[nodeDisp 3 3] [sensLambda 2 $p]”
        puts “[expr $fid_$p]” “[nodeDisp 3 3] [sensLambda 2 $p]”
        }
        print some checks
        print node 3
        foreach p [getParamTags] {
        set val [getParamValue $p]
        puts “Parameter $p: $val”
        close [expr $fid_$p]
        }

        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

        Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.