def define_material(self,
                        f_cu=45,
                        f_tu=80,
                        eps_y=4e-3,
                        eps_r=13e-3,
                        eps_tu=7.1e-3):
        '''
        Define a material object and assign appropriate properties to each 
        fiber in the section.
        
        Args:
            f_cu: A float ultimate compressive strength, MPa (default=45MPa).
            f_tu: A float ultimate tensile strength, MPa (default=80MPa).
            eps_y: A float yield compression strain (default=4e-3).
            eps_r: A float compressive strain at rupture (default=13e-3).
            eps_tu: A float tensile strain at rupture (default=7.1d-3).
        '''

        if self.section == None:
            raise Exception('No section is defined.')

        self.material = Material(f_cu, f_tu, eps_y, eps_r, eps_tu)
        for T, mattag in self.section.temp_dict.items():
            stress, strain = self.material.get_stress_strain(
                T, self.section.Ti)
            ops.uniaxialMaterial('ElasticMultiLinear', mattag, 0.0, '-strain',
                                 *strain, '-stress', *stress)
Beispiel #2
0
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 GetSections(E):
    # remove existing model
    op.wipe()
    
    # set modelbuilder
    op.model('basic', '-ndm', 2, '-ndf', 3)
    
    # define materials
    op.uniaxialMaterial("Elastic", 1, E)
Beispiel #4
0
 def create_FEM(self):
     """Create the representation of the Steel4 material in OpenSEES."""
     ops.uniaxialMaterial('Steel4', self.id, self.f_y, self.E_0, '-asym',
                          '-kin', self.b_k, self.R_0, self.r_1, self.r_2,
                          self.b_kc, self.R_0c, self.r_1c, self.r_2c,
                          '-iso', self.b_i, self.rho_i, self.b_l, self.R_i,
                          self.l_yp, self.b_ic, self.rho_ic, self.b_lc,
                          self.R_ic, '-ult', self.f_u, self.R_u, self.f_uc,
                          self.R_uc)
Beispiel #5
0
def bilinear_material(mat_id):
    e_conc = 30e6
    depth = 0.4
    width = 0.3
    inertia = width * depth ** 3 / 12
    ei = e_conc * inertia
    eps_yield = 300.0e6 / 200e9
    phi_y = 2.1 * eps_yield / depth
    mat_props = [ei, 0.05 * ei, phi_y]
    op.uniaxialMaterial("ElasticBilin", mat_id, *mat_props)
Beispiel #6
0
def Model_Build(x, y, A, E):
    '''
    Description
    -----------
    This function is used to determine the basic parameters of the structural
    problem at hand.
    
    Parameters
    ----------
    x : LIST OF FLOATS
        The list of the coordinates of the nodes along the x-axis.
    y : LIST OF FLOATS
        The list of the coordinates of the nodes along the y-axis.
    A : LIST OF FLOATS
        The list with the materials used for the different elements.
    E : FLOAT
        The modulus of elesticity of the elements.
    Returns
    -------
    None.

    '''
    # Delete existing model.
    ops.wipe()

    # Define the model.
    ops.model('basic', '-ndm', 2, '-ndf', 3)

    # Define materials.
    ops.uniaxialMaterial('Elastic', 1, E)

    # Define the nodes.
    m = len(x)

    [ops.node(i + 1, *[x[i], y[i]]) for i in range(m)]

    # Fix the nodes.
    fixxity = [[0, 0, 1], [0, 1, 1], [1, 0, 1], [1, 1, 1]]

    [
        ops.fix(i +
                1, *fixxity[3]) if i + 1 != 4 else ops.fix(i + 1, *fixxity[0])
        for i in range(m)
    ]

    # Define elements.
    conn = [[1, 4], [2, 4], [3, 4]]
    [
        ops.element('Truss', i + 1, *conn[i], A[1], 1)
        if i != 0 else ops.element('Truss', i + 1, *conn[i], A[0], 1)
        for i in range(len(conn))
    ]

    # Plot model.
    opsplt.plot_model()
Beispiel #7
0
def add_beam_hinges(dict_of_hinges, dict_of_hinges_2):

    # obtain nonlinear hinge properties
    data = read_nonlinear_hinge_properties()

    #    dict_of_hinges = {real joint: (new joint, zero length element ID, orientation)}

    # iterate through all the hinges and add the uniaxial material and zero length element to the opensees model
    for key, value in dict_of_hinges.items():
        node_R = key
        node_C = value[0]
        matTag = value[1]
        dirn = value[2]

        row = data.loc[data['Hinge NAME'] == dict_of_hinges_2[matTag]]
        K0 = row['K0'].values[0]
        as_Plus = row['as_Plus'].values[0]
        as_Neg = row['as_Neg'].values[0]
        My_Plus = row['My_Plus'].values[0]
        My_Neg = row['My_Neg'].values[0]
        Lamda_S = row['Lamda_S'].values[0]
        Lamda_C = row['Lamda_C'].values[0]
        Lamda_A = row['Lamda_A'].values[0]
        Lamda_K = row['Lamda_K'].values[0]
        c_S = row['c_S'].values[0]
        c_C = row['c_C'].values[0]
        c_A = row['c_A'].values[0]
        c_K = row['c_K'].values[0]
        theta_p_Plus = row['theta_p_Plus'].values[0]
        theta_p_Neg = row['theta_p_Neg'].values[0]
        theta_pc_Plus = row['theta_pc_Plus'].values[0]
        theta_pc_Neg = row['theta_pc_Neg'].values[0]
        Res_Pos = row['Res_Pos'].values[0]
        Res_Neg = row['Res_Neg'].values[0]
        theta_u_Plus = row['theta_u_Plus'].values[0]
        theta_u_Neg = row['theta_u_Neg'].values[0]
        D_Plus = row['D_Plus'].values[0]
        D_Neg = row['D_Neg'].values[0]
        nFactor = row['nFactor'].values[0]

        # define the uniaxial material
        op.uniaxialMaterial('Bilin', matTag, K0, as_Plus, as_Neg, My_Plus,
                            My_Neg, Lamda_S, Lamda_C, Lamda_A, Lamda_K, c_S,
                            c_C, c_A, c_K, theta_p_Plus, theta_p_Neg,
                            theta_pc_Plus, theta_pc_Neg, Res_Pos, Res_Neg,
                            theta_u_Plus, theta_u_Neg, D_Plus, D_Neg, nFactor)

        # add the zero length element
        op.element('zeroLength', matTag, node_R, node_C, '-mat', matTag,
                   '-dir', dirn, '-doRayleigh', 1)

        # constrain the nodes connecting the rero lengrth element - all DOFs are constrained except the major bending
        op.equalDOF(node_R, node_C, 1, 2, 3, int(9 - dirn), 6)
        op.region(key, matTag)
    return
Beispiel #8
0
def elements(A, E, analysis_type):

    matTag = 10

    ops.uniaxialMaterial('Elastic', matTag, E)

    ##########################################################################

    eleTag = 1

    member_type = 'Truss'
    if analysis_type != 'Linear': member_type = 'corotTruss'

    ops.element(member_type, eleTag, *[1, 2], A, matTag)
Beispiel #9
0
def ops_material():
    # 混凝土
    # 抗压强度 抗压应变 初始弹模
    # 压缩方程形状参数
    # 抗压临界应变
    # 抗拉强度 抗拉应变
    # 拉伸方程形状参数
    # 抗拉临界应变
    ops.uniaxialMaterial('ConcreteCM', 1, -31.7, -0.00234, 3.25e4, 7, 0.03,
                         6.34, 0.001, 1.2, 10000, 1)
    # GFRP 拉筋
    ops.uniaxialMaterial('Steel02', 2, 1255.5, 64.9e3, 1e-20)
    # SFCB 纵筋
    ops.uniaxialMaterial('Steel02', 3, 348.7, 170.931e3, 0.2210)
    # 箍筋和中部纵筋
    ops.uniaxialMaterial('Steel02', 4, 257.5, 131.378e3, 0.320)

    # 约束区FSAM
    ops.nDMaterial('FSAM', 5, 2360e-3, 4, 3, 1,
                   0.02179008664529880590197689450643,
                   0.04712388980384689857693965074919, 0.1, 0.01)
    # 中部区域FSAM
    ops.nDMaterial('FSAM', 6, 2360e-3, 4, 4, 1,
                   0.00827704944465790858560291110048,
                   0.00654498469497873591346384038183, 0.1, 0.01)
Beispiel #10
0
def run_analysis():

    # build the model

    ops.model('basic', '-ndm', 2, '-ndf', 2)

    ops.node(1, 0, 0)
    ops.node(2, 4000, 0)
    ops.node(3, 8000, 0)
    ops.node(4, 12000, 0)
    ops.node(5, 4000, 4000)
    ops.node(6, 8000, 4000)

    ops.fix(1, 1, 1)
    ops.fix(4, 0, 1)

    ops.uniaxialMaterial('Elastic', 1, E)

    ops.element('truss', 1, 1, 2, Ao, 1)
    ops.element('truss', 2, 2, 3, Ao, 1)
    ops.element('truss', 3, 3, 4, Ao, 1)
    ops.element('truss', 4, 1, 5, Au, 1)
    ops.element('truss', 5, 5, 6, Au, 1)
    ops.element('truss', 6, 6, 4, Au, 1)
    ops.element('truss', 7, 2, 5, Ao, 1)
    ops.element('truss', 8, 3, 6, Ao, 1)
    ops.element('truss', 9, 5, 3, Ao, 1)

    ops.timeSeries('Linear', 1)
    ops.pattern('Plain', 1, 1)

    ops.load(2, 0, -P)
    ops.load(3, 0, -P)

    # build and perform the analysis

    ops.algorithm('Linear')
    ops.integrator('LoadControl', 1.0)
    ops.system('ProfileSPD')
    ops.numberer('RCM')
    ops.constraints('Plain')
    ops.analysis('Static')
    ops.analyze(1)

    node_disp = [[ops.nodeDisp(node_i, dof_j) for dof_j in [1, 2]]
                 for node_i in range(1, 7)]

    return node_disp
Beispiel #11
0
def set_uniaxial_metrial():
    '''
    @Brief set material
    '''
    ops.uniaxialMaterial('Steel02', 1, *(argu.longitudinal_steel))
    logger.info("material tag 1 by [steel 02] and used on longitudinal steel")
    logger.info(argu.longitudinal_steel)

    ops.uniaxialMaterial('Steel02', 2, *(argu.transverse_steel))
    logger.info("material tag 2 by [steel 02] and used on transverse steel")
    logger.info(argu.transverse_steel)

    # set nDMaterial
    ops.nDMaterial('PlaneStressUserMaterial', 3, *(argu.c30_con[0:-1]))
    logger.info(
        "material tag 30 by [PlaneStressUserMaterial] and used on C30 concrete"
    )
    logger.info((argu.c30_con[0:-1]))
    ops.nDMaterial('PlateFromPlaneStress', 30, 3, argu.c30_con[-1])
    logger.info(
        "material tag 30 by [PlateFromPlaneStress] and used on C30 concrete OutofPlaneModulus %d",
        argu.c30_con[-1])

    # logger.info(
    #     "material tag 40 by [PlaneStressUserMaterial] and used on C40 concrete")
    # ops.nDMaterial('PlaneStressUserMaterial', 4, *(argu.c40_con[0:-1]))

    # logger.info(
    #     "material tag 40 by [PlateFromPlaneStress] and used on C40 concrete")
    # ops.nDMaterial('PlateFromPlaneStress', 40, 4, argu.c40_con[-1])

    logger.info(
        "material tag 5 by [PlateRebar] and used on angle 90 d = 10 longitudinal steel"
    )
    ops.nDMaterial('PlateRebar', 5, 1, 90)

    logger.info(
        "material tag 6 by [PlateRebar] and used angle 90 d = 6 transverse steel"
    )
    ops.nDMaterial('PlateRebar', 6, 2, 90)

    logger.info(
        "material tag 7 by [PlateRebar] and used angle 0 d = 6 transverse steel"
    )
    ops.nDMaterial('PlateRebar', 7, 2, 0)
    def buildModel(K, periodStruct, dampRatio):

        wn = 2.0 * PI / periodStruct
        m = K / (wn * wn)

        ops.wipe()
        ops.model('basic', '-ndm', 1, '-ndf', 1)

        ops.node(1, 0.)
        ops.node(2, 0., '-mass', m)

        ops.uniaxialMaterial('Elastic', 1, K)
        ops.element('zeroLength', 1, 1, 2, '-mat', 1, '-dir', 1)
        ops.fix(1, 1)

        # add damping using rayleigh damping on the mass term
        a0 = 2.0 * wn * dampRatio
        ops.rayleigh(a0, 0., 0., 0.)
