Пример #1
0
def add_nodes(joints_df, mass_df, list_new_joints, dict_of_hinges):

    # Identify the joints that were auto created by ETABS (like COM joints)
    points_df = joints_df[joints_df.IsAuto == 'Yes'].copy()

    # create joints in opensees mdoel
    joints_df.apply(lambda row: op.node(row.UniqueName, row.X, row.Y, row.Z),
                    axis='columns')
    # add restraints to the joints
    joints_df.apply(
        lambda row: op.fix(row.UniqueName, *[int(r) for r in row.Restraints]),
        axis='columns')
    # special joint restraints for the COM joints
    points_df.apply(lambda row: op.fix(row.UniqueName, *[0, 0, 1, 1, 1, 0]),
                    axis='columns')

    op.constraints('Transformation')

    # if the model diaphragm is rigid, define rigidity on each floor
    if rigid_dia:

        # obtain the list of floors in terms of the elevation (Z coordinate)
        floor_list = set(joints_df[joints_df.Z > joints_df.Z.min()].Z)

        # iterate through each floor to define rigid diaphragm
        for floor in floor_list:
            nodes_list = list(
                joints_df.loc[joints_df.Z == floor]['UniqueName'])
            remove_list = list(set(nodes_list) & set(list_new_joints)) + list(
                dict_of_hinges.keys())
            nodes = [i for i in nodes_list if i not in remove_list]
            op.rigidDiaphragm(3, *nodes)

    # apply mass to the respective nodes
    mass_df.apply(lambda row: op.mass(row.PointElm, row.UX, row.UY, row.UZ, row
                                      .RX, row.RY, row.RZ),
                  axis='columns')

    return
Пример #2
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")
Пример #3
0
E = 25.0e6
G = 9615384.6

# Lx, Ly, Lz = 4., 3., 5.
Lx, Ly, Lz = 4., 4., 4.

ops.node(1, 0., 0., 0.)
ops.node(2, 0., 0., Lz)
ops.node(3, Lx, 0., Lz)
ops.node(4, Lx, Ly, Lz)

ops.fix(1, 1, 1, 1, 1, 1, 1)

lmass = 200.

ops.mass(2, lmass, lmass, lmass, 0.001, 0.001, 0.001)
ops.mass(3, lmass, lmass, lmass, 0.001, 0.001, 0.001)
ops.mass(4, lmass, lmass, lmass, 0.001, 0.001, 0.001)

gTTagz = 1
gTTagx = 2
gTTagy = 3

coordTransf = 'Linear'
ops.geomTransf(coordTransf, gTTagz, 0., -1., 0.)
ops.geomTransf(coordTransf, gTTagx, 0., -1., 0.)
ops.geomTransf(coordTransf, gTTagy, 1., 0., 0.)

