OpenSees Cloud

OpenSees AMI

Life of OpenSees Pi

Original Post - 16 Nov 2023 - Michael H. Scott

Visit Structural Analysis Is Simple on Substack.


This is blog post #314, or \(100\pi\) to three sig figs. A more recognizable \(\pi\)-times-a-power-of-10 post than post #31 or post #3. And I’ll have to maintain the current pace of post writing into my mid 80s in order to reach post #3141.



In the G3 days of OpenSees, the inverse sine function was used to set \(\pi\) as a constant in many Tcl scripts.

set pi [expr 2*asin(1.0)]

To save a flop in the script, you could use inverse cosine.

set pi [expr acos(-1.0)]

I’m not sure why we needed such precision in computing the areas of steel reinforcing bars or the areas of reinforced concrete columns. We’re talking about reinforced concrete after all, so set pi 3.14 should suffice.

In a script, the computational expense of calling an inverse trigonometric function is inconsequential.

But, if you’re going to use \(\pi\) down in the low levels of the C++ core of OpenSees, you should do better than the automatic local variable double pi = acos(-1.0). I know, the computational expense is not that big of a deal in this case, but every nanosecond counts. With that said, three alternatives come to mind.

The first option is to declare pi as a static variable. This basically means the variable is initialized once, not every time program execution enters the scope, so go ahead and use your favorite inverse trigonometric function.

static const double pi = acos(-1.0);

The const is optional and prevents you from accidentally overwriting pi later on.

The second option is to visit an online \(\pi\) calculator, e.g., here, and copy-paste.

static const double pi = 3.141592653589793;

I took the first Google result, so the digits must be correct.

The third option is to “pound define”, or, if you grew up with a smartphone, “hashtag define” the constant using a pre-processor directive. In other words, prior to compiling the code, the compiler will substitute the 16 digits wherever you use pi in your code.

#define pi 3.141592653589793

In general, using more than 16 digits for \(\pi\) is unnecessary if you want to mitigate round off errors.

Some gentle grepping shows over 50 definitions of \(\pi\) in various OpenSees classes. The award for biggest slice of \(\pi\) goes to the authors of ZeroLengthInterface2D and ZeroLengthContactNTS2D, who pound defined a whopping 46 digits!