Beispiel #13
0
def elements(coords, A, E, analysis_type):

    matTag = 10

    ops.uniaxialMaterial('Elastic', matTag, E)

    ##########################################################################

    eleTag = 1

    member_type = 'Truss'
    if analysis_type != 'Linear': member_type = 'corotTruss'

    temp = len(coords) - 3
    for i in range(0, temp, 2):
        eleTag = connections(member_type, A, matTag, i, eleTag)

    temp += 1
    ops.element(member_type, eleTag, *[temp, temp + 1], A, matTag)
Beispiel #14
0
def material_create():
    ''' create material
    '''
    ops.uniaxialMaterial("Elastic", 1, 1.999E+005)
    ops.uniaxialMaterial("Elastic", 2, 2.482E+004)
    ops.uniaxialMaterial("Elastic", 3, 1.999E+005)
    logger.info("material_create")
Beispiel #15
0
def ops_material():
    ''' define material '''
    # concrete
    # 抗压强度 抗压强度/10 残余强度 最大应变 残余应变 拉伸应变 剪切保留因子
    ops.nDMaterial('PlaneStressUserMaterial', 1, 40, 7, 31.7e6,
                   3.17e6, -6.16e6, -0.002, -0.005, 0.001, 0.1)
    # 平面外剪切模量
    ops.nDMaterial('PlateFromPlaneStress', 2, 1, 1.23E15)

    # 屈服强度 初始弹模 硬化率

    # 端部GFRP 20
    # 强度 1255.5 MPa 屈服应变 1.98% 弹性模量 63.5GPa
    ops.uniaxialMaterial('Steel02', 3, 1255.5e6, 63.5e9, 0.0, 15, 0.925, 0.15)

    # 端部纵筋 S16G2
    # 屈服强度 348.7MPa 屈服应变 0.204%
    # 极限强度 718.4MPa 极限应变 1.823%
    # 弹性模量 170.931GPa
    ops.uniaxialMaterial('Steel02', 4, 348.7e6,
                         170.931e9, 0.2210, 15, 0.925, 0.15)

    # 中部纵筋 10mm 和 箍筋 8mm S6G2
    # 屈服强度 257.5MPa 屈服应变 0.196%
    # 极限强度 837.2MPa 极限应变 1.658%
    # 弹性模量 131.378GPa
    ops.uniaxialMaterial('Steel02', 5, 257.5e6,
                         131.378e9, 0.320, 15, 0.925, 0.15)

    # 钢筋层
    # 箍筋
    ops.nDMaterial('PlateRebar', 6, 5, 0)
    # 纵筋
    ops.nDMaterial('PlateRebar', 7, 5, 90)
Beispiel #16
0
def ops_material():
    # 中部混凝土
    ops.nDMaterial('PlaneStressUserMaterial', 1, 40, 7, 31.7, 3.17, -6.34,
                   -0.00234, -0.03, 0.001, 0.05)
    ops.nDMaterial('PlateFromPlaneStress', 2, 1, 1.23e9)

    # 端部拉锁
    ops.uniaxialMaterial('Steel02', 3, 156.9375, 7937500, 1e-15)
    # 端部纵筋
    ops.uniaxialMaterial('Steel02', 4, 348.7, 170.931e6, 0.2210)
    # 中部纵筋和箍筋
    ops.uniaxialMaterial("Steel02", 5, 257.5, 131.378e6, 0.320)

    # 中部箍筋层
    ops.nDMaterial("PlateRebar", 6, 5, 0)
    # 中部纵筋层
    ops.nDMaterial("PlateRebar", 7, 5, 90)
    # 边缘区混凝土
    ops.uniaxialMaterial('Concrete01', 6, -31.7, -0.00234, 0.0, -0.005)

    # 中部壳
    ops.section('LayeredShell', 1, 12, 2, 20, 6, 0.65345127, 7, 0.6544985, 2,
                26.2274, 2, 26.2274, 2, 26.2274, 2, 26.2274, 2, 26.2274, 2,
                26.2274, 7, 0.6544985, 6, 0.65345127, 2, 20)
    # 边缘约束区
    ops.section('Fiber', 2, '-GJ', 0)
    # 混凝土
    ops.fiber(100, 0, 40000, 6)
    # 端部SFCB纵筋
    ops.fiber(0, 100, 314, 4)
    ops.fiber(0, -100, 314, 4)
    ops.fiber(100, 100, 314, 4)
    ops.fiber(100, -100, 314, 4)
    ops.fiber(200, 100, 314, 4)
    ops.fiber(200, -100, 314, 4)
    # 端部GFRP拉锁
    ops.fiber(200, 70, 314, 3)
    ops.fiber(200, -70, 314, 3)
Beispiel #17
0
    def create_FEM(self):
        """
        Create the representation of the elastic material in OpenSEES.

        """
        ops.uniaxialMaterial('Elastic', self.id, self.E_0)
