Discretized Members Only

I wrote a DiscretizeMember procedure in Tcl many years ago–I don’t know exactly when, definitely after the 1980s and definitely before moving to Eastchester.

Members Only.“Members Only.” by The Semi-Frozen Trombone is licensed under CC BY 2.0

After carrying the function around for years, and probably spawning more variations than uniaxial Concrete models, the procedure went in to svn (now in GitHub) in 2014 as part of a reliability example. Even there, it’s buried and hard to find.

Then, along came OpenSeesPy. One of the cool things about the OpenSees Python package (pip) is you can include helper functions and entire modules written in native Python. For example, there are a couple of very nice post-processing libraries, Get_Rendering and ops_vis.

With a little bit (meaning, a lot) of help from Minjie, I added a Python version of the DiscretizeMember function to a pre-processing library in OpenSeesPy.

The Python version is basically the same as the Tcl version, but with some minor differences to handle beam integration objects and the input and output of node and element tags. The function inputs are shown below.

def DiscretizeMember(ndI,ndJ,numEle,eleType,integrTag,transfTag,nodeTag,eleTag):

Elements are created between ndI and ndJ. All numEle elements have the same eleType, which can be 'forceBeamColumn', 'dispBeamColumn', or others, and the same beam integration tag (integrTag) and geometric transformation tag (transfTag). The function works for 3D models where all discretized elements for a member should have the same vector in the x-z plane.

The inputs nodeTag and eleTag tell the function where to start numbering the internal nodes and elements from ndI to ndJ.

The function returns two lists: one of the element tags created and the other of the node tags created. These lists are useful if you need to circle back and add loads along the member.

Below is an example for the frame model from this post.

import openseespy.opensees as ops
import openseespy.preprocessing.DiscretizeMember as dm

H = 360
L = 144

ops.wipe()
ops.model('basic','-ndm',2,'-ndf',3)

ops.node(1,0,0); ops.fix(1,1,1,1)
ops.node(2,0,L)
ops.node(3,H,L)
ops.node(4,H,0); ops.fix(4,1,1,1)

E = 29000

# W14x90
ops.section('Elastic',1,E,26.5,999)
ops.beamIntegration('Legendre',1,1,2)

# W18x76
ops.section('Elastic',2,E,22.3,1330)
ops.beamIntegration('Legendre',2,2,2)

# Corotational transformation
ops.geomTransf('Corotational',1)

# Number of elements/member
Nele = 8

# Columns
dm.DiscretizeMember(1,2,Nele,'dispBeamColumn',1,1,10,10)
dm.DiscretizeMember(3,4,Nele,'dispBeamColumn',1,1,30,30)

# Beam - storing and printing the return values for demonstration
elems,nodes = dm.DiscretizeMember(2,3,Nele,'dispBeamColumn',2,1,50,20)

print(f'Beam nodes: {nodes}')
print(f'Beam elements: {elems}')

Give the code a try. You should see the lists of node and element tags created for the beam member.

3 thoughts on “Discretized Members Only

  1. Perfect Prof. Scott! This command helps a lot and I wasn’t sure about how to use it. Thank you very much. Just a little thing: I think in the code, the line where you store the return values for demonstration, it should be “elems,nodes = dm.DiscretizeMember(2,3,Nele,’dispBeamColumn’,2,1,50,20)” because, as you said in the post, the first output of the command is the list of element tags and the second output is the list of node tags. Thanks again!

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.