def test_beam_integration_mid_point_w_steel01(): lp_i = 0.1 lp_j = 0.2 op.wipe() op.model('basic', '-ndm', 2, '-ndf', 3) # 2 dimensions, 3 dof per node section1_id = 1 section2_id = 2 section3_id = 3 uniaxial_steel01_section(section1_id) uniaxial_steel01_section(section2_id) uniaxial_steel01_section(section3_id) integ_tag = 1 op.beamIntegration('HingeMidpoint', integ_tag, section1_id, lp_i, section2_id, lp_j, section3_id) with_force_beam_column = 1 if with_force_beam_column: # Establish nodes bot_node = 1 top_node = 2 transf_tag = 1 op.geomTransf('Linear', transf_tag, *[]) op.node(bot_node, 0., 0.) op.node(top_node, 0., 5.) ele_i = 1 op.element('forceBeamColumn', ele_i, bot_node, top_node, transf_tag, integ_tag)
def add_frames(frames_df, frame_props_df): # function to identify and assign beam and columns their respective tags def determine_tag(label): if 'C' in label: tag = col_transf_tag else: tag = beam_transf_tag return tag # construct a coordinate-transformation object, which transforms beam and column element # stiffness and resisting force from the basic system to the global-coordinate system. op.geomTransf(coordTransf, col_transf_tag, 1, 0, 0) op.geomTransf(coordTransf, beam_transf_tag, 0, 0, 1) # add all the frame elements which are oriented with the major axis frames_df[frames_df.Angle == 0.00].apply(lambda row: op.element('ElasticTimoshenkoBeam' , row.UniqueName, \ row.PointI , row.PointJ, \ E, G , frame_props_df.loc[row.Prop, 'Area'], \ frame_props_df.loc[row.Prop, 'J'] , frame_props_df.loc[row.Prop, 'I33'] , \ frame_props_df.loc[row.Prop, 'I22'] , frame_props_df.loc[row.Prop, 'As3'] , \ frame_props_df.loc[row.Prop, 'As2'] , determine_tag(row.Label) , \ '-mass' , M, massType), axis='columns') # add all the frame elements which are oriented perpandicular to the major axis by switching the properties in the two aixs frames_df[frames_df.Angle == 90.0].apply(lambda row: op.element('ElasticTimoshenkoBeam' , row.UniqueName, \ row.PointI , row.PointJ, \ E, G , frame_props_df.loc[row.Prop, 'Area'], \ frame_props_df.loc[row.Prop, 'J'] , frame_props_df.loc[row.Prop, 'I22'] , \ frame_props_df.loc[row.Prop, 'I33'] , frame_props_df.loc[row.Prop, 'As2'] , \ frame_props_df.loc[row.Prop, 'As3'] , determine_tag(row.Label) , \ '-mass' , M, massType), axis='columns') return
def run(arg_1, arg_2, arg_3, arg_4): ops.reset() ops.wipe() ops.model('basic', '-ndm', 3, '-ndf', 6) ops.node(1, 0.0, 0.0, 0.0) ops.node(2, 0.0, 3.2, 0.0) ops.fix(1, 1, 1, 1, 1, 1, 1) ops.uniaxialMaterial('Concrete01', 1, -80.0e6, -0.002, 0.0, -0.005) ops.section('Fiber', 1, '-GJ', 1) ops.patch('rect', 1, 10, 10, -0.8, -0.1, 0.8, 0.1) ops.geomTransf('Linear', 1, 0, 0, 1) ops.beamIntegration('Legendre', 1, 1, 10) ops.element('dispBeamColumn', 1, 1, 2, 1, 1) ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) ops.load(2, 0, -24586.24, 0, 0, 0, 0) ops.constraints('Plain') ops.numberer('RCM') ops.system('UmfPack') ops.test('NormDispIncr', 1.0e-6, 2000) ops.algorithm('Newton') ops.integrator('LoadControl', 0.01) ops.analysis('Static') ops.analyze(100) ops.wipeAnalysis() ops.loadConst('-time', 0.0) ops.recorder('Node', '-file', 'disp.out', ' -time', '-node', 2, '-dof', 1, 'disp') ops.recorder('Node', '-file', 'react.out', '-time ', '-node', 2, '-dof', 1, 'reaction') ops.timeSeries('Linear', 2) ops.pattern('Plain', 2, 2) ops.load(2, 11500, 0, 0, 0, 0, 0) ops.constraints('Plain') ops.numberer('RCM') ops.system('UmfPack') ops.test('NormDispIncr', 1.0, 2000) ops.algorithm('Newton') ops.integrator('LoadControl', 0.01) ops.analysis('Static') # ops.analyze(100) step = 100 data = np.zeros((step, 2)) for i in range(step): ops.analyze(1) data[i, 0] = ops.nodeDisp(2, 1) data[i, 1] = ops.getLoadFactor(2) * 11500 return data
def define_force_beam_column(ele_i, integ_tag): # Establish nodes bot_node = 1 top_node = 2 transf_tag = 1 op.geomTransf('Linear', transf_tag, *[]) op.node(bot_node, 0., 0.) op.node(top_node, 0., 5.) op.element('forceBeamColumn', ele_i, bot_node, top_node, transf_tag, integ_tag)
def ops_section(): ''' define section ''' # 保护层壳 ops.section('LayeredShell', 1, 4, 2, 50/1000, 2, 50/1000, 2, 50/1000, 2, 50/1000) # 加强区壳 ops.section('LayeredShell', 2, 10, 2, 20/1000, # 保护层 6, 1.28177/1000, # 箍筋层 2, 26.239/1000, # 核心区混凝土 2, 26.239/1000, # 核心区混凝土 2, 26.239/1000, # 核心区混凝土 2, 26.239/1000, # 核心区混凝土 2, 26.239/1000, # 核心区混凝土 2, 26.239/1000, # 核心区混凝土 6, 1.28177/1000, # 箍筋层 2, 20/1000 # 保护层 ) # 中部壳 ops.section('LayeredShell', 3, 12, 2, 20/1000, # 保护层 6, 0.65345127/1000, # 箍筋层 7, 0.6544985/1000, # 纵筋层 2, 26.2274/1000, # 核心区混凝土 2, 26.2274/1000, # 核心区混凝土 2, 26.2274/1000, # 核心区混凝土 2, 26.2274/1000, # 核心区混凝土 2, 26.2274/1000, # 核心区混凝土 2, 26.2274/1000, # 核心区混凝土 7, 0.6544985/1000, # 纵筋层 6, 0.65345127/1000, # 箍筋层 2, 20/1000 # 保护层 ) ops.section('Fiber', 4, '-GJ', 1) # 端部 GFRP 拉锁 ops.patch('circ', 3, 10, 10, 0, 0, 0, 0.01414, 0, 360) # 端部 SFCB 纵筋 ops.patch('circ', 4, 10, 10, 0, 0.015, 0, 0.01414, 0, 360) ops.beamIntegration('Legendre', 1, 1, 9) # 0 1 0 # 端部 SFCB 拉锁 ops.section('Fiber', 5, '-GJ', 1) ops.patch('circ', 4, 10, 10, 0, 0, 0, 0.01414, 0, 360) ops.beamIntegration('Legendre', 2, 2, 9) ops.geomTransf('Linear', 1, 0, 1, 0)
def ops_element(): ops.beamIntegration('Legendre', 1, 2, 9) ops.geomTransf('Linear', 1, 0, -1, 0) i = 1 for _i in range(0, 56, 6): for _j in range(_i + 2, _i + 5): # print(f'element = {i}, node = {_j},{_j + 1},{_j + 7},{_j + 6 }') ops.element("ShellNLDKGQ", i, _j, _j + 1, _j + 7, _j + 6, 1) i = i + 1 for _k in range(1, 61, 6): # print(f'element = {i}, node = {_k},{_k + 6}') ops.element('dispBeamColumn', i, _k, _k + 6, 1, 1) i = i + 1 for _l in range(6, 66, 6): # print(f'element = {i}, node = {_l},{_l + 6}') ops.element('dispBeamColumn', i, _l, _l + 6, 1, 1) i = i + 1
def elements(Nnodes, L, A, E, Iz): # Define the number of elements: Nelems = Nnodes - 1 ########################################################################## # Define the geometric nonlinearity: TransfTag = 1 ops.geomTransf('Corotational', TransfTag) ########################################################################## # Define the elements: [ ops.element('elasticBeamColumn', i + 1, *[i + 1, i + 2], A, E, Iz, TransfTag) for i in range(Nelems) ]
def define_geometry(self, nodes, elements, fixities, num_integ=10): ''' Define geometry of the structure (all dimensions are in mm). Args: nodes: A list of nodes in a form [node_tag, coord1, coord2]. elements: A list of elements in a form [ele_tag, node1, node2, disc]. fixities: A list of fixities in a form [node, x, y, z]. num_integ: Number of integration points along each element (default=10) ''' self.nodes = nodes self.elements = elements self.fixities = fixities if self.section == None: raise Exception('No section is defined.') ops.geomTransf('PDelta', 1) ops.beamIntegration('Lobatto', 1, 1, num_integ) for nd in self.nodes: ops.node(*nd) for el in self.elements: ele_tag, node1, node2, disc = el DiscretizeMember.DiscretizeMember(node1, node2, disc, 'forceBeamColumn', 1, 1, nodeTag=len(ops.getNodeTags()) + 1, eleTag=len(ops.getEleTags()) + 1) for fx in self.fixities: ops.fix(*fx)
def RunAnalysis(): AnalysisType = 'Pushover' # Pushover Gravity ## ------------------------------ ## Start of model generation ## ----------------------------- # remove existing model ops.wipe() # set modelbuilder ops.model('basic', '-ndm', 2, '-ndf', 3) import math ############################################ ### Units and Constants ################### ############################################ inch = 1 kip = 1 sec = 1 # Dependent units sq_in = inch * inch ksi = kip / sq_in ft = 12 * inch # Constants g = 386.2 * inch / (sec * sec) pi = math.acos(-1) ####################################### ##### Dimensions ####################################### # Dimensions Input H_story = 10.0 * ft W_bayX = 16.0 * ft W_bayY_ab = 5.0 * ft + 10.0 * inch W_bayY_bc = 8.0 * ft + 4.0 * inch W_bayY_cd = 5.0 * ft + 10.0 * inch # Calculated dimensions W_structure = W_bayY_ab + W_bayY_bc + W_bayY_cd ################ ### Material ################ # Steel02 Material matTag = 1 matConnAx = 2 matConnRot = 3 Fy = 60.0 * ksi # Yield stress Es = 29000.0 * ksi # Modulus of Elasticity of Steel v = 0.2 # Poisson's ratio Gs = Es / (1 + v) # Shear modulus b = 0.10 # Strain hardening ratio params = [18.0, 0.925, 0.15] # R0,cR1,cR2 R0 = 18.0 cR1 = 0.925 cR2 = 0.15 a1 = 0.05 a2 = 1.00 a3 = 0.05 a4 = 1.0 sigInit = 0.0 alpha = 0.05 ops.uniaxialMaterial('Steel02', matTag, Fy, Es, b, R0, cR1, cR2, a1, a2, a3, a4, sigInit) # ################## # ## Sections # ################## colSecTag1 = 1 colSecTag2 = 2 beamSecTag1 = 3 beamSecTag2 = 4 beamSecTag3 = 5 # COMMAND: section('WFSection2d', secTag, matTag, d, tw, bf, tf, Nfw, Nff) ops.section('WFSection2d', colSecTag1, matTag, 10.5 * inch, 0.26 * inch, 5.77 * inch, 0.44 * inch, 15, 16) # outer Column ops.section('WFSection2d', colSecTag2, matTag, 10.5 * inch, 0.26 * inch, 5.77 * inch, 0.44 * inch, 15, 16) # Inner Column ops.section('WFSection2d', beamSecTag1, matTag, 8.3 * inch, 0.44 * inch, 8.11 * inch, 0.685 * inch, 15, 15) # outer Beam ops.section('WFSection2d', beamSecTag2, matTag, 8.2 * inch, 0.40 * inch, 8.01 * inch, 0.650 * inch, 15, 15) # Inner Beam ops.section('WFSection2d', beamSecTag3, matTag, 8.0 * inch, 0.40 * inch, 7.89 * inch, 0.600 * inch, 15, 15) # Inner Beam # Beam size - W10x26 Abeam = 7.61 * inch * inch IbeamY = 144. * (inch**4) # Inertia along horizontal axis IbeamZ = 14.1 * (inch**4) # inertia along vertical axis # BRB input data Acore = 2.25 * inch Aend = 10.0 * inch LR_BRB = 0.55 # ########################### # ##### Nodes # ########################### # Create All main nodes ops.node(1, 0.0, 0.0) ops.node(2, W_bayX, 0.0) ops.node(3, 2 * W_bayX, 0.0) ops.node(11, 0.0, H_story) ops.node(12, W_bayX, H_story) ops.node(13, 2 * W_bayX, H_story) ops.node(21, 0.0, 2 * H_story) ops.node(22, W_bayX, 2 * H_story) ops.node(23, 2 * W_bayX, 2 * H_story) ops.node(31, 0.0, 3 * H_story) ops.node(32, W_bayX, 3 * H_story) ops.node(33, 2 * W_bayX, 3 * H_story) # Beam Connection nodes ops.node(1101, 0.0, H_story) ops.node(1201, W_bayX, H_story) ops.node(1202, W_bayX, H_story) ops.node(1301, 2 * W_bayX, H_story) ops.node(2101, 0.0, 2 * H_story) ops.node(2201, W_bayX, 2 * H_story) ops.node(2202, W_bayX, 2 * H_story) ops.node(2301, 2 * W_bayX, 2 * H_story) ops.node(3101, 0.0, 3 * H_story) ops.node(3201, W_bayX, 3 * H_story) ops.node(3202, W_bayX, 3 * H_story) ops.node(3301, 2 * W_bayX, 3 * H_story) # ############### # Constraints # ############### ops.fix(1, 1, 1, 1) ops.fix(2, 1, 1, 1) ops.fix(3, 1, 1, 1) # ####################### # ### Elements # ####################### # ### Assign beam-integration tags ColIntTag1 = 1 ColIntTag2 = 2 BeamIntTag1 = 3 BeamIntTag2 = 4 BeamIntTag3 = 5 ops.beamIntegration('Lobatto', ColIntTag1, colSecTag1, 4) ops.beamIntegration('Lobatto', ColIntTag2, colSecTag2, 4) ops.beamIntegration('Lobatto', BeamIntTag1, beamSecTag1, 4) ops.beamIntegration('Lobatto', BeamIntTag2, beamSecTag2, 4) ops.beamIntegration('Lobatto', BeamIntTag3, beamSecTag3, 4) # Assign geometric transformation ColTransfTag = 1 BeamTranfTag = 2 ops.geomTransf('PDelta', ColTransfTag) ops.geomTransf('Linear', BeamTranfTag) # Assign Elements ############## # ## Add non-linear column elements ops.element('forceBeamColumn', 1, 1, 11, ColTransfTag, ColIntTag1, '-mass', 0.0) ops.element('forceBeamColumn', 2, 2, 12, ColTransfTag, ColIntTag2, '-mass', 0.0) ops.element('forceBeamColumn', 3, 3, 13, ColTransfTag, ColIntTag1, '-mass', 0.0) ops.element('forceBeamColumn', 11, 11, 21, ColTransfTag, ColIntTag1, '-mass', 0.0) ops.element('forceBeamColumn', 12, 12, 22, ColTransfTag, ColIntTag2, '-mass', 0.0) ops.element('forceBeamColumn', 13, 13, 23, ColTransfTag, ColIntTag1, '-mass', 0.0) ops.element('forceBeamColumn', 21, 21, 31, ColTransfTag, ColIntTag1, '-mass', 0.0) ops.element('forceBeamColumn', 22, 22, 32, ColTransfTag, ColIntTag2, '-mass', 0.0) ops.element('forceBeamColumn', 23, 23, 33, ColTransfTag, ColIntTag1, '-mass', 0.0) # ### Add linear main beam elements, along x-axis #element('elasticBeamColumn', 101, 1101, 1201, Abeam, Es, Gs, Jbeam, IbeamY, IbeamZ, beamTransfTag, '-mass', 0.0) ops.element('forceBeamColumn', 101, 1101, 1201, BeamTranfTag, BeamIntTag1, '-mass', 0.0) ops.element('forceBeamColumn', 102, 1202, 1301, BeamTranfTag, BeamIntTag1, '-mass', 0.0) ops.element('forceBeamColumn', 201, 2101, 2201, BeamTranfTag, BeamIntTag2, '-mass', 0.0) ops.element('forceBeamColumn', 202, 2202, 2301, BeamTranfTag, BeamIntTag2, '-mass', 0.0) ops.element('forceBeamColumn', 301, 3101, 3201, BeamTranfTag, BeamIntTag3, '-mass', 0.0) ops.element('forceBeamColumn', 302, 3202, 3301, BeamTranfTag, BeamIntTag3, '-mass', 0.0) # Assign constraints between beam end nodes and column nodes (RIgid beam column connections) ops.equalDOF(11, 1101, 1, 2, 3) ops.equalDOF(12, 1201, 1, 2, 3) ops.equalDOF(12, 1202, 1, 2, 3) ops.equalDOF(13, 1301, 1, 2, 3) ops.equalDOF(21, 2101, 1, 2, 3) ops.equalDOF(22, 2201, 1, 2, 3) ops.equalDOF(22, 2202, 1, 2, 3) ops.equalDOF(23, 2301, 1, 2, 3) ops.equalDOF(31, 3101, 1, 2, 3) ops.equalDOF(32, 3201, 1, 2, 3) ops.equalDOF(32, 3202, 1, 2, 3) ops.equalDOF(33, 3301, 1, 2, 3) AllNodes = ops.getNodeTags() massX = 0.49 for nodes in AllNodes: ops.mass(nodes, massX, massX, 0.00001) ################ ## Gravity Load ################ # create TimeSeries ops.timeSeries("Linear", 1) # create a plain load pattern ops.pattern("Plain", 1, 1) # Create the nodal load ops.load(11, 0.0, -5.0 * kip, 0.0) ops.load(12, 0.0, -6.0 * kip, 0.0) ops.load(13, 0.0, -5.0 * kip, 0.0) ops.load(21, 0., -5. * kip, 0.0) ops.load(22, 0., -6. * kip, 0.0) ops.load(23, 0., -5. * kip, 0.0) ops.load(31, 0., -5. * kip, 0.0) ops.load(32, 0., -6. * kip, 0.0) ops.load(33, 0., -5. * kip, 0.0) ############################### ### PUSHOVER ANALYSIS ############################### if (AnalysisType == "Pushover"): print("<<<< Running Pushover Analysis >>>>") # Create load pattern for pushover analysis # create a plain load pattern ops.pattern("Plain", 2, 1) ops.load(11, 1.61, 0.0, 0.0) ops.load(21, 3.22, 0.0, 0.0) ops.load(31, 4.83, 0.0, 0.0) ControlNode = 31 ControlDOF = 1 MaxDisp = 0.15 * H_story DispIncr = 0.1 NstepsPush = int(MaxDisp / DispIncr) Model = 'test' LoadCase = 'Pushover' dt = 0.2 opp.createODB(Model, LoadCase, Nmodes=3) ops.system("ProfileSPD") ops.numberer("Plain") ops.constraints("Plain") ops.integrator("DisplacementControl", ControlNode, ControlDOF, DispIncr) ops.algorithm("Newton") ops.test('NormUnbalance', 1e-8, 10) ops.analysis("Static") # analyze(NstepsPush) ops.analyze(100) print("Pushover analysis complete")
def test_ElasticFrame(): # # some parameter # PI = 2.0 * asin(1.0) g = 386.4 ft = 12.0 Load1 = 1185.0 Load2 = 1185.0 Load3 = 970.0 # floor masses m1 = Load1 / (4 * g) # 4 nodes per floor m2 = Load2 / (4 * g) m3 = Load3 / (4 * g) # floor distributed loads w1 = Load1 / (90 * ft) # frame 90 ft long w2 = Load2 / (90 * ft) w3 = Load3 / (90 * ft) # ------------------------------ # Start of model generation # ------------------------------ # Remove existing model ops.wipe() # Create ModelBuilder (with two-dimensions and 2 DOF/node) ops.model('BasicBuilder', '-ndm', 2, '-ndf', 3) # Create nodes # ------------ # Create nodes & add to Domain - command: node nodeId xCrd yCrd <-mass massX massY massRz> # NOTE: mass in optional ops.node(1, 0.0, 0.0) ops.node(2, 360.0, 0.0) ops.node(3, 720.0, 0.0) ops.node(4, 1080.0, 0.0) ops.node(5, 0.0, 162.0, '-mass', m1, m1, 0.0) ops.node(6, 360.0, 162.0, '-mass', m1, m1, 0.0) ops.node(7, 720.0, 162.0, '-mass', m1, m1, 0.0) ops.node(8, 1080.0, 162.0, '-mass', m1, m1, 0.0) ops.node(9, 0.0, 324.0, '-mass', m2, m2, 0.0) ops.node(10, 360.0, 324.0, '-mass', m2, m2, 0.0) ops.node(11, 720.0, 324.0, '-mass', m2, m2, 0.0) ops.node(12, 1080.0, 324.0, '-mass', m2, m2, 0.0) ops.node(13, 0.0, 486.0, '-mass', m3, m3, 0.0) ops.node(14, 360.0, 486.0, '-mass', m3, m3, 0.0) ops.node(15, 720.0, 486.0, '-mass', m3, m3, 0.0) ops.node(16, 1080.0, 486.0, '-mass', m3, m3, 0.0) # the boundary conditions - command: fix nodeID xResrnt? yRestrnt? rZRestrnt? ops.fix(1, 1, 1, 1) ops.fix(2, 1, 1, 1) ops.fix(3, 1, 1, 1) ops.fix(4, 1, 1, 1) # Define geometric transformations for beam-column elements ops.geomTransf('Linear', 1) # beams ops.geomTransf('PDelta', 2) # columns # Define elements # Create elastic beam-column - command: element elasticBeamColumn eleID node1 node2 A E Iz geomTransfTag # Define the Columns ops.element('elasticBeamColumn', 1, 1, 5, 75.6, 29000.0, 3400.0, 2) # W14X257 ops.element('elasticBeamColumn', 2, 5, 9, 75.6, 29000.0, 3400.0, 2) # W14X257 ops.element('elasticBeamColumn', 3, 9, 13, 75.6, 29000.0, 3400.0, 2) # W14X257 ops.element('elasticBeamColumn', 4, 2, 6, 91.4, 29000.0, 4330.0, 2) # W14X311 ops.element('elasticBeamColumn', 5, 6, 10, 91.4, 29000.0, 4330.0, 2) # W14X311 ops.element('elasticBeamColumn', 6, 10, 14, 91.4, 29000.0, 4330.0, 2) # W14X311 ops.element('elasticBeamColumn', 7, 3, 7, 91.4, 29000.0, 4330.0, 2) # W14X311 ops.element('elasticBeamColumn', 8, 7, 11, 91.4, 29000.0, 4330.0, 2) # W14X311 ops.element('elasticBeamColumn', 9, 11, 15, 91.4, 29000.0, 4330.0, 2) # W14X311 ops.element('elasticBeamColumn', 10, 4, 8, 75.6, 29000.0, 3400.0, 2) # W14X257 ops.element('elasticBeamColumn', 11, 8, 12, 75.6, 29000.0, 3400.0, 2) # W14X257 ops.element('elasticBeamColumn', 12, 12, 16, 75.6, 29000.0, 3400.0, 2) # W14X257 # Define the Beams ops.element('elasticBeamColumn', 13, 5, 6, 34.7, 29000.0, 5900.0, 1) # W33X118 ops.element('elasticBeamColumn', 14, 6, 7, 34.7, 29000.0, 5900.0, 1) # W33X118 ops.element('elasticBeamColumn', 15, 7, 8, 34.7, 29000.0, 5900.0, 1) # W33X118 ops.element('elasticBeamColumn', 16, 9, 10, 34.2, 29000.0, 4930.0, 1) # W30X116 ops.element('elasticBeamColumn', 17, 10, 11, 34.2, 29000.0, 4930.0, 1) # W30X116 ops.element('elasticBeamColumn', 18, 11, 12, 34.2, 29000.0, 4930.0, 1) # W30X116 ops.element('elasticBeamColumn', 19, 13, 14, 20.1, 29000.0, 1830.0, 1) # W24X68 ops.element('elasticBeamColumn', 20, 14, 15, 20.1, 29000.0, 1830.0, 1) # W24X68 ops.element('elasticBeamColumn', 21, 15, 16, 20.1, 29000.0, 1830.0, 1) # W24X68 # Define loads for Gravity Analysis # --------------------------------- #create a Linear TimeSeries (load factor varies linearly with time): command timeSeries Linear tag ops.timeSeries('Linear', 1) # Create a Plain load pattern with a linear TimeSeries: # command pattern Plain tag timeSeriesTag { loads } ops.pattern('Plain', 1, 1) ops.eleLoad('-ele', 13, 14, 15, '-type', '-beamUniform', -w1) ops.eleLoad('-ele', 16, 17, 18, '-type', '-beamUniform', -w2) ops.eleLoad('-ele', 19, 20, 21, '-type', '-beamUniform', -w3) # --------------------------------- # Create Analysis for Gravity Loads # --------------------------------- # Create the system of equation, a SPD using a band storage scheme ops.system('BandSPD') # Create the DOF numberer, the reverse Cuthill-McKee algorithm ops.numberer('RCM') # Create the constraint handler, a Plain handler is used as h**o constraints ops.constraints('Plain') # Create the integration scheme, the LoadControl scheme using steps of 1.0 ops.integrator('LoadControl', 1.0) # Create the solution algorithm, a Linear algorithm is created ops.test('NormDispIncr', 1.0e-10, 6) ops.algorithm('Newton') # create the analysis object ops.analysis('Static') # --------------------------------- # Perform Gravity Analysis # --------------------------------- ops.analyze(1) # print "node 5: nodeDisp 5" # print "node 6: nodeDisp 6" # print "node 7: nodeDisp 7" # print "node 8: nodeDisp 8" # print "node 9: nodeDisp 9" # print "node 10: nodeDisp 10" # --------------------------------- # Check Equilibrium # --------------------------------- # invoke command to determine nodal reactions ops.reactions() node1Rxn = ops.nodeReaction( 1 ) # nodeReaction command returns nodal reactions for specified node in a list node2Rxn = ops.nodeReaction(2) node3Rxn = ops.nodeReaction(3) node4Rxn = ops.nodeReaction(4) inputedFy = -Load1 - Load2 - Load3 # loads added negative Fy diren to ele computedFx = node1Rxn[0] + node2Rxn[0] + node3Rxn[0] + node4Rxn[0] computedFy = node1Rxn[1] + node2Rxn[1] + node3Rxn[1] + node4Rxn[1] print("\nEqilibrium Check After Gravity:") print("SumX: Inputed: 0.0 + Computed:", computedFx, " = ", 0.0 + computedFx) print("SumY: Inputed: ", inputedFy, " + Computed: ", computedFy, " = ", inputedFy + computedFy) # --------------------------------- # Lateral Load # --------------------------------- # gravity loads constant and time in domain to e 0.0 ops.loadConst('-time', 0.0) ops.timeSeries('Linear', 2) ops.pattern('Plain', 2, 2) ops.load(13, 220.0, 0.0, 0.0) ops.load(9, 180.0, 0.0, 0.0) ops.load(5, 90.0, 0.0, 0.0) # --------------------------------- # Create Recorder # --------------------------------- #recorder Element -file EleForces.out -ele 1 4 7 10 forces # --------------------------------- # Perform Lateral Analysis # --------------------------------- ops.analyze(1) # print "node 5: nodeDisp 5" # print "node 6: nodeDisp 6" # print "node 7: nodeDisp 7" # print "node 8: nodeDisp 8" # print "node 9: nodeDisp 9" # print "node 10: nodeDisp 10" # --------------------------------- # Check Equilibrium # --------------------------------- ops.reactions() node1Rxn = ops.nodeReaction( 1 ) # =nodeReaction( command returns nodal reactions for specified node in a list node2Rxn = ops.nodeReaction(2) node3Rxn = ops.nodeReaction(3) node4Rxn = ops.nodeReaction(4) inputedFx = 220.0 + 180.0 + 90.0 computedFx = node1Rxn[0] + node2Rxn[0] + node3Rxn[0] + node4Rxn[0] computedFy = node1Rxn[1] + node2Rxn[1] + node3Rxn[1] + node4Rxn[1] print("\nEqilibrium Check After Lateral Loads:") print("SumX: Inputed: ", inputedFx, " + Computed: ", computedFx, " = ", inputedFx + computedFx) print("SumY: Inputed: ", inputedFy, " + Computed: ", computedFy, " = ", inputedFy + computedFy) # print ele information for columns at base #print ele 1 4 7 10 # --------------------------------- # Check Eigenvalues # --------------------------------- eigenValues = ops.eigen(5) print("\nEigenvalues:") eigenValue = eigenValues[0] T1 = 2 * PI / sqrt(eigenValue) print("T1 = ", T1) eigenValue = eigenValues[1] T2 = 2 * PI / sqrt(eigenValue) print("T2 = ", T2) eigenValue = eigenValues[2] T3 = 2 * PI / sqrt(eigenValue) print("T3 = ", T3) eigenValue = eigenValues[3] T4 = 2 * PI / sqrt(eigenValue) print("T4 = ", T4) eigenValue = eigenValues[4] T5 = 2 * PI / sqrt(eigenValue) print("T5 = ", T5) assert abs(T1 - 1.0401120938612862) < 1e-12 and abs( T2 - 0.3526488583606463 ) < 1e-12 and abs(T3 - 0.1930409642350476) < 1e-12 and abs( T4 - 0.15628823050715784) < 1e-12 and abs(T5 - 0.13080166151268388) < 1e-12 #recorder Node -file eigenvector.out -nodeRange 5 16 -dof 1 2 3 eigen 0 #record print("==========================")
ops.node(4, Lx, Ly, Lz) ops.fix(1, 1, 1, 1, 1, 1, 1) lmass = 200. ops.mass(2, lmass, lmass, lmass, 0.001, 0.001, 0.001) ops.mass(3, lmass, lmass, lmass, 0.001, 0.001, 0.001) ops.mass(4, lmass, lmass, lmass, 0.001, 0.001, 0.001) gTTagz = 1 gTTagx = 2 gTTagy = 3 coordTransf = 'Linear' ops.geomTransf(coordTransf, gTTagz, 0., -1., 0.) ops.geomTransf(coordTransf, gTTagx, 0., -1., 0.) ops.geomTransf(coordTransf, gTTagy, 1., 0., 0.) ops.element('elasticBeamColumn', 1, 1, 2, A, E, G, J, Iy, Iz, gTTagz) ops.element('elasticBeamColumn', 2, 2, 3, A, E, G, J, Iy, Iz, gTTagx) ops.element('elasticBeamColumn', 3, 3, 4, A, E, G, J, Iy, Iz, gTTagy) Ew = {} Px = -4.e1 Py = -2.5e1 Pz = -3.e1 ops.timeSeries('Constant', 1) ops.pattern('Plain', 1, 1)
#---------------------------------------------------------- # create pile nodes #---------------------------------------------------------- # pile nodes created with 3 dimensions, 6 degrees of freedom op.model('basic', '-ndm', 3, '-ndf', 6) # create pile nodes for i in range(1, nNodePile + 1): zCoord = eleSize * i op.node(i + 200, 0.0, 0.0, zCoord) print("Finished creating all pile nodes...") # create coordinate-transformation object op.geomTransf('Linear', 1, 0.0, -1.0, 0.0) # create fixity at pile head (location of loading) op.fix(200 + nNodePile, 0, 1, 0, 1, 0, 1) # create fixities for remaining pile nodes for i in range(201, 200 + nNodePile): op.fix(i, 0, 1, 0, 1, 0, 1) print("Finished creating all pile node fixities...") #---------------------------------------------------------- # define equal dof between pile and spring nodes #---------------------------------------------------------- for i in range(1, nNodeEmbed + 1):
E = 200.e9 Ep = {1: [E, Acol, IzCol], 2: [E, Acol, IzCol], 3: [E, Agir, IzGir]} ops.node(1, 0., 0.) ops.node(2, 0., colL) ops.node(3, girL, 0.) ops.node(4, girL, colL) ops.fix(1, 1, 1, 1) ops.fix(3, 1, 1, 0) ops.geomTransf('Linear', 1) # columns ops.element('elasticBeamColumn', 1, 1, 2, Acol, E, IzCol, 1) ops.element('elasticBeamColumn', 2, 3, 4, Acol, E, IzCol, 1) # girder ops.element('elasticBeamColumn', 3, 2, 4, Agir, E, IzGir, 1) Px = 2.e+3 Wy = -10.e+3 Wx = 0. Ew = {3: ['-beamUniform', Wy, Wx]} ops.timeSeries('Constant', 1) ops.pattern('Plain', 1, 1)
def get_multi_pile_m( pile_layout, cap_edge=0, cap_thickness=2, pile_z0=-2.5, pile_z1=-30, pile_d=2, m0=7500000, top_f=0.0, top_h=0.0, top_m=0.0 ): if cap_edge == 0: if pile_d <= 1: cap_edge = max(0.25, 0.5 * pile_d) else: cap_edge = max(0.5, 0.3 * pile_d) cap_w = max(pile_layout[0]) - min(pile_layout[0]) + pile_d + cap_edge * 2 cap_l = max(pile_layout[1]) - min(pile_layout[1]) + pile_d + cap_edge * 2 top_f += cap_w * cap_l * cap_thickness * 26e3 # 承台自重 top_f += (cap_w * cap_l) * (-pile_z0 - cap_thickness) * 15e3 # 盖梁重量 pile_rows = len(pile_layout[1]) # 桩排数 top_f /= pile_rows # 桩顶力分配 top_h /= pile_rows # 桩顶水平力分配 top_m /= pile_rows # 桩顶弯矩分配 cap_i = cap_l * cap_thickness ** 3 / 12 / pile_rows # 承台横向刚度 pile_h = pile_z0 - pile_z1 pile_a = np.pi * (pile_d / 2) ** 2 pile_i = np.pi * pile_d ** 4 / 64 pile_b1 = 0.9 * (1.5 + 0.5 / pile_d) * 1 * pile_d # 建立模型 ops.wipe() ops.model('basic', '-ndm', 2, '-ndf', 3) # 建立节点 cap_bot = pile_z0 # ops.node(1, 0, cap_top) # 承台竖向节点 if 0 not in pile_layout[0]: ops.node(2, 0, cap_bot) # 建立桩基节点 node_z = np.linspace(pile_z0, pile_z1, elem_num + 1) for i, j in enumerate(pile_layout[0]): node_start = 100 + i * 300 for m, n in enumerate(node_z): ops.node(node_start + m + 1, j, n) ops.node(node_start + m + 151, j, n) nodes = {} for i in ops.getNodeTags(): nodes[i] = ops.nodeCoord(i) # 建立约束 for i, j in enumerate(pile_layout[0]): node_start = 100 + i * 300 for m, n in enumerate(node_z): ops.fix(node_start + m + 151, 1, 1, 1) if n == node_z[-1]: ops.fix(node_start + m + 1, 1, 1, 1) # 建立材料 for i in range(len(node_z)): pile_depth = i * (pile_h / elem_num) pile_depth_nominal = 10 if pile_depth <= 10 else pile_depth soil_k = m0 * pile_depth_nominal * pile_b1 * (pile_h / elem_num) if i == 0: ops.uniaxialMaterial('Elastic', 1 + i, soil_k / 2) continue ops.uniaxialMaterial('Elastic', 1 + i, soil_k) # 装配 ops.geomTransf('Linear', 1) # 建立单元 if len(pile_layout[0]) > 1: # 承台横向单元 cap_nodes = [] for i in nodes: if nodes[i][1] == cap_bot: if len(cap_nodes) == 0: cap_nodes.append(i) elif nodes[i][0] != nodes[cap_nodes[-1]][0]: cap_nodes.append(i) cap_nodes = sorted(cap_nodes, key=lambda x: nodes[x][0]) for i, j in enumerate(cap_nodes[:-1]): ops.element('elasticBeamColumn', 10 + i, j, cap_nodes[i+1], cap_l * cap_thickness, 3e10, cap_i, 1) pile_elem = [] for i, j in enumerate(pile_layout[0]): # 桩基单元 node_start = 100 + i * 300 pile_elem_i = [] for m, n in enumerate(node_z): if n != pile_z1: ops.element('elasticBeamColumn', node_start + m + 1, node_start + m + 1, node_start + m + 2, pile_a, 3e10, pile_i, 1) pile_elem_i.append(node_start + m + 1) ops.element('zeroLength', node_start + m + 151, node_start + m + 151, node_start + m + 1, '-mat', 1 + m, '-dir', 1) pile_elem.append(pile_elem_i) ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) for i in nodes: if nodes[i] == [0, pile_z0]: ops.load(i, -top_h, -top_f, top_m) # 加载 ops.system('BandGeneral') ops.numberer('Plain') ops.constraints('Plain') ops.integrator('LoadControl', 0.01) ops.test('EnergyIncr', 1e-6, 200) ops.algorithm('Newton') ops.analysis('Static') ops.analyze(100) node_disp = {} for i in ops.getNodeTags(): node_disp[i] = [j * 1000 for j in ops.nodeDisp(i)] elem_m = {} for i in pile_elem: for j in i: elem_m[j] = [k / 1000 for k in ops.eleForce(j)] plt.figure() for i, j in enumerate(pile_elem): plt.subplot(f'1{len(pile_elem)}{i+1}') if i == 0: plt.ylabel('Pile Depth(m)') node_disp_x = [] for m, n in enumerate(j): node_1 = ops.eleNodes(n)[0] if m == 0: plt.plot([0, node_disp[node_1][0]], [nodes[node_1][1], nodes[node_1][1]], linewidth=1.5, color='grey') else: plt.plot([0, node_disp[node_1][0]], [nodes[node_1][1], nodes[node_1][1]], linewidth=0.7, color='grey') node_disp_x.append(node_disp[node_1][0]) for m, n in enumerate(j): node_1 = ops.eleNodes(n)[0] if abs(node_disp[node_1][0]) == max([abs(i) for i in node_disp_x]): side = 1 if node_disp[node_1][0] > 0 else -1 plt.annotate(f'{node_disp[node_1][0]:.1f} mm', xy=(node_disp[node_1][0], nodes[node_1][1]), xytext=(0.4 + 0.1 * side, 0.5), textcoords='axes fraction', bbox=dict(boxstyle="round", fc="0.8"), arrowprops=dict(arrowstyle='->', connectionstyle=f"arc3,rad={side * 0.3}")) break plt.plot([0, 0], [node_z[0], node_z[-1]], linewidth=1.5, color='dimgray') plt.plot(node_disp_x, node_z[:-1], linewidth=1.5, color='midnightblue') plt.xlabel(f'Displacement_{i+1} (mm)') plt.show() plt.figure() for i, j in enumerate(pile_elem): plt.subplot(f'1{len(pile_elem)}{i + 1}') if i == 0: plt.ylabel('Pile Depth(m)') elem_mi = [] for m, n in enumerate(j): node_1 = ops.eleNodes(n)[0] if m == 0: plt.plot([0, elem_m[n][2]], [nodes[node_1][1], nodes[node_1][1]], linewidth=1.5, color='grey') else: plt.plot([0, elem_m[n][2]], [nodes[node_1][1], nodes[node_1][1]], linewidth=0.7, color='grey') elem_mi.append(elem_m[n][2]) for m, n in enumerate(j): node_1 = ops.eleNodes(n)[0] if abs(elem_m[n][2]) == max([abs(i) for i in elem_mi]): side = 1 if elem_m[n][2] > 0 else -1 plt.annotate(f'{elem_m[n][2]:.1f} kN.m', xy=(elem_m[n][2], nodes[node_1][1]), xytext=(0.4 + 0.1 * side, 0.5), textcoords='axes fraction', bbox=dict(boxstyle="round", fc="0.8"), arrowprops=dict(arrowstyle='->', connectionstyle=f"arc3,rad={side * 0.3}")) break plt.plot([0, 0], [node_z[0], node_z[-1]], linewidth=1.5, color='dimgray') plt.plot(elem_mi, node_z[:-1], linewidth=1.5, color='brown') plt.xlabel(f'Moment_{i + 1} (kN.m)') plt.show() return pile_elem, elem_m
nfZ = 4 # number of fibers for concrete in z-direction op.section('Fiber', ColSecTag) op.patch('quad', IDconcU, nfZ, nfY, -coverY, coverZ, -coverY, -coverZ, coverY, -coverZ, coverY, coverZ) # Define the concrete patch op.layer('straight', IDreinf, numBarsCol, barAreaCol, -coreY, coreZ, -coreY, -coreZ) op.layer('straight', IDreinf, numBarsCol, barAreaCol, coreY, coreZ, coreY, -coreZ) # BEAM section: op.section('Elastic', BeamSecTag, Ec, ABeam, IzBeam) # elastic beam section) ColTransfTag = 1 BeamTransfTag = 2 op.geomTransf('Linear', ColTransfTag) op.geomTransf('Linear', BeamTransfTag) numIntgrPts = 5 op.element('nonlinearBeamColumn', 1, 1, 3, numIntgrPts, ColSecTag, ColTransfTag) op.element('nonlinearBeamColumn', 2, 2, 4, numIntgrPts, ColSecTag, ColTransfTag) op.element('nonlinearBeamColumn', 3, 3, 4, numIntgrPts, BeamSecTag, BeamTransfTag) op.recorder('Node', '-file', 'Data-4-inelasticFiber/DFree.out', '-time', '-node', 3, 4, '-dof', 1, 2, 3, 'disp') op.recorder('Node', '-file', 'Data-4-inelasticFiber/DBase.out', '-time',
def main(): """ Create a Cantilever Problem """ ops.wipe() ops.model('basic', '-ndm', 2, '-ndf', 3) height = 5.0 nElem = 20 ElemLength = height / nElem nodeID = [] Ycoord = 0 for i in range(nElem + 1): nodeID.append(i) ops.node(i, 0.0, Ycoord) Ycoord += ElemLength IDctrlNode = i ops.fix(0, 1, 1, 1) ops.geomTransf('Linear', 1) concrete = 'Concrete04' steel = 'Steel02' matTAGConc = 319 matTAGSteel = 312 fcc = -20000 ec2c = -0.002 ecu2c = -0.0035 Ec = 30000000 fct = 2200 et = 0.001 fy = 500000 E0 = 200000000 b = 0.01 ops.uniaxialMaterial(concrete, matTAGConc, fcc, ec2c, ecu2c, Ec, fct, et) ops.uniaxialMaterial(steel, matTAGSteel, fy, E0, b, 20, 0.925, 0.15, 0, 1, 0, 1, 0) # Core Fibers ops.section('Fiber', 105) ops.patch('rect', 319, 11, 11, -0.20, -0.20, 0.20, 0.20) # Cover Fibers ops.patch('rect', 319, 15, 2, 0.250000, 0.200000, -0.250000, 0.250000) ops.patch('rect', 319, 15, 2, 0.250000, -0.250000, -0.250000, -0.200000) ops.patch('rect', 319, 2, 11, -0.250000, -0.200000, -0.200000, 0.200000) ops.patch('rect', 319, 2, 11, 0.200000, -0.200000, 0.250000, 0.200000) # create corner bars ops.layer('straight', 312, 4, 0.00025450, 0.200000, 0.200000, -0.200000, 0.200000) ops.layer('straight', 312, 4, 0.00025450, 0.200000, -0.200000, -0.200000, -0.200000) ops.beamIntegration('Lobatto', 100, 105, 3) for i in range(len(nodeID) - 1): ops.element('forceBeamColumn', i, nodeID[i], nodeID[i + 1], 1, 100, '-iter', 10, 1e-6) # Add Vertical Load at Top ops.timeSeries('Linear', 101) ops.pattern('Plain', 100, 101) ops.load(IDctrlNode, 0, -500, 0) # Solve Gravity First ops.system('UmfPack') ops.numberer('Plain') ops.constraints('Transformation') ops.integrator('LoadControl', 0.1) ops.test('RelativeTotalNormDispIncr', 0.001, 100, 2) ops.algorithm('Newton') ops.analysis('Static') LoadControlSubStep(10, 0.1, True) # Displacement Control Analysis(Pushover) ops.pattern('Plain', 200, 101) ops.load(IDctrlNode, 1, 0, 0) ops.system('UmfPack') ops.numberer('Plain') ops.constraints('Transformation') ops.test('RelativeTotalNormDispIncr', 1e-2, 500, 2) ops.algorithm('Newton') ops.analysis('Static') DispControlSubStep(100, IDctrlNode, 1, 1.0)
def test_EigenAnal_twoStoryFrame1(): ops.wipe() #input m = 100.0 / 386.0 numModes = 2 #material A = 63.41 I = 320.0 E = 29000.0 #geometry L = 240. h = 120. # define the model #--------------------------------- #model builder ops.model('BasicBuilder', '-ndm', 2, '-ndf', 3) # nodal coordinates: ops.node(1, 0., 0.) ops.node(2, L, 0.) ops.node(3, 0., h) ops.node(4, L, h) ops.node(5, 0., 2 * h) ops.node(6, L, 2 * h) # Single point constraints -- Boundary Conditions ops.fix(1, 1, 1, 1) ops.fix(2, 1, 1, 1) # assign mass ops.mass(3, m, 0., 0.) ops.mass(4, m, 0., 0.) ops.mass(5, m / 2., 0., 0.) ops.mass(6, m / 2., 0., 0.) # define geometric transformation: TransfTag = 1 ops.geomTransf('Linear', TransfTag) # define elements: # columns ops.element('elasticBeamColumn', 1, 1, 3, A, E, 2. * I, TransfTag) ops.element('elasticBeamColumn', 2, 3, 5, A, E, I, TransfTag) ops.element('elasticBeamColumn', 3, 2, 4, A, E, 2. * I, TransfTag) ops.element('elasticBeamColumn', 4, 4, 6, A, E, I, TransfTag) # beams ops.element('elasticBeamColumn', 5, 3, 4, A, E, 2 * I, TransfTag) ops.element('elasticBeamColumn', 6, 5, 6, A, E, I, TransfTag) # record eigenvectors #---------------------- # for { k 1 } { k <= numModes } { incr k } { # recorder Node -file format "modes/mode%i.out" k -nodeRange 1 6 -dof 1 2 3 "eigen k" # } # perform eigen analysis #----------------------------- lamb = ops.eigen(numModes) # calculate frequencies and periods of the structure #--------------------------------------------------- omega = [] f = [] T = [] pi = 3.141593 for lam in lamb: print("labmbda = ", lam) omega.append(math.sqrt(lam)) f.append(math.sqrt(lam) / (2 * pi)) T.append((2 * pi) / math.sqrt(lam)) print("periods are ", T) # write the output file cosisting of periods #-------------------------------------------- period = "Periods.txt" Periods = open(period, "w") for t in T: Periods.write(repr(t) + '\n') Periods.close() # create display for mode shapes #--------------------------------- # windowTitle xLoc yLoc xPixels yPixels # recorder display "Mode Shape 1" 10 10 500 500 -wipe # prp h h 1 # projection reference point (prp) defines the center of projection (viewer eye) # vup 0 1 0 # view-up vector (vup) # vpn 0 0 1 # view-plane normal (vpn) # viewWindow -200 200 -200 200 # coordiantes of the window relative to prp # display -1 5 20 # the 1st arg. is the tag for display mode (ex. -1 is for the first mode shape) # the 2nd arg. is magnification factor for nodes, the 3rd arg. is magnif. factor of deformed shape # recorder display "Mode Shape 2" 10 510 500 500 -wipe # prp h h 1 # vup 0 1 0 # vpn 0 0 1 # viewWindow -200 200 -200 200 # display -2 5 20 # Run a one step gravity load with no loading (to record eigenvectors) #----------------------------------------------------------------------- ops.integrator('LoadControl', 0.0, 1, 0.0, 0.0) # Convergence test # tolerance maxIter displayCode ops.test('EnergyIncr', 1.0e-10, 100, 0) # Solution algorithm ops.algorithm('Newton') # DOF numberer ops.numberer('RCM') # Constraint handler ops.constraints('Transformation') # System of equations solver ops.system('ProfileSPD') ops.analysis('Static') res = ops.analyze(1) if res < 0: print("Modal analysis failed") # get values of eigenvectors for translational DOFs #--------------------------------------------------- f11 = ops.nodeEigenvector(3, 1, 1) f21 = ops.nodeEigenvector(5, 1, 1) f12 = ops.nodeEigenvector(3, 2, 1) f22 = ops.nodeEigenvector(5, 2, 1) print("eigenvector 1: ", [f11 / f21, f21 / f21]) print("eigenvector 2: ", [f12 / f22, f22 / f22]) assert abs(T[0] - 0.628538768190688) < 1e-12 and abs( T[1] - 0.2359388635361575) < 1e-12 and abs( f11 / f21 - 0.3869004256389493) < 1e-12 and abs( f21 / f21 - 1.0) < 1e-12 and abs(f12 / f22 + 1.2923221761110006 ) < 1e-12 and abs(f22 / f22 - 1.0) < 1e-12
def geomTransf_create(): ''' create grometric Transform ''' ops.geomTransf("Linear", 1, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 2, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 3, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 4, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 5, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 6, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 7, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 8, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 9, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 10, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 11, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 12, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 13, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 14, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 15, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 16, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 17, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 18, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 19, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 20, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 21, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 22, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 23, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 24, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 25, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 26, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 27, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 28, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 29, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 30, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 31, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 32, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 33, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 34, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 35, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 36, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 37, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 38, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 39, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 40, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 41, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 42, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 43, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 44, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 45, 1.000, 0.000, 0.000) ops.geomTransf("Linear", 46, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 47, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 48, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 49, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 50, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 51, 0.000, 0.000, 1.000) ops.geomTransf("Linear", 52, 0.000, 0.000, 1.000) logger.info("geometric transform created")
#constraints for mass nodes mass_constraint_data= np.ones((num_story,7)) mass_constraint_data[:,0]= mass_node_data[0:mass_node_data.shape[0],0] mass_constraint_data[:,1:3]= 0 mass_constraint_data[:,6]= 1 for i in range(mass_constraint_data.shape[0]): ops.fix(mass_constraint_data[i,0], 0,0,1,1,1,0) # ============================================================================= # Define Coordinate Transformation # ============================================================================= ops.geomTransf('Linear', 1, 1, 0, 0) # ============================================================================= # Define Elements # ============================================================================= #in local coordinate system: 0.J 1.Iz 2.Iy moment_of_inertia= np.zeros((wall.shape[0],3)) for i in range(wall.shape[0]): moment_of_inertia[i,0]= wall.iat[i,3]*wall.iat[i,4]**3/3 if wall.iat[i,7]=='E/W': moment_of_inertia[i,1]= wall.iat[i,3]**3*wall.iat[i,4]/12 moment_of_inertia[i,2]= wall.iat[i,4]**3*wall.iat[i,3]/12 elif wall.iat[i,7]=='N/S': moment_of_inertia[i,1]= wall.iat[i,4]**3*wall.iat[i,3]/12
def test_EigenFrame(): ops.wipe() ops.model('Basic', '-ndm', 2) # units kip, ft # properties bayWidth = 20.0 storyHeight = 10.0 numBay = 10 numFloor = 9 A = 3.0 #area = 3ft^2 E = 432000.0 #youngs mod = 432000 k/ft^2 I = 1.0 #second moment of area I=1ft^4 M = 3.0 #mas/length = 4 kip sec^2/ft^2 coordTransf = "Linear" # Linear, PDelta, Corotational massType = "-lMass" # -lMass, -cMass # add the nodes # - floor at a time nodeTag = 1 yLoc = 0. for j in range(0, numFloor + 1): xLoc = 0. for i in range(0, numBay + 1): ops.node(nodeTag, xLoc, yLoc) xLoc += bayWidth nodeTag += 1 yLoc += storyHeight # fix base nodes for i in range(1, numBay + 2): ops.fix(i, 1, 1, 1) # add column element ops.geomTransf(coordTransf, 1) eleTag = 1 for i in range(0, numBay + 1): end1 = i + 1 end2 = end1 + numBay + 1 for j in range(0, numFloor): ops.element('elasticBeamColumn', eleTag, end1, end2, A, E, I, 1, '-mass', M, massType) end1 = end2 end2 = end1 + numBay + 1 eleTag += 1 # add beam elements for j in range(1, numFloor + 1): end1 = (numBay + 1) * j + 1 end2 = end1 + 1 for i in range(0, numBay): ops.element('elasticBeamColumn', eleTag, end1, end2, A, E, I, 1, '-mass', M, massType) end1 = end2 end2 = end1 + 1 eleTag += 1 # calculate eigenvalues numEigen = 3 eigenValues = ops.eigen(numEigen) PI = 2 * asin(1.0) #recorder('PVD','EigenFrame','eigen',numEigen) #record() # determine PASS/FAILURE of test testOK = 0 # print table of camparsion # Bathe & Wilson Peterson SAP2000 SeismoStruct comparisonResults = [[0.589541, 5.52695, 16.5878], [0.589541, 5.52696, 16.5879], [0.589541, 5.52696, 16.5879], [0.58955, 5.527, 16.588]] print("\n\nEigenvalue Comparisons:") tolerances = [9.99e-6, 9.99e-6, 9.99e-5] # tolerances prescribed by documented precision formatString = '{:>15}{:>15}{:>15}{:>15}{:>15}' print( formatString.format('OpenSees', 'Bathe&Wilson', 'Peterson', 'SAP2000', 'SeismoStruct')) formatString = '{:>15.5f}{:>15.4f}{:>15.4f}{:>15.4f}{:>15.3f}' for i in range(0, numEigen): lamb = eigenValues[i] print( formatString.format(lamb, comparisonResults[0][i], comparisonResults[1][i], comparisonResults[2][i], comparisonResults[3][i])) resultOther = comparisonResults[2][i] tol = tolerances[i] if abs(lamb - resultOther) > tol: testOK = -1 print("failed->", abs(lamb - resultOther), tol) assert testOK == 0
0.68 * inch], # [d, tw, bf, tf] "W14X90": [14.02 * inch, 0.44 * inch, 14.52 * inch, 0.71 * inch], # [d, tw, bf, tf] } # secTag, matTag, [d, tw, bf, tf], Nfw, Nff ops.section("WFSection2d", colSecTag, matTag, *WSection["W14X90"], 20, 4) # Column section ops.section("WFSection2d", beamSecTag, matTag, *WSection["W18x76"], 20, 4) # Beam section # Define elements # --------------- colTransTag, beamTransTag = 1, 2 # Linear, PDelta, Corotational ops.geomTransf("Corotational", colTransTag) ops.geomTransf("Linear", beamTransTag) colIntTag, beamIntTag = 1, 2 nip = 5 # Lobatto, Legendre, NewtonCotes, Radau, Trapezoidal, CompositeSimpson ops.beamIntegration("Lobatto", colIntTag, colSecTag, nip), ops.beamIntegration("Lobatto", beamIntTag, beamSecTag, nip) # Column elements ops.element("forceBeamColumn", 10, 1, 3, colTransTag, colIntTag, "-mass", 0.0) ops.element("forceBeamColumn", 11, 3, 5, colTransTag, colIntTag, "-mass", 0.0) ops.element("forceBeamColumn", 12, 2, 4, colTransTag, colIntTag, "-mass", 0.0) ops.element("forceBeamColumn", 13, 4, 6, colTransTag, colIntTag, "-mass", 0.0) # Beam elements
def runAnalysis(k): """ Tests and individual and returns the result of that test. The user should consider if it's possible for the test not to work. """ Fu = 21.1 * 10**3 # k = 2.6*10**6 b = 0.015 R0 = 19 cR1 = .95 cR2 = .15 Fu = 22.3 * 10**3 # k = 2.6*10**6 b = 0.0129 R0 = 3.1 cR1 = .3 cR2 = .01 # 21.1*10**3, 2.6*10**6, 0.015, 19, .95, .15] # 2.25427928e+04 3.33339323e+06 1.96273081e-02 5.46515829e+00 # 6.98429661e-01 5.28210755e-02 # 2.20833537e+04 3.03336982e+06 1.28872130e-02 3.13990345e+00 # 3.36067251e-01 1.04312516e-01 op.wipe() op.model('Basic', '-ndm', 2, '-ndf', 3) ## Analysis Parameters material(s) ## ------------------ LoadProtocol = np.array([ 0.0017, 0.005, 0.0075, 0.012, 0.018, 0.027, 0.04, 0.054, 0.068, 0.072, 0. ]) # Step size dx = 0.0001 op.uniaxialMaterial('Steel02', 1, Fu, k, b, R0, cR1, cR2, 0., 1., 0., 1.) ERelease = 1. op.uniaxialMaterial('Elastic', 2, ERelease, 0.0) ## Define geometric transformation(s) ## ---------------------------------- #geomTransf('Linear',1) op.geomTransf('PDelta', 1) op.beamIntegration('Lobatto', 1, 1, 3) # Define geometry # --------------- op.node(1, 0., 0., '-ndf', 3) op.node(2, 0., 0., '-ndf', 3) op.fix(1, 1, 1, 1) # Define element(s) # ----------------- op.element("zeroLength", 1, 1, 2, '-mat', 1, 2, 2, '-dir', 1, 2, 3, '-orient', 1., 0., 0., 0., 1., 0.) # Define Recorder(s) # ----------------- op.recorder('Node', '-file', 'RFrc.out', '-time', '-nodeRange', 1, 1, '-dof', 1, 'reaction') op.recorder('Node', '-file', 'Disp.out', '-time', '-nodeRange', 2, 2, '-dof', 1, 'disp') # Define Analysis Parameters # ----------------- op.timeSeries('Linear', 1, '-factor', 1.0) op.pattern('Plain', 1, 1, '-fact', 1.) op.load(2, 1., 0.0, 0.0) # op.initialize() op.constraints("Plain") op.numberer("Plain") # System of Equations op.system("UmfPack", '-lvalueFact', 10) # Convergence Test op.test('NormDispIncr', 1. * 10**-8, 25, 0, 2) # Solution Algorithm op.algorithm('Newton') # Integrator op.integrator('DisplacementControl', 2, 1, dx) # Analysis Type op.analysis('Static') ControlNode = 2 ControlNodeDof = 1 op.record() ok = 0 # Define Analysis for x in LoadProtocol: for ii in range(0, 2): # op. op.integrator('DisplacementControl', ControlNode, ControlNodeDof, dx) while (op.nodeDisp(2, 1) < x): ok = op.analyze(1) if ok != 0: print('Ending analysis') op.wipe() return np.array([0, 0]) op.integrator('DisplacementControl', ControlNode, ControlNodeDof, -dx) while (op.nodeDisp(2, 1) > -x): ok = op.analyze(1) if ok != 0: print('Ending analysis') op.wipe() return np.array([0, 0]) op.wipe() fileDispName = os.path.join('Disp.out') fileForceName = os.path.join('RFrc.out') disp = np.loadtxt(fileDispName) RFrc = np.loadtxt(fileForceName) # try: x = disp[:, 1] y = -RFrc[:, 1] xy = np.column_stack([x, y]) return xy
def test_EigenFrameExtra(): eleTypes = [ 'elasticBeam', 'forceBeamElasticSection', 'dispBeamElasticSection', 'forceBeamFiberSectionElasticMaterial', 'dispBeamFiberSectionElasticMaterial' ] for eleType in eleTypes: ops.wipe() ops.model('Basic', '-ndm', 2) # units kip, ft # properties bayWidth = 20.0 storyHeight = 10.0 numBay = 10 numFloor = 9 A = 3.0 #area = 3ft^2 E = 432000.0 #youngs mod = 432000 k/ft^2 I = 1.0 #second moment of area I=1ft^4 M = 3.0 #mas/length = 4 kip sec^2/ft^2 coordTransf = "Linear" # Linear, PDelta, Corotational massType = "-lMass" # -lMass, -cMass nPts = 3 # numGauss Points # an elastic material ops.uniaxialMaterial('Elastic', 1, E) # an elastic section ops.section('Elastic', 1, E, A, I) # a fiber section with A=3 and I = 1 (b=1.5, d=2) 2d bending about y-y axis # b 1.5 d 2.0 y = 2.0 z = 1.5 numFiberY = 2000 # note we only need so many to get the required accuracy on eigenvalue 1e-7! numFiberZ = 1 ops.section('Fiber', 2) # patch rect 1 numFiberY numFiberZ 0.0 0.0 z y ops.patch('quad', 1, numFiberY, numFiberZ, -y / 2.0, -z / 2.0, y / 2.0, -z / 2.0, y / 2.0, z / 2.0, -y / 2.0, z / 2.0) # add the nodes # - floor at a time nodeTag = 1 yLoc = 0. for j in range(0, numFloor + 1): xLoc = 0. for i in range(numBay + 1): ops.node(nodeTag, xLoc, yLoc) xLoc += bayWidth nodeTag += 1 yLoc += storyHeight # fix base nodes for i in range(1, numBay + 2): ops.fix(i, 1, 1, 1) # add column element transfTag = 1 ops.geomTransf(coordTransf, transfTag) integTag1 = 1 ops.beamIntegration('Lobatto', integTag1, 1, nPts) integTag2 = 2 ops.beamIntegration('Lobatto', integTag2, 2, nPts) eleTag = 1 for i in range(numBay + 1): end1 = i + 1 end2 = end1 + numBay + 1 for j in range(numFloor): if eleType == "elasticBeam": ops.element('elasticBeamColumn', eleTag, end1, end2, A, E, I, 1, '-mass', M, massType) elif eleType == "forceBeamElasticSection": ops.element('forceBeamColumn', eleTag, end1, end2, transfTag, integTag1, '-mass', M) elif eleType == "dispBeamElasticSection": ops.element('dispBeamColumn', eleTag, end1, end2, transfTag, integTag1, '-mass', M, massType) elif eleType == "forceBeamFiberSectionElasticMaterial": ops.element('forceBeamColumn', eleTag, end1, end2, transfTag, integTag2, '-mass', M) elif eleType == "dispBeamFiberSectionElasticMaterial": ops.element('dispBeamColumn', eleTag, end1, end2, transfTag, integTag2, '-mass', M, massType) else: print("BARF") end1 = end2 end2 = end1 + numBay + 1 eleTag += 1 # add beam elements for j in range(1, numFloor + 1): end1 = (numBay + 1) * j + 1 end2 = end1 + 1 for i in range(numBay): if eleType == "elasticBeam": ops.element('elasticBeamColumn', eleTag, end1, end2, A, E, I, 1, '-mass', M, massType) elif eleType == "forceBeamElasticSection": ops.element('forceBeamColumn', eleTag, end1, end2, transfTag, integTag1, '-mass', M) elif eleType == "dispBeamElasticSection": ops.element('dispBeamColumn', eleTag, end1, end2, transfTag, integTag1, '-mass', M, massType) elif eleType == "forceBeamFiberSectionElasticMaterial": ops.element('forceBeamColumn', eleTag, end1, end2, transfTag, integTag2, '-mass', M) elif eleType == "dispBeamFiberSectionElasticMaterial": ops.element('dispBeamColumn', eleTag, end1, end2, transfTag, integTag2, '-mass', M, massType) else: print("BARF") # element(elasticBeamColumn eleTag end1 end2 A E I 1 -mass M end1 = end2 end2 = end1 + 1 eleTag += 1 # calculate eigenvalues numEigen = 3 eigenValues = ops.eigen(numEigen) PI = 2 * asin(1.0) # determine PASS/FAILURE of test testOK = 0 # print table of camparsion # Bathe & Wilson Peterson SAP2000 SeismoStruct comparisonResults = [[0.589541, 5.52695, 16.5878], [0.589541, 5.52696, 16.5879], [0.589541, 5.52696, 16.5879], [0.58955, 5.527, 16.588]] print("\n\nEigenvalue Comparisons for eleType:", eleType) tolerances = [9.99e-7, 9.99e-6, 9.99e-5] formatString = '{:>15}{:>15}{:>15}{:>15}{:>15}' print( formatString.format('OpenSees', 'Bathe&Wilson', 'Peterson', 'SAP2000', 'SeismoStruct')) formatString = '{:>15.5f}{:>15.4f}{:>15.4f}{:>15.4f}{:>15.3f}' for i in range(numEigen): lamb = eigenValues[i] print( formatString.format(lamb, comparisonResults[0][i], comparisonResults[1][i], comparisonResults[2][i], comparisonResults[3][i])) resultOther = comparisonResults[2][i] tol = tolerances[i] if abs(lamb - resultOther) > tol: testOK = -1 print("failed->", abs(lamb - resultOther), tol) assert testOK == 0 solverTypes = [ '-genBandArpack', '-fullGenLapack', '-UmfPack', '-SuperLU', '-ProfileSPD' ] for solverType in solverTypes: eleType = 'elasticBeam' ops.wipe() ops.model('Basic', '-ndm', 2) # units kip, ft # properties bayWidth = 20.0 storyHeight = 10.0 numBay = 10 numFloor = 9 A = 3.0 #area = 3ft^2 E = 432000.0 #youngs mod = 432000 k/ft^2 I = 1.0 #second moment of area I=1ft^4 M = 3.0 #mas/length = 4 kip sec^2/ft^2 coordTransf = "Linear" # Linear, PDelta, Corotational massType = "-lMass" # -lMass, -cMass nPts = 3 # numGauss Points # an elastic material ops.uniaxialMaterial('Elastic', 1, E) # an elastic section ops.section('Elastic', 1, E, A, I) # a fiber section with A=3 and I = 1 (b=1.5, d=2) 2d bending about y-y axis # b 1.5 d 2.0 y = 2.0 z = 1.5 numFiberY = 2000 # note we only need so many to get the required accuracy on eigenvalue 1e-7! numFiberZ = 1 ops.section('Fiber', 2) # patch rect 1 numFiberY numFiberZ 0.0 0.0 z y ops.patch('quad', 1, numFiberY, numFiberZ, -y / 2.0, -z / 2.0, y / 2.0, -z / 2.0, y / 2.0, z / 2.0, -y / 2.0, z / 2.0) # add the nodes # - floor at a time nodeTag = 1 yLoc = 0. for j in range(0, numFloor + 1): xLoc = 0. for i in range(numBay + 1): ops.node(nodeTag, xLoc, yLoc) xLoc += bayWidth nodeTag += 1 yLoc += storyHeight # fix base nodes for i in range(1, numBay + 2): ops.fix(i, 1, 1, 1) # add column element transfTag = 1 ops.geomTransf(coordTransf, transfTag) integTag1 = 1 ops.beamIntegration('Lobatto', integTag1, 1, nPts) integTag2 = 2 ops.beamIntegration('Lobatto', integTag2, 2, nPts) eleTag = 1 for i in range(numBay + 1): end1 = i + 1 end2 = end1 + numBay + 1 for j in range(numFloor): if eleType == "elasticBeam": ops.element('elasticBeamColumn', eleTag, end1, end2, A, E, I, 1, '-mass', M, massType) elif eleType == "forceBeamElasticSection": ops.element('forceBeamColumn', eleTag, end1, end2, transfTag, integTag1, '-mass', M) elif eleType == "dispBeamElasticSection": ops.element('dispBeamColumn', eleTag, end1, end2, transfTag, integTag1, '-mass', M, massType) elif eleType == "forceBeamFiberSectionElasticMaterial": ops.element('forceBeamColumn', eleTag, end1, end2, transfTag, integTag2, '-mass', M) elif eleType == "dispBeamFiberSectionElasticMaterial": ops.element('dispBeamColumn', eleTag, end1, end2, transfTag, integTag2, '-mass', M, massType) else: print("BARF") end1 = end2 end2 = end1 + numBay + 1 eleTag += 1 # add beam elements for j in range(1, numFloor + 1): end1 = (numBay + 1) * j + 1 end2 = end1 + 1 for i in range(numBay): if eleType == "elasticBeam": ops.element('elasticBeamColumn', eleTag, end1, end2, A, E, I, 1, '-mass', M, massType) elif eleType == "forceBeamElasticSection": ops.element('forceBeamColumn', eleTag, end1, end2, transfTag, integTag1, '-mass', M) elif eleType == "dispBeamElasticSection": ops.element('dispBeamColumn', eleTag, end1, end2, transfTag, integTag1, '-mass', M, massType) elif eleType == "forceBeamFiberSectionElasticMaterial": ops.element('forceBeamColumn', eleTag, end1, end2, transfTag, integTag2, '-mass', M) elif eleType == "dispBeamFiberSectionElasticMaterial": ops.element('dispBeamColumn', eleTag, end1, end2, transfTag, integTag2, '-mass', M, massType) else: print("BARF") # element(elasticBeamColumn eleTag end1 end2 A E I 1 -mass M end1 = end2 end2 = end1 + 1 eleTag += 1 # calculate eigenvalues numEigen = 3 eigenValues = ops.eigen(solverType, numEigen) PI = 2 * asin(1.0) # determine PASS/FAILURE of test testOK = 0 # print table of camparsion # Bathe & Wilson Peterson SAP2000 SeismoStruct comparisonResults = [[0.589541, 5.52695, 16.5878], [0.589541, 5.52696, 16.5879], [0.589541, 5.52696, 16.5879], [0.58955, 5.527, 16.588]] print("\n\nEigenvalue Comparisons for solverType:", solverType) tolerances = [9.99e-7, 9.99e-6, 9.99e-5] formatString = '{:>15}{:>15}{:>15}{:>15}{:>15}' print( formatString.format('OpenSees', 'Bathe&Wilson', 'Peterson', 'SAP2000', 'SeismoStruct')) formatString = '{:>15.5f}{:>15.4f}{:>15.4f}{:>15.4f}{:>15.3f}' for i in range(numEigen): lamb = eigenValues[i] print( formatString.format(lamb, comparisonResults[0][i], comparisonResults[1][i], comparisonResults[2][i], comparisonResults[3][i])) resultOther = comparisonResults[2][i] tol = tolerances[i] if abs(lamb - resultOther) > tol: testOK = -1 print("failed->", abs(lamb - resultOther), tol) assert testOK == 0
def test_PortalFrame2d(): # set some properties print("================================================") print("PortalFrame2d.py: Verification 2d Elastic Frame") print(" - eigenvalue and static pushover analysis") ops.wipe() ops.model('Basic', '-ndm', 2) # properties # units kip, ft numBay = 2 numFloor = 7 bayWidth = 360.0 storyHeights = [162.0, 162.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 beams = [ 'W24X160', 'W24X160', 'W24X130', 'W24X130', 'W24X110', 'W24X110', 'W24X110' ] eColumn = [ 'W14X246', 'W14X246', 'W14X246', 'W14X211', 'W14X211', 'W14X176', 'W14X176' ] iColumn = [ 'W14X287', 'W14X287', 'W14X287', 'W14X246', 'W14X246', 'W14X211', 'W14X211' ] columns = [eColumn, iColumn, eColumn] WSection = { 'W14X176': [51.7, 2150.], 'W14X211': [62.1, 2670.], 'W14X246': [72.3, 3230.], 'W14X287': [84.4, 3910.], 'W24X110': [32.5, 3330.], 'W24X130': [38.3, 4020.], 'W24X160': [47.1, 5120.] } nodeTag = 1 # procedure to read def ElasticBeamColumn(eleTag, iNode, jNode, sectType, E, transfTag, M, massType): found = 0 prop = WSection[sectType] A = prop[0] I = prop[1] ops.element('elasticBeamColumn', eleTag, iNode, jNode, A, E, I, transfTag, '-mass', M, massType) # add the nodes # - floor at a time yLoc = 0. for j in range(0, numFloor + 1): xLoc = 0. for i in range(0, numBay + 1): ops.node(nodeTag, xLoc, yLoc) xLoc += bayWidth nodeTag += 1 if j < numFloor: storyHeight = storyHeights[j] yLoc += storyHeight # fix first floor ops.fix(1, 1, 1, 1) ops.fix(2, 1, 1, 1) ops.fix(3, 1, 1, 1) #rigid floor constraint & masses nodeTagR = 5 nodeTag = 4 for j in range(1, numFloor + 1): for i in range(0, numBay + 1): if nodeTag != nodeTagR: ops.equalDOF(nodeTagR, nodeTag, 1) else: ops.mass(nodeTagR, massX, 1.0e-10, 1.0e-10) nodeTag += 1 nodeTagR += numBay + 1 # add the columns # add column element ops.geomTransf(coordTransf, 1) eleTag = 1 for j in range(0, numBay + 1): end1 = j + 1 end2 = end1 + numBay + 1 thisColumn = columns[j] for i in range(0, numFloor): secType = thisColumn[i] ElasticBeamColumn(eleTag, end1, end2, secType, E, 1, M, massType) end1 = end2 end2 += numBay + 1 eleTag += 1 # add beam elements for j in range(1, numFloor + 1): end1 = (numBay + 1) * j + 1 end2 = end1 + 1 secType = beams[j - 1] for i in range(0, numBay): ElasticBeamColumn(eleTag, end1, end2, secType, E, 1, M, massType) end1 = end2 end2 = end1 + 1 eleTag += 1 # calculate eigenvalues & print results numEigen = 7 eigenValues = ops.eigen(numEigen) PI = 2 * asin(1.0) # # apply loads for static analysis & perform analysis # ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) ops.load(22, 20.0, 0., 0.) ops.load(19, 15.0, 0., 0.) ops.load(16, 12.5, 0., 0.) ops.load(13, 10.0, 0., 0.) ops.load(10, 7.5, 0., 0.) ops.load(7, 5.0, 0., 0.) ops.load(4, 2.5, 0., 0.) ops.integrator('LoadControl', 1.0) ops.algorithm('Linear') ops.analysis('Static') ops.analyze(1) # determine PASS/FAILURE of test ok = 0 # # print pretty output of comparsions # # SAP2000 SeismoStruct comparisonResults = [[ 1.2732, 0.4313, 0.2420, 0.1602, 0.1190, 0.0951, 0.0795 ], [1.2732, 0.4313, 0.2420, 0.1602, 0.1190, 0.0951, 0.0795]] print("\n\nPeriod Comparisons:") print('{:>10}{:>15}{:>15}{:>15}'.format('Period', 'OpenSees', 'SAP2000', 'SeismoStruct')) #formatString {%10s%15.5f%15.4f%15.4f} for i in range(0, numEigen): lamb = eigenValues[i] period = 2 * PI / sqrt(lamb) print('{:>10}{:>15.5f}{:>15.4f}{:>15.4f}'.format( i + 1, period, comparisonResults[0][i], comparisonResults[1][i])) resultOther = comparisonResults[0][i] if abs(period - resultOther) > 9.99e-5: ok = -1 # print table of camparsion # Parameter SAP2000 SeismoStruct comparisonResults = [[ "Disp Top", "Axial Force Bottom Left", "Moment Bottom Left" ], [1.45076, 69.99, 2324.68], [1.451, 70.01, 2324.71]] tolerances = [9.99e-6, 9.99e-3, 9.99e-3] print("\n\nSatic Analysis Result Comparisons:") print('{:>30}{:>15}{:>15}{:>15}'.format('Parameter', 'OpenSees', 'SAP2000', 'SeismoStruct')) for i in range(3): response = ops.eleResponse(1, 'forces') if i == 0: result = ops.nodeDisp(22, 1) elif i == 1: result = abs(response[1]) else: result = response[2] print('{:>30}{:>15.3f}{:>15.2f}{:>15.2f}'.format( comparisonResults[0][i], result, comparisonResults[1][i], comparisonResults[2][i])) resultOther = comparisonResults[1][i] tol = tolerances[i] if abs(result - resultOther) > tol: ok = -1 print("failed-> ", i, abs(result - resultOther), tol) assert ok == 0
import matplotlib.pyplot as plt ops.wipe() ops.model('basic', '-ndm', 3, '-ndf', 6) ops.node(1, 0.0, 5.0, 5.0) ops.node(2, 5.0, 5.0, 5.0) ops.node(3, 5.0, 5.0, 0.0) ops.node(4, 5.0, 0.0, 0.0) E_mod = 1 G_mod = 1 Area = 4000000 Iy = 1000000 Iz = 300000 Jxx = 300000 ops.geomTransf('Linear', 1, *[0,1,0]) ops.geomTransf('Linear', 2, *[0,0,-1]) ops.element('elasticBeamColumn', 1, 1, 2, Area, E_mod, G_mod, Jxx, Iy, Iz, 1) ops.element('elasticBeamColumn', 2, 3, 2, Area, E_mod, G_mod, Jxx, Iy, Iz, 1) ops.element('elasticBeamColumn', 3, 4, 3, Area, E_mod, G_mod, Jxx, Iy, Iz, 2) # definir restricciones (Dirichlet) ops.fix(1,*[1,1,1,1,1,1]) ops.fix(4,*[1,1,1,1,1,1]) # definir cargas (Neumann) ops.timeSeries('Linear',1) ops.pattern('Plain',1,1) ops.load(2,0.0,-100.0,0.0,0.0,0.0,0.0) fig = plt.figure(figsize=(4,4))
def geometric_Transf_create(): ''' create geometric Transform ''' ops.geomTransf("Linear", 1, 0.000, 0.000, 1.000) logger.info("geometric transform created")
def get_pile_m(pile_z0=0, pile_z1=-30, pile_d=2, m0=7.5, pile_f=0, pile_m=0): pile_h = pile_z0 - pile_z1 pile_a = np.pi * (pile_d / 2) ** 2 pile_i = np.pi * pile_d ** 4 / 64 pile_b1 = 0.9 * (1.5 + 0.5 / pile_d) * 1 * pile_d # 建立模型 ops.wipe() ops.model('basic', '-ndm', 2, '-ndf', 3) # 建立节点 node_z = np.linspace(pile_z0, pile_z1, elem_num + 1) for i, j in enumerate(node_z): ops.node(i + 1, 0, j) ops.node(i + 201, 0, j) # 约束 for i in range(len(node_z)): ops.fix(i + 1, 0, 1, 0) ops.fix(i + 201, 1, 1, 1) # 建立材料 ops.uniaxialMaterial('Elastic', 1, 3e4) for i in range(len(node_z)): pile_depth = i * (pile_h / elem_num) pile_depth_nominal = 10 if pile_depth <= 10 else pile_depth soil_k = m0 * pile_depth_nominal * pile_b1 * (pile_h / elem_num) if i == 0: ops.uniaxialMaterial('Elastic', 100 + i, soil_k / 2) continue ops.uniaxialMaterial('Elastic', 100 + i, soil_k) # 装配 ops.geomTransf('Linear', 1) # 建立单元 for i in range(elem_num): ops.element('elasticBeamColumn', i + 1, i + 1, i + 2, pile_a, 3e10, pile_i, 1) # 建立弹簧 for i in range(len(node_z)): ops.element('zeroLength', i + 201, i + 1, i + 201, '-mat', 100 + i, '-dir', 1) ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) ops.load(1, pile_f, 0, pile_m) ops.system('BandGeneral') ops.numberer('Plain') ops.constraints('Plain') ops.integrator('LoadControl', 0.01) ops.test('EnergyIncr', 1e-6, 200) ops.algorithm('Newton') ops.analysis('Static') ops.analyze(100) # 绘制位移图 node_disp = [] for i in range(101): node_disp.append(ops.nodeDisp(i + 1)) node_disp = np.array(node_disp) * 1000 plt.figure() plt.subplot(121) for i, j in enumerate(node_z): if abs(node_disp[:, 0][i]) > max(abs(node_disp[:, 0])) / 50: if i == 0: plt.plot([0, node_disp[:, 0][i]], [j, j], linewidth=1.5, color='grey') else: plt.plot([0, node_disp[:, 0][i]], [j, j], linewidth=0.7, color='grey') if abs(node_disp[:, 0][i]) == max(abs(node_disp[:, 0])): plt.annotate(f'{node_disp[:, 0][i]:.1f} mm', xy=(node_disp[:, 0][i], j), xytext=(0.3, 0.5), textcoords='axes fraction', bbox=dict(boxstyle="round", fc="0.8"), arrowprops=dict(arrowstyle='->', connectionstyle="arc3,rad=-0.3")) plt.plot([0, 0], [node_z[0], node_z[-1]], linewidth=1.5, color='dimgray') plt.plot(node_disp[:, 0], node_z, linewidth=1.5, color='midnightblue') plt.xlabel('Displacement(mm)') plt.ylabel('Pile Depth(m)') # 绘制弯矩图 elem_m = [] for i in range(100): elem_m.append(ops.eleForce(i + 1)) elem_m = np.array(elem_m) / 1000 plt.subplot(122) for i, j in enumerate(node_z[:-1]): if abs(elem_m[:, 2][i]) > max(abs(elem_m[:, 2])) / 50: if i == 0: plt.plot([0, elem_m[:, 2][i]], [j, j], linewidth=1.5, color='grey') else: plt.plot([0, elem_m[:, 2][i]], [j, j], linewidth=0.7, color='grey') if abs(elem_m[:, 2][i]) == max(abs(elem_m[:, 2])): plt.annotate(f'{elem_m[:, 2][i]:.1f} kN.m', xy=(elem_m[:, 2][i], j), xytext=(0.5, 0.5), textcoords='axes fraction', bbox=dict(boxstyle="round", fc="0.8"), arrowprops=dict(arrowstyle='->', connectionstyle="arc3,rad=0.3")) plt.plot([0, 0], [node_z[0], node_z[-1]], linewidth=1.5, color='dimgray') plt.plot(elem_m[:, 2], node_z[:-1], linewidth=1.5, color='brown') plt.xlabel('Moment(kN.m)') # plt.ylabel('Pile Depth(m)') plt.show() return abs(max(elem_m[:, 2]))
# ops.uniaxialMaterial("SteelMP", matTag, Fy, Es, b) # Sensitivity Params: sigmaY/fy, E, b # Define sections # --------------- # Sections defined with "canned" section ("WFSection2d"), otherwise use a FiberSection object (ops.section("Fiber",...)) beamSecTag = 1 beamWidth, beamDepth = 10 * cm, 50 * cm # secTag, matTag, d, tw, bf, tf, Nfw, Nff ops.section("WFSection2d", beamSecTag, matTag, beamDepth, beamWidth, beamWidth, 0, 20, 0) # Beam section # Define elements # --------------- beamTransTag, beamIntTag = 1, 1 # Linear, PDelta, Corotational ops.geomTransf("Corotational", beamTransTag) nip = 5 # Lobatto, Legendre, NewtonCotes, Radau, Trapezoidal, CompositeSimpson ops.beamIntegration("Legendre", beamIntTag, beamSecTag, nip) # Beam elements numEle = 5 meshSize = L / numEle # mesh size eleType = "dispBeamColumn" # forceBeamColumn, "dispBeamColumn" # tag, Npts, nodes, type, dofs, size, eleType, transfTag, beamIntTag ops.mesh("line", 1, 2, *[1, 2], 0, 3, meshSize, eleType, beamTransTag, beamIntTag) # Create a Plain load pattern with a Sine/Trig TimeSeries
def get_inelastic_response(fb, asig, extra_time=0.0, xi=0.05, analysis_dt=0.001): """ Run seismic analysis of a nonlinear FrameBuilding :param fb: FrameBuilding object :param asig: AccSignal object :param extra_time: float, additional analysis time after end of ground motion :param xi: damping ratio :param analysis_dt: time step to perform the analysis :return: """ op.wipe() op.model('basic', '-ndm', 2, '-ndf', 3) # 2 dimensions, 3 dof per node q_floor = 10000. # kPa trib_width = fb.floor_length trib_mass_per_length = q_floor * trib_width / 9.8 # Establish nodes and set mass based on trib area # Nodes named as: C<column-number>-S<storey-number>, first column starts at C1-S0 = ground level left nd = OrderedDict() col_xs = np.cumsum(fb.bay_lengths) col_xs = np.insert(col_xs, 0, 0) n_cols = len(col_xs) sto_ys = fb.heights sto_ys = np.insert(sto_ys, 0, 0) for cc in range(1, n_cols + 1): for ss in range(fb.n_storeys + 1): n_i = cc * 100 + ss nd["C%i-S%i" % (cc, ss)] = n_i op.node(n_i, col_xs[cc - 1], sto_ys[ss]) if ss != 0: if cc == 1: node_mass = trib_mass_per_length * fb.bay_lengths[0] / 2 elif cc == n_cols: node_mass = trib_mass_per_length * fb.bay_lengths[-1] / 2 else: node_mass = trib_mass_per_length * (fb.bay_lengths[cc - 2] + fb.bay_lengths[cc - 1] / 2) op.mass(n_i, node_mass) # Set all nodes on a storey to have the same displacement for ss in range(0, fb.n_storeys + 1): for cc in range(1, n_cols + 1): op.equalDOF(nd["C%i-S%i" % (1, ss)], nd["C%i-S%i" % (cc, ss)], opc.X) # Fix all base nodes for cc in range(1, n_cols + 1): op.fix(nd["C%i-S%i" % (cc, 0)], opc.FIXED, opc.FIXED, opc.FIXED) # Coordinate transformation geo_tag = 1 trans_args = [] op.geomTransf("Linear", geo_tag, *[]) l_hinge = fb.bay_lengths[0] * 0.1 # Define material e_conc = 30.0e6 i_beams = 0.4 * fb.beam_widths * fb.beam_depths ** 3 / 12 i_columns = 0.5 * fb.column_widths * fb.column_depths ** 3 / 12 a_beams = fb.beam_widths * fb.beam_depths a_columns = fb.column_widths * fb.column_depths ei_beams = e_conc * i_beams ei_columns = e_conc * i_columns eps_yield = 300.0e6 / 200e9 phi_y_col = calc_yield_curvature(fb.column_depths, eps_yield) phi_y_beam = calc_yield_curvature(fb.beam_depths, eps_yield) # Define beams and columns md = OrderedDict() # material dict sd = OrderedDict() # section dict ed = OrderedDict() # element dict # Columns named as: C<column-number>-S<storey-number>, first column starts at C1-S0 = ground floor left # Beams named as: B<bay-number>-S<storey-number>, first beam starts at B1-S1 = first storey left (foundation at S0) for ss in range(fb.n_storeys): # set columns for cc in range(1, fb.n_cols + 1): ele_i = cc * 100 + ss md["C%i-S%i" % (cc, ss)] = ele_i sd["C%i-S%i" % (cc, ss)] = ele_i ed["C%i-S%i" % (cc, ss)] = ele_i mat_props = elastic_bilin(ei_columns[ss][cc - 1], 0.05 * ei_columns[ss][cc - 1], phi_y_col[ss][cc - 1]) #print(opc.ELASTIC_BILIN, ele_i, *mat_props) op.uniaxialMaterial(opc.ELASTIC_BILIN, ele_i, *mat_props) # op.uniaxialMaterial("Elastic", ele_i, ei_columns[ss][cc - 1]) node_numbers = [nd["C%i-S%i" % (cc, ss)], nd["C%i-S%i" % (cc, ss + 1)]] op.element(opc.ELASTIC_BEAM_COLUMN, ele_i, *node_numbers, a_columns[ss - 1][cc - 1], e_conc, i_columns[ss - 1][cc - 1], geo_tag ) # Set beams for bb in range(1, fb.n_bays + 1): ele_i = bb * 10000 + ss md["B%i-S%i" % (bb, ss)] = ele_i sd["B%i-S%i" % (bb, ss)] = ele_i ed["B%i-S%i" % (bb, ss)] = ele_i mat_props = elastic_bilin(ei_beams[ss][bb - 1], 0.05 * ei_beams[ss][bb - 1], phi_y_beam[ss][bb - 1]) op.uniaxialMaterial(opc.ELASTIC_BILIN, ele_i, *mat_props) # op.uniaxialMaterial("Elastic", ele_i, ei_beams[ss][bb - 1]) node_numbers = [nd["C%i-S%i" % (bb, ss + 1)], nd["C%i-S%i" % (bb + 1, ss + 1)]] print((opc.BEAM_WITH_HINGES, ele_i, *node_numbers, sd["B%i-S%i" % (bb, ss)], l_hinge, sd["B%i-S%i" % (bb, ss)], l_hinge, sd["B%i-S%i" % (bb, ss)], geo_tag )) # Old definition # op.element(opc.BEAM_WITH_HINGES, ele_i, # *[nd["C%i-S%i" % (bb, ss - 1)], nd["C%i-S%i" % (bb + 1, ss)]], # sd["B%i-S%i" % (bb, ss)], l_hinge, # sd["B%i-S%i" % (bb, ss)], l_hinge, # e_conc, # a_beams[ss - 1][bb - 1], # i_beams[ss - 1][bb - 1], geo_tag # ) # New definition # op.element(opc.BEAM_WITH_HINGES, ele_i, # *node_numbers, # sd["B%i-S%i" % (bb, ss)], l_hinge, # sd["B%i-S%i" % (bb, ss)], l_hinge, # sd["B%i-S%i" % (bb, ss)], geo_tag # TODO: make this elastic # # ) # Elastic definition op.element(opc.ELASTIC_BEAM_COLUMN, ele_i, *node_numbers, a_beams[ss - 1][bb - 1], e_conc, i_beams[ss - 1][bb - 1], geo_tag ) # Define the dynamic analysis load_tag_dynamic = 1 pattern_tag_dynamic = 1 values = list(-1 * asig.values) # should be negative op.timeSeries('Path', load_tag_dynamic, '-dt', asig.dt, '-values', *values) op.pattern('UniformExcitation', pattern_tag_dynamic, opc.X, '-accel', load_tag_dynamic) # set damping based on first eigen mode angular_freq2 = op.eigen('-fullGenLapack', 1) if hasattr(angular_freq2, '__len__'): angular_freq2 = angular_freq2[0] angular_freq = angular_freq2 ** 0.5 if isinstance(angular_freq, complex): raise ValueError("Angular frequency is complex, issue with stiffness or mass") alpha_m = 0.0 beta_k = 2 * xi / angular_freq beta_k_comm = 0.0 beta_k_init = 0.0 period = angular_freq / 2 / np.pi print("period: ", period) op.rayleigh(alpha_m, beta_k, beta_k_init, beta_k_comm) # Run the dynamic analysis op.wipeAnalysis() op.algorithm('Newton') op.system('SparseGeneral') op.numberer('RCM') op.constraints('Transformation') op.integrator('Newmark', 0.5, 0.25) op.analysis('Transient') #op.test("NormDispIncr", 1.0e-1, 2, 0) tol = 1.0e-10 iter = 10 op.test('EnergyIncr', tol, iter, 0, 2) # TODO: make this test work analysis_time = (len(values) - 1) * asig.dt + extra_time outputs = { "time": [], "rel_disp": [], "rel_accel": [], "rel_vel": [], "force": [] } print("Analysis starting") while op.getTime() < analysis_time: curr_time = op.getTime() op.analyze(1, analysis_dt) outputs["time"].append(curr_time) outputs["rel_disp"].append(op.nodeDisp(nd["C%i-S%i" % (1, fb.n_storeys)], opc.X)) outputs["rel_vel"].append(op.nodeVel(nd["C%i-S%i" % (1, fb.n_storeys)], opc.X)) outputs["rel_accel"].append(op.nodeAccel(nd["C%i-S%i" % (1, fb.n_storeys)], opc.X)) op.reactions() react = 0 for cc in range(1, fb.n_cols): react += -op.nodeReaction(nd["C%i-S%i" % (cc, 0)], opc.X) outputs["force"].append(react) # Should be negative since diff node op.wipe() for item in outputs: outputs[item] = np.array(outputs[item]) return outputs
def RectCFSTSteelHysteretic(length: float, secHeight: float, secWidth: float, thickness: float, concrete_grade: float, steel_grade: float, axial_load_ratio: float, disp_control: Iterable[float]): '''Peakstress: concrete peak stress \n crushstress: concrete crush stress ''' #disp input # dispControl=[3,-3,7,-7,14,-14,14,-14,14,-14,28,-28,28,-28,28,-28,42,-42,42,-42,42,-42,56,-56,0] dispControl = tuple(disp_control) #Geometry # length=740 # secHeight=100 # secWidth=100 # thickness=7 #Materials ##steel_tube point1Steel, point2Steel, point3Steel = [460, 0.00309], [460, 0.02721 ], [530, 0.26969] point1SteelNegative, point2SteelNegative, point3SteelNegative = [ -460, -0.00309 ], [-460, -0.02721], [-736, -0.26969] pinchX = 0.2 pinchY = 0.7 damagedFactor = 0.01 densitySteel = 7.8 / 1000000000 ##concrete peakPointConcrete, crushPointConcrete = [-221.76, -0.0102], [-195, -0.051] unloadingLambda = 0.2 tensileStrength = 5.6 tensilePostStiffness = 0.01 densityConcrete = 2.4 / 1000000000 #axialLoadRatio # axialLoadRatio=0.4 #fix condition Fixed = 1 #section parameter areaConcrete = (secHeight - 2 * thickness) * (secWidth - 2 * thickness) areaSteel = secWidth * secHeight - areaConcrete # fck,Ec,nuConcrete=128.1,4.34*10000,0.21 # fy,epsilonSteely,Es,nuSteel=444.6,3067/1000000,1.99*100000,0.29 fck = peakPointConcrete[0] fy = point1Steel[0] #Computate parameter axialLoad = (areaConcrete * fck + areaSteel * fy) * axial_load_ratio #loading control parameter # for item in dispControlPercentage: # dispControl.append(item*length) # dispControl.append(-item*length) # print('displist:'dispControl) #wipe and build a model ops.wipe() ops.model('basic', '-ndm', 2, '-ndf', 3) #node coordinates meshNumLength = 5 meshVerticalSize = length / meshNumLength meshSteelSize = 10 nodes = [(i + 1, meshVerticalSize * i) for i in range(int(length / meshVerticalSize) + 1)] for item in nodes: ops.node(item[0], 0, item[1]) #boundary condition ops.fix(1, 1, 1, 1) # if bool(Fixed): # ops.fix(int(length/meshVerticalSize)+1,0,0,1) ##uppper constrain condition: free or no-rotation #mass defination(concentrate mass to nodes) nodeMassSteel = areaSteel * meshVerticalSize * densitySteel nodeMassConcrete = areaConcrete * meshVerticalSize * densityConcrete nodeMass = nodeMassSteel + nodeMassConcrete for i in range(len(nodes) - 1): arg = [0., nodeMass, 0.] ops.mass(i + 2, *arg) #transformation: ops.geomTransf('Linear', 1) #material defination ##steel ops.uniaxialMaterial('Hysteretic', 1001, *point1Steel, *point2Steel, *point3Steel, *point1SteelNegative, *point2SteelNegative, *point3SteelNegative, pinchX, pinchY, damagedFactor, 0, 0.0) ##concrete ##using concrete01 #peakPointConcrete,crushPointConcrete=[110.6,0.00544],[22.11,0.09145] #ops.uniaxialMaterial('Concrete01',1,*peakPointConcrete,*crushPointConcrete) ###using concrete02 ops.uniaxialMaterial('Concrete02', 1, *peakPointConcrete, *crushPointConcrete, unloadingLambda, tensileStrength, tensilePostStiffness) #section defination ops.section('Fiber', 1) ##inner concrete fiber fiberPointI, fiberPointJ = [ -(secHeight - 2 * thickness) / 2, -(secWidth - 2 * thickness) / 2 ], [(secHeight - 2 * thickness) / 2, (secWidth - 2 * thickness) / 2] ops.patch('rect', 1, 10, 1, *fiberPointI, *fiberPointJ ) # https://opensees.berkeley.edu/wiki/index.php/Patch_Command ##outside steel fiber steelFiberProperty = { 'height': meshSteelSize, 'area': meshSteelSize * thickness } steelFiberPropertyLeftAndRight = { 'height': secWidth, 'area': secWidth * thickness } ###left and right leftEdgeFiberY, rightEdgeFiberY = -( secHeight - 2 * thickness) / 2 - thickness / 2, ( secHeight - 2 * thickness) / 2 + thickness / 2 #rightEdgeFiberY might be wrong leftandRightEdgeFiberZ = [ -secWidth / 2 + steelFiberPropertyLeftAndRight['height'] * (1 / 2 + N) for N in range(int(secWidth / steelFiberPropertyLeftAndRight['height'])) ] ###up and down upEdgeFiberZ, downEdgeFiberZ = -( secWidth - 2 * thickness) / 2 - thickness / 2, ( secWidth - 2 * thickness) / 2 + thickness / 2 upandDownEdgeFiberY = [ -secHeight / 2 + thickness + steelFiberProperty['height'] * (1 / 2 + N) for N in range( int((secHeight - 2 * thickness) / steelFiberProperty['height'])) ] for i in leftandRightEdgeFiberZ: i = float(i) ops.fiber(float(leftEdgeFiberY), i, steelFiberPropertyLeftAndRight['area'], 1001) ops.fiber(float(rightEdgeFiberY), i, steelFiberPropertyLeftAndRight['area'], 1001) for j in upandDownEdgeFiberY: j = float(j) ops.fiber(j, float(upEdgeFiberZ), steelFiberProperty['area'], 1001) ops.fiber(j, float(downEdgeFiberZ), steelFiberProperty['area'], 1001) #beamInergration defination ops.beamIntegration('NewtonCotes', 1, 1, 5) #element defination for i in range(len(nodes) - 1): ops.element('dispBeamColumn', i + 1, i + 1, i + 2, 1, 1) #recorders ops.recorder('Node', '-file', 'topLateralDisp.txt', '-time', '-node', int(length / meshVerticalSize + 1), '-dof', 1, 2, 'disp') ops.recorder('Node', '-file', 'topLateralForce.txt', '-time', '-node', int(length / meshVerticalSize + 1), '-dof', 1, 2, 'reaction') ops.recorder('Element', '-file', 'topElementForce.txt', '-time', '-ele', int(length / meshVerticalSize), 'force') #gravity load ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) ops.load(int(length / meshVerticalSize + 1), 0, axialLoad, 0) ops.constraints('Plain') ops.numberer('RCM') ops.system('BandGeneral') ##convertage test tolerant, allowedIteralStep = 1 / 1000000, 6000 ops.test('NormDispIncr', tolerant, allowedIteralStep) ops.algorithm('Newton') ops.integrator('LoadControl', 0.1) ops.analysis('Static') ops.analyze(10) ops.loadConst('-time', 0) #lateraldisp analysis ops.pattern('Plain', 2, 1) ops.load(int(length / meshVerticalSize + 1), 100, 0, 0) for i in range(len(dispControl)): if i == 0: ops.integrator('DisplacementControl', int(length / meshVerticalSize + 1), 1, 0.1) ops.analyze(int(dispControl[i] / 0.1)) # print('Working on disp round',i) else: if dispControl[i] >= 0: ops.integrator('DisplacementControl', int(length / meshVerticalSize + 1), 1, 0.1) ops.analyze(int( abs(dispControl[i] - dispControl[i - 1]) / 0.1)) # print('Working on disp round',i) else: ops.integrator('DisplacementControl', int(length / meshVerticalSize + 1), 1, -0.1) ops.analyze(int( abs(dispControl[i] - dispControl[i - 1]) / 0.1))