Beispiel #18
0
def analisis_opensees(path, permutaciones):  #helper, #win
    ops.wipe()

    # bucle para generar los x análisis
    for i in range(len(permutaciones)):

        perfil = str(permutaciones[i][0])
        nf = permutaciones[i][2]
        amort = permutaciones[i][3]
        den = permutaciones[i][4]
        vel = permutaciones[i][5]
        capas = len(permutaciones[i][6])
        nstep = permutaciones[i][30]
        dt = float(permutaciones[i][31])

        # creación de elementos
        sElemX = permutaciones[i][1]  # elementos en X
        sElemZ = permutaciones[i][46]  # espesor en Z

        # =============================================================================
        #         ######## geometría de la columna ######
        # =============================================================================
        # límite entre capas
        limite_capa = []
        anterior = 0
        for j in range(capas):
            espesor = permutaciones[i][8][j]

            limite_capa.append(espesor + anterior)
            anterior = limite_capa[j]
            print('Límite de capa: ' + str(limite_capa[j]))

        # creación de elementos y nodos en x
        nElemX = 1  # elementos en x
        nNodeX = 2 * nElemX + 1  # nodos en x

        # creación de elementos y nodos para z
        nElemZ = 1

        # creación de elementos y nodos en Y y totales
        nElemY = []  # elementos en y
        sElemY = []  # dimension en y
        nElemT = 0
        for j in range(capas):
            espesor = permutaciones[i][8][j]

            nElemY.append(2 * espesor)
            nElemT += nElemY[j]
            print('Elementos en capa ' + str(j + 1) + ': ' + str(nElemY[j]))
            sElemY.append(permutaciones[i][8][j] / nElemY[j])
            print('Tamaño de los elementos en capa ' + str(j + 1) + ': ' +
                  str(sElemY[j]) + '\n')

        # number of nodes in vertical direction in each layer
        nNodeY = []  # dimension en y
        nNodeT = 0
        s = 0
        for j in range(capas - 1):
            nNodeY.append(4 * nElemY[j])
            nNodeT += nNodeY[j]
            s += 1
            print('Nodos en capa ' + str(j + 1) + ': ' + str(nNodeY[j]))

        nNodeY.append(4 * (nElemY[-1] + 1))
        nNodeT += nNodeY[-1]
        print('Nodos en capa ' + str(s + 1) + ': ' + str(nNodeY[s]))
        print('Nodos totales: ' + str(nNodeT))

        #win.ui.progressBar.setValue(15)

        # =============================================================================
        #         ######### Crear nodos del suelo ##########
        # =============================================================================
        # creación de nodos de presión de poros
        ops.model('basic', '-ndm', 3, '-ndf', 4)

        with open(path + '/Post-proceso/' + perfil + '/ppNodesInfo.dat',
                  'w') as f:
            count = 0.0
            yCoord = 0.0
            nodos = []
            dryNode = []
            altura_nf = 10 - nf

            for k in range(capas):
                for j in range(0, int(nNodeY[k]), 4):
                    ops.node(j + count + 1, 0.0, yCoord, 0.0)
                    ops.node(j + count + 2, 0.0, yCoord, sElemZ)
                    ops.node(j + count + 3, sElemX, yCoord, sElemZ)
                    ops.node(j + count + 4, sElemX, yCoord, 0.0)

                    f.write(
                        str(int(j + count + 1)) + '\t' + str(0.0) + '\t' +
                        str(yCoord) + '\t' + str(0.0) + '\n')
                    f.write(
                        str(int(j + count + 2)) + '\t' + str(0.0) + '\t' +
                        str(yCoord) + '\t' + str(sElemZ) + '\n')
                    f.write(
                        str(int(j + count + 3)) + '\t' + str(sElemX) + '\t' +
                        str(yCoord) + '\t' + str(sElemZ) + '\n')
                    f.write(
                        str(int(j + count + 4)) + '\t' + str(sElemX) + '\t' +
                        str(yCoord) + '\t' + str(0.0) + '\n')

                    nodos.append(str(j + count + 1))
                    nodos.append(str(j + count + 2))
                    nodos.append(str(j + count + 3))
                    nodos.append(str(j + count + 4))

                    #designate node sobre la superficie de agua
                    if yCoord >= altura_nf:
                        dryNode.append(j + count + 1)
                        dryNode.append(j + count + 2)
                        dryNode.append(j + count + 3)
                        dryNode.append(j + count + 4)

                    yCoord = (yCoord + sElemY[k])

                count = (count + nNodeY[k])

        print("Finished creating all soil nodes...")

        # =============================================================================
        #         ####### Condiciones de contorno en la base de la columna #########
        # =============================================================================
        ops.fix(1, *[0, 1, 1, 0])
        ops.fix(2, *[0, 1, 1, 0])
        ops.fix(3, *[0, 1, 1, 0])
        ops.fix(4, *[0, 1, 1, 0])
        ops.equalDOF(1, 2, 1)
        ops.equalDOF(1, 3, 1)
        ops.equalDOF(1, 4, 1)

        print('Fin de creación de nodos de la base de la columna\n\n')

        # =============================================================================
        #         ####### Condiciones de contorno en los nudos restantes #########
        # =============================================================================

        count = 0
        for k in range(5, int(nNodeT + 1), 4):
            ops.equalDOF(k, k + 1, *[1, 2, 3])
            ops.equalDOF(k, k + 2, *[1, 2, 3])
            ops.equalDOF(k, k + 3, *[1, 2, 3])

        print('Fin de creación equalDOF para nodos de presión de poros\n\n')

        for j in range(len(dryNode)):
            ops.fix(dryNode[j], *[0, 0, 0, 1])

        print("Finished creating all soil boundary conditions...")

        # =============================================================================
        #         ####### crear elemento y material de suelo #########
        # =============================================================================

        cargas = []
        for j in range(capas):
            pendiente = permutaciones[i][9][j]
            slope = math.atan(pendiente / 100)

            tipo_suelo = permutaciones[i][6][j]
            rho = permutaciones[i][10][j]
            Gr = permutaciones[i][12][j]
            Br = permutaciones[i][13][j]
            fric = permutaciones[i][15][j]
            refpress = permutaciones[i][18][j]
            gmax = permutaciones[i][19][j]
            presscoef = permutaciones[i][20][j]
            surf = permutaciones[i][21][j]
            ev = permutaciones[i][22][j]
            cc1 = permutaciones[i][23][j]
            cc3 = permutaciones[i][24][j]
            cd1 = permutaciones[i][25][j]
            cd3 = permutaciones[i][26][j]
            ptang = permutaciones[i][27][j]
            coh = permutaciones[i][28][j]

            if tipo_suelo == 'No cohesivo':
                if float(surf) > 0:
                    ops.nDMaterial('PressureDependMultiYield02', j + 1, 3.0,
                                   rho, Gr, Br, fric, gmax, refpress,
                                   presscoef, ptang, cc1, cc3, cd1, cd3,
                                   float(surf), 5.0, 3.0, *[1.0, 0.0], ev,
                                   *[0.9, 0.02, 0.7, 101.0])
                else:
                    ops.nDMaterial('PressureDependMultiYield02', j + 1, 3.0,
                                   rho, Gr, Br, fric, gmax, refpress,
                                   presscoef, ptang, cc1, cc3, cd1, cd3,
                                   float(surf), *permutaciones[i][29][j], 5.0,
                                   3.0, *[1.0,
                                          0.0], ev, *[0.9, 0.02, 0.7, 101.0])

            cargas.append(
                [0.0, -9.81 * math.cos(slope), -9.81 * math.sin(slope)])

        print('Fin de la creación de material de suelo\n\n')

        #-----------------------------------------------------------------------------------------
        #  5. CREATE SOIL ELEMENTS
        #-----------------------------------------------------------------------------------------

        count = 0
        alpha = 1.5e-6

        with open(path + '/Post-proceso/' + perfil + '/ppElemInfo.dat',
                  'w') as f:
            # crear elemento de suelo
            for k in range(capas):
                for j in range(int(nElemY[k])):
                    nI = 4 * (j + count + 1) - 3
                    nJ = nI + 1
                    nK = nI + 2
                    nL = nI + 3
                    nM = nI + 4
                    nN = nI + 5
                    nO = nI + 6
                    nP = nI + 7
                    f.write(
                        str(j + count + 1) + '\t' + str(nI) + '\t' + str(nJ) +
                        '\t' + str(nK) + '\t' + str(nL) + '\t' + str(nM) +
                        '\t' + str(nN) + '\t' + str(nO) + '\t' + str(nP) +
                        '\n')

                    Bc = permutaciones[i][14][k]
                    ev = permutaciones[i][22][k]

                    ops.element('SSPbrickUP', (j + count + 1),
                                *[nI, nJ, nK, nL, nM, nN, nO,
                                  nP], (k + 1), float(Bc), 1.0, 1.0, 1.0, 1.0,
                                float(ev), alpha, cargas[k][0], cargas[k][1],
                                cargas[k][2])

                count = (count + int(nElemY[k]))
        print('Fin de la creación del elemento del suelo\n\n')

        #win.ui.progressBar.setValue(25)

        # =============================================================================
        #         ######### Amortiguamiento de Lysmer ##########
        # =============================================================================

        ops.model('basic', '-ndm', 3, '-ndf', 3)

        # definir nodos y coordenadas del amortiguamiento
        dashF = nNodeT + 1
        dashX = nNodeT + 2
        dashZ = nNodeT + 3

        ops.node(dashF, 0.0, 0.0, 0.0)
        ops.node(dashX, 0.0, 0.0, 0.0)
        ops.node(dashZ, 0.0, 0.0, 0.0)

        # definir restricciones para los nodos de amortiguamiento
        ops.fix(dashF, 1, 1, 1)
        ops.fix(dashX, 0, 1, 1)
        ops.fix(dashZ, 1, 1, 0)

        # definir equalDOF para el amortiguamiento en la base del suelo
        ops.equalDOF(1, dashX, 1)
        ops.equalDOF(1, dashZ, 3)

        print(
            'Fin de la creación de condiciones de contorno de los nodos de amortiguamiento\n\n'
        )

        # definir el material de amortiguamiento
        colArea = sElemX * sElemZ
        dashpotCoeff = vel * den * colArea
        ops.uniaxialMaterial('Viscous', capas + 1, dashpotCoeff, 1.0)

        # definir el elemento
        ops.element('zeroLength', nElemT + 1, *[dashF, dashX], '-mat',
                    capas + 1, '-dir', *[1])
        ops.element('zeroLength', nElemT + 2, *[dashF, dashZ], '-mat',
                    capas + 1, '-dir', *[3])

        print('Fin de la creación del elemento de amortiguamiento\n\n')

        #-----------------------------------------------------------------------------------------
        #  9. DEFINE ANALYSIS PARAMETERS
        #-----------------------------------------------------------------------------------------

        # amortiguamiento de Rayleigh
        # frecuencia menor
        omega1 = 2 * math.pi * 0.2
        # frecuencia mayor
        omega2 = 2 * math.pi * 20

        a0 = 2.0 * (amort / 100) * omega1 * omega2 / (omega1 + omega2)
        a1 = 2.0 * (amort / 100) / (omega1 + omega2)
        print('Coeficientes de amortiguamiento' + '\n' + 'a0: ' +
              format(a0, '.6f') + '\n' + 'a1: ' + format(a1, '.6f') + '\n\n')

        #win.ui.progressBar.setValue(35)

        # =============================================================================
        #         ######## Determinación de análisis estático #########
        # =============================================================================
        #---DETERMINE STABLE ANALYSIS TIME STEP USING CFL CONDITION
        # se determina a partir de un análisis transitorio de largo tiempo
        duration = nstep * dt

        # tamaño mínimo del elemento y velocidad máxima
        minSize = sElemY[0]
        vsMax = permutaciones[i][11][0]
        for j in range(1, capas):
            if sElemY[j] < minSize:
                minSize = sElemY[j]
            if permutaciones[i][11][j] > vsMax:
                vsMax = permutaciones[i][11][j]

        # trial analysis time step
        kTrial = minSize / (vsMax**0.5)

        # tiempo de análisis y pasos de tiempo
        if dt <= kTrial:
            nStep = nstep
            dT = dt
        else:
            nStep = int(math.floor(duration / kTrial) + 1)
            dT = duration / nStep

        print('Número de pasos en el análisis: ' + str(nStep) + '\n')
        print('Incremento de tiempo: ' + str(dT) + '\n\n')

        #----------------------------------------------------------------------------------------
        #  7. GRAVITY ANALYSIS
        #-----------------------------------------------------------------------------------------
        ops.model('basic', '-ndm', 3, '-ndf', 4)

        ops.updateMaterialStage('-material', int(k + 1), '-stage', 0)

        # algoritmo de análisis estático
        ops.constraints(permutaciones[i][32][0],
                        float(permutaciones[i][32][1]),
                        float(permutaciones[i][32][2]))
        ops.test(permutaciones[i][34][0], float(permutaciones[i][34][1]),
                 int(permutaciones[i][34][2]), int(permutaciones[i][34][3]))
        ops.algorithm(permutaciones[i][38][0])
        ops.numberer(permutaciones[i][33][0])
        ops.system(permutaciones[i][36][0])
        ops.integrator(permutaciones[i][35][0], float(permutaciones[i][35][1]),
                       float(permutaciones[i][35][2]))
        ops.analysis(permutaciones[i][37][0])

        print('Inicio de análisis estático elástico\n\n')

        ops.start()
        ops.analyze(20, 5.0e2)

        print('Fin de análisis estático elástico\n\n')

        #win.ui.progressBar.setValue(40)

        # update materials to consider plastic behavior

        # =============================================================================

        ops.updateMaterialStage('-material', int(k + 1), '-stage', 1)

        # =============================================================================

        # plastic gravity loading
        print('Inicio de análisis estático plástico\n\n')

        ok = ops.analyze(40, 5.0e-2)

        if ok != 0:
            error = 'Error de convergencia en análisis estático de modelo' + str(
                perfil) + '\n\n'
            print(error)

            break

        print('Fin de análisis estático plástico\n\n')

        #-----------------------------------------------------------------------------------------
        #  11. UPDATE ELEMENT PERMEABILITY VALUES FOR POST-GRAVITY ANALYSIS
        #-----------------------------------------------------------------------------------------

        ini = 1
        aum = 0
        sum = 0
        for j in range(capas):
            #Layer 3
            ops.setParameter(
                '-val', permutaciones[i][16][j],
                ['-eleRange',
                 int(ini + aum),
                 int(nElemY[j] + sum)], 'xPerm')
            ops.setParameter(
                '-val', permutaciones[i][17][j],
                ['-eleRange',
                 int(ini + aum),
                 int(nElemY[j] + sum)], 'yPerm')
            ops.setParameter(
                '-val', permutaciones[i][16][j],
                ['-eleRange',
                 int(ini + aum),
                 int(nElemY[j] + sum)], 'zPerm')

            ini = nElemY[j] + sum
            sum += nElemY[j]
            aum = 1

        print("Finished updating permeabilities for dynamic analysis...")

        # =============================================================================
        #         ########### Grabadores dinámicos ##########
        # =============================================================================

        ops.setTime(0.0)
        ops.wipeAnalysis()
        ops.remove('recorders')

        # tiempo de la grabadora
        recDT = 10 * dt
        path_acel = path + '/Post-proceso/' + perfil + '/dinamico/aceleraciones/'

        ops.recorder('Node', '-file', path_acel + 'accelerationx.out', '-time',
                     '-dT', recDT, '-node', *nodos, '-dof', 1, 'accel')

        print('Fin de creación de grabadores\n\n')
        #win.ui.progressBar.setValue(50)

        # =============================================================================
        #         ######### Determinación de análisis dinámico ##########
        # =============================================================================

        # objeto de serie temporal para el historial de fuerza

        path_vel = path + '/Pre-proceso/' + perfil + '/TREASISL2.txt'

        ops.timeSeries('Path', 1, '-dt', dt, '-filePath', path_vel, '-factor',
                       dashpotCoeff)

        ops.pattern('Plain', 10, 1)
        ops.load(1, *[1.0, 0.0, 0.0, 0.0])  #CAMBIO REALIZADO OJO

        print('Fin de creación de carga dinámica\n\n')

        # algoritmo de análisis dinámico
        ops.constraints(permutaciones[i][39][0],
                        float(permutaciones[i][39][1]),
                        float(permutaciones[i][39][2]))
        ops.test(permutaciones[i][41][0], float(permutaciones[i][41][1]),
                 int(permutaciones[i][41][2]), int(permutaciones[i][41][3]))
        ops.algorithm(permutaciones[i][45][0])
        ops.numberer(permutaciones[i][40][0])
        ops.system(permutaciones[i][43][0])
        ops.integrator(permutaciones[i][42][0], float(permutaciones[i][42][1]),
                       float(permutaciones[i][42][2]))
        ops.analysis(permutaciones[i][44][0])
        # =============================================================================
        #         ops.rayleigh(a0, a1, 0.0, 0.0)
        # =============================================================================

        print('Inicio de análisis dinámico\n\n')
        #win.ui.progressBar.setValue(85)
        ok = ops.analyze(nStep, dT)

        if ok != 0:
            error = 'Error de convergencia en análisis dinámico de modelo' + str(
                permutaciones[i][0]) + '\n\n'
            print(error)
            curTime = ops.getTime()
            mTime = curTime
            print('cursTime:' + str(curTime))
            curStep = (curTime / dT)
            print('cursStep:' + str(curStep))
            rStep = (nStep - curStep) * 2.0
            remStep = int(nStep - curStep) * 2.0
            print('remSTep:' + str(curStep))
            dT = (dT / 2)
            print('dT:' + str(dT))

            ops.analyze(remStep, dT)

            if ok != 0:
                error = 'Error de convergencia en análisis dinámico de modelo' + str(
                    permutaciones[i][0]) + '\n\n'
                print(error)
                curTime = ops.getTime()
                print('cursTime:' + str(curTime))
                curStep = (curTime - mTime) / dT
                print('cursStep:' + str(curStep))
                remStep = int(rStep - curStep) * 2
                print('remSTep:' + str(curStep))
                dT = (dT / 2)
                print('dT:' + str(dT))

                ops.analyze(remStep, dT)

        print('Fin de análisis dinámico\n\n')

    ops.wipe()
    def __init__(self):
        # AIが取れるアクションの設定
        self.action = np.array([
            0, 0.02, 0.03, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1
        ])
        self.naction = len(self.action)

        self.beta = 1 / 4

        # 1質点系モデル
        self.T0 = 4
        self.h = self.action[0]
        self.hs = [self.h]
        self.m = 100
        self.k = 4 * np.pi**2 * self.m / self.T0**2

        # 入力地震動
        self.dt = 0.02
        to_meter = 0.01  # cmをmに変換する値
        self.wave_url = 'https://github.com/kakemotokeita/dqn-seismic-control/blob/master/wave/sample.csv'
        with urllib.request.urlopen(self.wave_url) as wave_file:
            self.wave_data = np.loadtxt(
                wave_file, usecols=(0, ), delimiter=',', skiprows=3) * to_meter

        # OpenSees設定
        op.wipe()
        op.model('basic', '-ndm', 2, '-ndf', 3)  # 2 dimensions, 3 dof per node

        # 節点
        self.bot_node = 1
        self.top_node = 2
        op.node(self.bot_node, 0., 0.)
        op.node(self.top_node, 0., 0.)

        # 境界条件
        op.fix(self.top_node, FREE, FIXED, FIXED)
        op.fix(self.bot_node, FIXED, FIXED, FIXED)
        op.equalDOF(1, 2, *[Y, ROTZ])

        # 質量
        op.mass(self.top_node, self.m, 0., 0.)

        # 弾性剛性
        elastic_mat_tag = 1
        Fy = 1e10
        E0 = self.k
        b = 1.0
        op.uniaxialMaterial('Steel01', elastic_mat_tag, Fy, E0, b)

        # Assign zero length element
        beam_tag = 1
        op.element('zeroLength', beam_tag, self.bot_node, self.top_node,
                   "-mat", elastic_mat_tag, "-dir", 1, '-doRayleigh', 1)

        # Define the dynamic analysis
        load_tag_dynamic = 1
        pattern_tag_dynamic = 1

        self.values = list(-1 * self.wave_data)  # should be negative
        op.timeSeries('Path', load_tag_dynamic, '-dt', self.dt, '-values',
                      *self.values)
        op.pattern('UniformExcitation', pattern_tag_dynamic, X, '-accel',
                   load_tag_dynamic)

        # 減衰の設定
        self.w0 = op.eigen('-fullGenLapack', 1)[0]**0.5
        self.alpha_m = 0.0
        self.beta_k = 2 * self.h / self.w0
        self.beta_k_init = 0.0
        self.beta_k_comm = 0.0

        op.rayleigh(self.alpha_m, self.beta_k, self.beta_k_init,
                    self.beta_k_comm)

        # Run the dynamic analysis

        op.wipeAnalysis()

        op.algorithm('Newton')
        op.system('SparseGeneral')
        op.numberer('RCM')
        op.constraints('Transformation')
        op.integrator('Newmark', 0.5, 0.25)
        op.analysis('Transient')

        tol = 1.0e-10
        iterations = 10
        op.test('EnergyIncr', tol, iterations, 0, 2)
        self.i_pre = 0
        self.i = 0
        self.i_next = 0
        self.time = 0
        self.analysis_time = (len(self.values) - 1) * self.dt
        self.dis = 0
        self.vel = 0
        self.acc = 0
        self.a_acc = 0
        self.force = 0
        self.resp = {
            "time": [],
            "dis": [],
            "acc": [],
            "a_acc": [],
            "vel": [],
            "force": [],
        }
        self.done = False
