In the early days of OpenSees, perhaps in its G3 infancy, an example Tcl script used BandGeneral for the system and Plain for the numberer.
numberer Plain
system BandGeneral
Who created the script, or why they chose those analysis options, is unimportant now–it could have been me for all I know. But this pair of commands has been posted online and copied into so many other Tcl scripts–and now Python–that someone new to OpenSees might assume these options are best practice.
The cargo culting has gone so far that if you ask ChatGPT to generate an OpenSees analysis script for a cantilever, chances are pretty good you’re going to get BandGeneral for the system and Plain for the numberer.
Go ahead and try it yourself (click the link, then hit Enter). Did you get the cargo culted analysis options? If not, maybe this post has already done its job.
To be fair, these options are fine for the small examples found at a workshop or in a classroom, but this combination of solver and numberer does not scale well to larger models.
In a previous post on the performance of all linear equation solvers and equation numberers available in OpenSees, we saw that BandGeneral is not the best solver, and also not the worst. However, the numberer does make a significant difference for this solver.

So if you’re going to use BandGeneral, at least switch to the RCM numberer, which will reduce the matrix bandwidth. But don’t use AMD, because its minimization of fill-in can lead to high matrix bandwidth, which is not good for banded equation solvers.
ops.numberer('RCM')
ops.system('BandGeneral')
As you get into larger models, you’ll want to use a sparse equation solver like SparseGeneral, UmfPack, or Mumps that only stores non-zero matrix entries.
ops.numberer('RCM') # or 'AMD'
ops.system('UmfPack')
Cargo is harmless for toy models. When you scale up, inspect the contents before they become your standard practice.
