14.7.1. A Procedure to Render 2D or 3D OpenSees Model and Mode Shapes

Note

Note that the openseespy.postprocessing.Get_Rendering module has been moved to its own respository at here. The following code may not work and please direct any questions to Anurag Upadhyay.

  1. The source code is developed by Anurag Upadhyay from University of Utah.
  2. The source code can be downloaded here.
  3. Below is an example showing how to visualize an OpenSeesPy model.
  4. Import by writing in the model file, “from openseespy.postprocessing.Get_Rendering import * “. (see line 11 in below example)
  5. Plot the model by writing “plot_model()” after defining all the nodes and elements. (see line 115 in below example)
  6. Plot mode shapes by writing “plot_modeshape(mode_number)” after performing the eigen analysis. (see line 114 in below example)
  7. Update openseespy to the latest version to get this function.
../_images/Model_Plot3D.png ../_images/ModeShape_5_Plot3D.png
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

##################################################################
## 3D frame example to show how to render opensees model and 
## plot mode shapes
##
## By - Anurag Upadhyay, PhD Candidate, University of Utah.
## Updated - 09/10/2020
##################################################################

import openseespy.postprocessing.Get_Rendering as opsplt
import openseespy.opensees as ops

import numpy as np

from math import asin, sqrt

# set some properties
ops.wipe()

ops.model('Basic', '-ndm', 3, '-ndf', 6)

# properties
# units kip, ft

numBayX = 2
numBayY = 2
numFloor = 7

bayWidthX = 120.0
bayWidthY = 120.0
storyHeights = [162.0, 162.0, 156.0, 156.0, 156.0, 156.0, 156.0, 156.0, 156.0, 156.0, 156.0]

E = 29500.0
massX = 0.49
M = 0.
coordTransf = "Linear"  # Linear, PDelta, Corotational
massType = "-lMass"  # -lMass, -cMass

nodeTag = 1

# add the nodes
#  - floor at a time
zLoc = 0.
for k in range(0, numFloor + 1):
	xLoc = 0. 
	for i in range(0, numBayX + 1):
		yLoc = 0.
		for j in range(0, numBayY + 1):
			ops.node(nodeTag, xLoc, yLoc, zLoc)
			ops.mass(nodeTag, massX, massX, 0.01, 1.0e-10, 1.0e-10, 1.0e-10)
			if k == 0:
				ops.fix(nodeTag, 1, 1, 1, 1, 1, 1)
				
			yLoc += bayWidthY
			nodeTag += 1
			
		xLoc += bayWidthX

	if k < numFloor:
		storyHeight = storyHeights[k]
	
	zLoc += storyHeight

# add column element
ops.geomTransf(coordTransf, 1, 1, 0, 0)
ops.geomTransf(coordTransf, 2, 0, 0, 1)

eleTag = 1
nodeTag1 = 1

for k in range(0, numFloor):
	for i in range(0, numBayX+1):
		for j in range(0, numBayY+1):
			nodeTag2 = nodeTag1 + (numBayX+1)*(numBayY+1)
			iNode = ops.nodeCoord(nodeTag1)
			jNode = ops.nodeCoord(nodeTag2)
			ops.element('elasticBeamColumn', eleTag, nodeTag1, nodeTag2, 50., E, 1000., 1000., 2150., 2150., 1, '-mass', M, massType)
			eleTag += 1
			nodeTag1 += 1


nodeTag1 = 1+ (numBayX+1)*(numBayY+1)
#add beam elements
for j in range(1, numFloor + 1):
	for i in range(0, numBayX):
		for k in range(0, numBayY+1):
			nodeTag2 = nodeTag1 + (numBayY+1)
			iNode = ops.nodeCoord(nodeTag1)
			jNode = ops.nodeCoord(nodeTag2)
			ops.element('elasticBeamColumn', eleTag, nodeTag1, nodeTag2, 50., E, 1000., 1000., 2150., 2150., 2, '-mass', M, massType)
			eleTag += 1
			nodeTag1 += 1
		
	nodeTag1 += (numBayY+1)

nodeTag1 = 1+ (numBayX+1)*(numBayY+1)
#add beam elements
for j in range(1, numFloor + 1):
	for i in range(0, numBayY+1):
		for k in range(0, numBayX):
			nodeTag2 = nodeTag1 + 1
			iNode = ops.nodeCoord(nodeTag1)
			jNode = ops.nodeCoord(nodeTag2)
			ops.element('elasticBeamColumn', eleTag, nodeTag1, nodeTag2, 50., E, 1000., 1000., 2150., 2150., 2, '-mass', M, massType)
			eleTag += 1
			nodeTag1 += 1
		nodeTag1 += 1

# calculate eigenvalues & print results
numEigen = 7
eigenValues = ops.eigen(numEigen)
PI = 2 * asin(1.0)

###################################
#### Display the active model with node tags only
opsplt.plot_model("nodes")

####  Display specific mode shape with scale factor of 300 using the active model
opsplt.plot_modeshape(5, 300)

###################################
# To save the analysis output for deformed shape, use createODB command before running the analysis
# The following command saves the model data, and output for gravity analysis and the first 3 modes 
# in a folder "3DFrame_ODB"

opsplt.createODB("3DFrame", "Gravity", Nmodes=3)


# Define Static Analysis
ops.timeSeries('Linear', 1)
ops.pattern('Plain', 1, 1)
ops.load(72, 1, 0, 0, 0, 0, 0)
ops.analysis('Static')

# Run Analysis
ops.analyze(10)

# IMPORTANT: Make sure to issue a wipe() command to close all the recorders. Not issuing a wipe() command
# ... can cause errors in the plot_deformedshape() command.

ops.wipe()

####################################
### Now plot mode shape 2 with scale factor of 300 and the deformed shape using the recorded output data

opsplt.plot_modeshape(2, 300, Model="3DFrame")
opsplt.plot_deformedshape(Model="3DFrame", LoadCase="Gravity")