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 initiate_model(): # remove existing model op.wipe() # set modelbuilder op.model('basic', '-ndm', 3) 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 test_force_beam_column(): opy.wipe() opy.model('basic', '-ndm', 2, '-ndf', 3) # 2 dimensions, 3 dof per node integ_tag = 1 ele_tag = 1 fn.define_beam_integration(integ_tag=integ_tag) fn.define_force_beam_column(ele_tag, integ_tag)
def test_beam_integration_lobatto_w_steel01(): op.wipe() op.model('basic', '-ndm', 2, '-ndf', 3) # 2 dimensions, 3 dof per node section_id = 1 uniaxial_steel01_material(section_id) int_tag = 1 op.beamIntegration('Lobatto', int_tag, section_id, 8) assert 1 == 1 # This pass
def test_elastic_isotropic(): opy.wipe() opy.model('basic', '-ndm', 2, '-ndf', 3) v_is_int = 1 v_is_float = 1. # with pytest.raises(opy.error): # TODO: can't find error class # opy.nDMaterial('ElasticIsotropic', 1, 1., v_is_int, 0.0) opy.nDMaterial('ElasticIsotropic', 1, 1., v_is_float, 0.0)
def GetSections(E): # remove existing model op.wipe() # set modelbuilder op.model('basic', '-ndm', 2, '-ndf', 3) # define materials op.uniaxialMaterial("Elastic", 1, E)
def test_beam_integration_mid_point_w_elastic(): lp_i = 0.1 lp_j = 0.2 op.wipe() op.model('basic', '-ndm', 2, '-ndf', 3) # 2 dimensions, 3 dof per node section_id = 1 elastic_section(section_id) integ_tag = 1 op.beamIntegration('HingeMidpoint', integ_tag, section_id, lp_i, section_id, lp_j, section_id)
def solver(coords, P, A, E, du, steps, tol, max_iter, analysis_type): ops.wipe() ops.model('basic', '-ndm', 2, '-ndf', 2) geom(coords) elements(A, E, analysis_type) recs(analysis_type) analysis(P, du, steps, tol, max_iter)
def Model_Build(x, y, A, E): ''' Description ----------- This function is used to determine the basic parameters of the structural problem at hand. Parameters ---------- x : LIST OF FLOATS The list of the coordinates of the nodes along the x-axis. y : LIST OF FLOATS The list of the coordinates of the nodes along the y-axis. A : LIST OF FLOATS The list with the materials used for the different elements. E : FLOAT The modulus of elesticity of the elements. Returns ------- None. ''' # Delete existing model. ops.wipe() # Define the model. ops.model('basic', '-ndm', 2, '-ndf', 3) # Define materials. ops.uniaxialMaterial('Elastic', 1, E) # Define the nodes. m = len(x) [ops.node(i + 1, *[x[i], y[i]]) for i in range(m)] # Fix the nodes. fixxity = [[0, 0, 1], [0, 1, 1], [1, 0, 1], [1, 1, 1]] [ ops.fix(i + 1, *fixxity[3]) if i + 1 != 4 else ops.fix(i + 1, *fixxity[0]) for i in range(m) ] # Define elements. conn = [[1, 4], [2, 4], [3, 4]] [ ops.element('Truss', i + 1, *conn[i], A[1], 1) if i != 0 else ops.element('Truss', i + 1, *conn[i], A[0], 1) for i in range(len(conn)) ] # Plot model. opsplt.plot_model()
def run_analysis(): # build the model ops.model('basic', '-ndm', 2, '-ndf', 2) ops.node(1, 0, 0) ops.node(2, 4000, 0) ops.node(3, 8000, 0) ops.node(4, 12000, 0) ops.node(5, 4000, 4000) ops.node(6, 8000, 4000) ops.fix(1, 1, 1) ops.fix(4, 0, 1) ops.uniaxialMaterial('Elastic', 1, E) ops.element('truss', 1, 1, 2, Ao, 1) ops.element('truss', 2, 2, 3, Ao, 1) ops.element('truss', 3, 3, 4, Ao, 1) ops.element('truss', 4, 1, 5, Au, 1) ops.element('truss', 5, 5, 6, Au, 1) ops.element('truss', 6, 6, 4, Au, 1) ops.element('truss', 7, 2, 5, Ao, 1) ops.element('truss', 8, 3, 6, Ao, 1) ops.element('truss', 9, 5, 3, Ao, 1) ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) ops.load(2, 0, -P) ops.load(3, 0, -P) # build and perform the analysis ops.algorithm('Linear') ops.integrator('LoadControl', 1.0) ops.system('ProfileSPD') ops.numberer('RCM') ops.constraints('Plain') ops.analysis('Static') ops.analyze(1) node_disp = [[ops.nodeDisp(node_i, dof_j) for dof_j in [1, 2]] for node_i in range(1, 7)] return node_disp
def __init__(self, ndm=2, ndf=3): ''' Initialise OpenSeesPy model. Args: ndm: An integer number of dimensions (default=2D). ndf: An integer number of degrees of freedom (default=3 DOF). ''' ops.wipe() ops.model('basic', '-ndm', ndm, '-ndf', ndf) self.material = None self.section = None self.nodes = None self.elements = None self.fixities = None self.loads = None
def buildModel(K, periodStruct, dampRatio): wn = 2.0 * PI / periodStruct m = K / (wn * wn) ops.wipe() ops.model('basic', '-ndm', 1, '-ndf', 1) ops.node(1, 0.) ops.node(2, 0., '-mass', m) ops.uniaxialMaterial('Elastic', 1, K) ops.element('zeroLength', 1, 1, 2, '-mat', 1, '-dir', 1) ops.fix(1, 1) # add damping using rayleigh damping on the mass term a0 = 2.0 * wn * dampRatio ops.rayleigh(a0, 0., 0., 0.)
def solver(Nnodes, P, F, L, A, E, Iz, steps, tol, max_iter, Nnodes_dir): ops.wipe() ops.model('basic', '-ndm', 2, '-ndf', 3) geom(L, Nnodes) elements(Nnodes, L, A, E, Iz) temp = Nnodes_dir + 'PointLoad/' recs(Nnodes, temp) PointLoad_analysis(Nnodes, F, tol, max_iter) ops.model('basic', '-ndm', 2, '-ndf', 3) geom(L, Nnodes) elements(Nnodes, L, A, E, Iz) temp = Nnodes_dir + 'PDelta/' recs(Nnodes, temp) PDelta_analysis(Nnodes, P, steps, tol, max_iter)
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
FunitTXT = 'kip' TunitTXT = 'sec' ft = 12 * inch ksi = kip / math.pow(inch, 2) psi = ksi / 1000 lbf = psi * inch * inch pcf = lbf / math.pow(ft, 3) inch2 = inch * inch inch4 = math.pow(inch, 4) cm = inch / 2.54 PI = 2 * math.asin(1.0) g = 32.2 * ft / math.pow(sec, 2) Ubig = 1e10 Usmall = 1 / Ubig op.model('basic', '-ndm', 2, '-ndf', 3) LCol = 36.0 * ft # column length LBeam = 42.0 * ft Weight = 2000.0 * kip # superstructure weight # define section geometry HCol = 5.0 * ft # Column Depth BCol = 5.0 * ft # Column Width HBeam = 8.0 * ft BBeam = 5.0 * ft # calculated parameters PCol = Weight / 2 # nodal dead-load weight per column #g = 386.4 Mass = PCol / g MCol = ((Weight / LBeam) * math.pow(LBeam, 2)) / 12
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]))
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
import openseespy.opensees as ops import argument as argu from liblog import logger import libCycliAnalysis as lib import perprocess import nodes ops.reset() ops.wipe() # set model ops.start() logger.info("begin") ops.model('basic', '-ndm', argu.ndm, '-ndf', argu.ndf) nodes.set_node() perprocess.set_uniaxial_metrial() perprocess.set_section() perprocess.set_element() ops.recorder('Node', '-file', 'output\\disp.out', '-node', 1008, 2008, 3008, 4008, 5008, 6008, 7008, 8008, '-time', '-dof', 3, 'disp') # set timeSeries ops.timeSeries('Linear', 1) logger.info("[Linear] timeSeries tag 1 created") # set load pattern ops.pattern('Plain', 1, 1) load: float = [0, 0, -225000, 0, 0, 0]
############################################################################ ### NOTE TO DEVELOPERS: ## 1. Test this example for the new command you are developing or ## editing. ## 2. Replace the above line with your own Get_Rendering library under ## development. For example see below, ############################################################################ from Development_Get_Rendering import * # ---------------------------- # Start of model generation # ---------------------------- ops.wipe() ops.model("BasicBuilder", "-ndm", 3, "-ndf", 3) # set default units ops.defaultUnits("-force", "kip", "-length", "in", "-time", "sec", "-temp", "F") # Define the material # ------------------- # matTag E nu rho ops.nDMaterial("ElasticIsotropic", 1, 10000.0, 0.25, 1.27) # Define geometry # --------------- Brick = "stdBrick" # Brick = "bbarBrick" # Brick = "SSPbrick"
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("==========================")
def analisis_opensees(path, permutaciones): #helper, #win ops.wipe() # bucle para generar los x análisis for i in range(len(permutaciones)): perfil = str(permutaciones[i][0]) nf = permutaciones[i][2] amort = permutaciones[i][3] den = permutaciones[i][4] vel = permutaciones[i][5] capas = len(permutaciones[i][6]) nstep = permutaciones[i][30] dt = float(permutaciones[i][31]) # creación de elementos sElemX = permutaciones[i][1] # elementos en X sElemZ = permutaciones[i][46] # espesor en Z # ============================================================================= # ######## geometría de la columna ###### # ============================================================================= # límite entre capas limite_capa = [] anterior = 0 for j in range(capas): espesor = permutaciones[i][8][j] limite_capa.append(espesor + anterior) anterior = limite_capa[j] print('Límite de capa: ' + str(limite_capa[j])) # creación de elementos y nodos en x nElemX = 1 # elementos en x nNodeX = 2 * nElemX + 1 # nodos en x # creación de elementos y nodos para z nElemZ = 1 # creación de elementos y nodos en Y y totales nElemY = [] # elementos en y sElemY = [] # dimension en y nElemT = 0 for j in range(capas): espesor = permutaciones[i][8][j] nElemY.append(2 * espesor) nElemT += nElemY[j] print('Elementos en capa ' + str(j + 1) + ': ' + str(nElemY[j])) sElemY.append(permutaciones[i][8][j] / nElemY[j]) print('Tamaño de los elementos en capa ' + str(j + 1) + ': ' + str(sElemY[j]) + '\n') # number of nodes in vertical direction in each layer nNodeY = [] # dimension en y nNodeT = 0 s = 0 for j in range(capas - 1): nNodeY.append(4 * nElemY[j]) nNodeT += nNodeY[j] s += 1 print('Nodos en capa ' + str(j + 1) + ': ' + str(nNodeY[j])) nNodeY.append(4 * (nElemY[-1] + 1)) nNodeT += nNodeY[-1] print('Nodos en capa ' + str(s + 1) + ': ' + str(nNodeY[s])) print('Nodos totales: ' + str(nNodeT)) #win.ui.progressBar.setValue(15) # ============================================================================= # ######### Crear nodos del suelo ########## # ============================================================================= # creación de nodos de presión de poros ops.model('basic', '-ndm', 3, '-ndf', 4) with open(path + '/Post-proceso/' + perfil + '/ppNodesInfo.dat', 'w') as f: count = 0.0 yCoord = 0.0 nodos = [] dryNode = [] altura_nf = 10 - nf for k in range(capas): for j in range(0, int(nNodeY[k]), 4): ops.node(j + count + 1, 0.0, yCoord, 0.0) ops.node(j + count + 2, 0.0, yCoord, sElemZ) ops.node(j + count + 3, sElemX, yCoord, sElemZ) ops.node(j + count + 4, sElemX, yCoord, 0.0) f.write( str(int(j + count + 1)) + '\t' + str(0.0) + '\t' + str(yCoord) + '\t' + str(0.0) + '\n') f.write( str(int(j + count + 2)) + '\t' + str(0.0) + '\t' + str(yCoord) + '\t' + str(sElemZ) + '\n') f.write( str(int(j + count + 3)) + '\t' + str(sElemX) + '\t' + str(yCoord) + '\t' + str(sElemZ) + '\n') f.write( str(int(j + count + 4)) + '\t' + str(sElemX) + '\t' + str(yCoord) + '\t' + str(0.0) + '\n') nodos.append(str(j + count + 1)) nodos.append(str(j + count + 2)) nodos.append(str(j + count + 3)) nodos.append(str(j + count + 4)) #designate node sobre la superficie de agua if yCoord >= altura_nf: dryNode.append(j + count + 1) dryNode.append(j + count + 2) dryNode.append(j + count + 3) dryNode.append(j + count + 4) yCoord = (yCoord + sElemY[k]) count = (count + nNodeY[k]) print("Finished creating all soil nodes...") # ============================================================================= # ####### Condiciones de contorno en la base de la columna ######### # ============================================================================= ops.fix(1, *[0, 1, 1, 0]) ops.fix(2, *[0, 1, 1, 0]) ops.fix(3, *[0, 1, 1, 0]) ops.fix(4, *[0, 1, 1, 0]) ops.equalDOF(1, 2, 1) ops.equalDOF(1, 3, 1) ops.equalDOF(1, 4, 1) print('Fin de creación de nodos de la base de la columna\n\n') # ============================================================================= # ####### Condiciones de contorno en los nudos restantes ######### # ============================================================================= count = 0 for k in range(5, int(nNodeT + 1), 4): ops.equalDOF(k, k + 1, *[1, 2, 3]) ops.equalDOF(k, k + 2, *[1, 2, 3]) ops.equalDOF(k, k + 3, *[1, 2, 3]) print('Fin de creación equalDOF para nodos de presión de poros\n\n') for j in range(len(dryNode)): ops.fix(dryNode[j], *[0, 0, 0, 1]) print("Finished creating all soil boundary conditions...") # ============================================================================= # ####### crear elemento y material de suelo ######### # ============================================================================= cargas = [] for j in range(capas): pendiente = permutaciones[i][9][j] slope = math.atan(pendiente / 100) tipo_suelo = permutaciones[i][6][j] rho = permutaciones[i][10][j] Gr = permutaciones[i][12][j] Br = permutaciones[i][13][j] fric = permutaciones[i][15][j] refpress = permutaciones[i][18][j] gmax = permutaciones[i][19][j] presscoef = permutaciones[i][20][j] surf = permutaciones[i][21][j] ev = permutaciones[i][22][j] cc1 = permutaciones[i][23][j] cc3 = permutaciones[i][24][j] cd1 = permutaciones[i][25][j] cd3 = permutaciones[i][26][j] ptang = permutaciones[i][27][j] coh = permutaciones[i][28][j] if tipo_suelo == 'No cohesivo': if float(surf) > 0: ops.nDMaterial('PressureDependMultiYield02', j + 1, 3.0, rho, Gr, Br, fric, gmax, refpress, presscoef, ptang, cc1, cc3, cd1, cd3, float(surf), 5.0, 3.0, *[1.0, 0.0], ev, *[0.9, 0.02, 0.7, 101.0]) else: ops.nDMaterial('PressureDependMultiYield02', j + 1, 3.0, rho, Gr, Br, fric, gmax, refpress, presscoef, ptang, cc1, cc3, cd1, cd3, float(surf), *permutaciones[i][29][j], 5.0, 3.0, *[1.0, 0.0], ev, *[0.9, 0.02, 0.7, 101.0]) cargas.append( [0.0, -9.81 * math.cos(slope), -9.81 * math.sin(slope)]) print('Fin de la creación de material de suelo\n\n') #----------------------------------------------------------------------------------------- # 5. CREATE SOIL ELEMENTS #----------------------------------------------------------------------------------------- count = 0 alpha = 1.5e-6 with open(path + '/Post-proceso/' + perfil + '/ppElemInfo.dat', 'w') as f: # crear elemento de suelo for k in range(capas): for j in range(int(nElemY[k])): nI = 4 * (j + count + 1) - 3 nJ = nI + 1 nK = nI + 2 nL = nI + 3 nM = nI + 4 nN = nI + 5 nO = nI + 6 nP = nI + 7 f.write( str(j + count + 1) + '\t' + str(nI) + '\t' + str(nJ) + '\t' + str(nK) + '\t' + str(nL) + '\t' + str(nM) + '\t' + str(nN) + '\t' + str(nO) + '\t' + str(nP) + '\n') Bc = permutaciones[i][14][k] ev = permutaciones[i][22][k] ops.element('SSPbrickUP', (j + count + 1), *[nI, nJ, nK, nL, nM, nN, nO, nP], (k + 1), float(Bc), 1.0, 1.0, 1.0, 1.0, float(ev), alpha, cargas[k][0], cargas[k][1], cargas[k][2]) count = (count + int(nElemY[k])) print('Fin de la creación del elemento del suelo\n\n') #win.ui.progressBar.setValue(25) # ============================================================================= # ######### Amortiguamiento de Lysmer ########## # ============================================================================= ops.model('basic', '-ndm', 3, '-ndf', 3) # definir nodos y coordenadas del amortiguamiento dashF = nNodeT + 1 dashX = nNodeT + 2 dashZ = nNodeT + 3 ops.node(dashF, 0.0, 0.0, 0.0) ops.node(dashX, 0.0, 0.0, 0.0) ops.node(dashZ, 0.0, 0.0, 0.0) # definir restricciones para los nodos de amortiguamiento ops.fix(dashF, 1, 1, 1) ops.fix(dashX, 0, 1, 1) ops.fix(dashZ, 1, 1, 0) # definir equalDOF para el amortiguamiento en la base del suelo ops.equalDOF(1, dashX, 1) ops.equalDOF(1, dashZ, 3) print( 'Fin de la creación de condiciones de contorno de los nodos de amortiguamiento\n\n' ) # definir el material de amortiguamiento colArea = sElemX * sElemZ dashpotCoeff = vel * den * colArea ops.uniaxialMaterial('Viscous', capas + 1, dashpotCoeff, 1.0) # definir el elemento ops.element('zeroLength', nElemT + 1, *[dashF, dashX], '-mat', capas + 1, '-dir', *[1]) ops.element('zeroLength', nElemT + 2, *[dashF, dashZ], '-mat', capas + 1, '-dir', *[3]) print('Fin de la creación del elemento de amortiguamiento\n\n') #----------------------------------------------------------------------------------------- # 9. DEFINE ANALYSIS PARAMETERS #----------------------------------------------------------------------------------------- # amortiguamiento de Rayleigh # frecuencia menor omega1 = 2 * math.pi * 0.2 # frecuencia mayor omega2 = 2 * math.pi * 20 a0 = 2.0 * (amort / 100) * omega1 * omega2 / (omega1 + omega2) a1 = 2.0 * (amort / 100) / (omega1 + omega2) print('Coeficientes de amortiguamiento' + '\n' + 'a0: ' + format(a0, '.6f') + '\n' + 'a1: ' + format(a1, '.6f') + '\n\n') #win.ui.progressBar.setValue(35) # ============================================================================= # ######## Determinación de análisis estático ######### # ============================================================================= #---DETERMINE STABLE ANALYSIS TIME STEP USING CFL CONDITION # se determina a partir de un análisis transitorio de largo tiempo duration = nstep * dt # tamaño mínimo del elemento y velocidad máxima minSize = sElemY[0] vsMax = permutaciones[i][11][0] for j in range(1, capas): if sElemY[j] < minSize: minSize = sElemY[j] if permutaciones[i][11][j] > vsMax: vsMax = permutaciones[i][11][j] # trial analysis time step kTrial = minSize / (vsMax**0.5) # tiempo de análisis y pasos de tiempo if dt <= kTrial: nStep = nstep dT = dt else: nStep = int(math.floor(duration / kTrial) + 1) dT = duration / nStep print('Número de pasos en el análisis: ' + str(nStep) + '\n') print('Incremento de tiempo: ' + str(dT) + '\n\n') #---------------------------------------------------------------------------------------- # 7. GRAVITY ANALYSIS #----------------------------------------------------------------------------------------- ops.model('basic', '-ndm', 3, '-ndf', 4) ops.updateMaterialStage('-material', int(k + 1), '-stage', 0) # algoritmo de análisis estático ops.constraints(permutaciones[i][32][0], float(permutaciones[i][32][1]), float(permutaciones[i][32][2])) ops.test(permutaciones[i][34][0], float(permutaciones[i][34][1]), int(permutaciones[i][34][2]), int(permutaciones[i][34][3])) ops.algorithm(permutaciones[i][38][0]) ops.numberer(permutaciones[i][33][0]) ops.system(permutaciones[i][36][0]) ops.integrator(permutaciones[i][35][0], float(permutaciones[i][35][1]), float(permutaciones[i][35][2])) ops.analysis(permutaciones[i][37][0]) print('Inicio de análisis estático elástico\n\n') ops.start() ops.analyze(20, 5.0e2) print('Fin de análisis estático elástico\n\n') #win.ui.progressBar.setValue(40) # update materials to consider plastic behavior # ============================================================================= ops.updateMaterialStage('-material', int(k + 1), '-stage', 1) # ============================================================================= # plastic gravity loading print('Inicio de análisis estático plástico\n\n') ok = ops.analyze(40, 5.0e-2) if ok != 0: error = 'Error de convergencia en análisis estático de modelo' + str( perfil) + '\n\n' print(error) break print('Fin de análisis estático plástico\n\n') #----------------------------------------------------------------------------------------- # 11. UPDATE ELEMENT PERMEABILITY VALUES FOR POST-GRAVITY ANALYSIS #----------------------------------------------------------------------------------------- ini = 1 aum = 0 sum = 0 for j in range(capas): #Layer 3 ops.setParameter( '-val', permutaciones[i][16][j], ['-eleRange', int(ini + aum), int(nElemY[j] + sum)], 'xPerm') ops.setParameter( '-val', permutaciones[i][17][j], ['-eleRange', int(ini + aum), int(nElemY[j] + sum)], 'yPerm') ops.setParameter( '-val', permutaciones[i][16][j], ['-eleRange', int(ini + aum), int(nElemY[j] + sum)], 'zPerm') ini = nElemY[j] + sum sum += nElemY[j] aum = 1 print("Finished updating permeabilities for dynamic analysis...") # ============================================================================= # ########### Grabadores dinámicos ########## # ============================================================================= ops.setTime(0.0) ops.wipeAnalysis() ops.remove('recorders') # tiempo de la grabadora recDT = 10 * dt path_acel = path + '/Post-proceso/' + perfil + '/dinamico/aceleraciones/' ops.recorder('Node', '-file', path_acel + 'accelerationx.out', '-time', '-dT', recDT, '-node', *nodos, '-dof', 1, 'accel') print('Fin de creación de grabadores\n\n') #win.ui.progressBar.setValue(50) # ============================================================================= # ######### Determinación de análisis dinámico ########## # ============================================================================= # objeto de serie temporal para el historial de fuerza path_vel = path + '/Pre-proceso/' + perfil + '/TREASISL2.txt' ops.timeSeries('Path', 1, '-dt', dt, '-filePath', path_vel, '-factor', dashpotCoeff) ops.pattern('Plain', 10, 1) ops.load(1, *[1.0, 0.0, 0.0, 0.0]) #CAMBIO REALIZADO OJO print('Fin de creación de carga dinámica\n\n') # algoritmo de análisis dinámico ops.constraints(permutaciones[i][39][0], float(permutaciones[i][39][1]), float(permutaciones[i][39][2])) ops.test(permutaciones[i][41][0], float(permutaciones[i][41][1]), int(permutaciones[i][41][2]), int(permutaciones[i][41][3])) ops.algorithm(permutaciones[i][45][0]) ops.numberer(permutaciones[i][40][0]) ops.system(permutaciones[i][43][0]) ops.integrator(permutaciones[i][42][0], float(permutaciones[i][42][1]), float(permutaciones[i][42][2])) ops.analysis(permutaciones[i][44][0]) # ============================================================================= # ops.rayleigh(a0, a1, 0.0, 0.0) # ============================================================================= print('Inicio de análisis dinámico\n\n') #win.ui.progressBar.setValue(85) ok = ops.analyze(nStep, dT) if ok != 0: error = 'Error de convergencia en análisis dinámico de modelo' + str( permutaciones[i][0]) + '\n\n' print(error) curTime = ops.getTime() mTime = curTime print('cursTime:' + str(curTime)) curStep = (curTime / dT) print('cursStep:' + str(curStep)) rStep = (nStep - curStep) * 2.0 remStep = int(nStep - curStep) * 2.0 print('remSTep:' + str(curStep)) dT = (dT / 2) print('dT:' + str(dT)) ops.analyze(remStep, dT) if ok != 0: error = 'Error de convergencia en análisis dinámico de modelo' + str( permutaciones[i][0]) + '\n\n' print(error) curTime = ops.getTime() print('cursTime:' + str(curTime)) curStep = (curTime - mTime) / dT print('cursStep:' + str(curStep)) remStep = int(rStep - curStep) * 2 print('remSTep:' + str(curStep)) dT = (dT / 2) print('dT:' + str(dT)) ops.analyze(remStep, dT) print('Fin de análisis dinámico\n\n') ops.wipe()
import openseespy.opensees as ops import openseespy.postprocessing.ops_vis as opsv 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)
def __init__(self): # AIが取れるアクションの設定 self.action = np.array([ 0, 0.02, 0.03, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 ]) self.naction = len(self.action) self.beta = 1 / 4 # 1質点系モデル self.T0 = 4 self.h = self.action[0] self.hs = [self.h] self.m = 100 self.k = 4 * np.pi**2 * self.m / self.T0**2 # 入力地震動 self.dt = 0.02 to_meter = 0.01 # cmをmに変換する値 self.wave_url = 'https://github.com/kakemotokeita/dqn-seismic-control/blob/master/wave/sample.csv' with urllib.request.urlopen(self.wave_url) as wave_file: self.wave_data = np.loadtxt( wave_file, usecols=(0, ), delimiter=',', skiprows=3) * to_meter # OpenSees設定 op.wipe() op.model('basic', '-ndm', 2, '-ndf', 3) # 2 dimensions, 3 dof per node # 節点 self.bot_node = 1 self.top_node = 2 op.node(self.bot_node, 0., 0.) op.node(self.top_node, 0., 0.) # 境界条件 op.fix(self.top_node, FREE, FIXED, FIXED) op.fix(self.bot_node, FIXED, FIXED, FIXED) op.equalDOF(1, 2, *[Y, ROTZ]) # 質量 op.mass(self.top_node, self.m, 0., 0.) # 弾性剛性 elastic_mat_tag = 1 Fy = 1e10 E0 = self.k b = 1.0 op.uniaxialMaterial('Steel01', elastic_mat_tag, Fy, E0, b) # Assign zero length element beam_tag = 1 op.element('zeroLength', beam_tag, self.bot_node, self.top_node, "-mat", elastic_mat_tag, "-dir", 1, '-doRayleigh', 1) # Define the dynamic analysis load_tag_dynamic = 1 pattern_tag_dynamic = 1 self.values = list(-1 * self.wave_data) # should be negative op.timeSeries('Path', load_tag_dynamic, '-dt', self.dt, '-values', *self.values) op.pattern('UniformExcitation', pattern_tag_dynamic, X, '-accel', load_tag_dynamic) # 減衰の設定 self.w0 = op.eigen('-fullGenLapack', 1)[0]**0.5 self.alpha_m = 0.0 self.beta_k = 2 * self.h / self.w0 self.beta_k_init = 0.0 self.beta_k_comm = 0.0 op.rayleigh(self.alpha_m, self.beta_k, self.beta_k_init, self.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') tol = 1.0e-10 iterations = 10 op.test('EnergyIncr', tol, iterations, 0, 2) self.i_pre = 0 self.i = 0 self.i_next = 0 self.time = 0 self.analysis_time = (len(self.values) - 1) * self.dt self.dis = 0 self.vel = 0 self.acc = 0 self.a_acc = 0 self.force = 0 self.resp = { "time": [], "dis": [], "acc": [], "a_acc": [], "vel": [], "force": [], } self.done = False
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 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_Truss(): # remove existing model ops.wipe() # set modelbuilder ops.model('basic', '-ndm', 2, '-ndf', 2) # create nodes ops.node(1, 0.0, 0.0) ops.node(2, 144.0, 0.0) ops.node(3, 168.0, 0.0) ops.node(4, 72.0, 96.0) # set boundary condition ops.fix(1, 1, 1) ops.fix(2, 1, 1) ops.fix(3, 1, 1) # define materials ops.uniaxialMaterial("Elastic", 1, 3000.0) # define elements ops.element("Truss", 1, 1, 4, 10.0, 1) ops.element("Truss", 2, 2, 4, 5.0, 1) ops.element("Truss", 3, 3, 4, 5.0, 1) # create TimeSeries ops.timeSeries("Linear", 1) # create a plain load pattern ops.pattern("Plain", 1, 1) # Create the nodal load - command: load nodeID xForce yForce ops.load(4, 100.0, -50.0) # ------------------------------ # Start of analysis generation # ------------------------------ # create SOE ops.system("BandSPD") # create DOF number ops.numberer("Plain") # create constraint handler ops.constraints("Plain") # create integrator ops.integrator("LoadControl", 1.0) # create algorithm ops.algorithm("Linear") # create analysis object ops.analysis("Static") # perform the analysis ops.analyze(1) ux = ops.nodeDisp(4, 1) uy = ops.nodeDisp(4, 2) assert abs(ux - 0.53009277713228375450) < 1e-12 and abs( uy + 0.17789363846931768864) < 1e-12
def _initialize(self): ops.wipe() ops.model('basic', '-ndm', self.ndm, '-ndf', self.ndf)
import openseespy.opensees as ops import os import math from collections import defaultdict import openseespy.postprocessing.ops_vis as opsv import matplotlib.pyplot as plt exec(open('source/tools.py').read()) exec(open('source/units.py').read()) ops.wipe() ops.model('basic', '-ndm', 2, '-ndf', 2) # lectura del archivo msh meshName = 'gmsh/beam2.msh' # generacion del diccionario nodeDic = {(0,1): 1,(0,4): 1, (0,2): 2, (0,3): 2, (1,4): 1, (1,2): 2} eleDic = {(2,1): 1} Node, Ele = readMesh(meshName, nodeDic, eleDic) nNode = len(Node) nEle = len(Ele) # paraview out # https://openseespydoc.readthedocs.io/en/latest/src/pvdRecorder.html outPV('out/Beam_1') # definir y construir el material mTg = 1 nu = 0.15 # Poisson's ratio of soil E = 2460000*N/cm**2
title("Sensitvity Analysis Completed!") print( f"Analysis elapsed time is {(time.time() - start_time):.3f} seconds.\n" ) return outputs # +===============================================================================+ # | Define model | # +===============================================================================+ # Create ModelBuilder # ------------------- ops.wipe() ops.model("basic", "-ndm", 2, "-ndf", 3) # Create nodes # ------------ L = 5 * m ops.node(1, 0.0, 0.0) # Fixed end ops.node(2, L, 0.0) # Free end # Fixed support # ------------- ops.fix(1, 1, 1, 1) # Define material # --------------- matTag = 1 Fy = 410 * MPa # Yield stress