ops.element('elasticBeamColumn', 1, 1, 2, A, E, G, J, Iy, Iz, gTTagz)
ops.element('elasticBeamColumn', 2, 2, 3, A, E, G, J, Iy, Iz, gTTagx)
ops.element('elasticBeamColumn', 3, 3, 4, A, E, G, J, Iy, Iz, gTTagy)
Пример #4
0
def test_PortalFrame2d():

    # set some properties
    print("================================================")
    print("PortalFrame2d.py: Verification 2d Elastic Frame")
    print("  - eigenvalue and static pushover analysis")

    ops.wipe()

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

    # properties

    #    units kip, ft

    numBay = 2
    numFloor = 7

    bayWidth = 360.0
    storyHeights = [162.0, 162.0, 156.0, 156.0, 156.0, 156.0, 156.0]

    E = 29500.0
    massX = 0.49
    M = 0.
    coordTransf = "Linear"  # Linear, PDelta, Corotational
    massType = "-lMass"  # -lMass, -cMass

    beams = [
        'W24X160', 'W24X160', 'W24X130', 'W24X130', 'W24X110', 'W24X110',
        'W24X110'
    ]
    eColumn = [
        'W14X246', 'W14X246', 'W14X246', 'W14X211', 'W14X211', 'W14X176',
        'W14X176'
    ]
    iColumn = [
        'W14X287', 'W14X287', 'W14X287', 'W14X246', 'W14X246', 'W14X211',
        'W14X211'
    ]
    columns = [eColumn, iColumn, eColumn]

    WSection = {
        'W14X176': [51.7, 2150.],
        'W14X211': [62.1, 2670.],
        'W14X246': [72.3, 3230.],
        'W14X287': [84.4, 3910.],
        'W24X110': [32.5, 3330.],
        'W24X130': [38.3, 4020.],
        'W24X160': [47.1, 5120.]
    }

    nodeTag = 1

    # procedure to read
    def ElasticBeamColumn(eleTag, iNode, jNode, sectType, E, transfTag, M,
                          massType):

        found = 0

        prop = WSection[sectType]

        A = prop[0]
        I = prop[1]
        ops.element('elasticBeamColumn', eleTag, iNode, jNode, A, E, I,
                    transfTag, '-mass', M, massType)

    # add the nodes
    #  - floor at a time
    yLoc = 0.
    for j in range(0, numFloor + 1):

        xLoc = 0.
        for i in range(0, numBay + 1):
            ops.node(nodeTag, xLoc, yLoc)
            xLoc += bayWidth
            nodeTag += 1

        if j < numFloor:
            storyHeight = storyHeights[j]

        yLoc += storyHeight

    # fix first floor
    ops.fix(1, 1, 1, 1)
    ops.fix(2, 1, 1, 1)
    ops.fix(3, 1, 1, 1)

    #rigid floor constraint & masses
    nodeTagR = 5
    nodeTag = 4
    for j in range(1, numFloor + 1):
        for i in range(0, numBay + 1):

            if nodeTag != nodeTagR:
                ops.equalDOF(nodeTagR, nodeTag, 1)
            else:
                ops.mass(nodeTagR, massX, 1.0e-10, 1.0e-10)

            nodeTag += 1

        nodeTagR += numBay + 1

    # add the columns
    # add column element
    ops.geomTransf(coordTransf, 1)
    eleTag = 1
    for j in range(0, numBay + 1):

        end1 = j + 1
        end2 = end1 + numBay + 1
        thisColumn = columns[j]

        for i in range(0, numFloor):
            secType = thisColumn[i]
            ElasticBeamColumn(eleTag, end1, end2, secType, E, 1, M, massType)
            end1 = end2
            end2 += numBay + 1
            eleTag += 1

    # add beam elements
    for j in range(1, numFloor + 1):
        end1 = (numBay + 1) * j + 1
        end2 = end1 + 1
        secType = beams[j - 1]
        for i in range(0, numBay):
            ElasticBeamColumn(eleTag, end1, end2, secType, E, 1, M, massType)
            end1 = end2
            end2 = end1 + 1
            eleTag += 1

    # calculate eigenvalues & print results
    numEigen = 7
    eigenValues = ops.eigen(numEigen)
    PI = 2 * asin(1.0)

    #
    # apply loads for static analysis & perform analysis
    #

    ops.timeSeries('Linear', 1)
    ops.pattern('Plain', 1, 1)
    ops.load(22, 20.0, 0., 0.)
    ops.load(19, 15.0, 0., 0.)
    ops.load(16, 12.5, 0., 0.)
    ops.load(13, 10.0, 0., 0.)
    ops.load(10, 7.5, 0., 0.)
    ops.load(7, 5.0, 0., 0.)
    ops.load(4, 2.5, 0., 0.)

    ops.integrator('LoadControl', 1.0)
    ops.algorithm('Linear')
    ops.analysis('Static')
    ops.analyze(1)

    # determine PASS/FAILURE of test
    ok = 0

    #
    # print pretty output of comparsions
    #

    #               SAP2000   SeismoStruct
    comparisonResults = [[
        1.2732, 0.4313, 0.2420, 0.1602, 0.1190, 0.0951, 0.0795
    ], [1.2732, 0.4313, 0.2420, 0.1602, 0.1190, 0.0951, 0.0795]]
    print("\n\nPeriod Comparisons:")
    print('{:>10}{:>15}{:>15}{:>15}'.format('Period', 'OpenSees', 'SAP2000',
                                            'SeismoStruct'))

    #formatString {%10s%15.5f%15.4f%15.4f}
    for i in range(0, numEigen):
        lamb = eigenValues[i]
        period = 2 * PI / sqrt(lamb)
        print('{:>10}{:>15.5f}{:>15.4f}{:>15.4f}'.format(
            i + 1, period, comparisonResults[0][i], comparisonResults[1][i]))
        resultOther = comparisonResults[0][i]
        if abs(period - resultOther) > 9.99e-5:
            ok = -1

    # print table of camparsion
    #       Parameter          SAP2000   SeismoStruct
    comparisonResults = [[
        "Disp Top", "Axial Force Bottom Left", "Moment Bottom Left"
    ], [1.45076, 69.99, 2324.68], [1.451, 70.01, 2324.71]]
    tolerances = [9.99e-6, 9.99e-3, 9.99e-3]

    print("\n\nSatic Analysis Result Comparisons:")
    print('{:>30}{:>15}{:>15}{:>15}'.format('Parameter', 'OpenSees', 'SAP2000',
                                            'SeismoStruct'))
    for i in range(3):
        response = ops.eleResponse(1, 'forces')
        if i == 0:
            result = ops.nodeDisp(22, 1)
        elif i == 1:
            result = abs(response[1])
        else:
            result = response[2]

        print('{:>30}{:>15.3f}{:>15.2f}{:>15.2f}'.format(
            comparisonResults[0][i], result, comparisonResults[1][i],
            comparisonResults[2][i]))
        resultOther = comparisonResults[1][i]
        tol = tolerances[i]
        if abs(result - resultOther) > tol:
            ok = -1
            print("failed-> ", i, abs(result - resultOther), tol)

    assert ok == 0
Пример #5
0
def test_EigenAnal_twoStoryFrame1():
    ops.wipe()

    #input
    m = 100.0 / 386.0
    numModes = 2

    #material
    A = 63.41
    I = 320.0
    E = 29000.0

    #geometry
    L = 240.
    h = 120.

    # define the model
    #---------------------------------
    #model builder
    ops.model('BasicBuilder', '-ndm', 2, '-ndf', 3)

    # nodal coordinates:
    ops.node(1, 0., 0.)
    ops.node(2, L, 0.)
    ops.node(3, 0., h)
    ops.node(4, L, h)
    ops.node(5, 0., 2 * h)
    ops.node(6, L, 2 * h)

    # Single point constraints -- Boundary Conditions
    ops.fix(1, 1, 1, 1)
    ops.fix(2, 1, 1, 1)

    # assign mass
    ops.mass(3, m, 0., 0.)
    ops.mass(4, m, 0., 0.)
    ops.mass(5, m / 2., 0., 0.)
    ops.mass(6, m / 2., 0., 0.)

    # define geometric transformation:
    TransfTag = 1
    ops.geomTransf('Linear', TransfTag)

    # define elements:
    # columns
    ops.element('elasticBeamColumn', 1, 1, 3, A, E, 2. * I, TransfTag)
    ops.element('elasticBeamColumn', 2, 3, 5, A, E, I, TransfTag)
    ops.element('elasticBeamColumn', 3, 2, 4, A, E, 2. * I, TransfTag)
    ops.element('elasticBeamColumn', 4, 4, 6, A, E, I, TransfTag)
    # beams
    ops.element('elasticBeamColumn', 5, 3, 4, A, E, 2 * I, TransfTag)
    ops.element('elasticBeamColumn', 6, 5, 6, A, E, I, TransfTag)

    # record eigenvectors
    #----------------------
    # for { k 1 } { k <= numModes } { incr k } {
    #     recorder Node -file format "modes/mode%i.out" k -nodeRange 1 6 -dof 1 2 3  "eigen k"
    # }

    # perform eigen analysis
    #-----------------------------
    lamb = ops.eigen(numModes)

    # calculate frequencies and periods of the structure
    #---------------------------------------------------
    omega = []
    f = []
    T = []
    pi = 3.141593

    for lam in lamb:
        print("labmbda = ", lam)
        omega.append(math.sqrt(lam))
        f.append(math.sqrt(lam) / (2 * pi))
        T.append((2 * pi) / math.sqrt(lam))

    print("periods are ", T)

    # write the output file cosisting of periods
    #--------------------------------------------
    period = "Periods.txt"
    Periods = open(period, "w")
    for t in T:
        Periods.write(repr(t) + '\n')

    Periods.close()

    # create display  for mode shapes
    #---------------------------------
    #                 windowTitle xLoc yLoc xPixels yPixels
    # recorder display "Mode Shape 1"  10    10     500      500     -wipe
    # prp h h 1                                         # 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 -200 200 -200 200                        # coordiantes of the window relative to prp
    # display -1 5 20
    # the 1st arg. is the tag for display mode (ex. -1 is for the first mode shape)
    # the 2nd arg. is magnification factor for nodes, the 3rd arg. is magnif. factor of deformed shape
    # recorder display "Mode Shape 2" 10 510 500 500 -wipe
    # prp h h 1
    # vup  0  1 0
    # vpn  0  0 1
    # viewWindow -200 200 -200 200
    # display -2 5 20

    # Run a one step gravity load with no loading (to record eigenvectors)
    #-----------------------------------------------------------------------
    ops.integrator('LoadControl', 0.0, 1, 0.0, 0.0)

    # Convergence test
    #                     tolerance maxIter displayCode
    ops.test('EnergyIncr', 1.0e-10, 100, 0)

    # Solution algorithm
    ops.algorithm('Newton')

    # DOF numberer
    ops.numberer('RCM')

    # Constraint handler
    ops.constraints('Transformation')

    # System of equations solver
    ops.system('ProfileSPD')

    ops.analysis('Static')
    res = ops.analyze(1)
    if res < 0:
        print("Modal analysis failed")

    # get values of eigenvectors for translational DOFs
    #---------------------------------------------------
    f11 = ops.nodeEigenvector(3, 1, 1)
    f21 = ops.nodeEigenvector(5, 1, 1)
    f12 = ops.nodeEigenvector(3, 2, 1)
    f22 = ops.nodeEigenvector(5, 2, 1)
    print("eigenvector 1: ", [f11 / f21, f21 / f21])
    print("eigenvector 2: ", [f12 / f22, f22 / f22])

    assert abs(T[0] - 0.628538768190688) < 1e-12 and abs(
        T[1] - 0.2359388635361575) < 1e-12 and abs(
            f11 / f21 - 0.3869004256389493) < 1e-12 and abs(
                f21 / f21 - 1.0) < 1e-12 and abs(f12 / f22 + 1.2923221761110006
                                                 ) < 1e-12 and abs(f22 / f22 -
                                                                   1.0) < 1e-12
