OpenSees was always meant to be an API and you can use various helper functions like ops.eleResponse()
and ops.nodeDisp()
to get selected response quantities. You will find, however, that the values returned by these commands are not always congruent with what you want.
In many cases, Python list comprehensions give an easy one-liner for morphing data to suit your needs. Here are a few examples.
Section Tags
You can obtain a list of section tags from most beam-column elements by calling the ops.eleResponse()
function with the 'sectionTags'
keyword. However, the result is a list of floating point values, e.g., [1.0,2.0,...,1.0]
instead of [1,2,...,1]
. No worries, you can use a list comprehension to convert the values to a list of integers.
eleTag = 23 # Or whatever
secTags = [int(tag) for tag in ops.eleResponse(eleTag,'sectionTags')]
You can also obtain the section tags as a list of integers using the ops.sectionTag()
command, but this comprehension was a good example of how to change data types.
Reducing Significant Digits
Nodal response helper commands, e.g. ops.nodeDisp()
and ops.nodeReaction()
, return values with 16 significant digits. This may be too many digits for some applications; or rather, it should be too many digits for most applications. Anyway, if you don’t want to store all that data, use a list comprehension.
ndTag = 8 # Or whatever
disp = [float(f"{u:.6g}") for u in ops.nodeDisp(ndTag)]
Note that the comprehension formats each value as a string with six significant digits (.6g
), then turns that string back into a float.
Fixity Conditions
After OpenSees performs an analysis, you can obtain the equation numbers from the ops.nodeDOFs()
command. Degrees of freedom (DOFs) with -1 for their equation number are constrained while unconstrained DOFs have equation numbers ranging from 0 to , where
is the number of equations, which you can obtain from
ops.systemSize()
. If you don’t care about the equation numbers and all you want is a list of -1/0 fixed/free codes, use a list comprehension.
ops.analyze(Nsteps) # or ops.eigen(Nmodes)
ndTag = 76 # Or whatever
fixity = [min(dof,0) for dof in ops.nodeDOFs(ndTag)]
There are many other list comprehensions that will come in handy as you navigate OpenSees with Python–the foregoing examples gave you a sense of what’s possible.
If you have an OpenSeesPy list comprehension you’d like to share, show us in the Comments section below.
Prof Scott, That was very beautiful explanation of comprehension list advantages. I don’t like this post because I love it. Also to continue this post I would like to say that paying attention to this detail some times causes 1000 times faster code. there is many speed differences between what you wrote as the 1st example and this type of coding:
eleTag = 23 # Or whatever
secTags = []
for tag in ops.eleResponse(eleTag,’sectionTags’):
secTags .append(int(tag))
the above code depend on the size of the eleResponse list can be slower so much time than what you wrote in 1st example and being able to write codes with list comprehension also makes codes faster. we used this ability in BraineryWiz also.
Again thanks for this valuable lovely post.
With best.
LikeLiked by 1 person
Thanks, Bijan! That is an excellent point about the speed of the comprehensions, especially for long lists of data.
LikeLiked by 1 person