Failure to Solve

Solving a system of simultaneous linear equations, canonically referred to as solving Ax=b in math speak, is at the heart of every equilibrium solution algorithm for nonlinear analysis. In the context of OpenSees, A is the effective tangent stiffness matrix, x is the vector of displacement increments, and b is the residual force vector.

However, there’s several reasons solving Ax=b can fail and they all boil down to rigid body motion, or mechanisms. In most cases, user error is to blame and some software will automatically correct the issue.

OpenSees is not one of those softwares. When the solution of Ax=b fails, you’ll see something like the following message among the small firestorm of output.

The first two lines of output tell you the solver failed. The first line will vary depending on which solver you use, but they all say essentially the same thing.

Now, here are common scenarios that lead to a failed solution of Ax=b.

Suppose we would like to model a cantilever column with two nodes. The solution will fail if there is a disconnected, or floating, node or if there is not sufficient boundary conditions to prevent rigid body motion, e.g., a pin instead of fixed support for the column.

Similarly, for simple beams in 3D, you will have to prevent rigid body spinning about the beam’s longitudinal axis.

Note that you could get a solution out of the two scenarios shown above by adding mass to all DOFs and performing a dynamic analysis. But rigid body dynamics is outside the scope of most earthquake engineering applications.

Also note that checking your model for floating nodes is straightforward. Build a list of connected node tags from ops.getEleTags() and ops.eleNodes(), then see if any nodes defined in the model (from ops.getNodeTags()) are not in the connected nodes list. The code below uses the “exclusive or” (XOR) operator, but there’s other ways to perform this check.

def floatingNodes():
    
    connectedNodes = []
    for ele in ops.getEleTags():
        for nd in ops.eleNodes(ele):
            connectedNodes.append(nd)
   
    definedNodes = ops.getNodeTags()

    # Use XOR operator, ^
    return list(set(connectedNodes) ^ set(definedNodes))

You can define an equivalent function in Tcl.

Now consider the same column but with a rotational spring at its base. The model has three nodes with two nodes collocated at the base for the zero length spring element.

With the two nodes at the base connected only through their rotational DOFs, the translational DOFs of these nodes must be constrained to have the same motion–otherwise, the solver will fail. This is simply another case of preventing rigid body motion.

# Constrain DOFs 1 and 2 of nodes I and J to be the same
ops.equalDOF(ndI,ndJ,1,2) 

Sure, for this particular case, we could just pin the node on top of the spring. However, the equalDOF is the way to go for models with rotational springs at beam-column joints where there are no external support conditions.

Even with a successful model definition, you can run into problems as the simulation advances through time. Consider the case of a displacement-controlled pushover analysis where the post-yield moment-rotation response of the spring is perfectly plastic. The tangent stiffness of the spring is zero and you will encounter an error with solvers that do not pivot. Use UmfPack or SparseGeneral -piv instead of ProfileSPD.

While the examples in this post were of simple cantilever columns, you’ll see similar situations in larger models of structural systems where you can have global or local mechanisms.

Although not addressed here, there are analogies for geotechnical models, most commonly p-y springs with zero stiffness or lack of equalDOF between spring nodes. You can also face issues with the equation solver based on which constraint handler you use for multi-point constraints.

9 thoughts on “Failure to Solve

  1. Is there any way to define constraint that mimics Abaqus Kinematic Coupling with all the rotational DOFs unrestrained? I have been trying to achieve something similiar using OpenSeesPy without any success (most methods lead to error shown in this post). I find the kinematic coupling in Abaqus to be useful in situations where one wants to apply forces/moments on a reference point and get the effects from the eccentricity.

    Like

    1. I am not familiar with the kinematic coupling in Abaqus and it is not clear from your description what the constraint should do or why you get an error in OpenSees. If you can provide a minimal example that would be helpful, or you can book a 1-on-1 session to discuss in detail how these models can fit into your professional workflows.

      Liked by 1 person

      1. Thanks for the reply. Imagine two columns fixed at bottom node, and one floating node between the column tops on which a point moment acts.

        Using Abaqus, one can define a kinematic coupling between the floating node and the column tops with all DOFs retrained, in which case it will give the same results as using rigidLink(“beam”…) in openseespy.

        Now in Abaqus, if one unrestrains the rotational DOFs (but keeps the translational DOFs), the moment is taken up as force couple between the two columns. This is what I have been trying to achieve in openseespy without any success. Using equalDOF and restraining only the translational DOFs leads to error like the one in this article. I hope I was clear with my explanation.

        Like

Leave a reply to Positive Definite Cancel reply

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