Пример #6
0
def get_inelastic_response(mass,
                           k_spring,
                           f_yield,
                           motion,
                           dt,
                           xi=0.05,
                           r_post=0.0):
    """
    Run seismic analysis of a nonlinear SDOF

    :param mass: SDOF mass
    :param k_spring: spring stiffness
    :param f_yield: yield strength
    :param motion: list, acceleration values
    :param dt: float, time step of acceleration values
    :param xi: damping ratio
    :param r_post: post-yield stiffness
    :return:
    """

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

    # Establish nodes
    bot_node = 1
    top_node = 2
    opy.node(bot_node, 0., 0.)
    opy.node(top_node, 0., 0.)

    # Fix bottom node
    opy.fix(top_node, opc.FREE, opc.FIXED, opc.FIXED)
    opy.fix(bot_node, opc.FIXED, opc.FIXED, opc.FIXED)
    # Set out-of-plane DOFs to be slaved
    opy.equalDOF(1, 2, *[2, 3])

    # nodal mass (weight / g):
    opy.mass(top_node, mass, 0., 0.)

    # Define material
    bilinear_mat_tag = 1
    mat_type = "Steel01"
    mat_props = [f_yield, k_spring, r_post]
    opy.uniaxialMaterial(mat_type, bilinear_mat_tag, *mat_props)

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

    # Define the dynamic analysis
    load_tag_dynamic = 1
    pattern_tag_dynamic = 1

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

    # set damping based on first eigen mode
    angular_freq2 = opy.eigen('-fullGenLapack', 1)
    if hasattr(angular_freq2, '__len__'):
        angular_freq2 = angular_freq2[0]
    angular_freq = angular_freq2**0.5
    alpha_m = 0.0
    beta_k = 2 * xi / angular_freq
    beta_k_comm = 0.0
    beta_k_init = 0.0

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

    # Run the dynamic analysis

    opy.wipeAnalysis()

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

    tol = 1.0e-10
    iterations = 10
    opy.test('EnergyIncr', tol, iterations, 0, 2)
    analysis_time = (len(values) - 1) * dt
    analysis_dt = 0.001
    outputs = {
        "time": [],
        "rel_disp": [],
        "rel_accel": [],
        "rel_vel": [],
        "force": []
    }

    while opy.getTime() < analysis_time:
        curr_time = opy.getTime()
        opy.analyze(1, analysis_dt)
        outputs["time"].append(curr_time)
        outputs["rel_disp"].append(opy.nodeDisp(top_node, 1))
        outputs["rel_vel"].append(opy.nodeVel(top_node, 1))
        outputs["rel_accel"].append(opy.nodeAccel(top_node, 1))
        opy.reactions()
        outputs["force"].append(
            -opy.nodeReaction(bot_node, 1))  # Negative since diff node
    opy.wipe()
    for item in outputs:
        outputs[item] = np.array(outputs[item])

    return outputs
Пример #7
0
#print(path1)

h = 432.0
w  =  504.0

op.node(1, 0.0, 0.0)
op.node(2, h, 0.0)
op.node(3, 0.0, w)
op.node(4, h, w)

op.fix(1, 1,1,1)
op.fix(2, 1,1,1)
op.fix(3, 0,0,0)
op.fix(4, 0,0,0)

op.mass(3, 5.18, 0.0, 0.0)
op.mass(4, 5.18, 0.0, 0.0)  

op.geomTransf('Linear', 1)
A = 3600000000.0
E = 4227.0
Iz = 1080000.0

A1 = 5760000000.0
Iz1 = 4423680.0
op.element('elasticBeamColumn', 1, 1, 3, A, E, Iz, 1)
op.element('elasticBeamColumn', 2, 2, 4, A, E, Iz, 1)
op.element('elasticBeamColumn', 3, 3, 4, A1, E, Iz1, 1)

