OpenSees Cloud

OpenSees AMI

Last Committed Stiffness

Original Post - 14 Nov 2020 - Michael H. Scott

Visit Structural Analysis Is Simple on Substack.


With the rayleigh command, OpenSees allows you to input three stiffness proportional damping factors: 1) the current tangent stiffness, 2) the initial stiffness, and 3) the last committed stiffness. Each option has drawbacks.

The current tangent stiffness is problematic because the tangent stiffness can change significantly at each iteration of the equilibrium solution algorithm. The damping force will change accordingly and you’ll likely experience convergence issues.

The initial stiffness is also problematic because it can overestimate damping forces in yielding elements where the stiffness is reduced and the velocities increase.

The last committed stiffness is generally thought to be the best option because it has the most up to date information on the stiffness. Here’s the source code for what is stored as the last committed stiffness:

int
Element::commitState(void)
{
  if (Kc != 0)
     *Kc = this->getTangentStiff();

  return 0;
}

The last committed stiffness is actually just the element’s tangent stiffness when commitState() is called at the end of a time step. This could be a little concerning because the last committed stiffness is not necessarily the stiffness that was used to find equilibrium in the global solution algorithm.

In fact, the tangent stiffness may not even be a good stiffness at all. What if Concrete23 returns a bad tangent? What if Concrete23 always returns the initial stiffness because the author of Concrete23 expected the global solution algorithm, e.g., KrylovNewton, to clean up the mess?

All that aside, for the last committed stiffness to work, each element needs to call the base class commitState(). For example, here are the first few lines of commitState() for the force-based beam-column element:

int
ForceBeamColumn2d::commitState()
{
  int err = 0;
  int i = 0;

  // call element commitState to do any base class stuff
  if ((err = this->Element::commitState()) != 0) {
    opserr << "ForceBeamColumn2d::commitState () - failed in base class";
  }

You’ll see similar calls in the commitState() implementation for other elements. So, be sure to make a call to Element::commitState() in your element implementation if you want the last committed stiffness proportional damping to work. If your element doesn’t call the base class Element::commitState(), the last committed stiffness will be the tangent stiffness at the time the rayleigh command was invoked–most likely the initial stiffness, which got us here in the first place.