def get_inelastic_response(fb, asig, extra_time=0.0, xi=0.05, analysis_dt=0.001):
    """
    Run seismic analysis of a nonlinear FrameBuilding

    :param fb: FrameBuilding object
    :param asig: AccSignal object
    :param extra_time: float, additional analysis time after end of ground motion
    :param xi: damping ratio
    :param analysis_dt: time step to perform the analysis
    :return:
    """

    op.wipe()
    op.model('basic', '-ndm', 2, '-ndf', 3)  # 2 dimensions, 3 dof per node

    q_floor = 10000.  # kPa
    trib_width = fb.floor_length
    trib_mass_per_length = q_floor * trib_width / 9.8

    # Establish nodes and set mass based on trib area
    # Nodes named as: C<column-number>-S<storey-number>, first column starts at C1-S0 = ground level left
    nd = OrderedDict()
    col_xs = np.cumsum(fb.bay_lengths)
    col_xs = np.insert(col_xs, 0, 0)
    n_cols = len(col_xs)
    sto_ys = fb.heights
    sto_ys = np.insert(sto_ys, 0, 0)
    for cc in range(1, n_cols + 1):
        for ss in range(fb.n_storeys + 1):
            n_i = cc * 100 + ss
            nd["C%i-S%i" % (cc, ss)] = n_i
            op.node(n_i, col_xs[cc - 1], sto_ys[ss])

            if ss != 0:
                if cc == 1:
                    node_mass = trib_mass_per_length * fb.bay_lengths[0] / 2
                elif cc == n_cols:
                    node_mass = trib_mass_per_length * fb.bay_lengths[-1] / 2
                else:
                    node_mass = trib_mass_per_length * (fb.bay_lengths[cc - 2] + fb.bay_lengths[cc - 1] / 2)
                op.mass(n_i, node_mass)

    # Set all nodes on a storey to have the same displacement
    for ss in range(0, fb.n_storeys + 1):
        for cc in range(1, n_cols + 1):
            op.equalDOF(nd["C%i-S%i" % (1, ss)], nd["C%i-S%i" % (cc, ss)],  opc.X)

    # Fix all base nodes
    for cc in range(1, n_cols + 1):
        op.fix(nd["C%i-S%i" % (cc, 0)], opc.FIXED, opc.FIXED, opc.FIXED)

    # Coordinate transformation
    geo_tag = 1
    trans_args = []
    op.geomTransf("Linear", geo_tag, *[])

    l_hinge = fb.bay_lengths[0] * 0.1

    # Define material
    e_conc = 30.0e6
    i_beams = 0.4 * fb.beam_widths * fb.beam_depths ** 3 / 12
    i_columns = 0.5 * fb.column_widths * fb.column_depths ** 3 / 12
    a_beams = fb.beam_widths * fb.beam_depths
    a_columns = fb.column_widths * fb.column_depths
    ei_beams = e_conc * i_beams
    ei_columns = e_conc * i_columns
    eps_yield = 300.0e6 / 200e9
    phi_y_col = calc_yield_curvature(fb.column_depths, eps_yield)
    phi_y_beam = calc_yield_curvature(fb.beam_depths, eps_yield)

    # Define beams and columns

    md = OrderedDict()  # material dict
    sd = OrderedDict()  # section dict
    ed = OrderedDict()  # element dict
    # Columns named as: C<column-number>-S<storey-number>, first column starts at C1-S0 = ground floor left
    # Beams named as: B<bay-number>-S<storey-number>, first beam starts at B1-S1 = first storey left (foundation at S0)
    for ss in range(fb.n_storeys):

        # set columns
        for cc in range(1, fb.n_cols + 1):
            ele_i = cc * 100 + ss
            md["C%i-S%i" % (cc, ss)] = ele_i
            sd["C%i-S%i" % (cc, ss)] = ele_i
            ed["C%i-S%i" % (cc, ss)] = ele_i
            mat_props = elastic_bilin(ei_columns[ss][cc - 1], 0.05 * ei_columns[ss][cc - 1], phi_y_col[ss][cc - 1])
            #print(opc.ELASTIC_BILIN, ele_i, *mat_props)
            op.uniaxialMaterial(opc.ELASTIC_BILIN, ele_i, *mat_props)
            # op.uniaxialMaterial("Elastic", ele_i, ei_columns[ss][cc - 1])

            node_numbers = [nd["C%i-S%i" % (cc, ss)], nd["C%i-S%i" % (cc, ss + 1)]]
            op.element(opc.ELASTIC_BEAM_COLUMN, ele_i,
                       *node_numbers,
                       a_columns[ss - 1][cc - 1],
                       e_conc,
                       i_columns[ss - 1][cc - 1],
                       geo_tag
                       )

        # Set beams
        for bb in range(1, fb.n_bays + 1):
            ele_i = bb * 10000 + ss
            md["B%i-S%i" % (bb, ss)] = ele_i
            sd["B%i-S%i" % (bb, ss)] = ele_i
            ed["B%i-S%i" % (bb, ss)] = ele_i
            mat_props = elastic_bilin(ei_beams[ss][bb - 1], 0.05 * ei_beams[ss][bb - 1], phi_y_beam[ss][bb - 1])
            op.uniaxialMaterial(opc.ELASTIC_BILIN, ele_i, *mat_props)
            # op.uniaxialMaterial("Elastic", ele_i, ei_beams[ss][bb - 1])
            node_numbers = [nd["C%i-S%i" % (bb, ss + 1)], nd["C%i-S%i" % (bb + 1, ss + 1)]]
            print((opc.BEAM_WITH_HINGES, ele_i,
                       *node_numbers,
                        sd["B%i-S%i" % (bb, ss)], l_hinge,
                       sd["B%i-S%i" % (bb, ss)], l_hinge,
                       sd["B%i-S%i" % (bb, ss)], geo_tag
                       ))
            # Old definition
            # op.element(opc.BEAM_WITH_HINGES, ele_i,
            #  *[nd["C%i-S%i" % (bb, ss - 1)], nd["C%i-S%i" % (bb + 1, ss)]],
            #  sd["B%i-S%i" % (bb, ss)], l_hinge,
            #  sd["B%i-S%i" % (bb, ss)], l_hinge,
            #  e_conc,
            #  a_beams[ss - 1][bb - 1],
            #  i_beams[ss - 1][bb - 1], geo_tag
            #  )
            # New definition
            # op.element(opc.BEAM_WITH_HINGES, ele_i,
            #            *node_numbers,
            #             sd["B%i-S%i" % (bb, ss)], l_hinge,
            #            sd["B%i-S%i" % (bb, ss)], l_hinge,
            #            sd["B%i-S%i" % (bb, ss)], geo_tag  # TODO: make this elastic
            #
            #            )

            # Elastic definition
            op.element(opc.ELASTIC_BEAM_COLUMN, ele_i,
                       *node_numbers,
                       a_beams[ss - 1][bb - 1],
                       e_conc,
                       i_beams[ss - 1][bb - 1],
                       geo_tag
                       )

    # Define the dynamic analysis
    load_tag_dynamic = 1
    pattern_tag_dynamic = 1

    values = list(-1 * asig.values)  # should be negative
    op.timeSeries('Path', load_tag_dynamic, '-dt', asig.dt, '-values', *values)
    op.pattern('UniformExcitation', pattern_tag_dynamic, opc.X, '-accel', load_tag_dynamic)

    # set damping based on first eigen mode
    angular_freq2 = op.eigen('-fullGenLapack', 1)
    if hasattr(angular_freq2, '__len__'):
        angular_freq2 = angular_freq2[0]
    angular_freq = angular_freq2 ** 0.5
    if isinstance(angular_freq, complex):
        raise ValueError("Angular frequency is complex, issue with stiffness or mass")
    alpha_m = 0.0
    beta_k = 2 * xi / angular_freq
    beta_k_comm = 0.0
    beta_k_init = 0.0
    period = angular_freq / 2 / np.pi
    print("period: ", period)

    op.rayleigh(alpha_m, beta_k, beta_k_init, beta_k_comm)

    # Run the dynamic analysis

    op.wipeAnalysis()

    op.algorithm('Newton')
    op.system('SparseGeneral')
    op.numberer('RCM')
    op.constraints('Transformation')
    op.integrator('Newmark', 0.5, 0.25)
    op.analysis('Transient')
    #op.test("NormDispIncr", 1.0e-1, 2, 0)
    tol = 1.0e-10
    iter = 10
    op.test('EnergyIncr', tol, iter, 0, 2)  # TODO: make this test work
    analysis_time = (len(values) - 1) * asig.dt + extra_time
    outputs = {
        "time": [],
        "rel_disp": [],
        "rel_accel": [],
        "rel_vel": [],
        "force": []
    }
    print("Analysis starting")
    while op.getTime() < analysis_time:
        curr_time = op.getTime()
        op.analyze(1, analysis_dt)
        outputs["time"].append(curr_time)
        outputs["rel_disp"].append(op.nodeDisp(nd["C%i-S%i" % (1, fb.n_storeys)], opc.X))
        outputs["rel_vel"].append(op.nodeVel(nd["C%i-S%i" % (1, fb.n_storeys)], opc.X))
        outputs["rel_accel"].append(op.nodeAccel(nd["C%i-S%i" % (1, fb.n_storeys)], opc.X))
        op.reactions()
        react = 0
        for cc in range(1, fb.n_cols):
            react += -op.nodeReaction(nd["C%i-S%i" % (cc, 0)], opc.X)
        outputs["force"].append(react)  # Should be negative since diff node
    op.wipe()
    for item in outputs:
        outputs[item] = np.array(outputs[item])

    return outputs
