Software does exactly what you tell it to do. But problems arise when you don’t know–or assume you know–what instructions you’re giving.
For example, many people like to use the
'fullGenLapack' eigenvalue solver in OpenSees because it will compute all N eigenpairs (eigenvalue with corresponding eigenvector) for a model whereas the default eigenvalue solver will only compute up to N-1 eigenpairs.
Nmodes = 3 ;# Or whatever # Default eigenvalue solver ops.eigen(Nmodes) # fullGenLapack eigenvalue solver ops.eigen('fullGenLapack',Nmodes)
The non-default eigenvalue solver is OK for small OpenSees models from textbooks and blogs (e.g., here), but as Frank described in his response to GitHub issue #804, regardless of how many modes you ask for with the
eigen command, even if it’s only one mode, the
'fullGenLapack' eigenvalue solver will compute the eigenpairs for all N modes (as stated in the
dggev documentation), making this option a killer for models with more than a few hundred DOFs.
I will demonstrate the long computation times using a 3D solid model with tetrahedral elements. A material mass density of 0.00029 gives all N degrees of freedom mass. Reducing the element mesh size is an easy way to increase the number of DOFs.
For a few mesh sizes, I compute the eigenpairs of the model with the default and
'fullGenLapack' eigenvalue solvers. First, I ask
ops.eigen() for 10 modes, then I ask for N-1 modes. The model sizes are not large with N=585, 1200, and 2304.
Whether you ask for 10 modes or N-1 modes, the
'fullGenLapack' option takes essentially the same amount of time whereas the default eigenvalue solver takes relatively no time (under one second for these model sizes) to compute 10 modes and does much better than
'fullGenLapack' for N-1 modes.
For the model with N=2304, a call to
ops.eigen() with the
'fullGenLapack' option takes over three minutes (wall time) on my half-way decent laptop. Doing some back of the envelope fitting of a cubic function to the
'fullGenLapack' data points shown in the figure, a call to
ops.eigen('fullGenLapack',...) for this model refined to N=10,000 would take about 7.5 hours on my laptop–even if I ask for only one mode. Biting off way more than I can chew…
So, never use
'fullGenLapack' in OpenSees.
But what should you do if you really want all N eigenpairs for something larger than a toy model, e.g., because you want to show modal damping who’s boss? You should use the default eigenvalue solver after adding a high frequency (high stiffness with low mass) SDF appendage to your model. The appendage gives you N+1 modes, then you can call the default eigenvalue solver to give you the N modes you care about. Just be sure to attach the SDF appendage to a fixed DOF so that there is no interference, or coupling, with your actual model.
Here is an explanation of the
fullGenLapack issue from a recent OpenSees Cafe. I admit, I was either unaware or had forgotten about this issue. That’s why it’s important to write things down!