def test_DynAnal_BeamWithQuadElements(): ops.wipe() # clear opensees model # create data directory # file mkdir Data #----------------------------- # Define the model # ---------------------------- # Create ModelBuilder with 2 dimensions and 2 DOF/node ops.model('BasicBuilder', '-ndm', 2, '-ndf', 2) # create the material ops.nDMaterial('ElasticIsotropic', 1, 1000.0, 0.25, 3.0) # set type of quadrilateral element (uncomment one of the three options) Quad = 'quad' #set Quad bbarQuad #set Quad enhancedQuad # set up the arguments for the three considered elements if Quad == "enhancedQuad": eleArgs = "PlaneStress2D 1" if Quad == "quad": eleArgs = "1 PlaneStress2D 1" if Quad == "bbarQuad": eleArgs = "1" # set up the number of elements in x (nx) and y (ny) direction nx = 16 # NOTE: nx MUST BE EVEN FOR THIS EXAMPLE ny = 4 # define numbering of node at the left support (bn), and the two nodes at load application (l1, l2) bn = nx + 1 l1 = int(nx / 2 + 1) l2 = int(l1 + ny * (nx + 1)) # create the nodes and elements using the block2D command ops.block2D(nx, ny, 1, 1, Quad, 1., 'PlaneStress2D', 1, 1, 0., 0., 2, 40., 0., 3, 40., 10., 4, 0., 10.) # define boundary conditions ops.fix(1, 1, 1) ops.fix(bn, 0, 1) # define the recorder #--------------------- # recorder Node -file Data/Node.out -time -node l1 -dof 2 disp # define load pattern #--------------------- ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) ops.load(l1, 0.0, -1.0) ops.load(l2, 0.0, -1.0) # -------------------------------------------------------------------- # Start of static analysis (creation of the analysis & analysis itself) # -------------------------------------------------------------------- # Load control with variable load steps # init Jd min max ops.integrator('LoadControl', 1.0, 1, 1.0, 10.0) # Convergence test # tolerance maxIter displayCode ops.test('EnergyIncr', 1.0e-12, 10, 0) # Solution algorithm ops.algorithm('Newton') # DOF numberer ops.numberer('RCM') # Cosntraint handler ops.constraints('Plain') # System of equations solver ops.system('ProfileSPD') # Type of analysis analysis ops.analysis('Static') # Perform the analysis ops.analyze(10) # -------------------------- # End of static analysis # -------------------------- # ------------------------------------- # create display for transient analysis #-------------------------------------- # windowTitle xLoc yLoc xPixels yPixels # recorder display "Simply Supported Beam" 10 10 800 200 -wipe # prp 20 5.0 1.0 # projection reference point (prp) defines the center of projection (viewer eye) # vup 0 1 0 # view-up vector (vup) # vpn 0 0 1 # view-plane normal (vpn) # viewWindow -30 30 -10 10 # coordiantes of the window relative to prp # display 10 0 5 # the 1st arg. is the tag for display mode # the 2nd arg. is magnification factor for nodes, the 3rd arg. is magnif. factor of deformed shape # --------------------------------------- # Create and Perform the dynamic analysis # --------------------------------------- #define damping evals = ops.eigen(1) ops.rayleigh(0., 0., 0., 2 * 0.02 / sqrt(evals[0])) # Remove the static analysis & reset the time to 0.0 ops.wipeAnalysis() ops.setTime(0.0) # Now remove the loads and let the beam vibrate ops.remove('loadPattern', 1) uy1 = ops.nodeDisp(9, 2) print("uy(9) = ", uy1) # Create the transient analysis ops.test('EnergyIncr', 1.0e-12, 10, 0) ops.algorithm('Newton') ops.numberer('RCM') ops.constraints('Plain') ops.integrator('Newmark', 0.5, 0.25) ops.system('BandGeneral') ops.analysis('Transient') # Perform the transient analysis (50 sec) ops.analyze(1500, 0.5) uy2 = ops.nodeDisp(9, 2) print("uy(9) = ", uy2) assert abs(uy1 + 0.39426414168933876514) < 1e-12 and abs( uy2 + 0.00736847273806807632) < 1e-12 print("========================================")
op.pattern('Plain', 1, 1) 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 #applying Dynamic Ground motion analysis GMdirection = 1 GMfile = 'BM68elc.acc' GMfact = 1.0
time = [tCurrent] u3 = [0.0] u4 = [0.0] ok = 0 while tCurrent < tFinal: # ok = op.analyze(1, .01) for i in test: for j in algorithm: if j < 4: op.algorithm(algorithm[j], '-initial') else: op.algorithm(algorithm[j]) while ok == 0 and tCurrent < tFinal: op.test(test[i], Tol, maxNumIter) NewmarkGamma = 0.5 NewmarkBeta = 0.25 op.integrator('Newmark', NewmarkGamma, NewmarkBeta) op.analysis('Transient') ok = op.analyze(1, .01) if ok == 0: tCurrent = op.getTime() time.append(tCurrent) u3.append(op.nodeDisp(3, 1)) u4.append(op.nodeDisp(4, 1)) print(test[i], algorithm[j], 'tCurrent=', tCurrent) import matplotlib.pyplot as plt
def main(): """ Create a Cantilever Problem """ ops.wipe() ops.model('basic', '-ndm', 2, '-ndf', 3) height = 5.0 nElem = 20 ElemLength = height / nElem nodeID = [] Ycoord = 0 for i in range(nElem + 1): nodeID.append(i) ops.node(i, 0.0, Ycoord) Ycoord += ElemLength IDctrlNode = i ops.fix(0, 1, 1, 1) ops.geomTransf('Linear', 1) concrete = 'Concrete04' steel = 'Steel02' matTAGConc = 319 matTAGSteel = 312 fcc = -20000 ec2c = -0.002 ecu2c = -0.0035 Ec = 30000000 fct = 2200 et = 0.001 fy = 500000 E0 = 200000000 b = 0.01 ops.uniaxialMaterial(concrete, matTAGConc, fcc, ec2c, ecu2c, Ec, fct, et) ops.uniaxialMaterial(steel, matTAGSteel, fy, E0, b, 20, 0.925, 0.15, 0, 1, 0, 1, 0) # Core Fibers ops.section('Fiber', 105) ops.patch('rect', 319, 11, 11, -0.20, -0.20, 0.20, 0.20) # Cover Fibers ops.patch('rect', 319, 15, 2, 0.250000, 0.200000, -0.250000, 0.250000) ops.patch('rect', 319, 15, 2, 0.250000, -0.250000, -0.250000, -0.200000) ops.patch('rect', 319, 2, 11, -0.250000, -0.200000, -0.200000, 0.200000) ops.patch('rect', 319, 2, 11, 0.200000, -0.200000, 0.250000, 0.200000) # create corner bars ops.layer('straight', 312, 4, 0.00025450, 0.200000, 0.200000, -0.200000, 0.200000) ops.layer('straight', 312, 4, 0.00025450, 0.200000, -0.200000, -0.200000, -0.200000) ops.beamIntegration('Lobatto', 100, 105, 3) for i in range(len(nodeID) - 1): ops.element('forceBeamColumn', i, nodeID[i], nodeID[i + 1], 1, 100, '-iter', 10, 1e-6) # Add Vertical Load at Top ops.timeSeries('Linear', 101) ops.pattern('Plain', 100, 101) ops.load(IDctrlNode, 0, -500, 0) # Solve Gravity First ops.system('UmfPack') ops.numberer('Plain') ops.constraints('Transformation') ops.integrator('LoadControl', 0.1) ops.test('RelativeTotalNormDispIncr', 0.001, 100, 2) ops.algorithm('Newton') ops.analysis('Static') LoadControlSubStep(10, 0.1, True) # Displacement Control Analysis(Pushover) ops.pattern('Plain', 200, 101) ops.load(IDctrlNode, 1, 0, 0) ops.system('UmfPack') ops.numberer('Plain') ops.constraints('Transformation') ops.test('RelativeTotalNormDispIncr', 1e-2, 500, 2) ops.algorithm('Newton') ops.analysis('Static') DispControlSubStep(100, IDctrlNode, 1, 1.0)
def RunAnalysis(): # ---------------------------- # Start of model generation # ---------------------------- # remove existing model ops.wipe() ops.model("BasicBuilder", "-ndm", 3, "-ndf", 6) # set default units ops.defaultUnits("-force", "kip", "-length", "in", "-time", "sec", "-temp", "F") # Define the section # ------------------ # secTag E nu h rho ops.section("ElasticMembranePlateSection", 1, 3.0E3, 0.25, 1.175, 1.27) # Define geometry # --------------- # these should both be even nx = 10 ny = 2 # loaded nodes mid = int(((nx + 1) * (ny + 1) + 1) / 2) side1 = int((nx + 2) / 2) side2 = int((nx + 1) * (ny + 1) - side1 + 1) # generate the nodes and elements # numX numY startNode startEle eleType eleArgs? coords? ops.block2D(nx, ny, 1, 1, "ShellMITC4", 1, 1, -20.0, 0.0, 0.0, 2, -20.0, 0.0, 40.0, 3, 20.0, 0.0, 40.0, 4, 20.0, 0.0, 0.0, 5, -10.0, 10.0, 20.0, 7, 10.0, 10.0, 20.0, 9, 0.0, 10.0, 20.0) # define the boundary conditions ops.fixZ(0.0, 1, 1, 1, 0, 1, 1) ops.fixZ(40.0, 1, 1, 1, 0, 1, 1) ops.mass(20, 10.0, 10.0, 10.0, 0.0, 0.0, 0.0) # create a Linear time series ops.timeSeries("Linear", 1) # add some loads ops.pattern("Plain", 1, 1, "-fact", 1.0) ops.load(mid, 0.0, -0.50, 0.0, 0.0, 0.0, 0.0) ops.load(side1, 0.0, -0.25, 0.0, 0.0, 0.0, 0.0) ops.load(side2, 0.0, -0.25, 0.0, 0.0, 0.0, 0.0) # ------------------------ # Start of static analysis # ------------------------ # Load control with variable load steps # init Jd min max ops.integrator("LoadControl", 1.0, 1, 1.0, 10.0) ops.test("EnergyIncr", 1.0E-10, 20, 0) ops.algorithm("Newton") ops.numberer("RCM") ops.constraints("Plain") ops.system("SparseGeneral", "-piv") ops.analysis("Static") ops.analyze(5) # --------------------------------------- # Create and Perform the dynamic analysis # --------------------------------------- # Remove the static analysis & reset the time to 0.0 ops.wipeAnalysis() ops.setTime(0.0) # Now remove the loads and let the beam vibrate ops.remove("loadPattern", 1) Model = 'test' LoadCase = 'Transient' LoadCase2 = 'Transient_5s' opp.createODB(Model, LoadCase, Nmodes=3, recorders=[]) opp.createODB(Model, LoadCase2, Nmodes=3, deltaT=5., recorders=[]) # Create the transient analysis ops.test("EnergyIncr", 1.0E-10, 20, 0) ops.algorithm("Newton") ops.numberer("RCM") ops.constraints("Plain") ops.system("SparseGeneral", "-piv") ops.integrator("Newmark", 0.50, 0.25) ops.analysis("Transient") # Perform the transient analysis (20 sec) ops.analyze(100, 0.2)
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))
op.recorder('Node', '-file', 'Data-1b/DFree.out','-time', '-node', 3,4, '-dof', 1,2,3, 'disp') op.recorder('Node', '-file', 'Data-1b/DBase.out','-time', '-node', 1,2, '-dof', 1,2,3, 'disp') op.recorder('Node', '-file', 'Data-1b/RBase.out','-time', '-node', 1,2, '-dof', 1,2,3, 'reaction') #op.recorder('Drift', '-file', 'Data-1b/Drift.out','-time', '-node', 1, '-dof', 1,2,3, 'disp') op.recorder('Element', '-file', 'Data-1b/FCol.out','-time', '-ele', 1,2, 'globalForce') op.recorder('Element', '-file', 'Data-1b/DCol.out','-time', '-ele', 3, 'deformations') #defining gravity loads op.timeSeries('Linear', 1) op.pattern('Plain', 1, 1) op.eleLoad('-ele', 3, '-type', '-beamUniform', -7.94) op.constraints('Plain') op.numberer('Plain') op.system('BandGeneral') op.test('NormDispIncr', 1e-8, 6) op.algorithm('Newton') op.integrator('LoadControl', 0.1) op.analysis('Static') op.analyze(10) op.loadConst('-time', 0.0) #applying Dynamic Ground motion analysis op.timeSeries('Path', 2, '-dt', 0.01, '-filePath', 'BM68elc.acc', '-factor', 1.0) op.pattern('UniformExcitation', 2, 1, '-accel', 2) #how to give accelseriesTag? eigen = op. eigen('-fullGenLapack', 1) import math power = math.pow(eigen, 0.5) betaKcomm = 2 * (0.02/power)
ops.mesh('tri', wallTag, 2, 1, 2, wall_id, ndf, h) for nd in ops.getNodeTags('-mesh', wallTag): ops.fix(nd, 1, 1, 1) # save the original modal ops.record() # create constraint object ops.constraints('Plain') # create numberer object ops.numberer('Plain') # create convergence test object ops.test('PFEM', 1e-5, 1e-5, 1e-5, 1e-5, 1e-15, 1e-15, 20, 3, 1, 2) # create algorithm object ops.algorithm('Newton') # create integrator object ops.integrator('PFEM') # create SOE object ops.system('PFEM') # create analysis object ops.analysis('PFEM', dtmax, dtmin, b2) # analysis while ops.getTime() < totaltime:
tk = 1. Tp = 1/pf P0 = 15000. dt = 0.002 n_steps = int((tk-t0)/dt) tsTag = 1 ops.timeSeries('Trig', tsTag, t0, tk, Tp, '-factor', P0) patTag = 1 ops.pattern('Plain', patTag, tsTag) ops.load(1, 1., 0., 0.) ops.constraints('Transformation') ops.numberer('RCM') ops.test('NormDispIncr', 1.0e-6, 10, 1) ops.algorithm('Linear') ops.system('ProfileSPD') ops.integrator('Newmark', 0.5, 0.25) ops.analysis('Transient') el_tags = ops.getEleTags() nels = len(el_tags) Eds = np.zeros((n_steps, nels, 6)) timeV = np.zeros(n_steps) # transient analysis loop and collecting the data for step in range(n_steps): ops.analyze(1, dt)
ops.element('Truss', 74, 20, 25, 223.53e-6, 7) ops.element('Truss', 75, 25, 30, 223.53e-6, 7) ops.element('Truss', 76, 30, 35, 223.53e-6, 7) ops.element('Truss', 77, 35, 40, 223.53e-6, 7) ops.element('Truss', 78, 40, 45, 223.53e-6, 7) ops.element('Truss', 79, 45, 50, 223.53e-6, 7) ops.element('Truss', 80, 50, 55, 223.53e-6, 7) ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) ops.load(53, 0, -246000, 0, 0, 0, 0) ops.constraints('Plain') ops.numberer('RCM') ops.system('BandGeneral') ops.test('NormDispIncr', 1.0e-6, 2000) ops.algorithm('Newton') ops.integrator('LoadControl', 0.01) ops.analysis('Static') ops.analyze(100) logger.info("gravity analyze ok...") ops.wipeAnalysis() ops.loadConst('-time', 0.0) ops.recorder('Node', '-file', '53.txt', ' -time', '-node', 53, '-dof', 1, 'disp') ops.recorder('Node', '-file', '1.txt', '-time ', '-node', 1, 2, 3, 4, 5, '-dof', 1, 'reaction')
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
ops.constraints('Transformation') print("\n constraints完成") ops.numberer('RCM') print("\n numberer完成") # ops.system('SparseSYM') ops.system('SparseGeneral') print("\n system完成") # ============================================================================= # for test # ============================================================================= # test('NormDispIncr', tol, iter, pFlag=0, nType=2) ops.test("NormDispIncr", 0.1, 2000, 2) print("\n test完成") # ============================================================================= # # ============================================================================= ops.algorithm("NewtonLineSearch", False, False, False, False, 0.75) # ops.algorithm('Newton') print("\n algorithm完成") # integrator('LoadControl', incr, numIter=1, minIncr=incr, maxIncr=incr) ops.integrator("LoadControl", 0.1) print("\n integrator完成") ops.analysis("Static")
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 run_nlth_analysis_on_sdof_ops_py(capacity_curve, gmr, damping, degradation): cap_df = pd.DataFrame(capacity_curve) if any(cap_df.duplicated()): warnings.warn( "Warning: Duplicated pairs have been found in capacity curve!") ops.wipe() ops.model('basic', '-ndm', 1, '-ndf', 1) d_cap = capacity_curve[:, 0] f_cap = capacity_curve[:, 1] * 9.81 f_vec = np.zeros([5, 1]) d_vec = np.zeros([5, 1]) if len(f_cap) == 3: #bilinear curve f_vec[1] = f_cap[1] f_vec[4] = f_cap[-1] d_vec[1] = d_cap[1] d_vec[4] = d_cap[-1] d_vec[2] = d_vec[1] + (d_vec[4] - d_vec[1]) / 3 d_vec[3] = d_vec[1] + 2 * ((d_vec[4] - d_vec[1]) / 3) f_vec[2] = np.interp(d_vec[2], d_cap, f_cap) f_vec[3] = np.interp(d_vec[3], d_cap, f_cap) elif len(f_cap) == 4: f_vec[1] = f_cap[1] f_vec[4] = f_cap[-1] d_vec[1] = d_cap[1] d_vec[4] = d_cap[-1] f_vec[2] = f_cap[2] d_vec[2] = d_cap[2] d_vec[3] = np.mean([d_vec[2], d_vec[-1]]) f_vec[3] = np.interp(d_vec[3], d_cap, f_cap) elif len(f_cap) == 5: f_vec[1] = f_cap[1] f_vec[4] = f_cap[-1] d_vec[1] = d_cap[1] d_vec[4] = d_cap[-1] f_vec[2] = f_cap[2] d_vec[2] = d_cap[2] f_vec[3] = f_cap[3] d_vec[3] = d_cap[3] matTag_pinching = 10 if degradation == True: matargs = [ f_vec[1, 0], d_vec[1, 0], f_vec[2, 0], d_vec[2, 0], f_vec[3, 0], d_vec[3, 0], f_vec[4, 0], d_vec[4, 0], -1 * f_vec[1, 0], -1 * d_vec[1, 0], -1 * f_vec[2, 0], -1 * d_vec[2, 0], -1 * f_vec[3, 0], -1 * d_vec[3, 0], -1 * f_vec[4, 0], -1 * d_vec[4, 0], 0.5, 0.25, 0.05, 0.5, 0.25, 0.05, 0, 0.1, 0, 0, 0.2, 0, 0.1, 0, 0, 0.2, 0, 0.4, 0, 0.4, 0.9, 10, 'energy' ] else: matargs = [ f_vec[1, 0], d_vec[1, 0], f_vec[2, 0], d_vec[2, 0], f_vec[3, 0], d_vec[3, 0], f_vec[4, 0], d_vec[4, 0], -1 * f_vec[1, 0], -1 * d_vec[1, 0], -1 * f_vec[2, 0], -1 * d_vec[2, 0], -1 * f_vec[3, 0], -1 * d_vec[3, 0], -1 * f_vec[4, 0], -1 * d_vec[4, 0], 0.5, 0.25, 0.05, 0.5, 0.25, 0.05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 'energy' ] ops.uniaxialMaterial('Pinching4', matTag_pinching, *matargs) matTag_minmax = int(matTag_pinching / 10) ops.uniaxialMaterial('MinMax', matTag_minmax, matTag_pinching, '-min', -1 * d_vec[4, 0], '-max', d_vec[4, 0]) mx = 1 kx = f_vec[1, 0] / d_vec[1, 0] omega = np.sqrt(kx / mx) dt = gmr[1, 0] - gmr[0, 0] ops.node(1, 0) ops.node(2, 0, '-mass', float(mx)) ops.fix(1, 1) ops.element('zeroLength', 1, 1, 2, "-mat", matTag_minmax, "-dir", 1, '-doRayleigh', 1) gmr_values = gmr[:, 1] * 9.81 gmr_times = gmr[:, 0] ops.timeSeries('Path', 2, '-values', *gmr_values, '-time', *gmr_times) ops.pattern('UniformExcitation', 2, 1, '-accel', 2) ops.constraints('Plain') ops.numberer('RCM') ops.test('NormDispIncr', 1e-6, 50) ops.algorithm('Newton') ops.system('BandGeneral') ops.integrator('Newmark', 0.5, 0.25) ops.analysis('Transient') t_final = gmr[-1, 0] t_current = ops.getTime() ok = 0 #betaKinit=2*damping/omega alphaM = 2 * damping * omega time = [t_current] disps = [0.0] accels = [0.0] #ops.rayleigh(0,0,betaKinit,0) ops.rayleigh(alphaM, 0, 0, 0) # mass proportional damping while ok == 0 and t_current < t_final: ok = ops.analyze(1, dt) if ok != 0: print( "regular newton failed ... lets try an initail stiffness for this step" ) ops.test('NormDispIncr', 1.0e-6, 100, 0) ops.algorithm('ModifiedNewton', '-initial') ok = ops.analyze(1, dt) if ok != 0: print("reducing dt by 10") ndt = dt / 10 ok = ops.analyze(10, ndt) if ok == 0: print("that worked ... back to regular settings") ops.test('NormDispIncr', 1e-6, 50) ops.test('NormDispIncr', 1e-6, 50) t_current = ops.getTime() time.append(t_current) disps.append(ops.nodeDisp(2, 1)) accels.append(ops.nodeAccel(2, 1)) if ok != 0: print('NLTHA did not converge!') return time, disps, accels
Wy = -10.e+3 Wx = 0. Ew = {3: ['-beamUniform', Wy, Wx]} ops.timeSeries('Constant', 1) ops.pattern('Plain', 1, 1) ops.load(2, Px, 0., 0.) for etag in Ew: ops.eleLoad('-ele', etag, '-type', Ew[etag][0], Ew[etag][1], Ew[etag][2]) ops.constraints('Transformation') ops.numberer('RCM') ops.system('BandGeneral') ops.test('NormDispIncr', 1.0e-6, 6, 2) ops.algorithm('Linear') ops.integrator('LoadControl', 1) ops.analysis('Static') ops.analyze(1) ops.printModel() # 1. plot model with tag lebels szer, wys = 16., 10. fig = plt.figure(figsize=(szer / 2.54, wys / 2.54)) fig.subplots_adjust(left=.08, bottom=.08, right=.985, top=.94) ax1 = plt.subplot(111)
ops.setElementRayleighDampingFactors(i+1,a0,0,0,a1) #opsplt.plot_model() # make viscous boundarys #exec(open('code/vis_bound.py').read()) exec(open('code/fix_bound.py').read()) # rayleigh damping #ops.rayleigh(a0,0,0,a1) #opsplt.plot_model() exec(open('code/load.py').read()) else: ops.node(1, 0.0, 0.0) # analysis commands ops.constraints('Transformation') ops.numberer('ParallelPlain') ops.system('Mumps') ops.test('NormDispIncr', 1e-6, 6) ops.algorithm('Newton') ops.integrator('Newmark', 0.5, 0.25) ops.analysis('Transient') # timers ops.start() ops.analyze(10,0.001) ops.stop() print(ops.nodeDisp(1,1))
loadValues = [3500.0, 0.0, 0.0, 0.0, 0.0, 0.0] op.timeSeries('Path', 1, '-values', *values, '-time', *time, '-factor', 1.0) op.pattern('Plain', 10, 1) op.load(nodeTag, *loadValues) print("Finished creating loading object...") #---------------------------------------------------------- # create the analysis #---------------------------------------------------------- op.integrator('LoadControl', 0.05) op.numberer('RCM') op.system('SparseGeneral') op.constraints('Transformation') op.test('NormDispIncr', 1e-5, 20, 1) op.algorithm('Newton') op.analysis('Static') print("Starting Load Application...") op.analyze(201) print("Load Application finished...") #print("Loading Analysis execution time: [expr $endT-$startT] seconds.") #op.wipe op.reactions() Nodereactions = dict() Nodedisplacements = dict() for i in range(201, nodeTag + 1):
def get_inelastic_response(mass, k_spring, f_yield, motion, dt, xi=0.05, r_post=0.0): """ Run seismic analysis of a nonlinear SDOF :param mass: SDOF mass :param k_spring: spring stiffness :param f_yield: yield strength :param motion: list, acceleration values :param dt: float, time step of acceleration values :param xi: damping ratio :param r_post: post-yield stiffness :return: """ op.wipe() op.model('basic', '-ndm', 2, '-ndf', 3) # 2 dimensions, 3 dof per node # Establish nodes bot_node = 1 top_node = 2 op.node(bot_node, 0., 0.) op.node(top_node, 0., 0.) # Fix bottom node op.fix(top_node, opc.FREE, opc.FIXED, opc.FIXED) op.fix(bot_node, opc.FIXED, opc.FIXED, opc.FIXED) # Set out-of-plane DOFs to be slaved op.equalDOF(1, 2, *[2, 3]) # nodal mass (weight / g): op.mass(top_node, mass, 0., 0.) # Define material bilinear_mat_tag = 1 mat_type = "Steel01" mat_props = [f_yield, k_spring, r_post] op.uniaxialMaterial(mat_type, bilinear_mat_tag, *mat_props) # Assign zero length element beam_tag = 1 op.element('zeroLength', beam_tag, bot_node, top_node, "-mat", bilinear_mat_tag, "-dir", 1, '-doRayleigh', 1) # Define the dynamic analysis load_tag_dynamic = 1 pattern_tag_dynamic = 1 values = list(-1 * motion) # should be negative op.timeSeries('Path', load_tag_dynamic, '-dt', dt, '-values', *values) op.pattern('UniformExcitation', pattern_tag_dynamic, opc.X, '-accel', load_tag_dynamic) # set damping based on first eigen mode angular_freq = op.eigen('-fullGenLapack', 1)**0.5 alpha_m = 0.0 beta_k = 2 * xi / angular_freq beta_k_comm = 0.0 beta_k_init = 0.0 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') tol = 1.0e-10 iterations = 10 op.test('EnergyIncr', tol, iterations, 0, 2) analysis_time = (len(values) - 1) * dt analysis_dt = 0.001 outputs = { "time": [], "rel_disp": [], "rel_accel": [], "rel_vel": [], "force": [] } 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(top_node, 1)) outputs["rel_vel"].append(op.nodeVel(top_node, 1)) outputs["rel_accel"].append(op.nodeAccel(top_node, 1)) op.reactions() outputs["force"].append( -op.nodeReaction(bot_node, 1)) # Negative since diff node op.wipe() for item in outputs: outputs[item] = np.array(outputs[item]) return outputs
# create a Linear time series ops.timeSeries("Linear", 1) # add some loads ops.pattern("Plain", 1, 1, "-fact", 1.0) ops.load(mid, 0.0, -0.50, 0.0, 0.0, 0.0, 0.0) ops.load(side1, 0.0, -0.25, 0.0, 0.0, 0.0, 0.0) ops.load(side2, 0.0, -0.25, 0.0, 0.0, 0.0, 0.0) # ------------------------ # Start of static analysis # ------------------------ # Load control with variable load steps # init Jd min max ops.integrator("LoadControl", 1.0, 1, 1.0, 10.0) ops.test("EnergyIncr", 1.0E-10, 20, 0) ops.algorithm("Newton") ops.numberer("RCM") ops.constraints("Plain") ops.system("SparseGeneral", "-piv") ops.analysis("Static") ops.analyze(5) # --------------------------------------- # Create and Perform the dynamic analysis # --------------------------------------- # Remove the static analysis & reset the time to 0.0 ops.wipeAnalysis() ops.setTime(0.0)
upper = [5 * L, 3 * L] ops.mesh('bg', h, *lower, *upper, '-structure', sid, len(sNodes), *sNodes, '-structure', sid, len(wallNodes), *wallNodes) print('num nodes =', len(ops.getNodeTags())) print('num particles =', nx * ny) # create constraint object ops.constraints('Plain') # 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, 100, 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') # system('PFEM', '-mumps') Linux version can use mumps # create analysis object ops.analysis('PFEM', dtmax, dtmin, b2) # analysis