def ops_cyclic(): ops.remove('recorders') ops.wipeAnalysis() ops.loadConst('-time', 0.0) # set hysteresis ops.recorder('Node', '-file', f'output\\cyclic_81_disp_{argv[0]}.out', '-time', '-node', 81, '-dof', 1, 'disp') ops.recorder('Node', '-file', f'output\\cyclic_81_rea_{argv[0]}.out', '-time', '-nodeRange', 1, 8, '-dof', 1, 'reaction') # ops.timeSeries("Path", 2, '-dt', 0.1, '-filePath', 'disp.txt') ops.timeSeries('Linear', 2) ops.pattern('Plain', 2, 2) # ops.sp(81, 1, 1) ops.load(81, 1, 0, 0, 0, 0, 0) # ops.constraints('Penalty', 1e20, 1e20) # ops.numberer('RCM') # ops.system('BandGeneral') # ops.test('NormDispIncr', 1e-4, 1e6, 2) # ops.algorithm('KrylovNewton') # ops.integrator('LoadControl', 0.1) # ops.analysis('Static') # # ops.analyze(12961) # with open('disp.txt', 'r') as f: # i = 1 # lines = f.readlines() # count = len(lines) # for line in lines: # logger.info( # 'position = {} line = {} and {:3%}'.format(line[:-1], i, i/count)) # ops.analyze(1) # i = i + 1 CyclicDisplace(1e-3, 80, 1e-3, 81, 1, 1e-6, 1e6)
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 ops_cyclic(): ops.remove('recorders') ops.wipeAnalysis() ops.loadConst('-time', 0.0) # set hysteresis ops.recorder('Node', '-file', 'output\\cyclic_657.out', '-time', '-node', 651, '-dof', 1, 'disp') ops.pattern('Plain', 2, 1) ops.load(651, 1, 0, 0, 0, 0, 0) CyclicDisplace(1e-3, 80, 1e-3, 651, 1, 1, 1e6)
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()
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 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)
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("==========================")
T[0, 0], 'X', D, omega_soil) #%% ================== # PUSHOVER ANALYSIS # ================== time_o = timer() BldTypCo = 'Sh-T' BldTypCm = 'C-MF' dtarget = OPSDAN.POTargetDisp(Ss, S1, Tver[0, 0], W, Vso[0], NStr[0], BldTypCo, BldTypCm) # Aplication of forces to the model. # ---------------------------------- ops.loadConst('-time', 0.0) MdeShape = OPSDMOD.POForceGen(NStr[0], FxF[:, 0], dirs[0], flex) # Execution of the analysis and output results. # --------------------------------------------- (results,dtg) = \ OPSDAN.POAnalysisProc(Ss,S1,Vso[0],NbaysX[0],NbaysZ,NStr[0],StoryH,\ BldTypCo,BldTypCm,Tver[0,0],W,dirs[0]) # [Disp,Force] ttime = timer() - time_o print(f'Elapsed Time {round(ttime/60,2)} [m]') plt.figure() plt.plot(results[:, 0], results[:, 1]) plt.grid() #%% ======================
def build_model(model_params): """ Generates OpenSeesPy model of an elastic cantilever and runs gravity analysis. Assumes that length is measured in inches and acceleration in in/s2 Parameters ---------- NumberOfStories: int Number of stories StructureType: string Type of structural system - expects one of the HAZUS structure classes PlanArea: float Area of the structure's footprint """ # Assumptions h_story = 12 # Story height [ft] w_story = 200 # Story weight [psf] # constants for unit conversion ft = 1.0 inch = 12.0 m = 3.28084 ft2 = 1.0 inch2 = inch**2. m2 = m**2. psf = 1.0 Nsm = 4.88242 # N per square meter stories = model_params["NumberOfStories"] node_tags = list(range(stories + 1)) # The fundamental period is approximated as per ASCE 7-16 12.8.2.1 h_n = stories * h_story # [ft] if model_params['StructureType'] in [ 'S1', ]: # steel moment-resisting frames C_t = 0.028 x = 0.8 elif model_params['StructureType'] in [ 'C1', ]: # concrete moment-resisting frames C_t = 0.016 x = 0.9 elif model_params['StructureType'] in ['BRBF', 'ECBF']: # steel eccentrically braced frames or # steel buckling-restrained braced frame C_t = 0.03 x = 0.75 else: C_t = 0.02 x = 0.75 T1 = C_t * h_n**x # Eq 12.8-7 in ASCE 7-16 # check the units units = model_params["units"] if 'length' in units.keys(): if units['length'] == 'm': G = 9.81 h_story = h_story * m w_story = w_story * Nsm elif units['length'] == 'ft': G = 32.174 h_story = h_story * ft w_story = w_story / ft2 else: # elif units['length'] == 'in': G = 386.1 h_story = h_story * inch w_story = w_story / inch2 # The weight at each story is assumed to be identical W = model_params["PlanArea"] * w_story m = W / G # We calculate stiffness assuming half of the mass vibrates at the top K = ((m * stories) / 2.) / (T1 / (2 * pi))**2. # set model dimensions and degrees of freedom ops.model('basic', '-ndm', 3, '-ndf', 6) # define an elastic and a rigid material elastic_tag = 100 rigid_tag = 110 ops.uniaxialMaterial('Elastic', elastic_tag, K) ops.uniaxialMaterial('Elastic', rigid_tag, 1.e9) # define pattern for gravity loads ops.timeSeries('Linear', 1) ops.pattern('Plain', 101, 1) for story in range(0, stories + 1): # define nodes ops.node(node_tags[story], 0., 0., story * h_story) # define fixities if story == 0: ops.fix(node_tags[0], 1, 1, 1, 1, 1, 1) else: ops.fix(node_tags[story], 0, 0, 0, 1, 1, 1) # define elements if story > 0: element_tag = 1000 + story - 1 ops.element('twoNodeLink', element_tag, node_tags[story - 1], node_tags[story], '-mat', rigid_tag, elastic_tag, elastic_tag, '-dir', 1, 2, 3, '-orient', 0., 0., 1., 0., 1., 0., '-doRayleigh') # define masses ops.mass(node_tags[story], m, m, m, 0., 0., 0.) # define loads ops.load(node_tags[story], 0., 0., -W, 0., 0., 0.) # define damping based on first eigenmode damp_ratio = 0.05 angular_freq = ops.eigen(1)[0]**0.5 beta_k = 2 * damp_ratio / angular_freq ops.rayleigh(0., beta_k, 0., 0.) # run gravity analysis tol = 1e-8 # convergence tolerance for test iter = 100 # max number of iterations nstep = 100 # apply gravity loads in 10 steps incr = 1. / nstep # first load increment # analysis settings ops.constraints( 'Transformation' ) # enforce boundary conditions using transformation constraint handler ops.numberer( 'RCM') # renumbers dof's to minimize band-width (optimization) ops.system( 'BandGeneral' ) # stores system of equations as 1D array of size bandwidth x number of unknowns ops.test( 'EnergyIncr', tol, iter, 0 ) # tests for convergence using dot product of solution vector and norm of right-hand side of matrix equation ops.algorithm( 'Newton' ) # use Newton's solution algorithm: updates tangent stiffness at every iteration ops.integrator( 'LoadControl', incr ) # determine the next time step for an analysis # apply gravity in 10 steps ops.analysis('Static') # define type of analysis, static or transient ops.analyze(nstep) # perform gravity analysis # after gravity analysis, change time and tolerance for the dynamic analysis ops.loadConst('-time', 0.0)
def run_sensitivity_pushover_analysis(ctrlNode, baseNodes, dof, Dincr, max_disp, SensParam, IOflag=False): """ Run pushover analysis with sensitivity """ ops.wipeAnalysis() start_time = time.time() ops.loadConst("-time", 0.0) title("Running Displacement-Control Pushover Sensitivity Analysis ...") testType = "NormDispIncr" # EnergyIncr tolInit = 1.0E-8 iterInit = 10 # Set the initial Max Number of Iterations algorithmType = "Newton" # Set the algorithm type ops.system("BandGeneral") ops.constraints("Transformation") ops.numberer("RCM") ops.test(testType, tolInit, iterInit) ops.algorithm(algorithmType) # Change the integration scheme to be displacement control # node dof init Jd min max ops.integrator("DisplacementControl", ctrlNode, dof, Dincr) ops.analysis("Static") ops.sensitivityAlgorithm( "-computeAtEachStep" ) # automatically compute sensitivity at the end of each step if IOflag: print( f"Single Pushover: Push node {ctrlNode} to {max_disp} {LunitTXT}.\n" ) # Set some parameters tCurrent = ops.getTime() currentStep = 1 outputs = { "time": np.array([]), "disp": np.array([]), "force": np.array([]), } for sens in SensParam: outputs[f"sensLambda_{sens}"] = np.array([]), nodeList = [] for node in baseNodes: nodeList.append(f"- ops.nodeReaction({node}, dof) ") nodeList = "".join(nodeList) currentDisp = ops.nodeDisp(ctrlNode, dof) ok = 0 while ok == 0 and currentDisp < max_disp: ops.reactions() ok = ops.analyze(1) tCurrent = ops.getTime() currentDisp = ops.nodeDisp(ctrlNode, dof) if IOflag: print( f"Current displacement ==> {ops.nodeDisp(ctrlNode, dof):.3f} {LunitTXT}" ) # if the analysis fails try initial tangent iteration if ok != 0: print("\n==> Trying relaxed convergence...") ops.test(testType, tolInit / 0.01, iterInit * 50) ok = ops.analyze(1) if ok == 0: print("==> that worked ... back to default analysis...\n") ops.test(testType, tolInit, iterInit) if ok != 0: print("\n==> Trying Newton with initial then current...") ops.test(testType, tolInit / 0.01, iterInit * 50) ops.algorithm("Newton", "-initialThenCurrent") ok = ops.analyze(1) if ok == 0: print("==> that worked ... back to default analysis...\n") ops.algorithm(algorithmType) ops.test(testType, tolInit, iterInit) if ok != 0: print("\n==> Trying ModifiedNewton with initial...") ops.test(testType, tolInit / 0.01, iterInit * 50) ops.algorithm("ModifiedNewton", "-initial") ok = ops.analyze(1) if ok == 0: print("==> that worked ... back to default analysis...\n") ops.algorithm(algorithmType) ops.test(testType, tolInit, iterInit) currentStep += 1 tCurrent = ops.getTime() outputs["time"] = np.append(outputs["time"], tCurrent) outputs["disp"] = np.append(outputs["disp"], ops.nodeDisp(ctrlNode, dof)) outputs["force"] = np.append(outputs["force"], eval(nodeList)) for sens in SensParam: # sensLambda(patternTag, paramTag) outputs[f"sensLambda_{sens}"] = np.append( outputs[f"sensLambda_{sens}"], ops.sensLambda(1, sens)) # Print a message to indicate if analysis completed succesfully or not if ok == 0: title("Pushover Analysis Completed Successfully!") else: title("Pushover Analysis Completed Failed!") print( f"Analysis elapsed time is {(time.time() - start_time):.3f} seconds.\n" ) return outputs
def RectCFSTSteelHysteretic(length: float, secHeight: float, secWidth: float, thickness: float, concrete_grade: float, steel_grade: float, axial_load_ratio: float, disp_control: Iterable[float]): '''Peakstress: concrete peak stress \n crushstress: concrete crush stress ''' #disp input # dispControl=[3,-3,7,-7,14,-14,14,-14,14,-14,28,-28,28,-28,28,-28,42,-42,42,-42,42,-42,56,-56,0] dispControl = tuple(disp_control) #Geometry # length=740 # secHeight=100 # secWidth=100 # thickness=7 #Materials ##steel_tube point1Steel, point2Steel, point3Steel = [460, 0.00309], [460, 0.02721 ], [530, 0.26969] point1SteelNegative, point2SteelNegative, point3SteelNegative = [ -460, -0.00309 ], [-460, -0.02721], [-736, -0.26969] pinchX = 0.2 pinchY = 0.7 damagedFactor = 0.01 densitySteel = 7.8 / 1000000000 ##concrete peakPointConcrete, crushPointConcrete = [-221.76, -0.0102], [-195, -0.051] unloadingLambda = 0.2 tensileStrength = 5.6 tensilePostStiffness = 0.01 densityConcrete = 2.4 / 1000000000 #axialLoadRatio # axialLoadRatio=0.4 #fix condition Fixed = 1 #section parameter areaConcrete = (secHeight - 2 * thickness) * (secWidth - 2 * thickness) areaSteel = secWidth * secHeight - areaConcrete # fck,Ec,nuConcrete=128.1,4.34*10000,0.21 # fy,epsilonSteely,Es,nuSteel=444.6,3067/1000000,1.99*100000,0.29 fck = peakPointConcrete[0] fy = point1Steel[0] #Computate parameter axialLoad = (areaConcrete * fck + areaSteel * fy) * axial_load_ratio #loading control parameter # for item in dispControlPercentage: # dispControl.append(item*length) # dispControl.append(-item*length) # print('displist:'dispControl) #wipe and build a model ops.wipe() ops.model('basic', '-ndm', 2, '-ndf', 3) #node coordinates meshNumLength = 5 meshVerticalSize = length / meshNumLength meshSteelSize = 10 nodes = [(i + 1, meshVerticalSize * i) for i in range(int(length / meshVerticalSize) + 1)] for item in nodes: ops.node(item[0], 0, item[1]) #boundary condition ops.fix(1, 1, 1, 1) # if bool(Fixed): # ops.fix(int(length/meshVerticalSize)+1,0,0,1) ##uppper constrain condition: free or no-rotation #mass defination(concentrate mass to nodes) nodeMassSteel = areaSteel * meshVerticalSize * densitySteel nodeMassConcrete = areaConcrete * meshVerticalSize * densityConcrete nodeMass = nodeMassSteel + nodeMassConcrete for i in range(len(nodes) - 1): arg = [0., nodeMass, 0.] ops.mass(i + 2, *arg) #transformation: ops.geomTransf('Linear', 1) #material defination ##steel ops.uniaxialMaterial('Hysteretic', 1001, *point1Steel, *point2Steel, *point3Steel, *point1SteelNegative, *point2SteelNegative, *point3SteelNegative, pinchX, pinchY, damagedFactor, 0, 0.0) ##concrete ##using concrete01 #peakPointConcrete,crushPointConcrete=[110.6,0.00544],[22.11,0.09145] #ops.uniaxialMaterial('Concrete01',1,*peakPointConcrete,*crushPointConcrete) ###using concrete02 ops.uniaxialMaterial('Concrete02', 1, *peakPointConcrete, *crushPointConcrete, unloadingLambda, tensileStrength, tensilePostStiffness) #section defination ops.section('Fiber', 1) ##inner concrete fiber fiberPointI, fiberPointJ = [ -(secHeight - 2 * thickness) / 2, -(secWidth - 2 * thickness) / 2 ], [(secHeight - 2 * thickness) / 2, (secWidth - 2 * thickness) / 2] ops.patch('rect', 1, 10, 1, *fiberPointI, *fiberPointJ ) # https://opensees.berkeley.edu/wiki/index.php/Patch_Command ##outside steel fiber steelFiberProperty = { 'height': meshSteelSize, 'area': meshSteelSize * thickness } steelFiberPropertyLeftAndRight = { 'height': secWidth, 'area': secWidth * thickness } ###left and right leftEdgeFiberY, rightEdgeFiberY = -( secHeight - 2 * thickness) / 2 - thickness / 2, ( secHeight - 2 * thickness) / 2 + thickness / 2 #rightEdgeFiberY might be wrong leftandRightEdgeFiberZ = [ -secWidth / 2 + steelFiberPropertyLeftAndRight['height'] * (1 / 2 + N) for N in range(int(secWidth / steelFiberPropertyLeftAndRight['height'])) ] ###up and down upEdgeFiberZ, downEdgeFiberZ = -( secWidth - 2 * thickness) / 2 - thickness / 2, ( secWidth - 2 * thickness) / 2 + thickness / 2 upandDownEdgeFiberY = [ -secHeight / 2 + thickness + steelFiberProperty['height'] * (1 / 2 + N) for N in range( int((secHeight - 2 * thickness) / steelFiberProperty['height'])) ] for i in leftandRightEdgeFiberZ: i = float(i) ops.fiber(float(leftEdgeFiberY), i, steelFiberPropertyLeftAndRight['area'], 1001) ops.fiber(float(rightEdgeFiberY), i, steelFiberPropertyLeftAndRight['area'], 1001) for j in upandDownEdgeFiberY: j = float(j) ops.fiber(j, float(upEdgeFiberZ), steelFiberProperty['area'], 1001) ops.fiber(j, float(downEdgeFiberZ), steelFiberProperty['area'], 1001) #beamInergration defination ops.beamIntegration('NewtonCotes', 1, 1, 5) #element defination for i in range(len(nodes) - 1): ops.element('dispBeamColumn', i + 1, i + 1, i + 2, 1, 1) #recorders ops.recorder('Node', '-file', 'topLateralDisp.txt', '-time', '-node', int(length / meshVerticalSize + 1), '-dof', 1, 2, 'disp') ops.recorder('Node', '-file', 'topLateralForce.txt', '-time', '-node', int(length / meshVerticalSize + 1), '-dof', 1, 2, 'reaction') ops.recorder('Element', '-file', 'topElementForce.txt', '-time', '-ele', int(length / meshVerticalSize), 'force') #gravity load ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) ops.load(int(length / meshVerticalSize + 1), 0, axialLoad, 0) ops.constraints('Plain') ops.numberer('RCM') ops.system('BandGeneral') ##convertage test tolerant, allowedIteralStep = 1 / 1000000, 6000 ops.test('NormDispIncr', tolerant, allowedIteralStep) ops.algorithm('Newton') ops.integrator('LoadControl', 0.1) ops.analysis('Static') ops.analyze(10) ops.loadConst('-time', 0) #lateraldisp analysis ops.pattern('Plain', 2, 1) ops.load(int(length / meshVerticalSize + 1), 100, 0, 0) for i in range(len(dispControl)): if i == 0: ops.integrator('DisplacementControl', int(length / meshVerticalSize + 1), 1, 0.1) ops.analyze(int(dispControl[i] / 0.1)) # print('Working on disp round',i) else: if dispControl[i] >= 0: ops.integrator('DisplacementControl', int(length / meshVerticalSize + 1), 1, 0.1) ops.analyze(int( abs(dispControl[i] - dispControl[i - 1]) / 0.1)) # print('Working on disp round',i) else: ops.integrator('DisplacementControl', int(length / meshVerticalSize + 1), 1, -0.1) ops.analyze(int( abs(dispControl[i] - dispControl[i - 1]) / 0.1))
def DispControlSubStep(Nsteps:int , IDctrlNode:int, IDctrlDOF:int, Dmax:float, fac1=2, fac2=4, fac3=8, fac4=16, LoadConstandTimeZero=False): """ :param Nsteps: Number of Steps for the Analysis :param IDctrlNode: ID of the Control Node :param IDctrlDOF: DOF for Monitoring :param Dmax: Target Displacement :param LoadConstandTimeZero: True if you want to define pseudotime at the end of the analysis. Default is False """ if not fac1 < fac2: raise ValueError("fac1 must be smaller than fac2") if not fac2 < fac3: raise ValueError("fac2 must be smaller than fac3") if not fac3 < fac4: raise ValueError("fac3 must be smaller than fac4") NodeDisplacement = [] NodeReaction = [] committedSteps = 0 Dincr = Dmax / Nsteps for i in range(Nsteps): ops.integrator('DisplacementControl', IDctrlNode, IDctrlDOF, Dincr) AnalOk = ops.analyze(1) #NodeDisplacement.append(ops.nodeDisp(IDctrlNode, IDctrlDOF)) #NodeReaction.append(ops.nodeResponse(0, IDctrlDOF, 6)) if AnalOk != 0: break else: committedSteps += 1 # Start SubStepping if AnalOk != 0: firstFail = 1 Dstep = 0.0 Nk = 1 AnalOk = 0 retrunToInitStepFlag = False while Dstep <= 1.0 and AnalOk == 0: controlDisp = ops.nodeDisp(IDctrlNode, IDctrlDOF) Dstep = controlDisp / Dmax if (Nk == 2 and AnalOk == 0) or (Nk == 1 and AnalOk == 0): Nk = 1 if retrunToInitStepFlag: print("Back to Initial Step") retrunToInitStepFlag = False if firstFail == 0: ops.integrator('DisplacementControl', IDctrlNode, IDctrlDOF, Dincr) AnalOk = ops.analyze(1) else: AnalOk = 1 firstFail = 0 if AnalOk == 0: committedSteps += 1 # substepping /2 if (AnalOk != 0 and Nk == 1) or (AnalOk == 0 and Nk == fac2): Nk = fac1 continueFlag = 1 DincrReduced = Dincr / Nk print(f"Initial Step id Divided by {fac1}") ops.integrator('DisplacementControl', IDctrlNode, IDctrlDOF, DincrReduced) for ik in range(Nk - 1): if continueFlag == 0: break AnalOk = ops.analyze(1) if AnalOk == 0: committedSteps += 1 else: continueFlag = 0 if AnalOk == 0: retrunToInitStepFlag = True # substepping /4 if (AnalOk != 0 and Nk == fac1) or (AnalOk == 0 and Nk == fac3): Nk = fac2 continueFlag = 1 print(f"Initial Step is Divided by {fac2}") DincrReduced = Dincr / Nk ops.integrator('DisplacementControl', IDctrlNode, IDctrlDOF, DincrReduced) for i in range(Nk - 1): if continueFlag == 0: break AnalOk = ops.analyze(1) if AnalOk == 0: committedSteps += 1 else: continueFlag = 0 if AnalOk == 0: retrunToInitStepFlag = True # substepping / 8 if (AnalOk != 0 and Nk == fac2) or (AnalOk == 0 and Nk == fac4): Nk = fac3 continueFlag = 1 print(f"Initial Step is Divided by {fac3}") DincrReduced = Dincr / Nk ops.integrator('DisplacementControl', IDctrlNode, IDctrlDOF, DincrReduced) for i in range(Nk - 1): if continueFlag == 0: break AnalOk = ops.analyze(1) if AnalOk == 0: committedSteps += 1 else: continueFlag = 0 if AnalOk == 0: retrunToInitStepFlag = True if (AnalOk != 0 and Nk == fac3): Nk = fac4 continueFlag = 1 print(f"Initial Step is Divided by {fac4}") DincrReduced = Dincr / Nk ops.integrator('DisplacementControl', IDctrlNode, IDctrlDOF, DincrReduced) for i in range(Nk - 1): if continueFlag == 0: break AnalOk = ops.analyze(1) if AnalOk == 0: committedSteps += 1 else: continueFlag = 0 if AnalOk == 0: retrunToInitStepFlag = True controlDisp = ops.nodeDisp(IDctrlNode, IDctrlDOF) Dstep = controlDisp / Dmax # Analysis Status if AnalOk == 0: print("Analysis Completed SUCCESSFULLY") print("Commited Steps {}".format(committedSteps)) else: print("Analysis FAILED") print("Commited Steps {}".format(committedSteps)) if LoadConstandTimeZero == True: ops.loadConst('-time', 0.0) ops.setTime(0.0)
def test_RCFramePushover(): ops.wipe() # ---------------------------------------------------- # Start of Model Generation & Initial Gravity Analysis # ---------------------------------------------------- # Do operations of Example3.1 by sourcing in the tcl file exec(open('RCFrameGravity.py', 'r').read()) print("Gravity Analysis Completed") # Set the gravity loads to be constant & reset the time in the domain ops.loadConst('-time', 0.0) # ---------------------------------------------------- # End of Model Generation & Initial Gravity Analysis # ---------------------------------------------------- # ---------------------------------------------------- # Start of additional modelling for lateral loads # ---------------------------------------------------- # Define lateral loads # -------------------- # Set some parameters H = 10.0 # Reference lateral load # Set lateral load pattern with a Linear TimeSeries ops.pattern('Plain', 2, 1) # Create nodal loads at nodes 3 & 4 # nd FX FY MZ ops.load(3, H, 0.0, 0.0) ops.load(4, H, 0.0, 0.0) # ---------------------------------------------------- # End of additional modelling for lateral loads # ---------------------------------------------------- # ---------------------------------------------------- # Start of modifications to analysis for push over # ---------------------------------------------------- # Set some parameters dU = 0.1 # Displacement increment # Change the integration scheme to be displacement control # node dof init Jd min max ops.integrator('DisplacementControl', 3, 1, dU, 1, dU, dU) # ---------------------------------------------------- # End of modifications to analysis for push over # ---------------------------------------------------- # ------------------------------ # Start of recorder generation # ------------------------------ # Stop the old recorders by destroying them # remove recorders # Create a recorder to monitor nodal displacements #recorder Node -file node32.out -time -node 3 4 -dof 1 2 3 disp # Create a recorder to monitor element forces in columns #recorder EnvelopeElement -file ele32.out -time -ele 1 2 forces # -------------------------------- # End of recorder generation # --------------------------------- # ------------------------------ # Finally perform the analysis # ------------------------------ # Set some parameters maxU = 15.0 # Max displacement currentDisp = 0.0 ok = 0 ops.test('NormDispIncr', 1.0e-12, 1000) ops.algorithm('ModifiedNewton', '-initial') while ok == 0 and currentDisp < maxU: ok = ops.analyze(1) # if the analysis fails try initial tangent iteration if ok != 0: print("modified newton failed") break # print "regular newton failed .. lets try an initail stiffness for this step" # test('NormDispIncr', 1.0e-12, 1000) # # algorithm('ModifiedNewton', '-initial') # ok = analyze(1) # if ok == 0: # print "that worked .. back to regular newton" # test('NormDispIncr', 1.0e-12, 10) # algorithm('Newton') currentDisp = ops.nodeDisp(3, 1) assert ok == 0
def test_Ex1aCanti2DEQmodif(): # SET UP ---------------------------------------------------------------------------- ops.wipe() # clear opensees model ops.model('basic', '-ndm', 2, '-ndf', 3) # 2 dimensions, 3 dof per node # file mkdir data # create data directory # define GEOMETRY ------------------------------------------------------------- # nodal coordinates: ops.node(1, 0., 0.) # node#, X Y ops.node(2, 0., 432.) # Single point constraints -- Boundary Conditions ops.fix(1, 1, 1, 1) # node DX DY RZ # nodal masses: ops.mass(2, 5.18, 0., 0.) # node#, Mx My Mz, Mass=Weight/g. # Define ELEMENTS ------------------------------------------------------------- # define geometric transformation: performs a linear geometric transformation of beam stiffness and resisting force from the basic system to the global-coordinate system ops.geomTransf('Linear', 1) # associate a tag to transformation # connectivity: ops.element('elasticBeamColumn', 1, 1, 2, 3600.0, 3225.0, 1080000.0, 1) # define GRAVITY ------------------------------------------------------------- ops.timeSeries('Linear', 1) ops.pattern( 'Plain', 1, 1, ) ops.load(2, 0., -2000., 0.) # node#, FX FY MZ -- superstructure-weight ops.constraints('Plain') # how it handles boundary conditions ops.numberer( 'Plain' ) # renumber dof's to minimize band-width (optimization), if you want to ops.system( 'BandGeneral' ) # how to store and solve the system of equations in the analysis ops.algorithm('Linear') # use Linear algorithm for linear analysis ops.integrator( 'LoadControl', 0.1 ) # determine the next time step for an analysis, # apply gravity in 10 steps ops.analysis('Static') # define type of analysis static or transient ops.analyze(10) # perform gravity analysis ops.loadConst('-time', 0.0) # hold gravity constant and restart time # DYNAMIC ground-motion analysis ------------------------------------------------------------- # create load pattern G = 386.0 ops.timeSeries( 'Path', 2, '-dt', 0.005, '-filePath', 'A10000.dat', '-factor', G ) # define acceleration vector from file (dt=0.005 is associated with the input file gm) ops.pattern( 'UniformExcitation', 2, 1, '-accel', 2) # define where and how (pattern tag, dof) acceleration is applied # set damping based on first eigen mode evals = ops.eigen('-fullGenLapack', 1) freq = evals[0]**0.5 dampRatio = 0.02 ops.rayleigh(0., 0., 0., 2 * dampRatio / freq) # display displacement shape of the column # recorder display "Displaced shape" 10 10 500 500 -wipe # prp 200. 50. 1 # vup 0 1 0 # vpn 0 0 1 # display 1 5 40 # create the analysis ops.wipeAnalysis() # clear previously-define analysis parameters ops.constraints('Plain') # how it handles boundary conditions ops.numberer( 'Plain' ) # renumber dof's to minimize band-width (optimization), if you want to ops.system( 'BandGeneral' ) # how to store and solve the system of equations in the analysis ops.algorithm('Linear') # use Linear algorithm for linear analysis ops.integrator('Newmark', 0.5, 0.25) # determine the next time step for an analysis ops.analysis('Transient') # define type of analysis: time-dependent ops.analyze(3995, 0.01) # apply 3995 0.01-sec time steps in analysis u2 = ops.nodeDisp(2, 2) print("u2 = ", u2) assert abs(u2 + 0.07441860465116277579) < 1e-12 ops.wipe() print("=========================================")
def LoadControlSubStep(Nsteps: int, Lincr: float, fac1=2, fac2=4, fac3=8, fac4=16, LoadConstandTimeZero=False): """ :param Nsteps: Number of Analysis Steps :param Lincr: LoadFactor Increment :param LoadConstandTimeZero: True if you want to define pseudotime at the end of the analysis. Default is False (optional) """ if not fac1 < fac2: raise ValueError("fac1 must be smaller than fac2") if not fac2 < fac3: raise ValueError("fac2 must be smaller than fac3") if not fac3 < fac4: raise ValueError("fac3 must be smaller than fac4") LoadCounter = 0 committedSteps = 1 for i in range(Nsteps): AnalOk = ops.analyze(1) if AnalOk != 0: break else: LoadCounter += 1 committedSteps += 1 if AnalOk != 0: firstFail = 1 AnalOk = 0 Nk = 1 retrunToInitStepFlag = False while (LoadCounter < Nsteps) and (AnalOk == 0): if (Nk == 2 and AnalOk == 0) or (Nk == 1 and AnalOk == 0): Nk = 1 if retrunToInitStepFlag: print("Back to Initial Step") retrunToInitStepFlag = False if firstFail == 0: ops.integrator('LoadControl', Lincr) AnalOk = ops.analyze(1) else: AnalOk = 1 firstFail = 0 if AnalOk == 0: LoadCounter = LoadCounter + 1 / Nk committedSteps += 1 # substepping /2 if (AnalOk != 0 and Nk == 1) or (AnalOk == 0 and Nk == fac2): Nk = fac1 continueFlag = 1 print(f"Initial Step is Devided by {fac1}") LincrReduced = Lincr / Nk ops.integrator('LoadControl', LincrReduced) for i in range(Nk - 1): if continueFlag == 0: break AnalOk = ops.analyze(1) if AnalOk == 0: LoadCounter = LoadCounter + 1 / Nk committedSteps += 1 else: continueFlag = 0 if AnalOk == 0: retrunToInitStepFlag = True # substepping /4 if (AnalOk != 0 and Nk == fac1) or (AnalOk == 0 and Nk == fac3): Nk = fac2 continueFlag = 1 print(f'Initial Step is Devided by {fac2}') LincrReduced = Lincr / Nk ops.integrator('LoadControl', LincrReduced) for i in range(Nk - 1): if continueFlag == 0: break AnalOk = ops.analyze(1) if AnalOk == 0: LoadCounter = LoadCounter + 1 / Nk committedSteps += 1 else: continueFlag = 0 if AnalOk == 0: retrunToInitStepFlag = True # substepping /8 if (AnalOk != 0 and Nk == fac2) or (AnalOk == 0 and Nk == fac4): Nk = fac3 continueFlag = 1 print(f'Initial Step is Devided by {fac3}') LincrReduced = Lincr / Nk ops.integrator('LoadControl', LincrReduced) for i in range(Nk - 1): if continueFlag == 0: break AnalOk = ops.analyze(1) if AnalOk == 0: LoadCounter = LoadCounter + 1 / Nk committedSteps += 1 else: continueFlag = 0 if AnalOk == 0: retrunToInitStepFlag = True # substepping /16 if (AnalOk != 0 and Nk == fac3): Nk = fac4 continueFlag = 1 print(f'Initial Step is Devided by {fac4}') LincrReduced = Lincr / Nk ops.integrator('LoadControl', LincrReduced) for i in range(Nk - 1): if continueFlag == 0: break AnalOk = ops.analyze(1) if AnalOk == 0: LoadCounter = LoadCounter + 1 / Nk committedSteps += 1 else: continueFlag = 0 if AnalOk == 0: retrunToInitStepFlag = True # Analysis Status if AnalOk == 0: print("Analysis Completed SUCCESSFULLY") print("Committed Steps {}".format(committedSteps)) else: print("Analysis FAILED") print("Committed Steps {}".format(committedSteps)) if LoadConstandTimeZero == True: ops.loadConst('-time', 0.0) ops.setTime(0.0)