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.