OpenSeesPyAssistant 1.1
OpenSeesPy for everyone
GeometryTemplate.py
Go to the documentation of this file.
1"""
2Module with geometry templates (nodes and/or elements with associated fibers, material models, etc).
3Carmine Schipani, 2021
4"""
5
6# Import libraries
7from openseespy.opensees import *
8import matplotlib.pyplot as plt
9import numpy as np
10import os
11from copy import copy, deepcopy
12import openseespy.postprocessing.Get_Rendering as opsplt
16from OpenSeesPyAssistant.Units import *
23
24
25def Initialize2DModel(data_dir = "Results"):
26 """
27 Function that initialise the project creating the 2D model with 3 DOF per node and set up a directory for the results.
28
29 @param data_dir (str, optional): Directory where the data will be stored.
30 The function forces the user to define it just for good practice and consistency between projects.
31 Defaults to "Results".
32 """
33 # Clear all
34 wipe()
35
36 # Build model (2D - 3 DOF/node)
37 model('basic', '-ndm', 2, '-ndf', 3)
38
39 # Main Results Folder
40 if not os.path.exists(data_dir):
41 os.makedirs(data_dir)
42
43
44def DefineFrameNodes(n_hor_axis: int, n_vert_axis: int, storey_width, storey_height, half_pz_height = np.array([]),
45 origin = [0, 0], first_hor_axis = 1, first_vert_axis = 1, show_plot = True):
46 """
47 Function that declares and initialises the grid nodes of a frame. Option to offset the grid node of the panel zones
48 with the master node of the panel zone being the grid one (top center one). The function can be used multiple times
49 to create more complex geometries.
50
51 @param n_hor_axis (int): Number of horizontal axis (or piers) for the grid of the frame.
52 @param n_vert_axis (int): Number of vertical axis (or floors) for the grid of the frame.
53 @param storey_width (float): Width of the bays.
54 @param storey_height (float): Height of the storeys.
55 @param half_pz_height (np.ndarray, optional): Array of 1 dimension with half the height of the panel zone for each floor.
56 The first floor should be 0 (no panel zone in the support). Defaults to np.array([]), e.g. no panel zone.
57 @param origin (list, optional): List of two entry with the origin position. Defaults to [0, 0].
58 @param first_hor_axis (int, optional): Number of the first pier. Defaults to 1.
59 @param first_vert_axis (int, optional): Number of the first floor. Defaults to 1.
60 @param show_plot (bool, optional): Option to show the plot of the nodes declared and initialised. Defaults to True.
61
62 @exception NegativeValue: n_hor_axis needs to be a positive integer.
63 @exception NegativeValue: n_vert_axis needs to be a positive integer.
64 @exception NegativeValue: storey_width needs to be positive.
65 @exception NegativeValue: storey_height needs to be positive.
66 @exception WrongDimension: origin has a dimension of 2.
67 @exception NegativeValue: first_hor_axis needs to be a positive integer.
68 @exception NegativeValue: first_vert_axis needs to be a positive integer.
69 @exception WrongDimension: size of half_pz_height needs to be equal to n_vert_axis, if different from 0.
70
71 @returns list: List with the nodes declared.
72 """
73 if n_hor_axis < 1: raise NegativeValue()
74 if n_vert_axis < 1: raise NegativeValue()
75 if storey_width < 0: raise NegativeValue()
76 if storey_height < 0: raise NegativeValue()
77 if len(origin) != 2: raise WrongDimension()
78 if first_hor_axis < 1: raise NegativeValue()
79 if first_vert_axis < 1: raise NegativeValue()
80 if np.size(half_pz_height) != 0 and np.size(half_pz_height) != n_vert_axis: raise WrongDimension()
81
82 if np.size(half_pz_height) == 0: half_pz_height = np.zeros(n_vert_axis)
83 node_array = []
84 max_n_x = n_hor_axis + first_hor_axis - 1
85 max_n_y = n_vert_axis + first_vert_axis - 1
86 for xx in range(n_hor_axis):
87 x_axis = xx + first_hor_axis
88 for yy in range(n_vert_axis):
89 y_axis = yy + first_vert_axis
90 node_ID = GridIDConvention(x_axis, y_axis, max_n_x, max_n_y)
91 node(node_ID, origin[0]+xx*storey_width, origin[1]+yy*storey_height+half_pz_height[yy])
92 if y_axis == 1 and half_pz_height[yy] != 0: print("Warning: the nodes at the base have a panel zone height")
93 node_array.append(node_ID)
94
95 if show_plot:
96 plot_nodes(node_array, "Frame geometry template with only nodes", True)
97 plt.grid()
98
99 return node_array
100
101
102def DefineFrameNodesAndElementsSteelIShape(n_hor_axis: int, n_vert_axis: int, storey_width, storey_height,
103 list_col: list, list_beam: list, geo_trans_ID: int, N_G = np.array([]), t_dp = np.array([]), L_b_col = np.array([]), L_b_beam = np.array([]),
104 fix_support = True, show_plot = True, panel_zone = True):
105 """
106 WIP (Work In Progress). Function that declares and initialises the grid nodes of a frame and the members using steel I shape SpringBasedElements.
107 WARNING: Current limit of the geometry: n_hor_axis and n_vert_axis < 10; if exceeded, there are problems with the IDs (ID limit is exceeded, ~2.2e9).
108 WARNING: if the section of the columns change, the function does not account for the splacing. Each colum section is defined from floor to floor;
109 if there is a change in the column section, it happens right after the panel zone (not realistic but good enough for predesign).
110 WIP: Solve ID limit for large building need implementations (for example the use of a different ID convention or the use of the class IDGenerator).
111
112 @param n_hor_axis (int): Number of horizontal axis (or piers) for the grid of the frame.
113 @param n_vert_axis (int): Number of vertical axis (or floors) for the grid of the frame.
114 @param storey_width (float): Width of the bays.
115 @param storey_height (float): Height of the storeys.
116 @param list_col (list(SteelIShape)): List with the sections of the columns for every floor.
117 @param list_beam (list(SteelIShape)): List with the sections of the beams for every bay.
118 @param geo_trans_ID (int): The geometric transformation (for more information, see OpenSeesPy documentation).
119 @param N_G (np.ndarray, optional): Array of dimension 1 with the axial load for each column (starting at floor 2). Defaults to np.array([]), e.g. 0.
120 @param t_dp (np.ndarray, optional): Array of dimension 1 with the doubler plate thickness for each bay's beam. Defaults to np.array([]), e.g. 0.
121 @param L_b_col (np.ndarray, optional): Array of dimension 1 with the maxiaml unbraced lateral buckling length for each column. Defaults to np.array([]), e.g. -1.
122 @param L_b_beam (np.ndarray, optional): Array of dimension 1 with the maxiaml unbraced lateral buckling length for each beam. Defaults to np.array([]), e.g. -1.
123 @param fix_support (bool, optional): Option to fix the support of the frame. Defaults to True.
124 @param show_plot (bool, optional): Option to show the plot of the nodes declared and initialised. Defaults to True.
125 @param panel_zone (bool, optional): Option to add the panel zones in the model. Defaults to True.
126
127 @exception WrongDimension: N_G dimension needs to be equal to n_vert_axis-1, if different from 0.
128 @exception WrongDimension: t_dp dimension needs to be equal to n_vert_axis-1, if different from 0.
129 @exception WrongDimension: L_b_col dimension needs to be equal to n_vert_axis-1, if different from 0.
130 @exception WrongDimension: L_b_beam dimension needs to be equal to n_hor_axis-1, if different from 0.
131 @exception WrongDimension: list_col dimension needs to be equal to n_vert_axis-1.
132 @exception WrongDimension: list_beam dimension needs to be equal to n_vert_axis-1.
133 @exception NegativeValue: geo_trans_ID needs to be a positive integer.
134
135 @returns List: List with the element objects in the frame.
136 """
137 panel_zone = True
138 if np.size(N_G) == 0: N_G = np.zeros(n_vert_axis-1)
139 if np.size(t_dp) == 0: t_dp = np.zeros(n_vert_axis-1)
140 if np.size(L_b_col) == 0: L_b_col = np.ones(n_vert_axis-1) * (-1.0)
141 if np.size(L_b_beam) == 0: L_b_beam = np.ones(n_hor_axis-1) * (-1.0)
142
143 if np.size(list_col) != n_vert_axis-1: raise WrongDimension()
144 if np.size(list_beam) != n_vert_axis-1: raise WrongDimension()
145 if np.size(N_G) != n_vert_axis-1: raise WrongDimension()
146 if np.size(t_dp) != n_vert_axis-1: raise WrongDimension()
147 if np.size(L_b_col) != n_vert_axis-1: raise WrongDimension()
148 if np.size(L_b_beam) != n_hor_axis-1: raise WrongDimension()
149 if geo_trans_ID < 1: raise NegativeValue()
150
151 half_pz_height = np.zeros(n_vert_axis)
152 if panel_zone:
153 for ii, beam in enumerate(list_beam):
154 half_pz_height[ii+1] = beam.d/2
155
156 node_array = DefineFrameNodes(n_hor_axis, n_vert_axis, storey_width, storey_height, half_pz_height, [0, 0], 1, 1, False)
157
158 beam_column_pzspring = [[], [], []]
159 for xx in range(n_hor_axis):
160 for yy in range(n_vert_axis):
161 node_ID = node_array[xx*n_vert_axis + yy]
162 if yy != 0:
163 # Panel Zone
164 if half_pz_height[yy] == 0:
165 col_j_node_ID = node_ID
166 beam_j_node_ID = node_ID
167 else:
168 tmp_pz = PanelZoneSteelIShapeSkiadopoulos2021(node_ID, list_col[yy-1], list_beam[yy-1], geo_trans_ID, t_dp[yy-1])
169 tmp_pz.CreateMember()
170 col_j_node_ID = IDConvention(node_ID, 5, 1)
171 beam_j_node_ID = IDConvention(node_ID, 8, 1)
172 beam_column_pzspring[2].append(deepcopy(tmp_pz))
173
174 # Column
175 col_i_node_ID = node_array[xx*n_vert_axis + yy - 1]
176 col_mat_i = OffsetNodeIDConvention(col_i_node_ID, "vertical", "i")
177 col_mat_j = OffsetNodeIDConvention(col_j_node_ID, "vertical", "j")
178 ele_ID = col_i_node_ID if panel_zone else -1
179 tmp_col = SpringBasedElementModifiedIMKSteelIShape(col_i_node_ID, col_j_node_ID, list_col[yy-1], geo_trans_ID,
180 col_mat_i, col_mat_j, N_G[yy-1], L_b=L_b_col[yy-1], ele_ID = ele_ID)
181 tmp_col.CreateMember()
182 beam_column_pzspring[1].append(deepcopy(tmp_col))
183
184 if xx != 0:
185 # Beam
186 if half_pz_height[yy] == 0:
187 beam_i_node_ID = node_array[(xx-1)*n_vert_axis + yy]
188 else:
189 beam_i_node_ID = IDConvention(node_array[(xx-1)*n_vert_axis + yy], 2, 1)
190 beam_mat_i = OffsetNodeIDConvention(beam_i_node_ID, "horizontal", "i")
191 beam_mat_j = OffsetNodeIDConvention(beam_j_node_ID, "horizontal", "j")
192 ele_ID = beam_i_node_ID if panel_zone else -1
193 tmp_beam = SpringBasedElementModifiedIMKSteelIShape(beam_i_node_ID, beam_j_node_ID, list_beam[yy-1], geo_trans_ID,
194 beam_mat_i, beam_mat_j, L_b=L_b_beam[xx-1], ele_ID = ele_ID)
195 tmp_beam.CreateMember()
196 beam_column_pzspring[0].append(deepcopy(tmp_beam))
197 else:
198 if fix_support: RigidSupport(node_ID)
199
200
201 if show_plot:
202 opsplt.plot_model("nodes", "elements")
203
204 return beam_column_pzspring
205
206
207def DefineSubassemblageNodes(beam_left_L_cl, beam_right_L_cl, col_top_L_cl, col_bottom_L_cl, depth_col, depth_beam,
208 boundary_condition = True, show_plot = True):
209 """
210 Function that declares and initialises the grid nodes of an interior subassemblage. The panel zone geometry is defined by the two arguments
211 depth_col and depth_beam.
212
213 @param beam_left_L_cl (float): Centerline length of the left beam (excluding the panel zone).
214 @param beam_right_L_cl (float): Centerline length of the right beam (excluding the panle zone).
215 @param col_top_L_cl (float): Centerline length of the top column (excluding the panel zone).
216 @param col_bottom_L_cl (float): Centerline length of the bottom column (excluding the panel zone).
217 @param depth_col (float): Depth of the columns for the panel zone.
218 @param depth_beam (float): Depth of the beams for the panel zone.
219 @param boundary_condition (bool, optional): Option to set already the boundary condition (bottom column pinned, beams fix only y movement).
220 Defaults to True.
221 @param show_plot (bool, optional): Option to show the plot of the nodes declared and initialised. Defaults to True.
222
223 @exception NegativeValue: beam_left_L_cl needs to be positive.
224 @exception NegativeValue: beam_right_L_cl needs to be positive.
225 @exception NegativeValue: col_top_L_cl needs to be positive.
226 @exception NegativeValue: col_bottom_L_cl needs to be positive.
227 @exception NegativeValue: depth_col needs to be positive.
228 @exception NegativeValue: depth_beam needs to be positive.
229
230 @returns list: List with the nodes declared.
231 """
232 # origin is the bottom left corner
233 if beam_left_L_cl < 0: raise NegativeValue()
234 if beam_right_L_cl < 0: raise NegativeValue()
235 if col_top_L_cl < 0: raise NegativeValue()
236 if col_bottom_L_cl < 0: raise NegativeValue()
237 if depth_col < 0: raise NegativeValue()
238 if depth_beam < 0: raise NegativeValue()
239
240 node(12, 0.0, col_bottom_L_cl+depth_beam/2)
241 node(21, beam_left_L_cl+depth_col/2, 0.0)
242 node(22, beam_left_L_cl+depth_col/2, col_bottom_L_cl+depth_beam)
243 node(23, beam_left_L_cl+depth_col/2, col_bottom_L_cl+depth_beam+col_top_L_cl)
244 node(32, beam_left_L_cl+depth_col+beam_right_L_cl, col_bottom_L_cl+depth_beam/2)
245 node_array = [12, 21, 22, 23, 32]
246
247 if boundary_condition:
248 fix(12, 0, 1, 0)
249 fix(32, 0, 1, 0)
250 fix(21, 1, 1, 0)
251
252 if show_plot:
253 plot_nodes(node_array, "Subassemblage geometry template with only nodes", True)
254 plt.grid()
255
256 return node_array
257
258
259# def DefineRCSSubassemblage():
260# # WIP and experimental
261
262
def RigidSupport(int NodeID)
Function that fixes the x, y movements and the rotation of one node.
Definition: Connections.py:9
def OffsetNodeIDConvention(int node_ID, str orientation, str position_i_or_j)
Function used to add node on top of existing ones in the extremes of memebers with springs.
def IDConvention(int prefix, int suffix, n_zeros_between=0)
Function used to construct IDs for elements and offgrid nodes.
def GridIDConvention(int pier_axis, int floor_axis, max_pier=-1, max_floor=-1)
Function used to construct the ID of the nodes in the grid (first nodes that define the geometry of t...
def plot_nodes(list nodes_array, name="Not defined", show_node_ID=True)
Function that plots a set of nodes.
def DefineFrameNodesAndElementsSteelIShape(int n_hor_axis, int n_vert_axis, storey_width, storey_height, list list_col, list list_beam, int geo_trans_ID, N_G=np.array([]), t_dp=np.array([]), L_b_col=np.array([]), L_b_beam=np.array([]), fix_support=True, show_plot=True, panel_zone=True)
WIP (Work In Progress).
def DefineFrameNodes(int n_hor_axis, int n_vert_axis, storey_width, storey_height, half_pz_height=np.array([]), origin=[0, 0], first_hor_axis=1, first_vert_axis=1, show_plot=True)
Function that declares and initialises the grid nodes of a frame.
def DefineSubassemblageNodes(beam_left_L_cl, beam_right_L_cl, col_top_L_cl, col_bottom_L_cl, depth_col, depth_beam, boundary_condition=True, show_plot=True)
Function that declares and initialises the grid nodes of an interior subassemblage.
def Initialize2DModel(data_dir="Results")
Function that initialise the project creating the 2D model with 3 DOF per node and set up a directory...