op.recorder('Node', '-file', 'Data-1b/DFree.out','-time', '-node', 3,4, '-dof', 1,2,3, 'disp')
op.recorder('Node', '-file', 'Data-1b/DBase.out','-time', '-node', 1,2, '-dof', 1,2,3, 'disp')
Пример #8
0
ABeam = HBeam * BBeam
IzCol = (BCol * math.pow(HCol, 3)) / 12  # Column moment of inertia
IzBeam = (BBeam * math.pow(HBeam, 3)) / 12  # Beam moment of inertia

op.node(1, 0.0, 0.0)
op.node(2, LBeam, 0.0)
op.node(3, 0.0, LCol)
op.node(4, LBeam, LCol)

op.fix(1, 1, 1, 0)
op.fix(2, 1, 1, 0)

IDctrlNode = 2
IDctrlDOF = 1

op.mass(3, Mass, 0.0, 0.0)
op.mass(4, Mass, 0.0, 0.0)

ColSecTag = 1  # assign a tag number to the column section
BeamSecTag = 2  # assign a tag number to the beam section

coverCol = 6.0 * inch  # Column cover to reinforcing steel NA.
numBarsCol = 10  # number of longitudinal-reinforcement bars in column. (symmetric top & bot)
barAreaCol = 2.25 * inch2  # area of longitudinal-reinforcement bars

# MATERIAL parameters
IDconcU = 1  # material ID tag -- unconfined cover concrete (here used for complete section)
IDreinf = 2  # material ID tag -- reinforcement

# nominal concrete compressive strength
fc = -4.0 * ksi  # CONCRETE Compressive Strength (+Tension, -Compression)
Пример #9
0
def get_inelastic_response(mass,
                           k_spring,
                           f_yield,
                           motion,
                           dt,
                           xi=0.05,
                           r_post=0.0):
    """
    Run seismic analysis of a nonlinear SDOF

    :param mass: SDOF mass
    :param k_spring: spring stiffness
    :param f_yield: yield strength
    :param motion: list, acceleration values
    :param dt: float, time step of acceleration values
    :param xi: damping ratio
    :param r_post: post-yield stiffness
    :return:
    """
    osi = o3.OpenSeesInstance(ndm=2)

    # Establish nodes
    bot_node = o3.node.Node(osi, 0, 0)
    top_node = o3.node.Node(osi, 0, 0)

    # Fix bottom node
    opy.fix(top_node.tag, o3.cc.FREE, o3.cc.FIXED, o3.cc.FIXED)
    opy.fix(bot_node.tag, o3.cc.FIXED, o3.cc.FIXED, o3.cc.FIXED)
    # Set out-of-plane DOFs to be slaved
    opy.equalDOF(top_node.tag, bot_node.tag, *[o3.cc.Y, o3.cc.ROTZ])

    # nodal mass (weight / g):
    opy.mass(top_node.tag, mass, 0., 0.)

    # Define material
    bilinear_mat = o3.uniaxial_material.Steel01(osi,
                                                fy=f_yield,
                                                e0=k_spring,
                                                b=r_post)

    # Assign zero length element, # Note: pass actual node and material objects into element
    o3.element.ZeroLength(osi, [bot_node, top_node],
                          mats=[bilinear_mat],
                          dirs=[o3.cc.DOF2D_X],
                          r_flag=1)

    # Define the dynamic analysis
    load_tag_dynamic = 1
    pattern_tag_dynamic = 1

    values = list(-1 * motion)  # should be negative
    opy.timeSeries('Path', load_tag_dynamic, '-dt', dt, '-values', *values)
    opy.pattern('UniformExcitation', pattern_tag_dynamic, o3.cc.X, '-accel',
                load_tag_dynamic)

    # set damping based on first eigen mode
    angular_freq2 = opy.eigen('-fullGenLapack', 1)
    if hasattr(angular_freq2, '__len__'):
        angular_freq2 = angular_freq2[0]
    angular_freq = angular_freq2**0.5
    beta_k = 2 * xi / angular_freq
    o3.rayleigh.Rayleigh(osi,
                         alpha_m=0.0,
                         beta_k=beta_k,
                         beta_k_init=0.0,
                         beta_k_comm=0.0)

    # Run the dynamic analysis

    opy.wipeAnalysis()
    newmark_gamma = 0.5
    newmark_beta = 0.25

    o3.algorithm.Newton(osi)
    o3.constraints.Transformation(osi)
    o3.algorithm.Newton(osi)
    o3.numberer.RCM(osi)
    o3.system.SparseGeneral(osi)
    o3.integrator.Newmark(osi, newmark_gamma, newmark_beta)
    o3.analysis.Transient(osi)

    o3.test_check.EnergyIncr(osi, tol=1.0e-10, max_iter=10)
    analysis_time = (len(values) - 1) * dt
    analysis_dt = 0.001
    outputs = {
        "time": [],
        "rel_disp": [],
        "rel_accel": [],
        "rel_vel": [],
        "force": []
    }

    while opy.getTime() < analysis_time:
        curr_time = opy.getTime()
        opy.analyze(1, analysis_dt)
        outputs["time"].append(curr_time)
        outputs["rel_disp"].append(opy.nodeDisp(top_node.tag, o3.cc.X))
        outputs["rel_vel"].append(opy.nodeVel(top_node.tag, o3.cc.X))
        outputs["rel_accel"].append(opy.nodeAccel(top_node.tag, o3.cc.X))
        opy.reactions()
        outputs["force"].append(-opy.nodeReaction(
            bot_node.tag, o3.cc.X))  # Negative since diff node
    opy.wipe()
    for item in outputs:
        outputs[item] = np.array(outputs[item])

    return outputs
