Although the material and element models are there, OpenSees is not well known for solid finite element analysis. Creating a good mesh is key to solid FEA and there aren’t many meshing tools implemented in OpenSees.
block3D commands work fine, but you have to manually join or tie adjacent meshes with loops and
equalDOF commands. Just be sure to use the Transformation constraint handler. If no re-meshing is required during an analysis, you’re better off to create a mesh using a third party tool then import the nodes and connectivity to OpenSees.
But what do you do when re-meshing is required during an analysis? For example, in a PFEM analysis, the fluid domain along the fluid-structure interface requires frequent re-meshing. Using a third party meshing tool would be virtually impossible.
To make re-meshing tractable for PFEM analyses in OpenSees, Minjie implemented triangular and tetrahedral meshing routines–and he did it in a way that the routines can be used for not just fluid elements, but also for solid elements.
This post will show how to use Minjie’s functions to analyze the bar shown below with a 2D mesh of
Tri31 triangular plane stress elements.
First define nodes for the mesh corner points.
import openseespy.opensees as ops ops.wipe() ops.model('basic','-ndm',2,'-ndf',2) L = 10 h = 2 t = 1 ops.node(1,0,-h/2) ops.node(2,0,h/2) ops.node(3,L,h/2) ops.node(4,L,-h/2)
Next, define line meshes around the perimeter. Each line has a tag, followed by the number of points that define the line, the nodes for those points, the type (use 0 when not FSI), the number of DOFs for each node, the size (spacing) of the nodes to be generated along the line.
c = h/5 # tag Npts nodes type dof size ops.mesh('line',1, 2, *[1,2], 0, 2, c) ops.mesh('line',2, 2, *[2,3], 0, 2, c) ops.mesh('line',3, 2, *[3,4], 0, 2, c) ops.mesh('line',4, 2, *[4,1], 0, 2, c)
Although not shown in this post, the advantage of line meshes is you don’t have to tie meshes together after creating elements. Instead, you just create element meshes based on the pre-defined lines.
For 2D meshes, you have two options: either make triangle elements in a triangulated mesh or make triangles from a quadrilateral mesh. Similar to the line mesh, there is a tag, lines that circumscribe the mesh, the type (still 0), DOFs per node, and the mesh size. The remaining arguments create elements–pass the element type, then all the information that would come after the nodes in the regular element command.
E = 29000 v = 0.3 ops.nDMaterial('ElasticIsotropic',1,E,v) # tag Nlines lines type dof size <ele args> ops.mesh('tri',5, 4, *[1,2,3,4], 0, 2, c, 'tri31',t,'PlaneStress',1)
The triangulated mesh is shown below.
Try changing the mesh size to see what happens.
If instead, you want a more regular mesh, you can make triangles out of quadrilateral–just use
'quad' instead of
# tag Nlines lines type dof size <ele args> ops.mesh('quad',5, 4, *[1,2,3,4], 0, 2, c, 'tri31',t,'PlaneStress',1)
The resulting mesh is shown below. The mesh size for the quadrilateral mesh doesn’t matter–the elements are always generated from the grid made by the points along each line.
To apply boundary conditions along a line, you can use the
fixY commands (
fixZ is available for 3D problems). The following command fixes the X and Y displacement (DOF 1 and 2) of all nodes with X-coordinate equal to zero.
# X 1 2 ops.fixX(0,1,1)
The meshes shown in this post were plotted using the
opsvis package developed by Seweryn Kokot.
Meshing a three-dimensional domain is a little more involved, so I will address that in another post.
Este video, desde el OpenSees Cafecito, demuestra el uso de los comandos de malla para muros. Although the video is in Spanish, you can see how the mesh commands are used for walls.
3 thoughts on “Two-Dimensional Meshing”