Beispiel #21
0
def get_pile_m(pile_z0=0, pile_z1=-30, pile_d=2, m0=7.5, pile_f=0, pile_m=0):
    pile_h = pile_z0 - pile_z1
    pile_a = np.pi * (pile_d / 2) ** 2
    pile_i = np.pi * pile_d ** 4 / 64
    pile_b1 = 0.9 * (1.5 + 0.5 / pile_d) * 1 * pile_d

    # 建立模型
    ops.wipe()
    ops.model('basic', '-ndm', 2, '-ndf', 3)

    # 建立节点
    node_z = np.linspace(pile_z0, pile_z1, elem_num + 1)
    for i, j in enumerate(node_z):
        ops.node(i + 1, 0, j)
        ops.node(i + 201, 0, j)

    # 约束
    for i in range(len(node_z)):
        ops.fix(i + 1, 0, 1, 0)
        ops.fix(i + 201, 1, 1, 1)

    # 建立材料
    ops.uniaxialMaterial('Elastic', 1, 3e4)
    for i in range(len(node_z)):
        pile_depth = i * (pile_h / elem_num)
        pile_depth_nominal = 10 if pile_depth <= 10 else pile_depth
        soil_k = m0 * pile_depth_nominal * pile_b1 * (pile_h / elem_num)
        if i == 0:
            ops.uniaxialMaterial('Elastic', 100 + i, soil_k / 2)
            continue
        ops.uniaxialMaterial('Elastic', 100 + i, soil_k)

    # 装配
    ops.geomTransf('Linear', 1)

    # 建立单元
    for i in range(elem_num):
        ops.element('elasticBeamColumn', i + 1, i + 1, i + 2, pile_a, 3e10, pile_i, 1)

    # 建立弹簧
    for i in range(len(node_z)):
        ops.element('zeroLength', i + 201, i + 1, i + 201, '-mat', 100 + i, '-dir', 1)

    ops.timeSeries('Linear', 1)
    ops.pattern('Plain', 1, 1)
    ops.load(1, pile_f, 0, pile_m)

    ops.system('BandGeneral')
    ops.numberer('Plain')
    ops.constraints('Plain')

    ops.integrator('LoadControl', 0.01)
    ops.test('EnergyIncr', 1e-6, 200)
    ops.algorithm('Newton')
    ops.analysis('Static')

    ops.analyze(100)

    # 绘制位移图
    node_disp = []
    for i in range(101):
        node_disp.append(ops.nodeDisp(i + 1))

    node_disp = np.array(node_disp) * 1000

    plt.figure()
    plt.subplot(121)
    for i, j in enumerate(node_z):
        if abs(node_disp[:, 0][i]) > max(abs(node_disp[:, 0])) / 50:
            if i == 0:
                plt.plot([0, node_disp[:, 0][i]], [j, j], linewidth=1.5, color='grey')
            else:
                plt.plot([0, node_disp[:, 0][i]], [j, j], linewidth=0.7, color='grey')
        if abs(node_disp[:, 0][i]) == max(abs(node_disp[:, 0])):
            plt.annotate(f'{node_disp[:, 0][i]:.1f} mm', xy=(node_disp[:, 0][i], j),
                         xytext=(0.3, 0.5), textcoords='axes fraction',
                         bbox=dict(boxstyle="round", fc="0.8"),
                         arrowprops=dict(arrowstyle='->', connectionstyle="arc3,rad=-0.3"))
    plt.plot([0, 0], [node_z[0], node_z[-1]], linewidth=1.5, color='dimgray')
    plt.plot(node_disp[:, 0], node_z, linewidth=1.5, color='midnightblue')

    plt.xlabel('Displacement(mm)')
    plt.ylabel('Pile Depth(m)')

    # 绘制弯矩图
    elem_m = []
    for i in range(100):
        elem_m.append(ops.eleForce(i + 1))
    elem_m = np.array(elem_m) / 1000

    plt.subplot(122)
    for i, j in enumerate(node_z[:-1]):
        if abs(elem_m[:, 2][i]) > max(abs(elem_m[:, 2])) / 50:
            if i == 0:
                plt.plot([0, elem_m[:, 2][i]], [j, j], linewidth=1.5, color='grey')
            else:
                plt.plot([0, elem_m[:, 2][i]], [j, j], linewidth=0.7, color='grey')
        if abs(elem_m[:, 2][i]) == max(abs(elem_m[:, 2])):
            plt.annotate(f'{elem_m[:, 2][i]:.1f} kN.m', xy=(elem_m[:, 2][i], j),
                         xytext=(0.5, 0.5), textcoords='axes fraction',
                         bbox=dict(boxstyle="round", fc="0.8"),
                         arrowprops=dict(arrowstyle='->', connectionstyle="arc3,rad=0.3"))

    plt.plot([0, 0], [node_z[0], node_z[-1]], linewidth=1.5, color='dimgray')
    plt.plot(elem_m[:, 2], node_z[:-1], linewidth=1.5, color='brown')
    plt.xlabel('Moment(kN.m)')
    # plt.ylabel('Pile Depth(m)')
    plt.show()

    return abs(max(elem_m[:, 2]))
Beispiel #22
0
import openseespy.opensees as op
import openseespytools.model as opm
import numpy as np

op.wipe()

op.model('basic', '-ndm', 3, '-ndf', 6)

mat1 = 1
op.nDMaterial('ElasticIsotropic', mat1, 1., 0.1)
mat2 = 2
op.uniaxialMaterial('Elastic', mat2, 1.)

nodeCoordsx = np.array([0, 1, 2, 3, 4]) * 1.
nodeCoordsy = np.array([0, 1]) * 1.
nodeCoordsz = np.array([0, 1]) * 1.

# Element connectivity
element1D = np.array([[1, 1, 11], [2, 2, 12], [3, 3, 13], [4, 4,
                                                           14], [5, 5, 15],
                      [6, 6, 16], [7, 7, 17], [8, 8, 18], [9, 9, 19],
                      [10, 10, 20]])
element4D = np.array([[21, 12, 13, 18, 17], [22, 13, 14, 19, 18]])
element8D = np.array([[30, 1, 2, 7, 6, 11, 12, 17, 16],
                      [31, 4, 5, 10, 9, 14, 15, 20, 19]])

elements = [element1D, element4D, element8D]

# Define Nodes
tag = 0
for z in nodeCoordsz:
Beispiel #23
0
def material_create():
    ''' create material
    '''
    ops.uniaxialMaterial("Steel01", 1, 335, 200000, 0.00001)
    ops.uniaxialMaterial("Concrete01", 2, -26.8, -0.002, -10, -0.0033)
    logger.info("material_create")
Beispiel #24
0
# definir y construir el material
mTg = 1
rho = 2000 * kg / m**3  # densidad del suelo
Vs = 350.0 * m / s  # velocidad de inda de corte del suelo
G = rho * Vs * Vs  # modulo de corte
nu = 0.15  # coeficiente de poisson
E = 2 * G * (1 + nu)
ops.nDMaterial('ElasticIsotropic', mTg, E, nu, rho)

# material de los bordes viscosos
lm = nu * E / ((1 + nu) * (1 - 2 * nu))
Vc = math.sqrt((lm + 2 * G) / rho)
Cn = rho * Vc
Ct = rho * Vs
ops.uniaxialMaterial('Viscous', 100, Cn, 1.0)
ops.uniaxialMaterial('Viscous', 101, Ct, 1.0)
# https://openseespydoc.readthedocs.io/en/latest/src/Viscous.html

# espesor de los elementos
B = 1 * m

# construccion de nodos
for i in range(nNode):
    ops.node(i + 1, *Node[i][1:])

# construccion de elementos
for i in range(nEle):
    if (Ele[i][0] == 1):
        ops.element('quad', i + 1, *Ele[i][2:], B, 'PlaneStrain', Ele[i][0])