Пример #10
0
# 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
def RectCFSTSteelHysteretic(length: float, secHeight: float, secWidth: float,
                            thickness: float, concrete_grade: float,
                            steel_grade: float, axial_load_ratio: float,
                            disp_control: Iterable[float]):
    '''Peakstress: concrete peak stress \n crushstress: concrete crush stress
    '''
    #disp input
    # dispControl=[3,-3,7,-7,14,-14,14,-14,14,-14,28,-28,28,-28,28,-28,42,-42,42,-42,42,-42,56,-56,0]
    dispControl = tuple(disp_control)
    #Geometry
    # length=740
    # secHeight=100
    # secWidth=100
    # thickness=7
    #Materials
    ##steel_tube
    point1Steel, point2Steel, point3Steel = [460, 0.00309], [460, 0.02721
                                                             ], [530, 0.26969]
    point1SteelNegative, point2SteelNegative, point3SteelNegative = [
        -460, -0.00309
    ], [-460, -0.02721], [-736, -0.26969]
    pinchX = 0.2
    pinchY = 0.7
    damagedFactor = 0.01
    densitySteel = 7.8 / 1000000000
    ##concrete
    peakPointConcrete, crushPointConcrete = [-221.76, -0.0102], [-195, -0.051]

    unloadingLambda = 0.2
    tensileStrength = 5.6
    tensilePostStiffness = 0.01
    densityConcrete = 2.4 / 1000000000
    #axialLoadRatio
    # axialLoadRatio=0.4
    #fix condition
    Fixed = 1

    #section parameter
    areaConcrete = (secHeight - 2 * thickness) * (secWidth - 2 * thickness)
    areaSteel = secWidth * secHeight - areaConcrete

    # fck,Ec,nuConcrete=128.1,4.34*10000,0.21
    # fy,epsilonSteely,Es,nuSteel=444.6,3067/1000000,1.99*100000,0.29
    fck = peakPointConcrete[0]
    fy = point1Steel[0]

    #Computate parameter
    axialLoad = (areaConcrete * fck + areaSteel * fy) * axial_load_ratio

    #loading control parameter
    # for item in dispControlPercentage:
    #     dispControl.append(item*length)
    #     dispControl.append(-item*length)
    # print('displist:'dispControl)

    #wipe and build a model
    ops.wipe()
    ops.model('basic', '-ndm', 2, '-ndf', 3)

    #node coordinates
    meshNumLength = 5
    meshVerticalSize = length / meshNumLength
    meshSteelSize = 10
    nodes = [(i + 1, meshVerticalSize * i)
             for i in range(int(length / meshVerticalSize) + 1)]
    for item in nodes:
        ops.node(item[0], 0, item[1])

    #boundary condition
    ops.fix(1, 1, 1, 1)
    # if bool(Fixed):
    #     ops.fix(int(length/meshVerticalSize)+1,0,0,1)  ##uppper constrain condition: free or no-rotation

    #mass defination(concentrate mass to nodes)
    nodeMassSteel = areaSteel * meshVerticalSize * densitySteel
    nodeMassConcrete = areaConcrete * meshVerticalSize * densityConcrete
    nodeMass = nodeMassSteel + nodeMassConcrete
    for i in range(len(nodes) - 1):
        arg = [0., nodeMass, 0.]
        ops.mass(i + 2, *arg)

    #transformation:
    ops.geomTransf('Linear', 1)

    #material defination
    ##steel

    ops.uniaxialMaterial('Hysteretic', 1001, *point1Steel, *point2Steel,
                         *point3Steel, *point1SteelNegative,
                         *point2SteelNegative, *point3SteelNegative, pinchX,
                         pinchY, damagedFactor, 0, 0.0)
    ##concrete
    ##using concrete01
    #peakPointConcrete,crushPointConcrete=[110.6,0.00544],[22.11,0.09145]
    #ops.uniaxialMaterial('Concrete01',1,*peakPointConcrete,*crushPointConcrete)
    ###using concrete02

    ops.uniaxialMaterial('Concrete02', 1, *peakPointConcrete,
                         *crushPointConcrete, unloadingLambda, tensileStrength,
                         tensilePostStiffness)

    #section defination
    ops.section('Fiber', 1)
    ##inner concrete fiber
    fiberPointI, fiberPointJ = [
        -(secHeight - 2 * thickness) / 2, -(secWidth - 2 * thickness) / 2
    ], [(secHeight - 2 * thickness) / 2, (secWidth - 2 * thickness) / 2]
    ops.patch('rect', 1, 10, 1, *fiberPointI, *fiberPointJ
              )  # https://opensees.berkeley.edu/wiki/index.php/Patch_Command
    ##outside steel fiber
    steelFiberProperty = {
        'height': meshSteelSize,
        'area': meshSteelSize * thickness
    }
    steelFiberPropertyLeftAndRight = {
        'height': secWidth,
        'area': secWidth * thickness
    }
    ###left and right
    leftEdgeFiberY, rightEdgeFiberY = -(
        secHeight - 2 * thickness) / 2 - thickness / 2, (
            secHeight -
            2 * thickness) / 2 + thickness / 2  #rightEdgeFiberY might be wrong
    leftandRightEdgeFiberZ = [
        -secWidth / 2 + steelFiberPropertyLeftAndRight['height'] * (1 / 2 + N)
        for N in range(int(secWidth /
                           steelFiberPropertyLeftAndRight['height']))
    ]
    ###up and down
    upEdgeFiberZ, downEdgeFiberZ = -(
        secWidth - 2 * thickness) / 2 - thickness / 2, (
            secWidth - 2 * thickness) / 2 + thickness / 2
    upandDownEdgeFiberY = [
        -secHeight / 2 + thickness + steelFiberProperty['height'] * (1 / 2 + N)
        for N in range(
            int((secHeight - 2 * thickness) / steelFiberProperty['height']))
    ]
    for i in leftandRightEdgeFiberZ:
        i = float(i)
        ops.fiber(float(leftEdgeFiberY), i,
                  steelFiberPropertyLeftAndRight['area'], 1001)
        ops.fiber(float(rightEdgeFiberY), i,
                  steelFiberPropertyLeftAndRight['area'], 1001)
    for j in upandDownEdgeFiberY:
        j = float(j)
        ops.fiber(j, float(upEdgeFiberZ), steelFiberProperty['area'], 1001)
        ops.fiber(j, float(downEdgeFiberZ), steelFiberProperty['area'], 1001)
    #beamInergration defination
    ops.beamIntegration('NewtonCotes', 1, 1, 5)

    #element defination
    for i in range(len(nodes) - 1):
        ops.element('dispBeamColumn', i + 1, i + 1, i + 2, 1, 1)

    #recorders
    ops.recorder('Node', '-file', 'topLateralDisp.txt', '-time', '-node',
                 int(length / meshVerticalSize + 1), '-dof', 1, 2, 'disp')
    ops.recorder('Node', '-file', 'topLateralForce.txt', '-time', '-node',
                 int(length / meshVerticalSize + 1), '-dof', 1, 2, 'reaction')
    ops.recorder('Element', '-file', 'topElementForce.txt', '-time', '-ele',
                 int(length / meshVerticalSize), 'force')

    #gravity load
    ops.timeSeries('Linear', 1)
    ops.pattern('Plain', 1, 1)
    ops.load(int(length / meshVerticalSize + 1), 0, axialLoad, 0)
    ops.constraints('Plain')
    ops.numberer('RCM')
    ops.system('BandGeneral')
    ##convertage test
    tolerant, allowedIteralStep = 1 / 1000000, 6000
    ops.test('NormDispIncr', tolerant, allowedIteralStep)
    ops.algorithm('Newton')
    ops.integrator('LoadControl', 0.1)
    ops.analysis('Static')
    ops.analyze(10)
    ops.loadConst('-time', 0)

    #lateraldisp analysis
    ops.pattern('Plain', 2, 1)
    ops.load(int(length / meshVerticalSize + 1), 100, 0, 0)
    for i in range(len(dispControl)):
        if i == 0:
            ops.integrator('DisplacementControl',
                           int(length / meshVerticalSize + 1), 1, 0.1)
            ops.analyze(int(dispControl[i] / 0.1))
            # print('Working on disp round',i)
        else:
            if dispControl[i] >= 0:
                ops.integrator('DisplacementControl',
                               int(length / meshVerticalSize + 1), 1, 0.1)
                ops.analyze(int(
                    abs(dispControl[i] - dispControl[i - 1]) / 0.1))
                # print('Working on disp round',i)
            else:
                ops.integrator('DisplacementControl',
                               int(length / meshVerticalSize + 1), 1, -0.1)
                ops.analyze(int(
                    abs(dispControl[i] - dispControl[i - 1]) / 0.1))
