Three-Dimensional Meshing

Two previous posts showed how to use Minjie‘s meshing functions to create line meshes for beam-column elements and 2D meshes for solid elements. This post will complete the trilogy by showing how to make a 3D mesh for solid elements.

The bar shown below is the same model used in the post on 2D meshing.

To begin a 3D solid model of the bar, define nodes for the eight corner points.

import openseespy.opensees as ops

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

L = 10
h = 2
t = 1

ops.node(1,0, t/2, h/2)
ops.node(2,0,-t/2, h/2)
ops.node(3,0,-t/2,-h/2)
ops.node(4,0, t/2,-h/2)

ops.node(5,L, t/2, h/2)
ops.node(6,L,-t/2, h/2)
ops.node(7,L,-t/2,-h/2)
ops.node(8,L, t/2,-h/2)

The next step is to define line meshes for the edges of the bar. Each of the 12 edges has a tag, followed by information about the end points of each line, the type (use 0 when not FSI), the number of DOFs per node, and the spacing of the nodes along each line.

c = t/2

#              tag Npts nodes type dof size
ops.mesh('line',1,  2, *[1,4],  0,  3,   c)
ops.mesh('line',2,  2, *[4,3],  0,  3,   c)
ops.mesh('line',3,  2, *[3,2],  0,  3,   c)
ops.mesh('line',4,  2, *[2,1],  0,  3,   c)

ops.mesh('line',5,  2, *[5,8],  0,  3,   c)
ops.mesh('line',6,  2, *[8,7],  0,  3,   c)
ops.mesh('line',7,  2, *[7,6],  0,  3,   c)
ops.mesh('line',8,  2, *[6,5],  0,  3,   c)

ops.mesh('line', 9, 2, *[1,5],  0,  3,   c)
ops.mesh('line',10, 2, *[2,6],  0,  3,   c)
ops.mesh('line',11, 2, *[3,7],  0,  3,   c)
ops.mesh('line',12, 2, *[4,8],  0,  3,   c)

Compared to 2D meshing, 3D meshing requires an extra step before creating elements–nodes must be generated over each of the six faces of the bar. Call the mesh command with mesh tag, the number of lines that circumscribe the face, the line tags, the type (still 0), DOFs per node, and mesh size–but leave off the element arguments.

meshType = 'tri'
#meshType = 'quad'
#                tag  Nlines   lines   type dof size
ops.mesh(meshType,13,   4,  *[1,2,3,4],  0,  3,   c)
ops.mesh(meshType,14,   4,  *[5,6,7,8],  0,  3,   c)
ops.mesh(meshType,15,   4,  *[4,9,8,10], 0,  3,   c)
ops.mesh(meshType,16,   4,  *[2,12,6,11],0,  3,   c)
ops.mesh(meshType,17,   4,  *[3,11,7,10],0,  3,   c)
ops.mesh(meshType,18,   4,  *[1,12,5,9], 0,  3,   c)

For a quadrilateral mesh on each face, simply change 'tri' to 'quad'. The nodes created on all six faces are shown below. Yeah, it’s a little crowded, but when you give this a try, you can zoom and rotate the view to see what’s going on.

With nodes on all six faces of the bar, we can now create the element mesh. The only element available for 3D meshing with the mesh commands is the four node tetrahedral element. For brick elements, your only option for now is to use the block3D command.

E = 29000
v = 0.3

ops.nDMaterial('ElasticIsotropic',1,E,v)

#             tag Nlines     lines         type dof size <ele args>
ops.mesh('tet',20,  6,*[13,14,15,16,17,18],  0,  3,   c, 'FourNodeTetrahedron',1)

Again, the views are pretty crowded, but you can zoom and rotate when you give this a try.

To apply boundary conditions along a surface, you can use fixX, fixY, and fixZ. To fix the displacements of all nodes with X-coordinate equal to 0, use the following command.

#        X 1 2 3
ops.fixX(0,1,1,1)

As far as I know, there’s no easy way to apply traction stresses to solid models in OpenSees. While this functionality can be implemented via scripts, it should be implemented within the OpenSees core.


The meshes shown in this post were plotted using the opsvis package developed by Seweryn Kokot.

2 thoughts on “Three-Dimensional Meshing

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 )

Twitter picture

You are commenting using your Twitter 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.