Beispiel #25
0
def get_multi_pile_m(
        pile_layout,
        cap_edge=0,
        cap_thickness=2,
        pile_z0=-2.5,
        pile_z1=-30,
        pile_d=2,
        m0=7500000,
        top_f=0.0,
        top_h=0.0,
        top_m=0.0
):
    if cap_edge == 0:
        if pile_d <= 1:
            cap_edge = max(0.25, 0.5 * pile_d)
        else:
            cap_edge = max(0.5, 0.3 * pile_d)
    cap_w = max(pile_layout[0]) - min(pile_layout[0]) + pile_d + cap_edge * 2
    cap_l = max(pile_layout[1]) - min(pile_layout[1]) + pile_d + cap_edge * 2
    top_f += cap_w * cap_l * cap_thickness * 26e3       # 承台自重
    top_f += (cap_w * cap_l) * (-pile_z0 - cap_thickness) * 15e3    # 盖梁重量
    pile_rows = len(pile_layout[1])     # 桩排数
    top_f /= pile_rows      # 桩顶力分配
    top_h /= pile_rows      # 桩顶水平力分配
    top_m /= pile_rows      # 桩顶弯矩分配
    cap_i = cap_l * cap_thickness ** 3 / 12 / pile_rows     # 承台横向刚度

    pile_h = pile_z0 - pile_z1
    pile_a = np.pi * (pile_d / 2) ** 2
    pile_i = np.pi * pile_d ** 4 / 64
    pile_b1 = 0.9 * (1.5 + 0.5 / pile_d) * 1 * pile_d

    # 建立模型
    ops.wipe()
    ops.model('basic', '-ndm', 2, '-ndf', 3)

    # 建立节点
    cap_bot = pile_z0
    # ops.node(1, 0, cap_top)     # 承台竖向节点
    if 0 not in pile_layout[0]:
        ops.node(2, 0, cap_bot)

    # 建立桩基节点
    node_z = np.linspace(pile_z0, pile_z1, elem_num + 1)
    for i, j in enumerate(pile_layout[0]):
        node_start = 100 + i * 300
        for m, n in enumerate(node_z):
            ops.node(node_start + m + 1, j, n)
            ops.node(node_start + m + 151, j, n)

    nodes = {}
    for i in ops.getNodeTags():
        nodes[i] = ops.nodeCoord(i)

    # 建立约束
    for i, j in enumerate(pile_layout[0]):
        node_start = 100 + i * 300
        for m, n in enumerate(node_z):
            ops.fix(node_start + m + 151, 1, 1, 1)
            if n == node_z[-1]:
                ops.fix(node_start + m + 1, 1, 1, 1)

    # 建立材料
    for i in range(len(node_z)):
        pile_depth = i * (pile_h / elem_num)
        pile_depth_nominal = 10 if pile_depth <= 10 else pile_depth
        soil_k = m0 * pile_depth_nominal * pile_b1 * (pile_h / elem_num)
        if i == 0:
            ops.uniaxialMaterial('Elastic', 1 + i, soil_k / 2)
            continue
        ops.uniaxialMaterial('Elastic', 1 + i, soil_k)

    # 装配
    ops.geomTransf('Linear', 1)

    # 建立单元
    if len(pile_layout[0]) > 1:     # 承台横向单元
        cap_nodes = []
        for i in nodes:
            if nodes[i][1] == cap_bot:
                if len(cap_nodes) == 0:
                    cap_nodes.append(i)
                elif nodes[i][0] != nodes[cap_nodes[-1]][0]:
                    cap_nodes.append(i)
        cap_nodes = sorted(cap_nodes, key=lambda x: nodes[x][0])
        for i, j in enumerate(cap_nodes[:-1]):
            ops.element('elasticBeamColumn', 10 + i, j, cap_nodes[i+1], cap_l * cap_thickness, 3e10, cap_i, 1)

    pile_elem = []
    for i, j in enumerate(pile_layout[0]):      # 桩基单元
        node_start = 100 + i * 300
        pile_elem_i = []
        for m, n in enumerate(node_z):
            if n != pile_z1:
                ops.element('elasticBeamColumn', node_start + m + 1, node_start + m + 1,
                            node_start + m + 2, pile_a, 3e10, pile_i, 1)
                pile_elem_i.append(node_start + m + 1)
            ops.element('zeroLength', node_start + m + 151, node_start + m + 151,
                        node_start + m + 1, '-mat', 1 + m, '-dir', 1)
        pile_elem.append(pile_elem_i)

    ops.timeSeries('Linear', 1)
    ops.pattern('Plain', 1, 1)
    for i in nodes:
        if nodes[i] == [0, pile_z0]:
            ops.load(i, -top_h, -top_f, top_m)    # 加载

    ops.system('BandGeneral')
    ops.numberer('Plain')
    ops.constraints('Plain')

    ops.integrator('LoadControl', 0.01)
    ops.test('EnergyIncr', 1e-6, 200)
    ops.algorithm('Newton')
    ops.analysis('Static')

    ops.analyze(100)

    node_disp = {}
    for i in ops.getNodeTags():
        node_disp[i] = [j * 1000 for j in ops.nodeDisp(i)]

    elem_m = {}
    for i in pile_elem:
        for j in i:
            elem_m[j] = [k / 1000 for k in ops.eleForce(j)]

    plt.figure()
    for i, j in enumerate(pile_elem):
        plt.subplot(f'1{len(pile_elem)}{i+1}')
        if i == 0:
            plt.ylabel('Pile Depth(m)')
        node_disp_x = []
        for m, n in enumerate(j):
            node_1 = ops.eleNodes(n)[0]
            if m == 0:
                plt.plot([0, node_disp[node_1][0]], [nodes[node_1][1], nodes[node_1][1]],
                         linewidth=1.5, color='grey')
            else:
                plt.plot([0, node_disp[node_1][0]], [nodes[node_1][1], nodes[node_1][1]],
                         linewidth=0.7, color='grey')
            node_disp_x.append(node_disp[node_1][0])
        for m, n in enumerate(j):
            node_1 = ops.eleNodes(n)[0]
            if abs(node_disp[node_1][0]) == max([abs(i) for i in node_disp_x]):
                side = 1 if node_disp[node_1][0] > 0 else -1
                plt.annotate(f'{node_disp[node_1][0]:.1f} mm', xy=(node_disp[node_1][0], nodes[node_1][1]),
                             xytext=(0.4 + 0.1 * side, 0.5), textcoords='axes fraction',
                             bbox=dict(boxstyle="round", fc="0.8"),
                             arrowprops=dict(arrowstyle='->', connectionstyle=f"arc3,rad={side * 0.3}"))
                break
        plt.plot([0, 0], [node_z[0], node_z[-1]], linewidth=1.5, color='dimgray')
        plt.plot(node_disp_x, node_z[:-1], linewidth=1.5, color='midnightblue')
        plt.xlabel(f'Displacement_{i+1} (mm)')
    plt.show()

    plt.figure()
    for i, j in enumerate(pile_elem):
        plt.subplot(f'1{len(pile_elem)}{i + 1}')
        if i == 0:
            plt.ylabel('Pile Depth(m)')
        elem_mi = []
        for m, n in enumerate(j):
            node_1 = ops.eleNodes(n)[0]
            if m == 0:
                plt.plot([0, elem_m[n][2]], [nodes[node_1][1], nodes[node_1][1]],
                         linewidth=1.5, color='grey')
            else:
                plt.plot([0, elem_m[n][2]], [nodes[node_1][1], nodes[node_1][1]],
                         linewidth=0.7, color='grey')
            elem_mi.append(elem_m[n][2])
        for m, n in enumerate(j):
            node_1 = ops.eleNodes(n)[0]
            if abs(elem_m[n][2]) == max([abs(i) for i in elem_mi]):
                side = 1 if elem_m[n][2] > 0 else -1
                plt.annotate(f'{elem_m[n][2]:.1f} kN.m', xy=(elem_m[n][2], nodes[node_1][1]),
                             xytext=(0.4 + 0.1 * side, 0.5), textcoords='axes fraction',
                             bbox=dict(boxstyle="round", fc="0.8"),
                             arrowprops=dict(arrowstyle='->', connectionstyle=f"arc3,rad={side * 0.3}"))
                break
        plt.plot([0, 0], [node_z[0], node_z[-1]], linewidth=1.5, color='dimgray')
        plt.plot(elem_mi, node_z[:-1], linewidth=1.5, color='brown')
        plt.xlabel(f'Moment_{i + 1} (kN.m)')
    plt.show()

    return pile_elem, elem_m
Beispiel #26
0
def test_Truss():

    # remove existing model
    ops.wipe()

    # set modelbuilder
    ops.model('basic', '-ndm', 2, '-ndf', 2)

    # create nodes
    ops.node(1, 0.0, 0.0)
    ops.node(2, 144.0, 0.0)
    ops.node(3, 168.0, 0.0)
    ops.node(4, 72.0, 96.0)

    # set boundary condition
    ops.fix(1, 1, 1)
    ops.fix(2, 1, 1)
    ops.fix(3, 1, 1)

    # define materials
    ops.uniaxialMaterial("Elastic", 1, 3000.0)

    # define elements
    ops.element("Truss", 1, 1, 4, 10.0, 1)
    ops.element("Truss", 2, 2, 4, 5.0, 1)
    ops.element("Truss", 3, 3, 4, 5.0, 1)

    # create TimeSeries
    ops.timeSeries("Linear", 1)

    # create a plain load pattern
    ops.pattern("Plain", 1, 1)

    # Create the nodal load - command: load nodeID xForce yForce
    ops.load(4, 100.0, -50.0)

    # ------------------------------
    # Start of analysis generation
    # ------------------------------

    # create SOE
    ops.system("BandSPD")

    # create DOF number
    ops.numberer("Plain")

    # create constraint handler
    ops.constraints("Plain")

    # create integrator
    ops.integrator("LoadControl", 1.0)

    # create algorithm
    ops.algorithm("Linear")

    # create analysis object
    ops.analysis("Static")

    # perform the analysis
    ops.analyze(1)

    ux = ops.nodeDisp(4, 1)
    uy = ops.nodeDisp(4, 2)

    assert abs(ux - 0.53009277713228375450) < 1e-12 and abs(
        uy + 0.17789363846931768864) < 1e-12
Beispiel #27
0
fc2U = 0.2 * fc1U  # ultimate stress
eps2U = -0.05  # strain at ultimate stress
Lambda = 0.1  # ratio between unloading slope at $eps2 and initial slope $Ec

# tensile-strength properties
ftU = -0.14 * fc1U  # tensile strength +tension
Ets = ftU / 0.002  # tension softening stiffness

Fy = 66.8 * ksi  # STEEL yield stress
Es = 29000.0 * ksi  # modulus of steel
Bs = 0.01  # strain-hardening ratio
R0 = 18.0  # control the transition from elastic to plastic branches
cR1 = 0.925  # control the transition from elastic to plastic branches
cR2 = 0.15  # control the transition from elastic to plastic branches

op.uniaxialMaterial('Concrete02', IDconcU, fc1U, eps1U, fc2U, eps2U, Lambda,
                    ftU, Ets)  # build cover concrete (unconfined)
op.uniaxialMaterial('Steel02', IDreinf, Fy, Es, Bs, R0, cR1,
                    cR2)  # build reinforcement material
