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) ModelName = '3D_Shell' LoadCaseName = 'Transient' opp.createODB(ModelName, LoadCaseName, Nmodes=3) LoadCaseName2 = 'Transient_2ms' opp.createODB(ModelName, LoadCaseName2, deltaT=1 / 24, Nmodes=3) # Create the transient analysis ops.test("EnergyIncr", 1.0E-10, 20, 0) ops.algorithm("Newton") ops.numberer("RCM")
def analisis_opensees(path, permutaciones): #helper, #win ops.wipe() # bucle para generar los x análisis for i in range(len(permutaciones)): perfil = str(permutaciones[i][0]) nf = permutaciones[i][2] amort = permutaciones[i][3] den = permutaciones[i][4] vel = permutaciones[i][5] capas = len(permutaciones[i][6]) nstep = permutaciones[i][30] dt = float(permutaciones[i][31]) # creación de elementos sElemX = permutaciones[i][1] # elementos en X sElemZ = permutaciones[i][46] # espesor en Z # ============================================================================= # ######## geometría de la columna ###### # ============================================================================= # límite entre capas limite_capa = [] anterior = 0 for j in range(capas): espesor = permutaciones[i][8][j] limite_capa.append(espesor + anterior) anterior = limite_capa[j] print('Límite de capa: ' + str(limite_capa[j])) # creación de elementos y nodos en x nElemX = 1 # elementos en x nNodeX = 2 * nElemX + 1 # nodos en x # creación de elementos y nodos para z nElemZ = 1 # creación de elementos y nodos en Y y totales nElemY = [] # elementos en y sElemY = [] # dimension en y nElemT = 0 for j in range(capas): espesor = permutaciones[i][8][j] nElemY.append(2 * espesor) nElemT += nElemY[j] print('Elementos en capa ' + str(j + 1) + ': ' + str(nElemY[j])) sElemY.append(permutaciones[i][8][j] / nElemY[j]) print('Tamaño de los elementos en capa ' + str(j + 1) + ': ' + str(sElemY[j]) + '\n') # number of nodes in vertical direction in each layer nNodeY = [] # dimension en y nNodeT = 0 s = 0 for j in range(capas - 1): nNodeY.append(4 * nElemY[j]) nNodeT += nNodeY[j] s += 1 print('Nodos en capa ' + str(j + 1) + ': ' + str(nNodeY[j])) nNodeY.append(4 * (nElemY[-1] + 1)) nNodeT += nNodeY[-1] print('Nodos en capa ' + str(s + 1) + ': ' + str(nNodeY[s])) print('Nodos totales: ' + str(nNodeT)) #win.ui.progressBar.setValue(15) # ============================================================================= # ######### Crear nodos del suelo ########## # ============================================================================= # creación de nodos de presión de poros ops.model('basic', '-ndm', 3, '-ndf', 4) with open(path + '/Post-proceso/' + perfil + '/ppNodesInfo.dat', 'w') as f: count = 0.0 yCoord = 0.0 nodos = [] dryNode = [] altura_nf = 10 - nf for k in range(capas): for j in range(0, int(nNodeY[k]), 4): ops.node(j + count + 1, 0.0, yCoord, 0.0) ops.node(j + count + 2, 0.0, yCoord, sElemZ) ops.node(j + count + 3, sElemX, yCoord, sElemZ) ops.node(j + count + 4, sElemX, yCoord, 0.0) f.write( str(int(j + count + 1)) + '\t' + str(0.0) + '\t' + str(yCoord) + '\t' + str(0.0) + '\n') f.write( str(int(j + count + 2)) + '\t' + str(0.0) + '\t' + str(yCoord) + '\t' + str(sElemZ) + '\n') f.write( str(int(j + count + 3)) + '\t' + str(sElemX) + '\t' + str(yCoord) + '\t' + str(sElemZ) + '\n') f.write( str(int(j + count + 4)) + '\t' + str(sElemX) + '\t' + str(yCoord) + '\t' + str(0.0) + '\n') nodos.append(str(j + count + 1)) nodos.append(str(j + count + 2)) nodos.append(str(j + count + 3)) nodos.append(str(j + count + 4)) #designate node sobre la superficie de agua if yCoord >= altura_nf: dryNode.append(j + count + 1) dryNode.append(j + count + 2) dryNode.append(j + count + 3) dryNode.append(j + count + 4) yCoord = (yCoord + sElemY[k]) count = (count + nNodeY[k]) print("Finished creating all soil nodes...") # ============================================================================= # ####### Condiciones de contorno en la base de la columna ######### # ============================================================================= ops.fix(1, *[0, 1, 1, 0]) ops.fix(2, *[0, 1, 1, 0]) ops.fix(3, *[0, 1, 1, 0]) ops.fix(4, *[0, 1, 1, 0]) ops.equalDOF(1, 2, 1) ops.equalDOF(1, 3, 1) ops.equalDOF(1, 4, 1) print('Fin de creación de nodos de la base de la columna\n\n') # ============================================================================= # ####### Condiciones de contorno en los nudos restantes ######### # ============================================================================= count = 0 for k in range(5, int(nNodeT + 1), 4): ops.equalDOF(k, k + 1, *[1, 2, 3]) ops.equalDOF(k, k + 2, *[1, 2, 3]) ops.equalDOF(k, k + 3, *[1, 2, 3]) print('Fin de creación equalDOF para nodos de presión de poros\n\n') for j in range(len(dryNode)): ops.fix(dryNode[j], *[0, 0, 0, 1]) print("Finished creating all soil boundary conditions...") # ============================================================================= # ####### crear elemento y material de suelo ######### # ============================================================================= cargas = [] for j in range(capas): pendiente = permutaciones[i][9][j] slope = math.atan(pendiente / 100) tipo_suelo = permutaciones[i][6][j] rho = permutaciones[i][10][j] Gr = permutaciones[i][12][j] Br = permutaciones[i][13][j] fric = permutaciones[i][15][j] refpress = permutaciones[i][18][j] gmax = permutaciones[i][19][j] presscoef = permutaciones[i][20][j] surf = permutaciones[i][21][j] ev = permutaciones[i][22][j] cc1 = permutaciones[i][23][j] cc3 = permutaciones[i][24][j] cd1 = permutaciones[i][25][j] cd3 = permutaciones[i][26][j] ptang = permutaciones[i][27][j] coh = permutaciones[i][28][j] if tipo_suelo == 'No cohesivo': if float(surf) > 0: ops.nDMaterial('PressureDependMultiYield02', j + 1, 3.0, rho, Gr, Br, fric, gmax, refpress, presscoef, ptang, cc1, cc3, cd1, cd3, float(surf), 5.0, 3.0, *[1.0, 0.0], ev, *[0.9, 0.02, 0.7, 101.0]) else: ops.nDMaterial('PressureDependMultiYield02', j + 1, 3.0, rho, Gr, Br, fric, gmax, refpress, presscoef, ptang, cc1, cc3, cd1, cd3, float(surf), *permutaciones[i][29][j], 5.0, 3.0, *[1.0, 0.0], ev, *[0.9, 0.02, 0.7, 101.0]) cargas.append( [0.0, -9.81 * math.cos(slope), -9.81 * math.sin(slope)]) print('Fin de la creación de material de suelo\n\n') #----------------------------------------------------------------------------------------- # 5. CREATE SOIL ELEMENTS #----------------------------------------------------------------------------------------- count = 0 alpha = 1.5e-6 with open(path + '/Post-proceso/' + perfil + '/ppElemInfo.dat', 'w') as f: # crear elemento de suelo for k in range(capas): for j in range(int(nElemY[k])): nI = 4 * (j + count + 1) - 3 nJ = nI + 1 nK = nI + 2 nL = nI + 3 nM = nI + 4 nN = nI + 5 nO = nI + 6 nP = nI + 7 f.write( str(j + count + 1) + '\t' + str(nI) + '\t' + str(nJ) + '\t' + str(nK) + '\t' + str(nL) + '\t' + str(nM) + '\t' + str(nN) + '\t' + str(nO) + '\t' + str(nP) + '\n') Bc = permutaciones[i][14][k] ev = permutaciones[i][22][k] ops.element('SSPbrickUP', (j + count + 1), *[nI, nJ, nK, nL, nM, nN, nO, nP], (k + 1), float(Bc), 1.0, 1.0, 1.0, 1.0, float(ev), alpha, cargas[k][0], cargas[k][1], cargas[k][2]) count = (count + int(nElemY[k])) print('Fin de la creación del elemento del suelo\n\n') #win.ui.progressBar.setValue(25) # ============================================================================= # ######### Amortiguamiento de Lysmer ########## # ============================================================================= ops.model('basic', '-ndm', 3, '-ndf', 3) # definir nodos y coordenadas del amortiguamiento dashF = nNodeT + 1 dashX = nNodeT + 2 dashZ = nNodeT + 3 ops.node(dashF, 0.0, 0.0, 0.0) ops.node(dashX, 0.0, 0.0, 0.0) ops.node(dashZ, 0.0, 0.0, 0.0) # definir restricciones para los nodos de amortiguamiento ops.fix(dashF, 1, 1, 1) ops.fix(dashX, 0, 1, 1) ops.fix(dashZ, 1, 1, 0) # definir equalDOF para el amortiguamiento en la base del suelo ops.equalDOF(1, dashX, 1) ops.equalDOF(1, dashZ, 3) print( 'Fin de la creación de condiciones de contorno de los nodos de amortiguamiento\n\n' ) # definir el material de amortiguamiento colArea = sElemX * sElemZ dashpotCoeff = vel * den * colArea ops.uniaxialMaterial('Viscous', capas + 1, dashpotCoeff, 1.0) # definir el elemento ops.element('zeroLength', nElemT + 1, *[dashF, dashX], '-mat', capas + 1, '-dir', *[1]) ops.element('zeroLength', nElemT + 2, *[dashF, dashZ], '-mat', capas + 1, '-dir', *[3]) print('Fin de la creación del elemento de amortiguamiento\n\n') #----------------------------------------------------------------------------------------- # 9. DEFINE ANALYSIS PARAMETERS #----------------------------------------------------------------------------------------- # amortiguamiento de Rayleigh # frecuencia menor omega1 = 2 * math.pi * 0.2 # frecuencia mayor omega2 = 2 * math.pi * 20 a0 = 2.0 * (amort / 100) * omega1 * omega2 / (omega1 + omega2) a1 = 2.0 * (amort / 100) / (omega1 + omega2) print('Coeficientes de amortiguamiento' + '\n' + 'a0: ' + format(a0, '.6f') + '\n' + 'a1: ' + format(a1, '.6f') + '\n\n') #win.ui.progressBar.setValue(35) # ============================================================================= # ######## Determinación de análisis estático ######### # ============================================================================= #---DETERMINE STABLE ANALYSIS TIME STEP USING CFL CONDITION # se determina a partir de un análisis transitorio de largo tiempo duration = nstep * dt # tamaño mínimo del elemento y velocidad máxima minSize = sElemY[0] vsMax = permutaciones[i][11][0] for j in range(1, capas): if sElemY[j] < minSize: minSize = sElemY[j] if permutaciones[i][11][j] > vsMax: vsMax = permutaciones[i][11][j] # trial analysis time step kTrial = minSize / (vsMax**0.5) # tiempo de análisis y pasos de tiempo if dt <= kTrial: nStep = nstep dT = dt else: nStep = int(math.floor(duration / kTrial) + 1) dT = duration / nStep print('Número de pasos en el análisis: ' + str(nStep) + '\n') print('Incremento de tiempo: ' + str(dT) + '\n\n') #---------------------------------------------------------------------------------------- # 7. GRAVITY ANALYSIS #----------------------------------------------------------------------------------------- ops.model('basic', '-ndm', 3, '-ndf', 4) ops.updateMaterialStage('-material', int(k + 1), '-stage', 0) # algoritmo de análisis estático ops.constraints(permutaciones[i][32][0], float(permutaciones[i][32][1]), float(permutaciones[i][32][2])) ops.test(permutaciones[i][34][0], float(permutaciones[i][34][1]), int(permutaciones[i][34][2]), int(permutaciones[i][34][3])) ops.algorithm(permutaciones[i][38][0]) ops.numberer(permutaciones[i][33][0]) ops.system(permutaciones[i][36][0]) ops.integrator(permutaciones[i][35][0], float(permutaciones[i][35][1]), float(permutaciones[i][35][2])) ops.analysis(permutaciones[i][37][0]) print('Inicio de análisis estático elástico\n\n') ops.start() ops.analyze(20, 5.0e2) print('Fin de análisis estático elástico\n\n') #win.ui.progressBar.setValue(40) # update materials to consider plastic behavior # ============================================================================= ops.updateMaterialStage('-material', int(k + 1), '-stage', 1) # ============================================================================= # plastic gravity loading print('Inicio de análisis estático plástico\n\n') ok = ops.analyze(40, 5.0e-2) if ok != 0: error = 'Error de convergencia en análisis estático de modelo' + str( perfil) + '\n\n' print(error) break print('Fin de análisis estático plástico\n\n') #----------------------------------------------------------------------------------------- # 11. UPDATE ELEMENT PERMEABILITY VALUES FOR POST-GRAVITY ANALYSIS #----------------------------------------------------------------------------------------- ini = 1 aum = 0 sum = 0 for j in range(capas): #Layer 3 ops.setParameter( '-val', permutaciones[i][16][j], ['-eleRange', int(ini + aum), int(nElemY[j] + sum)], 'xPerm') ops.setParameter( '-val', permutaciones[i][17][j], ['-eleRange', int(ini + aum), int(nElemY[j] + sum)], 'yPerm') ops.setParameter( '-val', permutaciones[i][16][j], ['-eleRange', int(ini + aum), int(nElemY[j] + sum)], 'zPerm') ini = nElemY[j] + sum sum += nElemY[j] aum = 1 print("Finished updating permeabilities for dynamic analysis...") # ============================================================================= # ########### Grabadores dinámicos ########## # ============================================================================= ops.setTime(0.0) ops.wipeAnalysis() ops.remove('recorders') # tiempo de la grabadora recDT = 10 * dt path_acel = path + '/Post-proceso/' + perfil + '/dinamico/aceleraciones/' ops.recorder('Node', '-file', path_acel + 'accelerationx.out', '-time', '-dT', recDT, '-node', *nodos, '-dof', 1, 'accel') print('Fin de creación de grabadores\n\n') #win.ui.progressBar.setValue(50) # ============================================================================= # ######### Determinación de análisis dinámico ########## # ============================================================================= # objeto de serie temporal para el historial de fuerza path_vel = path + '/Pre-proceso/' + perfil + '/TREASISL2.txt' ops.timeSeries('Path', 1, '-dt', dt, '-filePath', path_vel, '-factor', dashpotCoeff) ops.pattern('Plain', 10, 1) ops.load(1, *[1.0, 0.0, 0.0, 0.0]) #CAMBIO REALIZADO OJO print('Fin de creación de carga dinámica\n\n') # algoritmo de análisis dinámico ops.constraints(permutaciones[i][39][0], float(permutaciones[i][39][1]), float(permutaciones[i][39][2])) ops.test(permutaciones[i][41][0], float(permutaciones[i][41][1]), int(permutaciones[i][41][2]), int(permutaciones[i][41][3])) ops.algorithm(permutaciones[i][45][0]) ops.numberer(permutaciones[i][40][0]) ops.system(permutaciones[i][43][0]) ops.integrator(permutaciones[i][42][0], float(permutaciones[i][42][1]), float(permutaciones[i][42][2])) ops.analysis(permutaciones[i][44][0]) # ============================================================================= # ops.rayleigh(a0, a1, 0.0, 0.0) # ============================================================================= print('Inicio de análisis dinámico\n\n') #win.ui.progressBar.setValue(85) ok = ops.analyze(nStep, dT) if ok != 0: error = 'Error de convergencia en análisis dinámico de modelo' + str( permutaciones[i][0]) + '\n\n' print(error) curTime = ops.getTime() mTime = curTime print('cursTime:' + str(curTime)) curStep = (curTime / dT) print('cursStep:' + str(curStep)) rStep = (nStep - curStep) * 2.0 remStep = int(nStep - curStep) * 2.0 print('remSTep:' + str(curStep)) dT = (dT / 2) print('dT:' + str(dT)) ops.analyze(remStep, dT) if ok != 0: error = 'Error de convergencia en análisis dinámico de modelo' + str( permutaciones[i][0]) + '\n\n' print(error) curTime = ops.getTime() print('cursTime:' + str(curTime)) curStep = (curTime - mTime) / dT print('cursStep:' + str(curStep)) remStep = int(rStep - curStep) * 2 print('remSTep:' + str(curStep)) dT = (dT / 2) print('dT:' + str(dT)) ops.analyze(remStep, dT) print('Fin de análisis dinámico\n\n') ops.wipe()
# record reaction force in the p-y springs op.recorder('Node', '-file', 'reaction.out', '-time', '-dT', timeStep, '-nodeRange', 1, nNodePile, '-dof', 1, 'reaction') # record element forces in pile elements op.recorder('Element', '-file', 'pileForce.out', '-time', '-dT', timeStep, '-eleRange', 201, 200 + nElePile, 'globalForce') print("Finished creating all recorders...") #---------------------------------------------------------- # create the loading #---------------------------------------------------------- op.setTime(10.0) # apply point load at the uppermost pile node in the x-direction values = [0.0, 0.0, 1.0, 1.0] time = [0.0, 10.0, 20.0, 10000.0] nodeTag = 200 + nNodePile 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...") #----------------------------------------------------------
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("========================================")
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 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 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)