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
ops.node(9, 2.5, .5) # comment for quad8n element ops.element('tri6n', 1, 1, 2, 3, 5, 6, 9, thk, 'PlaneStress', 1) ops.element('tri6n', 2, 1, 3, 4, 9, 7, 8, thk, 'PlaneStress', 1) ops.fix(1, 1, 1) ops.fix(4, 1, 0) ops.fix(8, 1, 0) ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) ops.load(2, P, 0.) ops.load(3, -P, 0.) ops.analysis('Static') ops.analyze(1) ops.printModel() stressAtNodes_ele1 = ops.eleResponse(1, 'stressAtNodes') print(f'\nTip vertical displacement (node 2) is {ops.nodeDisp(2, 2):.4f}') print(f'Stress sigma_xx at node 1 is {stressAtNodes_ele1[0]:.1f}') # verification: # tip vertical displacement (node 2 and 3) = 0.0075 # bottom extreme stress_xx (extrapolated) = 60000.0 exit()
def test_PortalFrame2d(): # set some properties print("================================================") print("PortalFrame2d.py: Verification 2d Elastic Frame") print(" - eigenvalue and static pushover analysis") ops.wipe() ops.model('Basic', '-ndm', 2) # properties # units kip, ft numBay = 2 numFloor = 7 bayWidth = 360.0 storyHeights = [162.0, 162.0, 156.0, 156.0, 156.0, 156.0, 156.0] E = 29500.0 massX = 0.49 M = 0. coordTransf = "Linear" # Linear, PDelta, Corotational massType = "-lMass" # -lMass, -cMass beams = [ 'W24X160', 'W24X160', 'W24X130', 'W24X130', 'W24X110', 'W24X110', 'W24X110' ] eColumn = [ 'W14X246', 'W14X246', 'W14X246', 'W14X211', 'W14X211', 'W14X176', 'W14X176' ] iColumn = [ 'W14X287', 'W14X287', 'W14X287', 'W14X246', 'W14X246', 'W14X211', 'W14X211' ] columns = [eColumn, iColumn, eColumn] WSection = { 'W14X176': [51.7, 2150.], 'W14X211': [62.1, 2670.], 'W14X246': [72.3, 3230.], 'W14X287': [84.4, 3910.], 'W24X110': [32.5, 3330.], 'W24X130': [38.3, 4020.], 'W24X160': [47.1, 5120.] } nodeTag = 1 # procedure to read def ElasticBeamColumn(eleTag, iNode, jNode, sectType, E, transfTag, M, massType): found = 0 prop = WSection[sectType] A = prop[0] I = prop[1] ops.element('elasticBeamColumn', eleTag, iNode, jNode, A, E, I, transfTag, '-mass', M, massType) # add the nodes # - floor at a time yLoc = 0. for j in range(0, numFloor + 1): xLoc = 0. for i in range(0, numBay + 1): ops.node(nodeTag, xLoc, yLoc) xLoc += bayWidth nodeTag += 1 if j < numFloor: storyHeight = storyHeights[j] yLoc += storyHeight # fix first floor ops.fix(1, 1, 1, 1) ops.fix(2, 1, 1, 1) ops.fix(3, 1, 1, 1) #rigid floor constraint & masses nodeTagR = 5 nodeTag = 4 for j in range(1, numFloor + 1): for i in range(0, numBay + 1): if nodeTag != nodeTagR: ops.equalDOF(nodeTagR, nodeTag, 1) else: ops.mass(nodeTagR, massX, 1.0e-10, 1.0e-10) nodeTag += 1 nodeTagR += numBay + 1 # add the columns # add column element ops.geomTransf(coordTransf, 1) eleTag = 1 for j in range(0, numBay + 1): end1 = j + 1 end2 = end1 + numBay + 1 thisColumn = columns[j] for i in range(0, numFloor): secType = thisColumn[i] ElasticBeamColumn(eleTag, end1, end2, secType, E, 1, M, massType) end1 = end2 end2 += numBay + 1 eleTag += 1 # add beam elements for j in range(1, numFloor + 1): end1 = (numBay + 1) * j + 1 end2 = end1 + 1 secType = beams[j - 1] for i in range(0, numBay): ElasticBeamColumn(eleTag, end1, end2, secType, E, 1, M, massType) end1 = end2 end2 = end1 + 1 eleTag += 1 # calculate eigenvalues & print results numEigen = 7 eigenValues = ops.eigen(numEigen) PI = 2 * asin(1.0) # # apply loads for static analysis & perform analysis # ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) ops.load(22, 20.0, 0., 0.) ops.load(19, 15.0, 0., 0.) ops.load(16, 12.5, 0., 0.) ops.load(13, 10.0, 0., 0.) ops.load(10, 7.5, 0., 0.) ops.load(7, 5.0, 0., 0.) ops.load(4, 2.5, 0., 0.) ops.integrator('LoadControl', 1.0) ops.algorithm('Linear') ops.analysis('Static') ops.analyze(1) # determine PASS/FAILURE of test ok = 0 # # print pretty output of comparsions # # SAP2000 SeismoStruct comparisonResults = [[ 1.2732, 0.4313, 0.2420, 0.1602, 0.1190, 0.0951, 0.0795 ], [1.2732, 0.4313, 0.2420, 0.1602, 0.1190, 0.0951, 0.0795]] print("\n\nPeriod Comparisons:") print('{:>10}{:>15}{:>15}{:>15}'.format('Period', 'OpenSees', 'SAP2000', 'SeismoStruct')) #formatString {%10s%15.5f%15.4f%15.4f} for i in range(0, numEigen): lamb = eigenValues[i] period = 2 * PI / sqrt(lamb) print('{:>10}{:>15.5f}{:>15.4f}{:>15.4f}'.format( i + 1, period, comparisonResults[0][i], comparisonResults[1][i])) resultOther = comparisonResults[0][i] if abs(period - resultOther) > 9.99e-5: ok = -1 # print table of camparsion # Parameter SAP2000 SeismoStruct comparisonResults = [[ "Disp Top", "Axial Force Bottom Left", "Moment Bottom Left" ], [1.45076, 69.99, 2324.68], [1.451, 70.01, 2324.71]] tolerances = [9.99e-6, 9.99e-3, 9.99e-3] print("\n\nSatic Analysis Result Comparisons:") print('{:>30}{:>15}{:>15}{:>15}'.format('Parameter', 'OpenSees', 'SAP2000', 'SeismoStruct')) for i in range(3): response = ops.eleResponse(1, 'forces') if i == 0: result = ops.nodeDisp(22, 1) elif i == 1: result = abs(response[1]) else: result = response[2] print('{:>30}{:>15.3f}{:>15.2f}{:>15.2f}'.format( comparisonResults[0][i], result, comparisonResults[1][i], comparisonResults[2][i])) resultOther = comparisonResults[1][i] tol = tolerances[i] if abs(result - resultOther) > tol: ok = -1 print("failed-> ", i, abs(result - resultOther), tol) assert ok == 0
def test_PlanarTruss(): A = 10.0 E = 3000. L = 200.0 alpha = 30.0 P = 200.0 sigmaYP = 60.0 pi = 2.0*asin(1.0) alphaRad = alpha*pi/180. cosA = cos(alphaRad) sinA = sin(alphaRad) # EXACT RESULTS per Popov F1 = P/(2*cosA*cosA*cosA + 1) F2 = F1*cosA*cosA disp = -F1*L/(A*E) # create the finite element model ops.wipe() ops.model('Basic', '-ndm', 2, '-ndf', 2) dX = L*tan(alphaRad) ops.node( 1, 0.0, 0.0) ops.node( 2, dX, 0.0) ops.node( 3, 2.0*dX, 0.0) ops.node( 4, dX, -L ) ops.fix( 1, 1, 1) ops.fix( 2, 1, 1) ops.fix( 3, 1, 1) ops.uniaxialMaterial('Elastic', 1, E) ops.element('Truss', 1, 1, 4, A, 1) ops.element('Truss', 2, 2, 4, A, 1) ops.element('Truss', 3, 3, 4, A, 1) ops.timeSeries('Linear', 1) ops.pattern('Plain', 1, 1) ops.load( 4, 0., -P) ops.numberer( 'Plain') ops.constraints( 'Plain') ops.algorithm( 'Linear') ops.system('ProfileSPD') ops.integrator('LoadControl', 1.0) ops.analysis('Static') ops.analyze(1) # determine PASS/FAILURE of test testOK = 0 # # print table of camparsion # comparisonResults = F2, F1, F2 print("\nElement Force Comparison:") tol = 1.0e-6 print('{:>10}{:>15}{:>15}'.format('Element','OpenSees','Popov')) for i in range(1,4): exactResult = comparisonResults[i-1] eleForce = ops.eleResponse(i, 'axialForce') print('{:>10d}{:>15.4f}{:>15.4f}'.format(i, eleForce[0], exactResult)) if abs(eleForce[0]-exactResult) > tol: testOK = -1 print("failed force-> ", abs(eleForce[0]-exactResult), " ", tol) print("\nDisplacement Comparison:") osDisp = ops.nodeDisp( 4, 2) print('{:>10}{:>15.8f}{:>10}{:>15.8f}'.format('OpenSees:',osDisp,'Exact:', disp)) if abs(osDisp-disp) > tol: testOK = -1 print("failed linear disp") print("\n\n - NonLinear (Example2.23)") #EXACT # Exact per Popov PA = (sigmaYP*A) * (1.0+2*cosA*cosA*cosA) dispA = PA/P*disp PB = (sigmaYP*A) * (1.0+2*cosA) dispB = dispA / (cosA*cosA) # create the new finite element model for nonlinear case # will apply failure loads and calculate displacements ops.wipe() ops.model('Basic', '-ndm', 2, '-ndf', 2) ops.node( 1, 0.0, 0.0) ops.node( 2, dX, 0.0) ops.node( 3, 2.0*dX, 0.0) ops.node( 4, dX, -L ) ops.fix( 1, 1, 1) ops.fix( 2, 1, 1) ops.fix( 3, 1, 1) ops.uniaxialMaterial( 'ElasticPP', 1, E, sigmaYP/E) ops.element('Truss', 1, 1, 4, A, 1) ops.element('Truss', 2, 2, 4, A, 1) ops.element('Truss', 3, 3, 4, A, 1) ops.timeSeries( 'Path', 1, '-dt', 1.0, '-values', 0.0, PA, PB, PB) ops.pattern('Plain', 1, 1) ops.load( 4, 0., -1.0) ops.numberer('Plain') ops.constraints('Plain') ops.algorithm('Linear') ops.system('ProfileSPD') ops.integrator('LoadControl', 1.0) ops.analysis('Static') ops.analyze(1) osDispA = ops.nodeDisp( 4, 2) #print node 4 #print ele ops.analyze(1) osDispB = ops.nodeDisp( 4, 2) #print node 4 #print ele # determine PASS/FAILURE of test testOK = 0 print("\nDisplacement Comparison:") print("elastic limit state:") osDisp = ops.nodeDisp( 4, 2) print('{:>10}{:>15.8f}{:>10}{:>15.8f}'.format('OpenSees:',osDispA,'Exact:',dispA)) if abs(osDispA-dispA) > tol: testOK = -1 print("failed nonlineaer elastic limit disp") print("collapse limit state:") print('{:>10}{:>15.8f}{:>10}{:>15.8f}'.format('OpenSees:',osDispB,'Exact:',dispB)) if abs(osDispB-dispB) > tol: testOK = -1 print("failed nonlineaer collapse limit disp") assert testOK == 0
mf.buildModel() # Show Model # opp.plot_model('node', 'elements') # Create Database Model = 'Cantilever' LoadCase = 'PushoverLcD' opp.createODB(Model, LoadCase) eleNumber = 1 sectionNumber = 1 opp.saveFiberData2D(Model, LoadCase, eleNumber, sectionNumber) # Run Analysis af.PushoverLcD(0.05) out = op.eleResponse(1, 'section', '1', 'fiberData') op.wipe() opp.plot_fiberResponse2D(Model, LoadCase, eleNumber, sectionNumber) opp.plot_fiberResponse2D(Model, LoadCase, eleNumber, sectionNumber, InputType='strain') # ani = opp.animate_fiberResponse2D(Model, LoadCase, eleNumber, sectionNumber)
def test_PlanarTrussExtra(): A = 10.0 E = 3000. L = 200.0 alpha = 30.0 P = 200.0 sigmaYP = 60.0 pi = 2.0*asin(1.0) alphaRad = alpha*pi/180. cosA = cos(alphaRad) sinA = sin(alphaRad) # EXACT RESULTS per Popov F1 = P/(2*cosA*cosA*cosA + 1) F2 = F1*cosA*cosA disp = -F1*L/(A*E) b = 1.0 d = A z = A y = 1.0 numFiberY = 10 # note we only need so many to get the required accuracy on eigenvalue 1e-7! numFiberZ = 1 # create the finite element model for sectType in ['Fiber', 'Uniaxial']: print(" - Linear (Example 2.14) sectType: ", sectType) testOK = 0 ops.wipe() ops.model( 'Basic', '-ndm', 2, '-ndf', 2) dX = L*tan(alphaRad) ops.node(1, 0.0, 0.0) ops.node(2, dX , 0.0) ops.node(3, 2.0*dX, 0.0) ops.node(4, dX, -L ) ops.fix(1, 1, 1) ops.fix(2, 1, 1) ops.fix(3, 1, 1) if sectType == "Uniaxial": ops.uniaxialMaterial( 'Elastic', 1, A*E) ops.section( 'Uniaxial', 1, 1, 'P') else: ops.uniaxialMaterial( 'Elastic', 1, E) ops.section('Fiber', 1) # patch rect 1 numFiberY numFiberZ [expr -z/2.0] [expr -y/2.0] [expr z/2.0] [expr y/2.0] ops.patch( 'rect', 1, numFiberY, numFiberZ, -z, -y, 0., 0.) ops.element('Truss', 1, 1, 4, 1) ops.element('Truss', 2, 2, 4, 1) ops.element('Truss', 3, 3, 4, 1) ops.timeSeries( 'Linear', 1) ops.pattern( 'Plain', 1, 1) ops.load( 4, 0., -P) ops.numberer( 'Plain') ops.constraints( 'Plain') ops.algorithm('Linear') ops.system('ProfileSPD') ops.integrator('LoadControl', 1.0) ops.analysis('Static') ops.analyze(1) # # print table of camparsion # comparisonResults = F2, F1, F2 print("\nElement Force Comparison:") tol = 1.0e-6 print('{:>10}{:>15}{:>15}'.format('Element','OpenSees','Popov')) for i in range(1,4): exactResult = comparisonResults[i-1] eleForce =ops.eleResponse( i, 'axialForce') print('{:>10d}{:>15.4f}{:>15.4f}'.format(i, eleForce[0], exactResult)) if abs(eleForce[0]-exactResult) > tol: testOK = -1 print("failed force-> ", abs(eleForce[0]-exactResult), " ", tol) print("\nDisplacement Comparison:") osDisp = ops.nodeDisp( 4, 2) print('{:>10}{:>15.8f}{:>10}{:>15.8f}'.format('OpenSees:',osDisp,'Exact:', disp)) if abs(osDisp-disp) > tol: testOK = -1 print("failed linear disp") print("\n\n - NonLinear (Example2.23) sectType: ", sectType) #EXACT # Exact per Popov PA = (sigmaYP*A) * (1.0+2*cosA*cosA*cosA) dispA = PA/P*disp PB = (sigmaYP*A) * (1.0+2*cosA) dispB = dispA / (cosA*cosA) # create the new finite element model for nonlinear case # will apply failure loads and calculate displacements ops.wipe() ops.model('Basic', '-ndm', 2, '-ndf', 2) ops.node( 1, 0.0, 0.0) ops.node( 2, dX, 0.0) ops.node( 3, 2.0*dX, 0.0) ops.node( 4, dX, -L ) ops.fix( 1, 1, 1) ops.fix( 2, 1, 1) ops.fix( 3, 1, 1) if sectType == "Uniaxial": ops.uniaxialMaterial( 'ElasticPP', 1, A*E, sigmaYP/E) ops.section( 'Uniaxial', 1, 1, 'P') else: ops.uniaxialMaterial( 'ElasticPP', 1, E, sigmaYP/E) ops.section( 'Fiber', 1) ops.patch( 'rect', 1, numFiberY, numFiberZ, -z/2.0, -y/2.0, z/2.0, y/2.0) ops.element('Truss', 1, 1, 4, 1) ops.element('Truss', 2, 2, 4, 1) ops.element('Truss', 3, 3, 4, 1) ops.timeSeries( 'Path', 1, '-dt', 1.0, '-values', 0.0, PA, PB, PB) ops.pattern('Plain', 1, 1) ops.load( 4, 0., -1.0) ops.numberer('Plain') ops.constraints('Plain') ops.algorithm('Linear') ops.system('ProfileSPD') ops.integrator('LoadControl', 1.0) ops.analysis('Static') ops.analyze(1) osDispA = ops.nodeDisp( 4, 2) ops.analyze(1) osDispB = ops.nodeDisp( 4, 2) print("\nDisplacement Comparison:") print("elastic limit state:") osDisp = ops.nodeDisp( 4, 2) print('{:>10}{:>15.8f}{:>10}{:>15.8f}'.format('OpenSees:',osDispA,'Exact:',dispA)) if abs(osDispA-dispA) > tol: testOK = -1 print("failed nonlineaer elastic limit disp") print("collapse limit state:") print('{:>10}{:>15.8f}{:>10}{:>15.8f}'.format('OpenSees:',osDispB,'Exact:',dispB)) if abs(osDispB-dispB) > tol: testOK = -1 print("failed nonlineaer collapse limit disp") assert testOK == 0