# FIBER SECTION properties -------------------------------------------------------------
# symmetric section
#                        y
#                        ^
#                        |
#             ---------------------     --   --
#             |   o     o     o    |     |    -- cover
#             |                       |     |
#             |                       |     |
#    z <--- |          +           |     H
#             |                       |     |
#             |                       |     |
#             |   o     o     o    |     |    -- cover
Beispiel #28
0
def RunAnalysis():
    AnalysisType = 'Pushover'
    #  Pushover  Gravity

    ## ------------------------------
    ## Start of model generation
    ## -----------------------------
    # remove existing model
    ops.wipe()

    # set modelbuilder
    ops.model('basic', '-ndm', 2, '-ndf', 3)

    import math

    ############################################
    ### Units and Constants  ###################
    ############################################

    inch = 1
    kip = 1
    sec = 1

    # Dependent units
    sq_in = inch * inch
    ksi = kip / sq_in
    ft = 12 * inch

    # Constants
    g = 386.2 * inch / (sec * sec)
    pi = math.acos(-1)

    #######################################
    ##### Dimensions
    #######################################

    # Dimensions Input
    H_story = 10.0 * ft
    W_bayX = 16.0 * ft
    W_bayY_ab = 5.0 * ft + 10.0 * inch
    W_bayY_bc = 8.0 * ft + 4.0 * inch
    W_bayY_cd = 5.0 * ft + 10.0 * inch

    # Calculated dimensions
    W_structure = W_bayY_ab + W_bayY_bc + W_bayY_cd

    ################
    ### Material
    ################

    # Steel02 Material

    matTag = 1
    matConnAx = 2
    matConnRot = 3

    Fy = 60.0 * ksi
    # Yield stress
    Es = 29000.0 * ksi
    # Modulus of Elasticity of Steel
    v = 0.2
    # Poisson's ratio
    Gs = Es / (1 + v)
    # Shear modulus
    b = 0.10
    # Strain hardening ratio
    params = [18.0, 0.925, 0.15]  # R0,cR1,cR2
    R0 = 18.0
    cR1 = 0.925
    cR2 = 0.15
    a1 = 0.05
    a2 = 1.00
    a3 = 0.05
    a4 = 1.0
    sigInit = 0.0
    alpha = 0.05

    ops.uniaxialMaterial('Steel02', matTag, Fy, Es, b, R0, cR1, cR2, a1, a2,
                         a3, a4, sigInit)

    # ##################
    # ## Sections
    # ##################

    colSecTag1 = 1
    colSecTag2 = 2
    beamSecTag1 = 3
    beamSecTag2 = 4
    beamSecTag3 = 5

    # COMMAND: section('WFSection2d', secTag, matTag, d, tw, bf, tf, Nfw, Nff)

    ops.section('WFSection2d', colSecTag1, matTag, 10.5 * inch, 0.26 * inch,
                5.77 * inch, 0.44 * inch, 15, 16)  # outer Column
    ops.section('WFSection2d', colSecTag2, matTag, 10.5 * inch, 0.26 * inch,
                5.77 * inch, 0.44 * inch, 15, 16)  # Inner Column

    ops.section('WFSection2d', beamSecTag1, matTag, 8.3 * inch, 0.44 * inch,
                8.11 * inch, 0.685 * inch, 15, 15)  # outer Beam
    ops.section('WFSection2d', beamSecTag2, matTag, 8.2 * inch, 0.40 * inch,
                8.01 * inch, 0.650 * inch, 15, 15)  # Inner Beam
    ops.section('WFSection2d', beamSecTag3, matTag, 8.0 * inch, 0.40 * inch,
                7.89 * inch, 0.600 * inch, 15, 15)  # Inner Beam

    # Beam size - W10x26
    Abeam = 7.61 * inch * inch
    IbeamY = 144. * (inch**4)
    # Inertia along horizontal axis
    IbeamZ = 14.1 * (inch**4)
    # inertia along vertical axis

    # BRB input data
    Acore = 2.25 * inch
    Aend = 10.0 * inch
    LR_BRB = 0.55

    # ###########################
    # ##### Nodes
    # ###########################

    # Create All main nodes
    ops.node(1, 0.0, 0.0)
    ops.node(2, W_bayX, 0.0)
    ops.node(3, 2 * W_bayX, 0.0)

    ops.node(11, 0.0, H_story)
    ops.node(12, W_bayX, H_story)
    ops.node(13, 2 * W_bayX, H_story)

    ops.node(21, 0.0, 2 * H_story)
    ops.node(22, W_bayX, 2 * H_story)
    ops.node(23, 2 * W_bayX, 2 * H_story)

    ops.node(31, 0.0, 3 * H_story)
    ops.node(32, W_bayX, 3 * H_story)
    ops.node(33, 2 * W_bayX, 3 * H_story)

    # Beam Connection nodes

    ops.node(1101, 0.0, H_story)
    ops.node(1201, W_bayX, H_story)
    ops.node(1202, W_bayX, H_story)
    ops.node(1301, 2 * W_bayX, H_story)

    ops.node(2101, 0.0, 2 * H_story)
    ops.node(2201, W_bayX, 2 * H_story)
    ops.node(2202, W_bayX, 2 * H_story)
    ops.node(2301, 2 * W_bayX, 2 * H_story)

    ops.node(3101, 0.0, 3 * H_story)
    ops.node(3201, W_bayX, 3 * H_story)
    ops.node(3202, W_bayX, 3 * H_story)
    ops.node(3301, 2 * W_bayX, 3 * H_story)

    # ###############
    #  Constraints
    # ###############

    ops.fix(1, 1, 1, 1)
    ops.fix(2, 1, 1, 1)
    ops.fix(3, 1, 1, 1)

    # #######################
    # ### Elements
    # #######################

    # ### Assign beam-integration tags

    ColIntTag1 = 1
    ColIntTag2 = 2
    BeamIntTag1 = 3
    BeamIntTag2 = 4
    BeamIntTag3 = 5

    ops.beamIntegration('Lobatto', ColIntTag1, colSecTag1, 4)
    ops.beamIntegration('Lobatto', ColIntTag2, colSecTag2, 4)
    ops.beamIntegration('Lobatto', BeamIntTag1, beamSecTag1, 4)
    ops.beamIntegration('Lobatto', BeamIntTag2, beamSecTag2, 4)
    ops.beamIntegration('Lobatto', BeamIntTag3, beamSecTag3, 4)

    # Assign geometric transformation

    ColTransfTag = 1
    BeamTranfTag = 2

    ops.geomTransf('PDelta', ColTransfTag)
    ops.geomTransf('Linear', BeamTranfTag)

    # Assign Elements  ##############

    # ## Add non-linear column elements
    ops.element('forceBeamColumn', 1, 1, 11, ColTransfTag, ColIntTag1, '-mass',
                0.0)
    ops.element('forceBeamColumn', 2, 2, 12, ColTransfTag, ColIntTag2, '-mass',
                0.0)
    ops.element('forceBeamColumn', 3, 3, 13, ColTransfTag, ColIntTag1, '-mass',
                0.0)

    ops.element('forceBeamColumn', 11, 11, 21, ColTransfTag, ColIntTag1,
                '-mass', 0.0)
    ops.element('forceBeamColumn', 12, 12, 22, ColTransfTag, ColIntTag2,
                '-mass', 0.0)
    ops.element('forceBeamColumn', 13, 13, 23, ColTransfTag, ColIntTag1,
                '-mass', 0.0)

    ops.element('forceBeamColumn', 21, 21, 31, ColTransfTag, ColIntTag1,
                '-mass', 0.0)
    ops.element('forceBeamColumn', 22, 22, 32, ColTransfTag, ColIntTag2,
                '-mass', 0.0)
    ops.element('forceBeamColumn', 23, 23, 33, ColTransfTag, ColIntTag1,
                '-mass', 0.0)

    #  ### Add linear main beam elements, along x-axis
    #element('elasticBeamColumn', 101, 1101, 1201, Abeam, Es, Gs, Jbeam, IbeamY, IbeamZ, beamTransfTag, '-mass', 0.0)

    ops.element('forceBeamColumn', 101, 1101, 1201, BeamTranfTag, BeamIntTag1,
                '-mass', 0.0)
    ops.element('forceBeamColumn', 102, 1202, 1301, BeamTranfTag, BeamIntTag1,
                '-mass', 0.0)

    ops.element('forceBeamColumn', 201, 2101, 2201, BeamTranfTag, BeamIntTag2,
                '-mass', 0.0)
    ops.element('forceBeamColumn', 202, 2202, 2301, BeamTranfTag, BeamIntTag2,
                '-mass', 0.0)

    ops.element('forceBeamColumn', 301, 3101, 3201, BeamTranfTag, BeamIntTag3,
                '-mass', 0.0)
    ops.element('forceBeamColumn', 302, 3202, 3301, BeamTranfTag, BeamIntTag3,
                '-mass', 0.0)

    # Assign constraints between beam end nodes and column nodes (RIgid beam column connections)
    ops.equalDOF(11, 1101, 1, 2, 3)
    ops.equalDOF(12, 1201, 1, 2, 3)
    ops.equalDOF(12, 1202, 1, 2, 3)
    ops.equalDOF(13, 1301, 1, 2, 3)

    ops.equalDOF(21, 2101, 1, 2, 3)
    ops.equalDOF(22, 2201, 1, 2, 3)
    ops.equalDOF(22, 2202, 1, 2, 3)
    ops.equalDOF(23, 2301, 1, 2, 3)

    ops.equalDOF(31, 3101, 1, 2, 3)
    ops.equalDOF(32, 3201, 1, 2, 3)
    ops.equalDOF(32, 3202, 1, 2, 3)
    ops.equalDOF(33, 3301, 1, 2, 3)

    AllNodes = ops.getNodeTags()
    massX = 0.49

    for nodes in AllNodes:
        ops.mass(nodes, massX, massX, 0.00001)

    ################
    ## Gravity Load
    ################
    # create TimeSeries
    ops.timeSeries("Linear", 1)

    # create a plain load pattern
    ops.pattern("Plain", 1, 1)

    # Create the nodal load
    ops.load(11, 0.0, -5.0 * kip, 0.0)
    ops.load(12, 0.0, -6.0 * kip, 0.0)
    ops.load(13, 0.0, -5.0 * kip, 0.0)

    ops.load(21, 0., -5. * kip, 0.0)
    ops.load(22, 0., -6. * kip, 0.0)
    ops.load(23, 0., -5. * kip, 0.0)

    ops.load(31, 0., -5. * kip, 0.0)
    ops.load(32, 0., -6. * kip, 0.0)
    ops.load(33, 0., -5. * kip, 0.0)

    ###############################
    ### PUSHOVER ANALYSIS
    ###############################

    if (AnalysisType == "Pushover"):

        print("<<<< Running Pushover Analysis >>>>")

        # Create load pattern for pushover analysis
        # create a plain load pattern
        ops.pattern("Plain", 2, 1)

        ops.load(11, 1.61, 0.0, 0.0)
        ops.load(21, 3.22, 0.0, 0.0)
        ops.load(31, 4.83, 0.0, 0.0)

        ControlNode = 31
        ControlDOF = 1
        MaxDisp = 0.15 * H_story
        DispIncr = 0.1
        NstepsPush = int(MaxDisp / DispIncr)

        Model = 'test'
        LoadCase = 'Pushover'
        dt = 0.2
        opp.createODB(Model, LoadCase, Nmodes=3)

        ops.system("ProfileSPD")
        ops.numberer("Plain")
        ops.constraints("Plain")
        ops.integrator("DisplacementControl", ControlNode, ControlDOF,
                       DispIncr)
        ops.algorithm("Newton")
        ops.test('NormUnbalance', 1e-8, 10)
        ops.analysis("Static")

        # 	analyze(NstepsPush)
        ops.analyze(100)

        print("Pushover analysis complete")
Beispiel #29
0
# Fixed support
# -------------
ops.fix(1, 1, 1, 1)

# Define material
# ---------------
matTag = 1
Fy = 410 * MPa  # Yield stress
Es = 200 * GPa  # Modulus of Elasticity of Steel
b = 2 / 100  # 2% Strain hardening ratio
Hkin = b / (1 - b) * Es

# Sensitivity-ready steel materials: Hardening, Steel01, SteelMP, BoucWen, SteelBRB, StainlessECThermal, SteelECThermal, ...
# Hardening Sensitivity Params: sigmaY/fy/Fy, E, H_kin/Hkin, H_iso/Hiso
ops.uniaxialMaterial("Hardening", matTag, Es, Fy, 0, Hkin)

# ops.uniaxialMaterial("Steel01", matTag, Fy, Es, b) # Sensitivity Params: sigmaY/fy/Fy, E, b, a1, a2, a3, a4
# ops.uniaxialMaterial("SteelMP", matTag, Fy, Es, b) # Sensitivity Params: sigmaY/fy, E, b

# Define sections
# ---------------
# Sections defined with "canned" section ("WFSection2d"), otherwise use a FiberSection object (ops.section("Fiber",...))
beamSecTag = 1
beamWidth, beamDepth = 10 * cm, 50 * cm
#                          secTag,     matTag, d,         tw,        bf,       tf, Nfw, Nff
ops.section("WFSection2d", beamSecTag, matTag, beamDepth, beamWidth, beamWidth,
            0, 20, 0)  # Beam section