Пример #12
0
def RunAnalysis():
    # ----------------------------
    # Start of model generation
    # ----------------------------
    # remove existing model
    ops.wipe()
    ops.model("BasicBuilder", "-ndm", 3, "-ndf", 6)

    # set default units
    ops.defaultUnits("-force", "kip", "-length", "in", "-time", "sec", "-temp",
                     "F")

    # Define the section
    # ------------------
    #                                       secTag  E     nu     h    rho
    ops.section("ElasticMembranePlateSection", 1, 3.0E3, 0.25, 1.175, 1.27)

    # Define geometry
    # ---------------
    # these should both be even

    nx = 10
    ny = 2

    # loaded nodes
    mid = int(((nx + 1) * (ny + 1) + 1) / 2)
    side1 = int((nx + 2) / 2)
    side2 = int((nx + 1) * (ny + 1) - side1 + 1)

    # generate the nodes and elements
    #          numX numY startNode startEle eleType eleArgs? coords?
    ops.block2D(nx, ny, 1, 1, "ShellMITC4", 1, 1, -20.0, 0.0, 0.0, 2, -20.0,
                0.0, 40.0, 3, 20.0, 0.0, 40.0, 4, 20.0, 0.0, 0.0, 5, -10.0,
                10.0, 20.0, 7, 10.0, 10.0, 20.0, 9, 0.0, 10.0, 20.0)

    # define the boundary conditions
    ops.fixZ(0.0, 1, 1, 1, 0, 1, 1)
    ops.fixZ(40.0, 1, 1, 1, 0, 1, 1)

    ops.mass(20, 10.0, 10.0, 10.0, 0.0, 0.0, 0.0)

    # create a Linear time series
    ops.timeSeries("Linear", 1)

    # add some loads
    ops.pattern("Plain", 1, 1, "-fact", 1.0)
    ops.load(mid, 0.0, -0.50, 0.0, 0.0, 0.0, 0.0)
    ops.load(side1, 0.0, -0.25, 0.0, 0.0, 0.0, 0.0)
    ops.load(side2, 0.0, -0.25, 0.0, 0.0, 0.0, 0.0)

    # ------------------------
    # Start of static analysis
    # ------------------------
    # Load control with variable load steps
    #                            init  Jd  min  max
    ops.integrator("LoadControl", 1.0, 1, 1.0, 10.0)
    ops.test("EnergyIncr", 1.0E-10, 20, 0)
    ops.algorithm("Newton")
    ops.numberer("RCM")
    ops.constraints("Plain")
    ops.system("SparseGeneral", "-piv")
    ops.analysis("Static")
    ops.analyze(5)

    # ---------------------------------------
    # Create and Perform the dynamic analysis
    # ---------------------------------------
    # Remove the static analysis & reset the time to 0.0

    ops.wipeAnalysis()
    ops.setTime(0.0)

    # Now remove the loads and let the beam vibrate
    ops.remove("loadPattern", 1)

    Model = 'test'
    LoadCase = 'Transient'
    LoadCase2 = 'Transient_5s'
    opp.createODB(Model, LoadCase, Nmodes=3, recorders=[])
    opp.createODB(Model, LoadCase2, Nmodes=3, deltaT=5., recorders=[])

    # Create the transient analysis
    ops.test("EnergyIncr", 1.0E-10, 20, 0)
    ops.algorithm("Newton")
    ops.numberer("RCM")
    ops.constraints("Plain")
    ops.system("SparseGeneral", "-piv")
    ops.integrator("Newmark", 0.50, 0.25)
    ops.analysis("Transient")

    # Perform the transient analysis (20 sec)
    ops.analyze(100, 0.2)
Пример #13
0
M = 0.
coordTransf = "Linear"  # Linear, PDelta, Corotational
massType = "-lMass"  # -lMass, -cMass

nodeTag = 1

# add the nodes
#  - floor at a time
zLoc = 0.
for k in range(0, numFloor + 1):
    xLoc = 0.
    for i in range(0, numBayX + 1):
        yLoc = 0.
        for j in range(0, numBayY + 1):
            ops.node(nodeTag, xLoc, yLoc, zLoc)
            ops.mass(nodeTag, massX, massX, 0.01, 1.0e-10, 1.0e-10, 1.0e-10)
            if k == 0:
                ops.fix(nodeTag, 1, 1, 1, 1, 1, 1)

            yLoc += bayWidthY
            nodeTag += 1

        xLoc += bayWidthX

    if k < numFloor:
        storyHeight = storyHeights[k]

    zLoc += storyHeight

