def RunPushoverAnalysis(Px,Py): # create TimeSeries op.timeSeries("Linear", 1) # create a plain load pattern op.pattern("Plain", 1, 1) # Create the nodal load - command: load nodeID xForce yForce op.load(4, Px, Py, 0.) # create SOE op.system("BandSPD") # create DOF number op.numberer("RCM") # create constraint handler op.constraints("Plain") # create integrator op.integrator("LoadControl", 1.0) # create algorithm op.algorithm("Newton") # create analysis object op.analysis("Static") # perform the analysis op.initialize() ok = op.analyze(1)
def analysis(P, du, steps, tol, max_iter): tsTag = 1 ops.timeSeries('Linear', tsTag) pattTag = 1 ops.pattern('Plain', pattTag, tsTag) ops.load(2, *P) ########################################################################## ops.constraints('Plain') ops.numberer('RCM') ops.system('BandGeneral') ops.test('NormUnbalance', tol, max_iter) ops.algorithm('Newton') ops.integrator('DisplacementControl', 2, 2, du, max_iter) ops.analysis('Static') ops.analyze(steps) ########################################################################## opsplt.plot_model() ########################################################################## ops.wipe()
def PDelta_analysis(Nnodes, P, steps, tol, max_iter): tsTag = 1 ops.timeSeries('Linear', tsTag) pattTag = 1 ops.pattern('Plain', pattTag, tsTag) ops.load(Nnodes, *P) ########################################################################## ops.constraints('Plain') ops.numberer('RCM') ops.system('BandGeneral') ops.test('NormUnbalance', tol, max_iter) ops.algorithm('Newton') temp = 1 / steps ops.integrator('LoadControl', temp) ops.analysis('Static') ops.analyze(steps) ########################################################################## opsplt.plot_model('nodes') ########################################################################## ops.wipe()
def PointLoad_analysis(Nnodes, P, tol, max_iter): tsTag = 10 ops.timeSeries('Linear', tsTag) pattTag = 10 ops.pattern('Plain', pattTag, tsTag) ops.load(Nnodes, *P) ########################################################################## ops.constraints('Plain') ops.numberer('RCM') ops.system('BandGeneral') ops.test('NormUnbalance', tol, max_iter) ops.algorithm('Newton') ops.integrator('LoadControl', 1) ops.analysis('Static') ops.analyze(1) ########################################################################## ops.wipe()
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 buildLinearAnalysis(gamma, beta): # do analysis ops.constraints('Plain') ops.numberer('Plain') ops.algorithm('Linear') ops.integrator('Newmark', gamma, beta) ops.system('ProfileSPD') ops.analysis('Transient')
def material_response(self, material, demand): """ Calculate the response of a material to a given load history. Parameters ---------- material: Material The material object to analyze. demand: DemandProtocol The load history the material shall be exposed to. Returns ------- response: DataFrame The DataFrame includes columns for strain (eps) and stress (sig). """ # initialize the analysis self._initialize() # define the structure struct = SDOF(Truss(material, l_tot=1., A_cs=1.)) struct.create_FEM(damping=False) id_ctrl_node = struct.ctrl_node load_dir = 1 # define the loading ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) if self.ndf == 1 and self.ndm == 1: ops.load(id_ctrl_node, 1.) # configure the analysis ops.constraints('Plain') ops.numberer('RCM') ops.system('UmfPack') ops.test('NormDispIncr', 1e-10, 100) ops.algorithm('NewtonLineSearch', '-maxIter', 100) # initialize the arrays for results result_size = demand.length response = pd.DataFrame(np.zeros((result_size + 1, 2)), columns=['eps', 'sig']) # perform the analysis for i, disp_incr in enumerate(demand.increments): ops.integrator('DisplacementControl', id_ctrl_node, load_dir, disp_incr) ops.analysis('Static') ops.analyze(1) response.loc[i + 1, 'eps'] = ops.nodeDisp(id_ctrl_node, load_dir) # response.loc[i+1, 'sig'] = ops.eleResponse(1, 'axialForce')[0] #![4] response.loc[i + 1, 'sig'] = ops.eleResponse(1, 'axialForce') #![4] return response
def analysis_plain(): ''' analysis create ''' ops.constraints('Plain') ops.numberer('Plain') ops.system('BandGeneral') ops.test('EnergyIncr', 1.0e-6, 200) ops.algorithm('KrylovNewton') ops.integrator('DisplacementControl', 5, 3, -0.1) ops.analysis('Static') ops.analyze(100) logger.info("analysis created")
def PushoverLcD(dispMax): ControlNode = 4 ControlNodeDof = 1 du = 0.00002 * m # Define time series # timeSeries('Constant', tag, '-factor', factor=1.0) op.timeSeries('Constant', 1) op.timeSeries('Linear', 2) # define loads op.pattern('Plain', 1, 2) op.sp(ControlNode, ControlNodeDof, du) # Define Analysis Options # create SOE op.system("BandGeneral") # create DOF number op.numberer("Plain") # create constraint handler op.constraints("Transformation") # create integrator op.integrator("LoadControl", 1) # create algorithm op.algorithm("Newton") # create analysis object op.analysis("Static") # Create Test op.test('NormDispIncr', 1. * 10**-6, 50) # Run Analysis op.record() # ok = op.analyze(Nsteps) nn = 0 while (op.nodeDisp(ControlNode, ControlNodeDof) < dispMax): ok = op.analyze(1) if ok != 0: ok = BasicAnalysisLoop(ok, nn) if ok != 0: print("Analysis failed at load factor:", nn) break nn = +1 print() print("# Analysis Complete #")
def analysis_rigid(): ''' for rigid ''' ops.constraints('Lagrange') ops.numberer('Plain') ops.system('BandGeneral') ops.test('EnergyIncr', 1.0e-6, 200) ops.algorithm('Newton') ops.integrator('LoadControl', 1e-2) ops.analysis('Static') ops.analyze(100) logger.info("analysis created")
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 run_gravity_analysis(steps=10): """ Run gravity analysis (in 10 steps) """ ops.wipeAnalysis() ops.system("BandGeneral") ops.numberer("RCM") ops.constraints("Transformation") ops.test("NormDispIncr", 1.0E-12, 10, 3) ops.algorithm("Newton") # KrylovNewton ops.integrator("LoadControl", 1 / steps) ops.analysis("Static") ops.analyze(steps) title("Gravity Analysis Completed!") # Set the gravity loads to be constant & reset the time in the domain ops.loadConst("-time", 0.0) ops.wipeAnalysis()
def analysis_plain_load(test_tol=1.0e-12, test_iter=1000, incr=0.1, num_incr=11): ''' @analysis create in load control @default parameter: test_tol=1.0e-6, test_iter=1000, incr=0.1, num_incr=101 ''' logger.info("test_tol = %f, test_iter = %f, incr = %f, num_incr = %f", test_tol, test_iter, incr, num_incr) ops.constraints('Plain') ops.numberer('Plain') ops.system('BandGeneral') ops.test('EnergyIncr', test_tol, test_iter,) ops.algorithm('KrylovNewton') ops.integrator('LoadControl', incr) ops.analysis('Static') ops.analyze(num_incr) logger.info("load control analysis created")
def analysis_plain_disp(test_tol=1.0e-3, test_iter=1000, nodeTag=0, dof=1, disp_incr=1, num_incr=10): ''' @analysis create in displacement control\n @default parameter: test_tol=1.0e-3, test_iter=1000, nodeTag=0, dof=1, disp_incr=1, num_incr=10 ''' logger.info("test_tol = %f, test_iter = %f, nodeTag = %d, dof = %d, disp_incr = %f, num_incr = %f", test_tol, test_iter, nodeTag, dof, disp_incr, num_incr) ops.constraints('Plain') ops.numberer('Plain') ops.system('BandGeneral') ops.test('EnergyIncr', test_tol, test_iter) ops.algorithm('KrylovNewton') ops.integrator('DisplacementControl', nodeTag, dof, disp_incr) ops.analysis('Static') ops.analyze(num_incr) logger.info("displacemen control analysis created")
def MomentCurvature(secTag, axialLoad, maxK, numIncr=100): # Define two nodes at (0,0) ops.node(1, 0.0, 0.0) ops.node(2, 0.0, 0.0) # Fix all degrees of freedom except axial and bending ops.fix(1, 1, 1, 1) ops.fix(2, 0, 1, 0) # Define element # tag ndI ndJ secTag ops.element('zeroLengthSection', 1, 1, 2, secTag) # Define constant axial load ops.timeSeries('Constant', 1) ops.pattern('Plain', 1, 1) ops.load(2, axialLoad, 0.0, 0.0) # Define analysis parameters ops.integrator('LoadControl', 0.0) ops.system('SparseGeneral', '-piv') ops.test('NormUnbalance', 1e-9, 10) ops.numberer('Plain') ops.constraints('Plain') ops.algorithm('Newton') ops.analysis('Static') # Do one analysis for constant axial load ops.analyze(1) # Define reference moment ops.timeSeries('Linear', 2) ops.pattern('Plain', 2, 2) ops.load(2, 0.0, 0.0, 1.0) # Compute curvature increment dK = maxK / numIncr # Use displacement control at node 2 for section analysis ops.integrator('DisplacementControl', 2, 3, dK, 1, dK, dK) # Do the section analysis ops.analyze(numIncr)
def ops_gravity(): ops.recorder('Node', '-file', 'output\\gravity_disp.out', '-nodeRange', 651, 663, '-time', '-dof', 3, 'disp') ops.recorder('Node', '-file', 'output\\gravity_reaction.out', '-nodeRange', 651, 663, '-time', '-dof', 3, 'reaction') ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) load: float = [0, 0, (gravity_load + dead_load) / 13, 0, 0, 0] for i in range(651, 664): ops.load(i, *load) ops.constraints('Plain') ops.numberer('Plain') ops.system('BandGen') ops.test('NormDispIncr', 1.0, 1000) ops.algorithm('Newton') ops.integrator('LoadControl', 0.01) ops.analysis('Static') ok = ops.analyze(100) logger.info("gravity analyze result is %s", ok == 0)
def PushoverDcF(Nsteps): ControlNode = 4 ControlNodeDof = 1 dForce = 1.*kN du = 0.00001*m # Define time series # timeSeries('Constant', tag, '-factor', factor=1.0) op.timeSeries('Constant',1) op.timeSeries('Linear', 2) # define loads op.pattern('Plain',1 , 2) op.load(ControlNode, dForce, 0., 0.) # Define Analysis Options # create SOE op.system("BandGeneral") # create DOF number op.numberer("Plain") # create constraint handler op.constraints("Transformation") # create integrator op.integrator("DisplacementControl", ControlNode, ControlNodeDof, du) # create algorithm op.algorithm("Newton") # create analysis object op.analysis("Static") # Create Test op.test('NormDispIncr', 1.*10**-11, 50) # Run Analysis op.record() ok = op.analyze(Nsteps)
def analyse(self, num_incr): ''' Analyse the system. Args: num_incr: An integer number of load increments. return_node_disp: ''' ops.constraints('Transformation') ops.numberer('RCM') ops.system('BandGeneral') ops.test('NormUnbalance', 2e-8, num_incr) ops.algorithm('Newton') ops.integrator('LoadControl', 1 / num_incr) ops.record() ops.analysis('Static') ok = ops.analyze(num_incr) # Report analysis status if ok == 0: print("Analysis done.") else: print("Convergence issue.")
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
WzBeam = Weight / LBeam op.timeSeries('Linear', 1) op.pattern('Plain', 1, 1) op.eleLoad('-ele', 3, '-type', '-beamUniform', -WzBeam, 0.0, 0.0) #op.load(2, 0.0, -PCol, 0.0) Tol = 1e-8 # convergence tolerance for test NstepGravity = 10 DGravity = 1 / NstepGravity op.integrator('LoadControl', DGravity) # determine the next time step for an analysis op.numberer( 'Plain' ) # renumber dof's to minimize band-width (optimization), if you want to op.system('BandGeneral' ) # how to store and solve the system of equations in the analysis op.constraints('Plain') # how it handles boundary conditions op.test( 'NormDispIncr', Tol, 6 ) # determine if convergence has been achieved at the end of an iteration step op.algorithm( 'Newton' ) # use Newton's solution algorithm: updates tangent stiffness at every iteration op.analysis('Static') # define type of analysis static or transient op.analyze(NstepGravity) # apply gravity op.loadConst('-time', 0.0) #maintain constant gravity loads and reset time to zero print('Model Built')
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 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
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 ModalAnalysis3D(numEigen): """ |-----------------------------------------------------------------------| | | | Modal Analysis of 3D systems | | | | Author: Volkan Ozsarac | | Affiliation: University School for Advanced Studies IUSS Pavia | | Earthquake Engineering PhD Candidate | | | |-----------------------------------------------------------------------| """ import numpy as np import openseespy.opensees as op import time import sys print('Extracting the mass matrix, ignore the following warnings...\n') op.wipeAnalysis() op.system('FullGeneral') op.analysis('Transient') # Extract the Mass Matrix op.integrator('GimmeMCK',1.0,0.0,0.0) op.analyze(1,0.0) time.sleep(0.5) # Number of equations in the model N = op.systemSize() # Has to be done after analyze Mmatrix = op.printA('-ret') # Or use op.printA('-file','M.out') Mmatrix = np.array(Mmatrix) # Convert the list to an array Mmatrix.shape = (N,N) # Make the array an NxN matrix print('\nExtracted the mass matrix, ignore the previous warnings...') # Rerrange the mass matrix in accordance with nodelist order from getNodeTags() DOFs = [] # These are the idx of all the DOFs used in the extract mass matrix, order is rearranged used = {} # Save here the nodes and their associated dofs used in global mass matrix lx = np.zeros([N,1]) # influence vector (x) ly = np.zeros([N,1]) # influence vector (y) lz = np.zeros([N,1]) # influence vector (z) lrx = np.zeros([N,1]) # influence vector (rx) lry = np.zeros([N,1]) # influence vector (ry) lrz = np.zeros([N,1]) # influence vector (rz) idx = 0 # index NDF = 6 # NDF is number of DOFs/node for node in op.getNodeTags(): used[node] = [] for j in range(NDF): temp = op.nodeDOFs(node)[j] if temp not in DOFs and temp >=0: DOFs.append(op.nodeDOFs(node)[j]) used[node].append(j+1) if j == 0: lx[idx,0] = 1 if j == 1: ly[idx,0] = 1 if j == 2: lz[idx,0] = 1 if j == 3: lrx[idx,0] = 1 if j == 4: lry[idx,0] = 1 if j == 5: lrz[idx,0] = 1 idx += 1 Mmatrix = Mmatrix[DOFs,:][:,DOFs] op.wipeAnalysis() listSolvers = ['-genBandArpack','-fullGenLapack','-symmBandLapack'] ok = 1 for s in listSolvers: print("Using %s as solver..." % s[1:]) try: eigenValues = op.eigen(s,numEigen) catchOK = 0 ok = 0 except: catchOK = 1 if catchOK==0: for i in range(numEigen): if eigenValues[i] < 0: ok = 1 if ok==0: print('Eigenvalue analysis is completed.') break if ok!=0: print("Error on Modal Analysis...") sys.exit() else: Lamda = np.asarray(eigenValues) Omega = Lamda**0.5 T = 2*np.pi/Omega f = 1/T print('Modal properties for the first %d modes:' % numEigen) Mx = []; My = []; Mz = []; Mrx = []; Mry = []; Mrz = [] dofs = ['x','y','z','rx','ry','rz'] print('Mode| T [sec] | f [Hz] | \u03C9 [rad/sec] | Mx [%] | My [%] | Mz [%] | \u2211Mx [%] | \u2211My [%] | \u2211Mz [%]') for mode in range(1,numEigen+1): # Although Mrx, Mry and Mrz are calculated, I am not printing these idx = 0 phi = np.zeros([N,1]) for node in used: for dof in used[node]: phi[idx,0]=op.nodeEigenvector(node,mode,dof) idx += 1 for dof in dofs: l = eval('l'+dof) Mtot = l.T@Mmatrix@l # Total mass in specified global dof Mn = phi.T@Mmatrix@phi # Modal mass in specified global dof Ln = phi.T@Mmatrix@l # Effective modal mass in specified global dof Mnstar = Ln**2/Mn/Mtot*100 # Normalised effective modal mass participating [%], in specified global dof eval('M'+dof).append(Mnstar[0,0]) # Save the modal mass for the specified dof print('%3s |%7s |%6s |%9s |%6s |%6s |%6s |%7s |%7s |%7s' \ % ("{:.0f}".format(mode), "{:.3f}".format(T[mode-1]), "{:.3f}".format(f[mode-1]), "{:.2f}".format(Omega[mode-1]), \ "{:.2f}".format(Mx[mode-1]), "{:.2f}".format(My[mode-1]), "{:.2f}".format(Mz[mode-1]), \ "{:.2f}".format(sum(Mx)), "{:.2f}".format(sum(My)), "{:.2f}".format(sum(Mz)))) Mtot = lx.T@Mmatrix@lx; Mtot = Mtot[0,0]
def NSProcedure(ndm, ndf, NbaysX, NbaysZ, NStr, XbayL, ZbayL, StoryH, lon, lat, SHL, Vso, gamma_soil, nu_soil, Re, fpc, Ec, gamma_conc, fy, E0, bsteel, ColTransfType, BeamEffFact, ColEffFact, g, Qsd, Ql, Qlr, EMs, R, Ie, StrType, BldTypCo, BldTypCm, DsgnType, dirs, directory): # The Nonlinear Static Procdure is executed in order to get responses # of a defined building. import openseespy.opensees as ops import OPSDefsMOD as OPSDMOD import OPSDefsAN as OPSDAN from timeit import default_timer as timer import ASCE716Seismic as ASCE716 import ASCE4117 import matplotlib.pyplot as plt import pickle import numpy as np for mm in range(len(NbaysX)): for nn in range(len(NStr)): for oo in range(len(Vso)): Teff = np.zeros( (len(dirs) )) # [s][LIST] effective lateral period of building. for ii in range(len(dirs)): time_o = timer() # Some previous definitions # ---------------------------- if DsgnType in ('conv_dsgn'): flex = 'no' elif DsgnType in ('ssi_dsgn'): flex = 'yes' # SiteClass = ASCE716.detSiteClass(Vso[oo]) # Unpicklin' some stored parameters from design process. # ------------------------------------------------------ workpath = directory + '\\RegularDesign\\' + str(NbaysX[mm])+'BayX'+str(NbaysZ)+\ 'BayZ'+str(NStr[nn])+'FLRS'+str(Vso[oo])+'.pickle' with open(workpath, 'rb') as f: ColDims, Colreinf, XBDims, XBreinf, ZBDims, ZBreinf, _, _, _, _, _, _, _, _, _, _ = pickle.load( f) # Calculation of height vector # ------------------------------ if flex in ('Y', 'YES', 'Yes', 'yES', 'yes', 'y'): # [m][LIST] with level height starting from first level or from base if foundation flexibility is included. hx = [0.0001] else: hx = [] for i in range(NStr[nn]): hx.append((i + 1) * StoryH) # Plan Dimensions of Building B = NbaysZ * ZbayL # [m] short side of building plan. L = NbaysX[mm] * XbayL # [m] long side of building plan. # Determination of MCEr spectral acceleration parameters # ------------------------------------------------------ (Sxs, Sx1) = ASCE4117.detSxi(lon, lat, Vso[oo], SHL) # MODELING OF THE STRUCTURE USING OPENSEESPY # =========================================== ops.wipe() OPSDMOD.ModelGen(ndm, ndf) OPSDMOD.NodeGen(NbaysX[mm], NbaysZ, XbayL, ZbayL, StoryH, NStr[nn], flex) OPSDMOD.MastNodeGen(NbaysX[mm], NbaysZ, XbayL, ZbayL, StoryH, NStr[nn], flex, coords=0) OPSDMOD.SPConstGen(NbaysX[mm], NbaysZ, flex) OPSDMOD.MPConstGen(NbaysX[mm], NbaysZ, NStr[nn], flex) OPSDMOD.MatGenRCB(fpc, Ec, fy, E0, bsteel) # OPSDMOD.GeomTransGen(ColTransfType,XBD=[min(XBDims[:,0]),min(XBDims[:,1])],\ # ZBD=[min(ZBDims[:,0]),min(ZBDims[:,1])],\ # ColD=[min(ColDims[:,0]),min(ColDims[:,1])]) OPSDMOD.GeomTransGen( ColTransfType, ColD=[min(ColDims[:, 0]), min(ColDims[:, 1])]) # OPSDMOD.GeomTransGen(ColTransfType) if flex in ('Y', 'YES', 'Yes', 'yES', 'yes', 'y'): # Interface elements generation for foundation flexibility considerations. # ========================================================================= # Materials generation: stiffness constants accounting for soil flexibility. # --------------------------------------------------------------------------- OPSDMOD.FoundFlexMaterials(NbaysX[mm],NbaysZ,XbayL,ZbayL,Sxs,Vso[oo],gamma_soil,nu_soil,B,L,Re,\ D=0,omega_soil=0,analtype='lat') # Zero-Length elements creation for connecting base nodes. OPSDMOD.FoundFlexZLElements(NbaysX[mm], NbaysZ, XbayL, ZbayL, B, L, Re) OPSDMOD.ElementGen(NbaysX[mm],NbaysZ,XbayL,ZbayL,NStr[nn],StoryH,XBDims,ZBDims,\ ColDims,BeamEffFact,ColEffFact,Ec,fy,EMs,\ XBreinf,ZBreinf,Colreinf,N=5,rec=0.0654,nuconc=0.2,dbar=0.025) [Wx,MassInputMatr] = \ OPSDMOD.LumpedMassGen(NbaysX[mm],NbaysZ,XBDims,ZBDims,ColDims,gamma_conc,g,XbayL,ZbayL,NStr[nn],StoryH,Qsd,flex) W = sum(Wx) # [kN] total weight of the building # GRAVITY LOADS APPLIED TO MODEL ACCORDINGO TO ASCE4117 # ====================================================== # According to ASCE4117 Section 7.2.2, equation (7-3), the combination # of gravitational loads mus be as follows: # Qg = Qd + 0.25*Ql + Qs (7-3) OPSDMOD.DeadLoadGen(NbaysX[mm], NbaysZ, NStr[nn], XBDims, ZBDims, ColDims, gamma_conc) OPSDMOD.SuperDeadLoadGen(NbaysX[mm], NbaysZ, NStr[nn], XbayL, ZbayL, Qsd) OPSDMOD.LiveLoadGen(NbaysX[mm], NbaysZ, NStr[nn], XbayL, ZbayL, 0.25 * Ql, 0.25 * Qlr) # GRAVITY-LOADS-CASE ANALYSIS. # ============================ ops.system('ProfileSPD') ops.constraints('Transformation') ops.numberer('RCM') ops.test('NormDispIncr', 1.0e-4, 100) ops.algorithm('KrylovNewton') ops.integrator('LoadControl', 1) ops.analysis('Static') ops.analyze(1) # Vertical reactions Calculation for verification. # ------------------------------------------------ ops.reactions() YReact = 0 for i in range((NbaysX[mm] + 1) * (NbaysZ + 1)): if flex in ('Y', 'YES', 'Yes', 'yES', 'yes', 'y'): YReact += ops.nodeReaction(int(i + 1), 2) else: YReact += ops.nodeReaction(int(i + 1 + 1e4), 2) # ========================================================================== # MODAL ANALYSIS FOR DETERMINING FUNDAMENTAL PERIOD AND ITS DIRECTION. # ========================================================================== (T, Tmaxver, Mast) = OPSDAN.ModalAnalysis(NStr[nn], B, L, Wx, flex) print(T) # ================== # PUSHOVER ANALYSIS # ================== # Lateral Force used for analysis # -------------------------------- # Using functions from ASCE716Seismic Module. (_,_,_,_,_,_,_,_,_,_,_,FxF,_,_,_) = \ ASCE716.ELFP(Sxs,Sx1,Vso[oo],Wx,R,Ie,hx,StrType,T[0,ii]) # Aplication of forces to the model. # ---------------------------------- ops.loadConst('-time', 0.0) MdeShape = OPSDMOD.POForceGen(NStr[nn], FxF, dirs[ii], flex) # ============================================= # First Execution of the analysis and output results. # ============================================= (results1,dtg1,tgfactor1) = \ OPSDAN.POAnalysisProc(lon,lat,Vso[oo],SHL,NbaysX[mm],NbaysZ,\ NStr[nn],StoryH,R,Ie,BldTypCo,BldTypCm,\ T[0,ii],W,dirs[ii],flex,\ DispIncr=0,beta=0.05,TL=8.,Tf=6.0,Npts=500,Vy=0,Te=0) # [Disp,Force] # ===================================================== # Determining the first approximation of values of Vy # and calculation of effective fundamental period for NSP # ===================================================== (Delta_y, V_y, Delta_d, V_d, Ke, alpha1, alpha2) = \ ASCE4117.IFDC(dtg1,results1) Ki = Mast[ii] * 4 * np.pi**2 / T[ 0, ii]**2 # [kN/m] elastic lateral stiffness of the building. Teff[ii] = T[0, ii] * ( Ki / Ke )**0.5 # [s] effctive fundamental period of building. # ============================================= # Second Execution of the analysis and output results. # ============================================= ops.wipe() OPSDMOD.ModelGen(ndm, ndf) OPSDMOD.NodeGen(NbaysX[mm], NbaysZ, XbayL, ZbayL, StoryH, NStr[nn], flex) OPSDMOD.MastNodeGen(NbaysX[mm], NbaysZ, XbayL, ZbayL, StoryH, NStr[nn], flex, coords=0) OPSDMOD.SPConstGen(NbaysX[mm], NbaysZ, flex) OPSDMOD.MPConstGen(NbaysX[mm], NbaysZ, NStr[nn], flex) OPSDMOD.MatGenRCB(fpc, Ec, fy, E0, bsteel) # OPSDMOD.GeomTransGen(ColTransfType,XBD=[min(XBDims[:,0]),min(XBDims[:,1])],\ # ZBD=[min(ZBDims[:,0]),min(ZBDims[:,1])],\ # ColD=[min(ColDims[:,0]),min(ColDims[:,1])]) OPSDMOD.GeomTransGen( ColTransfType, ColD=[min(ColDims[:, 0]), min(ColDims[:, 1])]) # OPSDMOD.GeomTransGen(ColTransfType) if flex in ('Y', 'YES', 'Yes', 'yES', 'yes', 'y'): # Interface elements generation for foundation flexibility considerations. # ========================================================================= # Materials generation: stiffness constants accounting for soil flexibility. # --------------------------------------------------------------------------- OPSDMOD.FoundFlexMaterials(NbaysX[mm],NbaysZ,XbayL,ZbayL,Sxs,Vso[oo],gamma_soil,nu_soil,B,L,Re,\ D=0,omega_soil=0,analtype='lat') # Zero-Length elements creation for connecting base nodes. OPSDMOD.FoundFlexZLElements(NbaysX[mm], NbaysZ, XbayL, ZbayL, B, L, Re) OPSDMOD.ElementGen(NbaysX[mm],NbaysZ,XbayL,ZbayL,NStr[nn],StoryH,XBDims,ZBDims,\ ColDims,BeamEffFact,ColEffFact,Ec,fy,EMs,\ XBreinf,ZBreinf,Colreinf,N=5,rec=0.0654,nuconc=0.2,dbar=0.025) [Wx,MassInputMatr] = \ OPSDMOD.LumpedMassGen(NbaysX[mm],NbaysZ,XBDims,ZBDims,ColDims,gamma_conc,g,XbayL,ZbayL,NStr[nn],StoryH,Qsd,flex) W = sum(Wx) # [kN] total weight of the building # GRAVITY LOADS APPLIED TO MODEL ACCORDINGO TO ASCE4117 # ====================================================== OPSDMOD.DeadLoadGen(NbaysX[mm], NbaysZ, NStr[nn], XBDims, ZBDims, ColDims, gamma_conc) OPSDMOD.SuperDeadLoadGen(NbaysX[mm], NbaysZ, NStr[nn], XbayL, ZbayL, Qsd) OPSDMOD.LiveLoadGen(NbaysX[mm], NbaysZ, NStr[nn], XbayL, ZbayL, 0.25 * Ql, 0.25 * Qlr) # GRAVITY-LOADS-CASE ANALYSIS. # ============================ ops.system('ProfileSPD') ops.constraints('Transformation') ops.numberer('RCM') ops.test('NormDispIncr', 1.0e-4, 100) ops.algorithm('KrylovNewton') ops.integrator('LoadControl', 1) ops.analysis('Static') ops.analyze(1) # ================== # PUSHOVER ANALYSIS # ================== # Lateral Force used for analysis # -------------------------------- # Using functions from ASCE716Seismic Module. (_,_,_,_,_,_,_,_,_,_,_,FxF,_,_,_) = \ ASCE716.ELFP(Sxs,Sx1,Vso[oo],Wx,R,Ie,hx,StrType,Teff[ii]) # Aplication of forces to the model. # ---------------------------------- ops.loadConst('-time', 0.0) MdeShape = OPSDMOD.POForceGen(NStr[nn], FxF, dirs[ii], flex) # ============================================= # First Execution of the analysis and output results. # ============================================= (results2,dtg2,tgfactor2) = \ OPSDAN.POAnalysisProc(lon,lat,Vso[oo],SHL,NbaysX[mm],NbaysZ,\ NStr[nn],StoryH,R,Ie,BldTypCo,BldTypCm,\ T[0,ii],W,dirs[ii],flex,\ DispIncr=0,beta=0.05,TL=8.,Tf=6.0,Npts=500,Vy=0,Te=Teff[ii]) # [Disp,Force]. # ===================================================== # Determining the "exact" values of Vy # and calculation of effective fundamental period for NSP # ===================================================== (Delta_y, V_y, Delta_d, V_d, Ke, alpha1, alpha2) = \ ASCE4117.IFDC(dtg1,results2) Ki = Mast[ii] * 4 * np.pi**2 / T[ 0, ii]**2 # [kN/m] elastic lateral stiffness of the building. Teff[ii] = T[0, ii] * ( Ki / Ke )**0.5 # [s] effctive fundamental period of building. ttime = timer() - time_o print(f'Elapsed Time {round(ttime/60,2)} [m]') plt.figure() plt.plot(results2[:, 0], results2[:, 1]) plt.grid() print('The mode shape is:') print(MdeShape) return (results1, results2), (dtg1, dtg2), (tgfactor1, tgfactor2), (tgfactor1 * dtg1, tgfactor2 * dtg2)
tf = 0.2 * s fr = 10 * Hz prd = 1 / fr ops.timeSeries('Trig', 1, ti, tf, prd) # https://openseespydoc.readthedocs.io/en/latest/src/pathTs.html ops.pattern('UniformExcitation', 1, 1, '-accel', 1) # https://openseespydoc.readthedocs.io/en/latest/src/uniformExcitation.html # amortiguamiento de rayleigh ops.rayleigh(*setRayParam(0.05, 0.05, 0.2, 20)) # analysis commands ops.constraints('Plain') ops.numberer('Plain') ops.system('UmfPack') ops.algorithm('Linear') ops.integrator('Newmark', 0.5, 0.25) ops.analysis('Transient') # analisis # ops.analyze(400,0.001) ops.start() for i in range(400): ops.analyze(1, 0.001) print(i) ops.stop() # Grafico de la deformada fig = plt.figure(figsize=(25, 5)) opsv.plot_defo(500) plt.show()
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()
def Analysis_Proc(Num: int, Node: int, dof: int, Dincr: float): ''' brief KrylovNewton → Newton -SecantNewton → ModifiedNewton → NewtonWithLineSearch → BGFS → Broyden\n pararm Num the number of analyze step\n return analyze if successful return 0 if NOT successful return < 0\n ''' for step in range(1, Num + 1): logger.info("No. %d of Cyclic. Anaylsis KrylovNewton..", step) ops.algorithm('KrylovNewton') ops.integrator("DisplacementControl", Node, dof, Dincr) ops.analysis("Static") ok = ops.analyze(1) if ok != 0: logger.info("No. %d of Cyclic. Anaylsis Trying SecantNewton ..", step) ops.algorithm('SecantNewton') ops.integrator("DisplacementControl", Node, dof, Dincr) ops.analysis("Static") ok = ops.analyze(1) if ok != 0: logger.info( "NO. %d of Cyclic. Anaylsis Trying NewtonLineSearch ..", step) ops.algorithm('NewtonLineSearch', True, False, True, False, 0.8, 1000, 0.1, 10.0) ops.integrator("DisplacementControl", Node, dof, Dincr) ops.analysis("Static") ok = ops.analyze(1) if ok != 0: logger.info("No. %d of Cyclic. Anaylsis Trying PeriodicNewton ..", step) ops.algorithm('PeriodicNewton') ops.integrator("DisplacementControl", Node, dof, Dincr) ops.analysis("Static") ok = ops.analyze(1) if ok != 0: logger.info( "NO. %d of Cyclic. Anaylsis Trying NewtonWithLineSearch ..", step) ops.algorithm('NewtonLineSearch') ops.integrator("DisplacementControl", Node, dof, Dincr) ops.analysis("Static") ok = ops.analyze(1) if ok != 0: logger.info("No. %d of Cyclic. Anaylsis Trying BFGS ..", step) ops.algorithm('BFGS', True, False, 10000000) ops.integrator("DisplacementControl", Node, dof, Dincr) ops.analysis("Static") ok = ops.analyze(1) if ok != 0: logger.info("No. %d of Cyclic. Anaylsis Trying Broyden ..", step) ops.algorithm('Broyden') ops.integrator("DisplacementControl", Node, dof, Dincr) ops.analysis("Static") ok = ops.analyze(1) if ok != 0: logger.info("No. $step of Cyclic. Analysis Convergence Failure!")
for i in range(nNode): ops.node(i+1, *Node[i][1:]) # construccion de elementos for i in range(nEle): if (Ele[i][0] == 1): ops.element('quad', i+1, *Ele[i][2:], B, 'PlaneStress', Ele[i][0]) # condiciones de frontera boundFix(nNode, Node) ops.timeSeries('Linear',1) ops.pattern('Plain',1,1) fx = 0 fy = -10*kN ops.load(2, fx, fy) #for i in range(nNode): # if (Node[i][0] == 2): # ops.load(i+1, fx, fy) ops.system('FullGeneral') # probar otros solvers: 'UmfPack' 'SparseSYM' ops.numberer('Plain') ops.constraints('Plain') ops.integrator('LoadControl',1) ops.algorithm('Linear') ops.analysis('Static') ops.analyze(1) # Desplazamiento disp = ops.nodeDisp(2,2) print(disp)
# create numberer object ops.numberer('Plain') # create convergence test object ops.test('PFEM', 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 10, 3, 1, 2) # create algorithm object ops.algorithm('Newton') # create integrator object ops.integrator('PFEM', 0.5, 0.25) # create SOE object ops.system('PFEM') # ops.system('PFEM', '-mumps) Linux version can use mumps # create analysis object ops.analysis('PFEM', dtmax, dtmin, b2) # analysis while ops.getTime() < totaltime: # analysis if ops.analyze() < 0: break ops.remesh() print("==========================================")