# Define elements
# ---------------
def test_EigenFrameExtra():

    eleTypes = [
        'elasticBeam', 'forceBeamElasticSection', 'dispBeamElasticSection',
        'forceBeamFiberSectionElasticMaterial',
        'dispBeamFiberSectionElasticMaterial'
    ]

    for eleType in eleTypes:

        ops.wipe()

        ops.model('Basic', '-ndm', 2)

        #    units kip, ft

        # properties
        bayWidth = 20.0
        storyHeight = 10.0

        numBay = 10
        numFloor = 9

        A = 3.0  #area = 3ft^2
        E = 432000.0  #youngs mod = 432000 k/ft^2
        I = 1.0  #second moment of area I=1ft^4
        M = 3.0  #mas/length = 4 kip sec^2/ft^2
        coordTransf = "Linear"  # Linear, PDelta, Corotational
        massType = "-lMass"  # -lMass, -cMass

        nPts = 3  # numGauss Points

        # an elastic material
        ops.uniaxialMaterial('Elastic', 1, E)

        # an elastic section
        ops.section('Elastic', 1, E, A, I)

        # a fiber section with A=3 and I = 1 (b=1.5, d=2) 2d bending about y-y axis
        #   b 1.5 d 2.0
        y = 2.0
        z = 1.5
        numFiberY = 2000  # note we only need so many to get the required accuracy on eigenvalue 1e-7!
        numFiberZ = 1
        ops.section('Fiber', 2)
        #   patch rect 1 numFiberY numFiberZ 0.0 0.0 z y
        ops.patch('quad', 1, numFiberY, numFiberZ, -y / 2.0, -z / 2.0, y / 2.0,
                  -z / 2.0, y / 2.0, z / 2.0, -y / 2.0, z / 2.0)

        # add the nodes
        #  - floor at a time
        nodeTag = 1
        yLoc = 0.
        for j in range(0, numFloor + 1):
            xLoc = 0.
            for i in range(numBay + 1):
                ops.node(nodeTag, xLoc, yLoc)
                xLoc += bayWidth
                nodeTag += 1

            yLoc += storyHeight

        # fix base nodes
        for i in range(1, numBay + 2):
            ops.fix(i, 1, 1, 1)

        # add column element
        transfTag = 1
        ops.geomTransf(coordTransf, transfTag)
        integTag1 = 1
        ops.beamIntegration('Lobatto', integTag1, 1, nPts)
        integTag2 = 2
        ops.beamIntegration('Lobatto', integTag2, 2, nPts)
        eleTag = 1
        for i in range(numBay + 1):
            end1 = i + 1
            end2 = end1 + numBay + 1
            for j in range(numFloor):

                if eleType == "elasticBeam":
                    ops.element('elasticBeamColumn', eleTag, end1, end2, A, E,
                                I, 1, '-mass', M, massType)
                elif eleType == "forceBeamElasticSection":
                    ops.element('forceBeamColumn', eleTag, end1, end2,
                                transfTag, integTag1, '-mass', M)
                elif eleType == "dispBeamElasticSection":
                    ops.element('dispBeamColumn', eleTag, end1, end2,
                                transfTag, integTag1, '-mass', M, massType)
                elif eleType == "forceBeamFiberSectionElasticMaterial":
                    ops.element('forceBeamColumn', eleTag, end1, end2,
                                transfTag, integTag2, '-mass', M)
                elif eleType == "dispBeamFiberSectionElasticMaterial":
                    ops.element('dispBeamColumn', eleTag, end1, end2,
                                transfTag, integTag2, '-mass', M, massType)
                else:
                    print("BARF")

                end1 = end2
                end2 = end1 + numBay + 1
                eleTag += 1

        # add beam elements
        for j in range(1, numFloor + 1):
            end1 = (numBay + 1) * j + 1
            end2 = end1 + 1
            for i in range(numBay):
                if eleType == "elasticBeam":
                    ops.element('elasticBeamColumn', eleTag, end1, end2, A, E,
                                I, 1, '-mass', M, massType)
                elif eleType == "forceBeamElasticSection":
                    ops.element('forceBeamColumn', eleTag, end1, end2,
                                transfTag, integTag1, '-mass', M)
                elif eleType == "dispBeamElasticSection":
                    ops.element('dispBeamColumn', eleTag, end1, end2,
                                transfTag, integTag1, '-mass', M, massType)
                elif eleType == "forceBeamFiberSectionElasticMaterial":
                    ops.element('forceBeamColumn', eleTag, end1, end2,
                                transfTag, integTag2, '-mass', M)
                elif eleType == "dispBeamFiberSectionElasticMaterial":
                    ops.element('dispBeamColumn', eleTag, end1, end2,
                                transfTag, integTag2, '-mass', M, massType)
                else:
                    print("BARF")

    #           element(elasticBeamColumn eleTag end1 end2 A E I 1 -mass M
                end1 = end2
                end2 = end1 + 1
                eleTag += 1

        # calculate eigenvalues
        numEigen = 3
        eigenValues = ops.eigen(numEigen)
        PI = 2 * asin(1.0)

        # determine PASS/FAILURE of test
        testOK = 0

        # print table of camparsion
        #                         Bathe & Wilson               Peterson                    SAP2000                  SeismoStruct

        comparisonResults = [[0.589541, 5.52695, 16.5878],
                             [0.589541, 5.52696, 16.5879],
                             [0.589541, 5.52696, 16.5879],
                             [0.58955, 5.527, 16.588]]
        print("\n\nEigenvalue Comparisons for eleType:", eleType)
        tolerances = [9.99e-7, 9.99e-6, 9.99e-5]
        formatString = '{:>15}{:>15}{:>15}{:>15}{:>15}'
        print(
            formatString.format('OpenSees', 'Bathe&Wilson', 'Peterson',
                                'SAP2000', 'SeismoStruct'))
        formatString = '{:>15.5f}{:>15.4f}{:>15.4f}{:>15.4f}{:>15.3f}'
        for i in range(numEigen):
            lamb = eigenValues[i]
            print(
                formatString.format(lamb, comparisonResults[0][i],
                                    comparisonResults[1][i],
                                    comparisonResults[2][i],
                                    comparisonResults[3][i]))
            resultOther = comparisonResults[2][i]
            tol = tolerances[i]
            if abs(lamb - resultOther) > tol:
                testOK = -1
                print("failed->", abs(lamb - resultOther), tol)

        assert testOK == 0

    solverTypes = [
        '-genBandArpack', '-fullGenLapack', '-UmfPack', '-SuperLU',
        '-ProfileSPD'
    ]

    for solverType in solverTypes:

        eleType = 'elasticBeam'

        ops.wipe()

        ops.model('Basic', '-ndm', 2)

        #    units kip, ft

        # properties
        bayWidth = 20.0
        storyHeight = 10.0

        numBay = 10
        numFloor = 9

        A = 3.0  #area = 3ft^2
        E = 432000.0  #youngs mod = 432000 k/ft^2
        I = 1.0  #second moment of area I=1ft^4
        M = 3.0  #mas/length = 4 kip sec^2/ft^2
        coordTransf = "Linear"  # Linear, PDelta, Corotational
        massType = "-lMass"  # -lMass, -cMass

        nPts = 3  # numGauss Points

        # an elastic material
        ops.uniaxialMaterial('Elastic', 1, E)

        # an elastic section
        ops.section('Elastic', 1, E, A, I)

        # a fiber section with A=3 and I = 1 (b=1.5, d=2) 2d bending about y-y axis
        #   b 1.5 d 2.0
        y = 2.0
        z = 1.5
        numFiberY = 2000  # note we only need so many to get the required accuracy on eigenvalue 1e-7!
        numFiberZ = 1
        ops.section('Fiber', 2)
        #   patch rect 1 numFiberY numFiberZ 0.0 0.0 z y
        ops.patch('quad', 1, numFiberY, numFiberZ, -y / 2.0, -z / 2.0, y / 2.0,
                  -z / 2.0, y / 2.0, z / 2.0, -y / 2.0, z / 2.0)

        # add the nodes
        #  - floor at a time
        nodeTag = 1
        yLoc = 0.
        for j in range(0, numFloor + 1):
            xLoc = 0.
            for i in range(numBay + 1):
                ops.node(nodeTag, xLoc, yLoc)
                xLoc += bayWidth
                nodeTag += 1

            yLoc += storyHeight

        # fix base nodes
        for i in range(1, numBay + 2):
            ops.fix(i, 1, 1, 1)

        # add column element
        transfTag = 1
        ops.geomTransf(coordTransf, transfTag)
        integTag1 = 1
        ops.beamIntegration('Lobatto', integTag1, 1, nPts)
        integTag2 = 2
        ops.beamIntegration('Lobatto', integTag2, 2, nPts)
        eleTag = 1
        for i in range(numBay + 1):
            end1 = i + 1
            end2 = end1 + numBay + 1
            for j in range(numFloor):

                if eleType == "elasticBeam":
                    ops.element('elasticBeamColumn', eleTag, end1, end2, A, E,
                                I, 1, '-mass', M, massType)

                elif eleType == "forceBeamElasticSection":
                    ops.element('forceBeamColumn', eleTag, end1, end2,
                                transfTag, integTag1, '-mass', M)

                elif eleType == "dispBeamElasticSection":
                    ops.element('dispBeamColumn', eleTag, end1, end2,
                                transfTag, integTag1, '-mass', M, massType)
                elif eleType == "forceBeamFiberSectionElasticMaterial":
                    ops.element('forceBeamColumn', eleTag, end1, end2,
                                transfTag, integTag2, '-mass', M)

                elif eleType == "dispBeamFiberSectionElasticMaterial":
                    ops.element('dispBeamColumn', eleTag, end1, end2,
                                transfTag, integTag2, '-mass', M, massType)
                else:
                    print("BARF")

                end1 = end2
                end2 = end1 + numBay + 1
                eleTag += 1

        # add beam elements
        for j in range(1, numFloor + 1):
            end1 = (numBay + 1) * j + 1
            end2 = end1 + 1
            for i in range(numBay):
                if eleType == "elasticBeam":
                    ops.element('elasticBeamColumn', eleTag, end1, end2, A, E,
                                I, 1, '-mass', M, massType)
                elif eleType == "forceBeamElasticSection":
                    ops.element('forceBeamColumn', eleTag, end1, end2,
                                transfTag, integTag1, '-mass', M)
                elif eleType == "dispBeamElasticSection":
                    ops.element('dispBeamColumn', eleTag, end1, end2,
                                transfTag, integTag1, '-mass', M, massType)
                elif eleType == "forceBeamFiberSectionElasticMaterial":
                    ops.element('forceBeamColumn', eleTag, end1, end2,
                                transfTag, integTag2, '-mass', M)
                elif eleType == "dispBeamFiberSectionElasticMaterial":
                    ops.element('dispBeamColumn', eleTag, end1, end2,
                                transfTag, integTag2, '-mass', M, massType)
                else:
                    print("BARF")

    #           element(elasticBeamColumn eleTag end1 end2 A E I 1 -mass M
                end1 = end2
                end2 = end1 + 1
                eleTag += 1

        # calculate eigenvalues
        numEigen = 3
        eigenValues = ops.eigen(solverType, numEigen)
        PI = 2 * asin(1.0)

        # determine PASS/FAILURE of test
        testOK = 0

        # print table of camparsion
        #                         Bathe & Wilson               Peterson                    SAP2000                  SeismoStruct

        comparisonResults = [[0.589541, 5.52695, 16.5878],
                             [0.589541, 5.52696, 16.5879],
                             [0.589541, 5.52696, 16.5879],
                             [0.58955, 5.527, 16.588]]
        print("\n\nEigenvalue Comparisons for solverType:", solverType)
        tolerances = [9.99e-7, 9.99e-6, 9.99e-5]
        formatString = '{:>15}{:>15}{:>15}{:>15}{:>15}'
        print(
            formatString.format('OpenSees', 'Bathe&Wilson', 'Peterson',
                                'SAP2000', 'SeismoStruct'))
        formatString = '{:>15.5f}{:>15.4f}{:>15.4f}{:>15.4f}{:>15.3f}'
        for i in range(numEigen):
            lamb = eigenValues[i]
            print(
                formatString.format(lamb, comparisonResults[0][i],
                                    comparisonResults[1][i],
                                    comparisonResults[2][i],
                                    comparisonResults[3][i]))
            resultOther = comparisonResults[2][i]
            tol = tolerances[i]
            if abs(lamb - resultOther) > tol:
                testOK = -1
                print("failed->", abs(lamb - resultOther), tol)

        assert testOK == 0