# add column element
ops.geomTransf(coordTransf, 1, 1, 0, 0)
Пример #14
0
# beam integration
inteTag = 1
numpts = 2
ops.beamIntegration('Legendre', inteTag, secTag, numpts)

# beam mesh
beamTag = 6
ndf = 3
ops.mesh('line', beamTag, 2, 12, 13, beam_id, ndf, h, 'dispBeamColumn',
         transfTag, inteTag)

ndmass = bmass / len(ops.getNodeTags('-mesh', beamTag))

for nd in ops.getNodeTags('-mesh', beamTag):
    ops.mass(nd, ndmass, ndmass, 0.0)

# fluid mesh
fluidTag = 4
ndf = 2
ops.mesh('line', 1, 10, 4, 5, 8, 9, 10, 11, 7, 6, 12, 2, wall_id, ndf, h)
ops.mesh('line', 2, 3, 2, 1, 4, wall_id, ndf, h)
ops.mesh('line', 3, 3, 2, 3, 4, water_bound_id, ndf, h)

eleArgs = ['PFEMElementBubble', rho, mu, b1, b2, thk, kappa]
ops.mesh('tri', fluidTag, 2, 2, 3, water_body_id, ndf, h, *eleArgs)

# wall mesh
wallTag = 5
ops.mesh('tri', wallTag, 2, 1, 2, wall_id, ndf, h)
Пример #15
0
def test_Ex1aCanti2DEQmodif():
    # SET UP ----------------------------------------------------------------------------
    ops.wipe()  # clear opensees model
    ops.model('basic', '-ndm', 2, '-ndf', 3)  # 2 dimensions, 3 dof per node
    # file mkdir data 				   # create data directory

    # define GEOMETRY -------------------------------------------------------------
    # nodal coordinates:
    ops.node(1, 0., 0.)  # node#, X Y
    ops.node(2, 0., 432.)

    # Single point constraints -- Boundary Conditions
    ops.fix(1, 1, 1, 1)  # node DX DY RZ

    # nodal masses:
    ops.mass(2, 5.18, 0., 0.)  # node#, Mx My Mz, Mass=Weight/g.

    # Define ELEMENTS -------------------------------------------------------------
    # define geometric transformation: performs a linear geometric transformation of beam stiffness and resisting force from the basic system to the global-coordinate system
    ops.geomTransf('Linear', 1)  # associate a tag to transformation

    # connectivity:
    ops.element('elasticBeamColumn', 1, 1, 2, 3600.0, 3225.0, 1080000.0, 1)

    # define GRAVITY -------------------------------------------------------------
    ops.timeSeries('Linear', 1)
    ops.pattern(
        'Plain',
        1,
        1,
    )
    ops.load(2, 0., -2000., 0.)  # node#, FX FY MZ --  superstructure-weight

    ops.constraints('Plain')  # how it handles boundary conditions
    ops.numberer(
        'Plain'
    )  # renumber dof's to minimize band-width (optimization), if you want to
    ops.system(
        'BandGeneral'
    )  # how to store and solve the system of equations in the analysis
    ops.algorithm('Linear')  # use Linear algorithm for linear analysis
    ops.integrator(
        'LoadControl', 0.1
    )  # determine the next time step for an analysis, # apply gravity in 10 steps
    ops.analysis('Static')  # define type of analysis static or transient
    ops.analyze(10)  # perform gravity analysis
    ops.loadConst('-time', 0.0)  # hold gravity constant and restart time

    # DYNAMIC ground-motion analysis -------------------------------------------------------------
    # create load pattern
    G = 386.0
    ops.timeSeries(
        'Path', 2, '-dt', 0.005, '-filePath', 'A10000.dat', '-factor', G
    )  # define acceleration vector from file (dt=0.005 is associated with the input file gm)
    ops.pattern(
        'UniformExcitation', 2, 1, '-accel',
        2)  # define where and how (pattern tag, dof) acceleration is applied

    # set damping based on first eigen mode
    evals = ops.eigen('-fullGenLapack', 1)
    freq = evals[0]**0.5
    dampRatio = 0.02
    ops.rayleigh(0., 0., 0., 2 * dampRatio / freq)

    # display displacement shape of the column
    # recorder display "Displaced shape" 10 10 500 500 -wipe
    # prp 200. 50. 1
    # vup  0  1 0
    # vpn  0  0 1
    # display 1 5 40

    # create the analysis
    ops.wipeAnalysis()  # clear previously-define analysis parameters
    ops.constraints('Plain')  # how it handles boundary conditions
    ops.numberer(
        'Plain'
    )  # renumber dof's to minimize band-width (optimization), if you want to
    ops.system(
        'BandGeneral'
    )  # how to store and solve the system of equations in the analysis
    ops.algorithm('Linear')  # use Linear algorithm for linear analysis
    ops.integrator('Newmark', 0.5,
                   0.25)  # determine the next time step for an analysis
    ops.analysis('Transient')  # define type of analysis: time-dependent
    ops.analyze(3995, 0.01)  # apply 3995 0.01-sec time steps in analysis

    u2 = ops.nodeDisp(2, 2)
    print("u2 = ", u2)

    assert abs(u2 + 0.07441860465116277579) < 1e-12
    ops.wipe()

    print("=========================================")
Пример #16
0
    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
Пример #17
0
BCol = 5.0 * ft  # Column Width

PCol = Weight  # nodal dead-load weight per column
#g = 386.4
Mass = PCol / g

ACol = HCol * BCol  # cross-sectional area
IzCol = (BCol * math.pow(HCol, 3)) / 12  # Column moment of inertia

op.node(1, 0.0, 0.0)
op.node(2, 0.0, LCol)

op.fix(1, 1, 1, 1)
IDctrlNode = 2
IDctrlDOF = 1
op.mass(2, Mass, 1e-9, 0.0)

ColSecTag = 1  # assign a tag number to the column section
coverCol = 5.0 * inch  # Column cover to reinforcing steel NA.
numBarsCol = 20  # number of longitudinal-reinforcement bars in column. (symmetric top & bot)
barAreaCol = 2.25 * inch2  # area of longitudinal-reinforcement bars

# MATERIAL parameters
IDconcU = 1  # material ID tag -- unconfined cover concrete (here used for complete section)
IDreinf = 2  # material ID tag -- reinforcement

