OpenSees Cloud
OpenSees AMI
Not Everything Should Be a Direct Translation
Original Post - 12 Feb 2023 - Michael H. Scott
Visit Structural Analysis Is Simple on Substack.
Like learning another language, not everything in OpenSees, and programming in general, is a direct translation from textbooks.
Your mother tongue could be x=A-1b, but
you should never invert the matrix then multiply. Instead, call an
equation solver. For small matrices in OpenSees, use A.Solve(b, x)
from
the Matrix class. In your Python scripts you can use np.linalg.solve
while In Tcl it’s ::math::linearalgebra::solveGauss
.
Another example of lengua materna is how you handle constants expressed in scientific notation. When you see \(2.1 \times 10^{-8}\), you may be inclined to type one of the following:
- C++:
2.1*pow(10,-8)
- Python:
2.1*10**-8
- Tcl:
2.1*10.0**-8
or2.1*pow(10,-8)
– Note:2.1*10**-8
will be zero due to integer division in Tcl.
I’ve seen constants defined with the above statements many times in OpenSees scripts and in the OpenSees source code.
But NO! There’s no need to use the pow
function or **
to calculate a
power of 10.
Just type 2.1e-8
This is a format all languages will accept for scientific notation.
You might say “What’s the big deal? There’s no difference in
performance.” And you would be correct for a single call with the pow
function taking only microseconds longer to evaluate than the literal
2.1e-8
. But when those pow calls are in a material model or in a script
that gets invoked a million times, those microseconds become seconds.
While interpreted languages like Python and Tcl can’t do much
optimization on your scripts, a decent C++ compiler will pick up your
slack–but that’s never a reliable approach. Here is a
good analysis
of the pow
function in C++.
Another issue with multiplication and powers of 10 is you could
introduce small, unnecessary round off errors. For example, in both
Python and Tcl, 2.1*10**-8
overflows slightly while 2.01*10**-8
underflows. These round off errors will pose a problem for logical
comparisons later in your script.
When your script performs many algebraic operations, you will accumulate
small round off errors no matter what. So, limit potential round off to
necessary computations like 57000*fc**0.5
and just type 2.1e-8
for the
literals.
Finally, never do the MATLAB-style exponent ^
in any language other than
MATLAB.
Expressions like 10^-8
are perfectly legal in C++, Python, and Tcl–the
compiler or interpreter will not complain. However, the ^
operator is
bit-wise
eXclusive OR
(XOR) on the two integers expressed in binary
format. Write 10 and -8 out in binary, then XOR the bits. The compiler
or interpreter is kind enough to convert the binary result back to an
integer and the results will be not at all what you expect.
I have no doubt the topics covered in this post have been and will be the source for many suspicious OpenSees analysis results. And, in some cases, those results have been and will be published. ¡Qué aterrador!