# nominal concrete compressive strength
fc = -4.0 * ksi  # CONCRETE Compressive Strength (+Tension, -Compression)
Ec = 57 * ksi * math.sqrt(
    -fc /
    psi)  # Concrete Elastic Modulus (the term in sqr root needs to be in psi
Пример #18
0
def build_model(model_params):
    """
    Generates OpenSeesPy model of an elastic cantilever and runs gravity analysis.

    Assumes that length is measured in inches and acceleration in in/s2

    Parameters
    ----------
    NumberOfStories: int
        Number of stories
    StructureType: string
        Type of structural system - expects one of the HAZUS structure classes
    PlanArea: float
        Area of the structure's footprint

    """

    # Assumptions
    h_story = 12  # Story height [ft]
    w_story = 200  # Story weight [psf]

    # constants for unit conversion
    ft = 1.0
    inch = 12.0
    m = 3.28084

    ft2 = 1.0
    inch2 = inch**2.
    m2 = m**2.

    psf = 1.0
    Nsm = 4.88242  # N per square meter

    stories = model_params["NumberOfStories"]
    node_tags = list(range(stories + 1))

    # The fundamental period is approximated as per ASCE 7-16 12.8.2.1
    h_n = stories * h_story  # [ft]

    if model_params['StructureType'] in [
            'S1',
    ]:
        # steel moment-resisting frames
        C_t = 0.028
        x = 0.8

    elif model_params['StructureType'] in [
            'C1',
    ]:
        # concrete moment-resisting frames
        C_t = 0.016
        x = 0.9

    elif model_params['StructureType'] in ['BRBF', 'ECBF']:
        # steel eccentrically braced frames or
        # steel buckling-restrained braced frame
        C_t = 0.03
        x = 0.75

    else:
        C_t = 0.02
        x = 0.75

    T1 = C_t * h_n**x  # Eq 12.8-7 in ASCE 7-16

    # check the units
    units = model_params["units"]

    if 'length' in units.keys():

        if units['length'] == 'm':
            G = 9.81
            h_story = h_story * m
            w_story = w_story * Nsm

        elif units['length'] == 'ft':
            G = 32.174
            h_story = h_story * ft
            w_story = w_story / ft2

        else:  # elif units['length'] == 'in':
            G = 386.1
            h_story = h_story * inch
            w_story = w_story / inch2

    # The weight at each story is assumed to be identical
    W = model_params["PlanArea"] * w_story

    m = W / G

    # We calculate stiffness assuming half of the mass vibrates at the top
    K = ((m * stories) / 2.) / (T1 / (2 * pi))**2.

    # set model dimensions and degrees of freedom
    ops.model('basic', '-ndm', 3, '-ndf', 6)

    # define an elastic and a rigid material
    elastic_tag = 100
    rigid_tag = 110
    ops.uniaxialMaterial('Elastic', elastic_tag, K)
    ops.uniaxialMaterial('Elastic', rigid_tag, 1.e9)

    # define pattern for gravity loads
    ops.timeSeries('Linear', 1)
    ops.pattern('Plain', 101, 1)

    for story in range(0, stories + 1):

        # define nodes
        ops.node(node_tags[story], 0., 0., story * h_story)

        # define fixities
        if story == 0:
            ops.fix(node_tags[0], 1, 1, 1, 1, 1, 1)
        else:
            ops.fix(node_tags[story], 0, 0, 0, 1, 1, 1)

        # define elements
        if story > 0:
            element_tag = 1000 + story - 1
            ops.element('twoNodeLink', element_tag, node_tags[story - 1],
                        node_tags[story], '-mat', rigid_tag, elastic_tag,
                        elastic_tag, '-dir', 1, 2, 3, '-orient', 0., 0., 1.,
                        0., 1., 0., '-doRayleigh')

            # define masses
            ops.mass(node_tags[story], m, m, m, 0., 0., 0.)

            # define loads
            ops.load(node_tags[story], 0., 0., -W, 0., 0., 0.)

    # define damping based on first eigenmode
    damp_ratio = 0.05
    angular_freq = ops.eigen(1)[0]**0.5
    beta_k = 2 * damp_ratio / angular_freq
    ops.rayleigh(0., beta_k, 0., 0.)

    # run gravity analysis
    tol = 1e-8  # convergence tolerance for test
    iter = 100  # max number of iterations
    nstep = 100  # apply gravity loads in 10 steps
    incr = 1. / nstep  # first load increment

    # analysis settings
    ops.constraints(
        'Transformation'
    )  # enforce boundary conditions using transformation constraint handler
    ops.numberer(
        'RCM')  # renumbers dof's to minimize band-width (optimization)
    ops.system(
        'BandGeneral'
    )  # stores system of equations as 1D array of size bandwidth x number of unknowns
    ops.test(
        'EnergyIncr', tol, iter, 0
    )  # tests for convergence using dot product of solution vector and norm of right-hand side of matrix equation
    ops.algorithm(
        'Newton'
    )  # use Newton's solution algorithm: updates tangent stiffness at every iteration
    ops.integrator(
        'LoadControl', incr
    )  # determine the next time step for an analysis # apply gravity in 10 steps
    ops.analysis('Static')  # define type of analysis, static or transient
    ops.analyze(nstep)  # perform gravity analysis

    # after gravity analysis, change time and tolerance for the dynamic analysis
    ops.loadConst('-time', 0.0)
Пример #19
0
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
Пример #20
0
    ops.section('Elastic', secTag, E, A, Iz)

# beam integration
inteTag = 1
numpts = 2
ops.beamIntegration('Legendre', inteTag, secTag, numpts)

coltag = 3
eleArgs = ['dispBeamColumn', transfTag, inteTag]
ops.mesh('line', coltag, 2, 1, 2, sid, ndf, h, *eleArgs)

# mass
sNodes = ops.getNodeTags('-mesh', coltag)
bmass = bmass / len(sNodes)
for nd in sNodes:
    ops.mass(int(nd), bmass, bmass, 0.0)

# background mesh
lower = [-h, -h]
upper = [5 * L, 3 * L]

ops.mesh('bg', h, *lower, *upper, '-structure', sid, len(sNodes), *sNodes,
         '-structure', sid, len(wallNodes), *wallNodes)

print('num nodes =', len(ops.getNodeTags()))
print('num particles =', nx * ny)

# create constraint object
ops.constraints('Plain')

# create numberer object