def test_RCFrameGravity():
    ops.wipe()
    exec(open('RCFrameGravity.py', 'r').read())

    u3 = ops.nodeDisp(3, 2)
    u4 = ops.nodeDisp(4, 2)

    assert abs(u3 + 0.0183736) < 1e-6 and abs(u4 + 0.0183736) < 1e-6
    def step(self, action=0):
        self.time = op.getTime()
        assert (self.time < self.analysis_time)

        # 選ばれたアクションに応じて減衰定数を変化させる
        self.h = self.action[action]
        self.hs.append(self.h)
        self.beta_k = 2 * self.h / self.w0
        op.rayleigh(self.alpha_m, self.beta_k, self.beta_k_init,
                    self.beta_k_comm)

        op.analyze(1, self.dt)
        op.reactions()

        self.dis = op.nodeDisp(self.top_node, 1)
        self.vel = op.nodeVel(self.top_node, 1)
        self.acc = op.nodeAccel(self.top_node, 1)
        self.a_acc = self.acc + self.values[self.i]
        self.force = -op.nodeReaction(self.bot_node,
                                      1)  # Negative since diff node

        self.resp["time"].append(self.time)
        self.resp["dis"].append(self.dis)
        self.resp["vel"].append(self.vel)
        self.resp["acc"].append(self.acc)
        self.resp["a_acc"].append(self.a_acc)
        self.resp["force"].append(self.force)

        next_time = op.getTime()
        self.done = next_time >= self.analysis_time

        self.i_pre = self.i
        self.i += 1
        self.i_next = self.i + 1 if not self.done else self.i
        return self.reward, self.done
Example #3
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
Example #4
0
def get_node_coords_and_disp():
    node_coords = dict()
    node_disp = dict()
    node_tags = ops.getNodeTags()
    for i in node_tags:
        node_coords[i] = ops.nodeCoord(i)
        node_disp[i] = ops.nodeDisp(i)
    return (node_coords,node_disp)
Example #5
0
    def material_response(self, material, demand):
        """
        Calculate the response of a material to a given load history.
        
        Parameters
        ----------
        material: Material
            The material object to analyze.
        demand: DemandProtocol
            The load history the material shall be exposed to.
            
        Returns
        -------
        response: DataFrame
            The DataFrame includes columns for strain (eps) and stress (sig).

        """
        # initialize the analysis
        self._initialize()

        # define the structure
        struct = SDOF(Truss(material, l_tot=1., A_cs=1.))
        struct.create_FEM(damping=False)
        id_ctrl_node = struct.ctrl_node
        load_dir = 1

        # define the loading
        ops.timeSeries('Linear', 1)
        ops.pattern('Plain', 1, 1)
        if self.ndf == 1 and self.ndm == 1:
            ops.load(id_ctrl_node, 1.)

        # configure the analysis
        ops.constraints('Plain')
        ops.numberer('RCM')
        ops.system('UmfPack')
        ops.test('NormDispIncr', 1e-10, 100)
        ops.algorithm('NewtonLineSearch', '-maxIter', 100)

        # initialize the arrays for results
        result_size = demand.length
        response = pd.DataFrame(np.zeros((result_size + 1, 2)),
                                columns=['eps', 'sig'])

        # perform the analysis
        for i, disp_incr in enumerate(demand.increments):
            ops.integrator('DisplacementControl', id_ctrl_node, load_dir,
                           disp_incr)
            ops.analysis('Static')
            ops.analyze(1)
            response.loc[i + 1, 'eps'] = ops.nodeDisp(id_ctrl_node, load_dir)
            #             response.loc[i+1, 'sig'] = ops.eleResponse(1, 'axialForce')[0] #![4]
            response.loc[i + 1, 'sig'] = ops.eleResponse(1,
                                                         'axialForce')  #![4]

        return response
Example #6
0
def PushoverLcD(dispMax):

    ControlNode = 4
    ControlNodeDof = 1
    du = 0.00002 * m

    # Define time series
    #  timeSeries('Constant', tag, '-factor', factor=1.0)
    op.timeSeries('Constant', 1)
    op.timeSeries('Linear', 2)

    # define loads
    op.pattern('Plain', 1, 2)
    op.sp(ControlNode, ControlNodeDof, du)

    # Define Analysis Options
    # create SOE
    op.system("BandGeneral")
    # create DOF number
    op.numberer("Plain")
    # create constraint handler
    op.constraints("Transformation")
    # create integrator
    op.integrator("LoadControl", 1)
    # create algorithm
    op.algorithm("Newton")
    # create analysis object
    op.analysis("Static")

    # Create Test
    op.test('NormDispIncr', 1. * 10**-6, 50)

    # Run Analysis

    op.record()
    # ok = op.analyze(Nsteps)

    nn = 0
    while (op.nodeDisp(ControlNode, ControlNodeDof) < dispMax):

        ok = op.analyze(1)

        if ok != 0:
            ok = BasicAnalysisLoop(ok, nn)

        if ok != 0:
            print("Analysis failed at load factor:", nn)
            break

        nn = +1

    print()
    print("# Analysis Complete #")
    def plot_deformed_shape(self,
                            xlim,
                            ylim,
                            scale=1,
                            arrow_len=10,
                            arrow_width=2,
                            save=''):
        '''
        Plot deformed shape of the model.
        
        Args:
            xlim: A list of left and right limits of the x axis.
            ylim: A list of bottom and top limits of the y axis.
            scale: A float scale of the displayed deformations (default=1).
            arrow_len: An integer length of the load arrows displayed 
                (default=10).
            arrow_width: An integer head width of the load arrows displayed 
                (default=2).
            save: A string indicating save path for the figure (default='',
                meaning that the figure will NOT be saved by default).
        '''

        fig, ax = plt.subplots(dpi=75)
        ax.set_axis_off()
        ax.grid(True, which='both', alpha=0.5)
        ax.axhline(y=0, color='k', lw=1)

        opsv.plot_defo(scale, fmt_undefo='k-', fmt_interp='k--')

        ax.axis('equal')
        ax.set(xlim=xlim, ylim=ylim)

        node_list = ops.getNodeTags()
        node_disp = np.array([ops.nodeDisp(n) for n in node_list])
        node_coord = np.array([ops.nodeCoord(n) for n in node_list])
        new_coord = node_disp[:, :-1] * scale + node_coord

        for node, Px, Py, M in self.loads:
            c = new_coord[node_list.index(node), :]
            ax.annotate('',
                        xytext=(c[0] + abs(Px) * arrow_len,
                                c[1] + abs(Py) * arrow_len),
                        xy=(c[0], c[1]),
                        arrowprops=dict(arrowstyle=f'-|>, \
                                          head_width={arrow_width/5},\
                                          head_length={arrow_width/2}',
                                        lw=arrow_width,
                                        fc='orangered',
                                        ec='orangered'))
        if save:
            fig.savefig(save, transparent=True)
        plt.show()
Example #8
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
Example #9
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
Example #10
0
print("Finished creating loading object...")

#----------------------------------------------------------
#  create the analysis
#----------------------------------------------------------
op.integrator('LoadControl', 0.05)
op.numberer('RCM')
op.system('SparseGeneral')
op.constraints('Transformation')
op.test('NormDispIncr', 1e-5, 20, 1)
op.algorithm('Newton')
op.analysis('Static')

print("Starting Load Application...")
op.analyze(201)

print("Load Application finished...")
#print("Loading Analysis execution time: [expr $endT-$startT] seconds.")

#op.wipe

op.reactions()
Nodereactions = dict()
Nodedisplacements = dict()
for i in range(201, nodeTag + 1):
    Nodereactions[i] = op.nodeReaction(i)
    Nodedisplacements[i] = op.nodeDisp(i)
print('Node Reactions are: ', Nodereactions)
print('Node Displacements are: ', Nodedisplacements)
            "regular newton failed .. lets try an initail stiffness for this step"
        )
        ops.test('NormDispIncr', 1.0e-12, 100, 0)
        ops.algorithm('ModifiedNewton', '-initial')
        ok = ops.analyze(1, .01)
        if ok == 0:
            print("that worked .. back to regular newton")
        ops.test('NormDispIncr', 1.0e-12, 10)
        ops.algorithm('Newton')

    tCurrent = ops.getTime()

    print(f'{tCurrent} [s] analyzed of {tFinal}')

    time.append(tCurrent)
    u3.append(ops.nodeDisp(2999, 1))

# Perform an eigenvalue analysis
eigenValues = ops.eigen(numEigen)
print("eigen values at end of transient:", eigenValues)

results = open('results.out', 'a+')

if ok == 0:
    results.write('PASSED : RCFrameEarthquake.py\n')
    print("Passed!")
else:
    results.write('FAILED : RCFrameEarthquake.py\n')
    print("Failed!")

results.close()
Example #12
0
ops.nDMaterial('ElasticIsotropic', 1, 3000.0, 0.3)

eleArgs = ['tri31', 1.0, 'PlaneStress', 1]

ops.mesh('quad', 5, 4, 1, 4, 2, 3, sid, ndf, meshsize, *eleArgs)

if pid == 0:
    ops.fix(pid, 1, 1)
    ops.fix(np + pid + 1, 1, 1)
if pid == np - 1:
    ops.timeSeries('Linear', 1)
    ops.pattern('Plain', 1, 1)
    ops.load(np + pid + 2, 0.0, -1.0)

ops.constraints('Transformation')
ops.numberer('ParallelPlain')
ops.system('Mumps')
ops.test('NormDispIncr', 1e-6, 6)
ops.algorithm('Newton')
ops.integrator('LoadControl', 1.0)
ops.analysis('Static')

ops.stop()
ops.start()
ops.analyze(1)

if pid == np - 1:
    print('Node', pid + 1, ops.nodeDisp(pid + 1))

ops.stop()
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
Example #14
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
Example #15
0
lowerBound = 1*inches**2
upperBound = 20*inches**2

Narea = 20
trialAreas = np.linspace(lowerBound,upperBound,Narea)
outputDisp = np.zeros([Narea,Narea])


for ii, A1 in enumerate(trialAreas):
    for jj, A2 in enumerate(trialAreas):
        GetSections(E)
        GetModel(A1,A2)
        RunGravityAnalysis(Py)
        
        outputDisp[ii,jj] = op.nodeDisp(4,2)
        
        
        op.wipe()
        


shiftOutput = np.abs(outputDisp - targetDisp)
[[MinIndexA1] ,[MinIndexA2] ] = np.where(shiftOutput == np.min(shiftOutput))


A1Optimal = trialAreas[MinIndexA1]
A2Optimal = trialAreas[MinIndexA2]


Example #16
0
    ops.fix(2, 1, 1)
    ops.fix(3, 1, 1)

    ops.element('Truss', 2, 2, 4, 5.0, 1)
    ops.element('Truss', 3, 3, 4, 5.0, 1)

ops.constraints('Transformation')
ops.numberer('ParallelPlain')
ops.system('Mumps')
ops.test('NormDispIncr', 1e-6, 6, 2)
ops.algorithm('Newton')
ops.integrator('LoadControl', 0.1)
ops.analysis('Static')

ops.analyze(10)

print('Node 4: ', [ops.nodeCoord(4), ops.nodeDisp(4)])

ops.loadConst('-time', 0.0)

if pid == 0:
    ops.pattern('Plain', 2, 1)
    ops.load(4, 1.0, 0.0)

ops.domainChange()
ops.integrator('ParallelDisplacementControl', 4, 1, 0.1)
ops.analyze(10)

print('Node 4: ', [ops.nodeCoord(4), ops.nodeDisp(4)])
ops.stop()
Example #17
0
ops.element('Truss', 1, 1, 4, 10.0, 1)
ops.timeSeries('Linear', 1)
ops.pattern('Plain', 1, 1)
ops.load(4, 100.0, -50.0)

ops.element('Truss', 2, 2, 4, 5.0, 1)
ops.element('Truss', 3, 3, 4, 5.0, 1)

ops.constraints('Transformation')
ops.numberer('ParallelPlain')
ops.system('Umfpack')
ops.test('NormDispIncr', 1e-6, 6)
ops.algorithm('Newton')
ops.integrator('LoadControl', 0.1)
ops.analysis('Static')

ops.analyze(10)

if pid == 0:
    print('Processor 0')
    print('Node 4 (E =', E, ') Disp :', ops.nodeDisp(4))

ops.barrier()

if pid == 1:
    print('Processor 1')
    print('Node 4 (E =', E, ') Disp :', ops.nodeDisp(4))

ops.stop()
Example #18
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
Example #19
0
def test_PlanarTruss():
    A = 10.0
    E = 3000.
    L = 200.0
    alpha = 30.0
    P = 200.0

    sigmaYP = 60.0

    pi = 2.0*asin(1.0)
    alphaRad = alpha*pi/180.
    cosA = cos(alphaRad)
    sinA = sin(alphaRad)

    # EXACT RESULTS per Popov
    F1 = P/(2*cosA*cosA*cosA + 1)
    F2 = F1*cosA*cosA
    disp = -F1*L/(A*E)

    # create the finite element model
    ops.wipe()

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

    dX = L*tan(alphaRad)

    ops.node( 1,    0.0,          0.0)
    ops.node( 2,    dX,          0.0)
    ops.node( 3, 2.0*dX,  0.0)
    ops.node( 4,    dX,         -L     )

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

    ops.uniaxialMaterial('Elastic', 1, E)
    ops.element('Truss', 1, 1, 4, A, 1)
    ops.element('Truss', 2, 2, 4, A, 1)
    ops.element('Truss', 3, 3, 4, A, 1)

    ops.timeSeries('Linear', 1)
    ops.pattern('Plain', 1, 1)
    ops.load( 4, 0., -P)

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


    # determine PASS/FAILURE of test
    testOK = 0

    #
    # print table of camparsion
    #          

    comparisonResults = F2, F1, F2
    print("\nElement Force Comparison:")
    tol = 1.0e-6
    print('{:>10}{:>15}{:>15}'.format('Element','OpenSees','Popov'))


    for i in range(1,4):
        exactResult = comparisonResults[i-1]
        eleForce = ops.eleResponse(i, 'axialForce')
        print('{:>10d}{:>15.4f}{:>15.4f}'.format(i, eleForce[0], exactResult))
        if abs(eleForce[0]-exactResult) > tol:
            testOK = -1
            print("failed force-> ", abs(eleForce[0]-exactResult), " ", tol)


    print("\nDisplacement Comparison:")
    osDisp = ops.nodeDisp( 4, 2)
    print('{:>10}{:>15.8f}{:>10}{:>15.8f}'.format('OpenSees:',osDisp,'Exact:', disp))
    if abs(osDisp-disp) > tol:
        testOK = -1
        print("failed linear disp")



    print("\n\n  - NonLinear (Example2.23)")

    #EXACT
    # Exact per Popov

    PA = (sigmaYP*A) * (1.0+2*cosA*cosA*cosA)
    dispA = PA/P*disp

    PB = (sigmaYP*A) * (1.0+2*cosA)
    dispB = dispA / (cosA*cosA)

    # create the new finite element model for nonlinear case
    #   will apply failure loads and calculate displacements

    ops.wipe()

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

    ops.node( 1,    0.0,          0.0)
    ops.node( 2,    dX,          0.0)
    ops.node( 3, 2.0*dX,  0.0)
    ops.node( 4,    dX,         -L     )

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

    ops.uniaxialMaterial( 'ElasticPP', 1, E, sigmaYP/E)
    ops.element('Truss', 1, 1, 4, A, 1)
    ops.element('Truss', 2, 2, 4, A, 1)
    ops.element('Truss', 3, 3, 4, A, 1)

    ops.timeSeries( 'Path', 1, '-dt', 1.0, '-values', 0.0, PA, PB, PB)
    ops.pattern('Plain', 1, 1)
    ops.load( 4, 0., -1.0)

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

    osDispA = ops.nodeDisp( 4, 2)
    #print node 4
    #print ele

    ops.analyze(1)
    osDispB = ops.nodeDisp( 4, 2)

    #print node 4
    #print ele


    # determine PASS/FAILURE of test
    testOK = 0

    print("\nDisplacement Comparison:")
    print("elastic limit state:")
    osDisp = ops.nodeDisp( 4, 2)
    print('{:>10}{:>15.8f}{:>10}{:>15.8f}'.format('OpenSees:',osDispA,'Exact:',dispA))
    if abs(osDispA-dispA) > tol:
        testOK = -1
        print("failed nonlineaer elastic limit disp")

    print("collapse limit state:")
    print('{:>10}{:>15.8f}{:>10}{:>15.8f}'.format('OpenSees:',osDispB,'Exact:',dispB))
    if abs(osDispB-dispB) > tol:
        testOK = -1
        print("failed nonlineaer collapse limit disp")

    assert testOK == 0
Example #20
0
def run_analysis(GM_dt, GM_npts, TS_List, EDP_specs, model_params):
    """
    Run dynamic analysis for a time history and return a dictionary of envelope EDPs.

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

    Parameters
    ----------
    GM_dt: float
        Time step of time series
    GM_npts: float
        Number of points in time series
    TS_List: float
        1x2 list where first component is a list of accelerations in the X
        direction, the second component is a list of accelerations in the Y
        direction.
    EDP_specs: dict

    """

    stories = model_params["NumberOfStories"]
    node_tags = list(range(stories + 1))
    height = ops.nodeCoord(node_tags[-1], 3) - ops.nodeCoord(node_tags[0], 3)

    # define parameters for dynamic analysis
    dt = GM_dt  # time increment for analysis

    GMX = TS_List[0]  # list of GM accelerations in X direction
    GMY = TS_List[1]  # list of GM accelerations in Y direction

    driftLimit = 0.20  # interstory drift limit indicating collapse
    tol = 1.e-08  # tolerance criteria to check for convergence
    maxiter = 30  # max number of iterations to check
    subSteps = 2  # number of subdivisions in cases of ill convergence

    # pad shorter record with zeros (free vibration) such that two horizontal records are the same length
    nsteps = max(len(GMX), len(GMY))
    for GM in [GMX, GMY]:
        if len(GM) < nsteps:
            diff = nsteps - len(GM)
            GM.extend(np.zeros(diff))

    # initialize dictionary of envelope EDPs
    envelopeDict = {}
    for edp in EDP_specs:
        envelopeDict[edp] = {}
        for loc in EDP_specs[edp]:
            envelopeDict[edp][loc] = np.zeros(len(
                EDP_specs[edp][loc])).tolist()
    #print(envelopeDict)

    # initialize dictionary of time history EDPs
    time_analysis = np.zeros(nsteps * 5)
    acc_history = {}
    for floor in range(stories + 1):
        acc_history.update(
            {floor: {
                1: time_analysis.copy(),
                2: time_analysis.copy()
            }})

    ops.wipeAnalysis()

    ops.constraints(
        'Transformation'
    )  # handles boundary conditions based on transformation equation method
    ops.numberer('RCM')  # renumber dof's to minimize band-width (optimization)
    ops.system('UmfPack'
               )  # constructs sparse system of equations using UmfPack solver
    ops.test(
        'NormDispIncr', tol, maxiter
    )  # tests for convergence using norm of left-hand side of matrix equation
    ops.algorithm(
        'NewtonLineSearch'
    )  # use Newton's solution algorithm: updates tangent stiffness at every iteration
    ops.integrator(
        'Newmark', 0.5,
        0.25)  # Newmark average acceleration method for numerical integration
    ops.analysis('Transient')  # define type of analysis: time-dependent

    # initialize variables
    maxDiv = 1024
    minDiv = subSteps
    step = 0
    ok = 0
    breaker = 0
    count = 0

    while step < nsteps and ok == 0 and breaker == 0:
        step = step + 1  # take 1 step
        ok = 2
        div = minDiv
        length = maxDiv
        while div <= maxDiv and length > 0 and breaker == 0:
            stepSize = dt / div
            # perform analysis for one increment; will return 0 if no convergence issues
            ok = ops.analyze(1, stepSize)
            if ok == 0:
                count = count + 1
                length = length - maxDiv / div

                floor = 1

                while floor <= stories:

                    # check if drift limits are satisfied
                    # check X direction drifts (direction 1)
                    drift_x = abs(
                        ops.nodeDisp(node_tags[1], 1) -
                        ops.nodeDisp(node_tags[0], 1)) / height
                    if drift_x >= driftLimit:
                        breaker = 1

                    # check Y direction drifts (direction 2)
                    drift_y = abs(
                        ops.nodeDisp(node_tags[1], 2) -
                        ops.nodeDisp(node_tags[0], 2)) / height
                    if drift_y >= driftLimit:
                        breaker = 1

                    # save parameter values in recording dictionaries at every step
                    time_analysis[count] = time_analysis[count - 1] + stepSize

                    envelopeDict['PID'][floor][0] = max(
                        drift_x, envelopeDict['PID'][floor][0])
                    envelopeDict['PID'][floor][1] = max(
                        drift_y, envelopeDict['PID'][floor][1])

                    floor = floor + 1

                for floor in range(stories + 1):
                    for dof in [1, 2]:
                        acc_history[floor][dof][count] = ops.nodeAccel(
                            node_tags[floor], dof)

            else:
                div = div * 2
                print("Number of increments increased to ", str(div))

        # end analysis once drift limit has been reached
        if breaker == 1:
            ok = 1
            print("Collapse drift has been reached")

    print("Number of analysis steps completed: {}".format(count))

    # remove extra zeros from the end of the time history
    time_analysis = time_analysis[1:count + 1]

    # generate time array from recording
    time_record = np.linspace(0, nsteps * dt, num=nsteps, endpoint=False)

    # remove extra zeros from accel time history, add GM to obtain absolute a
    # acceleration, and record envelope value
    GMX_interp = np.interp(time_analysis, time_record, GMX)
    GMY_interp = np.interp(time_analysis, time_record, GMY)
    for floor in range(0, stories + 1):
        # X direction
        envelopeDict['PFA'][floor][0] = max(
            abs(np.asarray(acc_history[floor][1][1:count + 1]) + GMX_interp))
        # Y direction
        envelopeDict['PFA'][floor][1] = max(
            abs(np.asarray(acc_history[floor][2][1:count + 1]) + GMY_interp))

    return envelopeDict
def run_sensitivity_pushover_analysis(ctrlNode,
                                      baseNodes,
                                      dof,
                                      Dincr,
                                      max_disp,
                                      SensParam,
                                      IOflag=False):
    """
    Run pushover analysis with sensitivity
    """
    ops.wipeAnalysis()
    start_time = time.time()
    ops.loadConst("-time", 0.0)

    title("Running Displacement-Control Pushover Sensitivity Analysis ...")

    testType = "NormDispIncr"  # EnergyIncr
    tolInit = 1.0E-8
    iterInit = 10  # Set the initial Max Number of Iterations
    algorithmType = "Newton"  # Set the algorithm type

    ops.system("BandGeneral")
    ops.constraints("Transformation")
    ops.numberer("RCM")
    ops.test(testType, tolInit, iterInit)
    ops.algorithm(algorithmType)
    # Change the integration scheme to be displacement control
    #                                     node      dof  init Jd min max
    ops.integrator("DisplacementControl", ctrlNode, dof, Dincr)
    ops.analysis("Static")
    ops.sensitivityAlgorithm(
        "-computeAtEachStep"
    )  # automatically compute sensitivity at the end of each step

    if IOflag:
        print(
            f"Single Pushover: Push node {ctrlNode} to {max_disp} {LunitTXT}.\n"
        )

    # Set some parameters
    tCurrent = ops.getTime()
    currentStep = 1

    outputs = {
        "time": np.array([]),
        "disp": np.array([]),
        "force": np.array([]),
    }

    for sens in SensParam:
        outputs[f"sensLambda_{sens}"] = np.array([]),

    nodeList = []
    for node in baseNodes:
        nodeList.append(f"- ops.nodeReaction({node}, dof) ")

    nodeList = "".join(nodeList)
    currentDisp = ops.nodeDisp(ctrlNode, dof)
    ok = 0

    while ok == 0 and currentDisp < max_disp:
        ops.reactions()
        ok = ops.analyze(1)
        tCurrent = ops.getTime()
        currentDisp = ops.nodeDisp(ctrlNode, dof)

        if IOflag:
            print(
                f"Current displacement ==> {ops.nodeDisp(ctrlNode, dof):.3f} {LunitTXT}"
            )

        # if the analysis fails try initial tangent iteration
        if ok != 0:
            print("\n==> Trying relaxed convergence...")
            ops.test(testType, tolInit / 0.01, iterInit * 50)
            ok = ops.analyze(1)
            if ok == 0:
                print("==> that worked ... back to default analysis...\n")
            ops.test(testType, tolInit, iterInit)

        if ok != 0:
            print("\n==> Trying Newton with initial then current...")
            ops.test(testType, tolInit / 0.01, iterInit * 50)
            ops.algorithm("Newton", "-initialThenCurrent")
            ok = ops.analyze(1)
            if ok == 0:
                print("==> that worked ... back to default analysis...\n")
            ops.algorithm(algorithmType)
            ops.test(testType, tolInit, iterInit)

        if ok != 0:
            print("\n==> Trying ModifiedNewton with initial...")
            ops.test(testType, tolInit / 0.01, iterInit * 50)
            ops.algorithm("ModifiedNewton", "-initial")
            ok = ops.analyze(1)
            if ok == 0:
                print("==> that worked ... back to default analysis...\n")
            ops.algorithm(algorithmType)
            ops.test(testType, tolInit, iterInit)

        currentStep += 1
        tCurrent = ops.getTime()

        outputs["time"] = np.append(outputs["time"], tCurrent)
        outputs["disp"] = np.append(outputs["disp"],
                                    ops.nodeDisp(ctrlNode, dof))
        outputs["force"] = np.append(outputs["force"], eval(nodeList))

        for sens in SensParam:
            # sensLambda(patternTag, paramTag)
            outputs[f"sensLambda_{sens}"] = np.append(
                outputs[f"sensLambda_{sens}"], ops.sensLambda(1, sens))

    # Print a message to indicate if analysis completed succesfully or not
    if ok == 0:
        title("Pushover Analysis Completed Successfully!")
    else:
        title("Pushover Analysis Completed Failed!")

    print(
        f"Analysis elapsed time is {(time.time() - start_time):.3f} seconds.\n"
    )

    return outputs
Example #22
0
    1: 'KrylovNewton',
    2: 'SecantNewton',
    4: 'RaphsonNewton',
    5: 'PeriodicNewton',
    6: 'BFGS',
    7: 'Broyden',
    8: 'NewtonLineSearch'
}

for i in test:
    for j in algorithm:

        if ok != 0:
            if j < 4:
                op.algorithm(algorithm[j], '-initial')

            else:
                op.algorithm(algorithm[j])

            op.test(test[i], Tol, 1000)
            ok = op.analyze(Nsteps)
            print(test[i], algorithm[j], ok)
            if ok == 0:
                break
        else:
            continue

u2 = op.nodeDisp(2, 1)
print("u2 = ", u2)

op.wipe()
Example #23
0
fx = 10 * kN
fy = 0
ops.load(8, fx, fy)
#for i in range(nNode):
#    if (Node[i][0] == 2):
#        ops.load(i+1, fx, fy)

ops.system('FullGeneral')  # probar otros solvers: 'UmfPack' 'SparseSYM'
ops.numberer('Plain')
ops.constraints('Plain')
ops.integrator('LoadControl', 0.1)
ops.algorithm('Linear')
ops.analysis('Static')
ops.analyze(10)

# Grafico de la deformada
fig = plt.figure(figsize=(10, 10))
opsv.plot_defo(200)
plt.show()

# Desplazamiento
disp = ops.nodeDisp(8, 2)
print(disp)

# plot esfuerzos quad 2D
fig = plt.figure(figsize=(10, 10))
sig_out = opsv.quad_sig_out_per_node()
# componentes: sxx, syy, sxy, svm, s1, s2, angle. (n_nodes x 7)
opsv.plot_stress_2d(sig_out[:, 1], mesh_outline=1, cmap='plasma')
plt.colorbar()
plt.show()
Example #24
0
def runAnalysis(k):
    """
    Tests and individual and returns the result of that test.
    
    The user should consider if it's possible for the test not to work.
    
    """

    Fu = 21.1 * 10**3
    # k = 2.6*10**6
    b = 0.015
    R0 = 19
    cR1 = .95
    cR2 = .15

    Fu = 22.3 * 10**3
    # k = 2.6*10**6
    b = 0.0129
    R0 = 3.1
    cR1 = .3
    cR2 = .01
    # 21.1*10**3, 2.6*10**6, 0.015, 19, .95, .15]
    # 2.25427928e+04 3.33339323e+06 1.96273081e-02 5.46515829e+00
    #  6.98429661e-01 5.28210755e-02
    # 2.20833537e+04 3.03336982e+06 1.28872130e-02 3.13990345e+00
    #  3.36067251e-01 1.04312516e-01
    op.wipe()

    op.model('Basic', '-ndm', 2, '-ndf', 3)

    ## Analysis Parameters material(s)
    ## ------------------
    LoadProtocol = np.array([
        0.0017, 0.005, 0.0075, 0.012, 0.018, 0.027, 0.04, 0.054, 0.068, 0.072,
        0.
    ])

    # Step size
    dx = 0.0001

    op.uniaxialMaterial('Steel02', 1, Fu, k, b, R0, cR1, cR2, 0., 1., 0., 1.)

    ERelease = 1.
    op.uniaxialMaterial('Elastic', 2, ERelease, 0.0)

    ## Define geometric transformation(s)
    ## ----------------------------------
    #geomTransf('Linear',1)
    op.geomTransf('PDelta', 1)
    op.beamIntegration('Lobatto', 1, 1, 3)

    # Define geometry
    # ---------------
    op.node(1, 0., 0., '-ndf', 3)
    op.node(2, 0., 0., '-ndf', 3)
    op.fix(1, 1, 1, 1)

    # Define element(s)
    # -----------------
    op.element("zeroLength", 1, 1, 2, '-mat', 1, 2, 2, '-dir', 1, 2, 3,
               '-orient', 1., 0., 0., 0., 1., 0.)

    # Define Recorder(s)
    # -----------------
    op.recorder('Node', '-file', 'RFrc.out', '-time', '-nodeRange', 1, 1,
                '-dof', 1, 'reaction')
    op.recorder('Node', '-file', 'Disp.out', '-time', '-nodeRange', 2, 2,
                '-dof', 1, 'disp')

    # Define Analysis Parameters
    # -----------------
    op.timeSeries('Linear', 1, '-factor', 1.0)
    op.pattern('Plain', 1, 1, '-fact', 1.)
    op.load(2, 1., 0.0, 0.0)

    # op.initialize()
    op.constraints("Plain")
    op.numberer("Plain")
    # System of Equations
    op.system("UmfPack", '-lvalueFact', 10)
    # Convergence Test
    op.test('NormDispIncr', 1. * 10**-8, 25, 0, 2)
    # Solution Algorithm
    op.algorithm('Newton')
    # Integrator
    op.integrator('DisplacementControl', 2, 1, dx)
    # Analysis Type
    op.analysis('Static')

    ControlNode = 2
    ControlNodeDof = 1

    op.record()

    ok = 0
    # Define Analysis
    for x in LoadProtocol:
        for ii in range(0, 2):

            # op.
            op.integrator('DisplacementControl', ControlNode, ControlNodeDof,
                          dx)
            while (op.nodeDisp(2, 1) < x):
                ok = op.analyze(1)
                if ok != 0:
                    print('Ending analysis')
                    op.wipe()
                    return np.array([0, 0])

            op.integrator('DisplacementControl', ControlNode, ControlNodeDof,
                          -dx)
            while (op.nodeDisp(2, 1) > -x):
                ok = op.analyze(1)
                if ok != 0:
                    print('Ending analysis')
                    op.wipe()
                    return np.array([0, 0])

    op.wipe()

    fileDispName = os.path.join('Disp.out')
    fileForceName = os.path.join('RFrc.out')

    disp = np.loadtxt(fileDispName)
    RFrc = np.loadtxt(fileForceName)

    # try:
    x = disp[:, 1]
    y = -RFrc[:, 1]

    xy = np.column_stack([x, y])
    return xy
Example #25
0
def test_PinchedCylinder():

    P = 1
    R = 300.
    L = 600.
    E = 3e6
    thickness = R / 100.

    uExact = -164.24 * P / (E * thickness)

    formatString = '{:>20s}{:>15.5e}'
    print("\n  Displacement Under Applied Load:\n")

    formatString = '{:>20s}{:>10s}{:>15s}{:>15s}{:>15s}'
    print(
        formatString.format("Element Type", "   mesh  ", "OpenSees", "Exact",
                            "%Error"))

    for shellType in ['ShellMITC4', 'ShellDKGQ', 'ShellNLDKGQ']:
        for numEle in [4, 16, 32]:

            ops.wipe()

            # ----------------------------
            # Start of model generation
            # ----------------------------
            ops.model('basic', '-ndm', 3, '-ndf', 6)

            radius = R
            length = L / 2.

            E = 3.0e6
            v = 0.3
            PI = 3.14159

            ops.nDMaterial('ElasticIsotropic', 1, E, v)
            ops.nDMaterial('PlateFiber', 2, 1)
            ops.section('PlateFiber', 1, 2, thickness)
            #section ElasticMembranePlateSection  1   E v thickness 0.
            nR = numEle
            nY = numEle

            tipNode = (nR + 1) * (nY + 1)

            #create nodes
            nodeTag = 1
            for i in range(nR + 1):
                theta = i * PI / (2.0 * nR)
                xLoc = 300 * cos(theta)
                zLoc = 300 * sin(theta)

                for j in range(nY + 1):
                    yLoc = j * length / (1.0 * nY)
                    ops.node(nodeTag, xLoc, yLoc, zLoc)
                    nodeTag += 1

            #create elements
            eleTag = 1
            for i in range(nR):
                iNode = i * (nY + 1) + 1
                jNode = iNode + 1
                lNode = iNode + (nY + 1)
                kNode = lNode + 1
                for j in range(nY):
                    ops.element(shellType, eleTag, iNode, jNode, kNode, lNode,
                                1)
                    eleTag += 1
                    iNode += 1
                    jNode += 1
                    kNode += 1
                    lNode += 1

            # define the boundary conditions
            ops.fixX(radius, 0, 0, 1, 1, 1, 0, '-tol', 1.0e-2)
            ops.fixZ(radius, 1, 0, 0, 0, 1, 1, '-tol', 1.0e-2)
            ops.fixY(0., 1, 0, 1, 0, 0, 0, '-tol', 1.0e-2)
            ops.fixY(length, 0, 1, 0, 1, 0, 1, '-tol', 1.0e-2)

            #define loads
            ops.timeSeries('Linear', 1)
            ops.pattern('Plain', 1, 1)
            ops.load(tipNode, 0., 0., -1. / 4.0, 0., 0., 0.)

            ops.integrator('LoadControl', 1.0)
            ops.test('EnergyIncr', 1.0e-10, 20, 0)
            ops.algorithm('Newton')
            ops.numberer('RCM')
            ops.constraints('Plain')
            ops.system('Umfpack')
            ops.analysis('Static')

            ops.analyze(1)
            res = ops.nodeDisp(tipNode, 3)
            err = abs(100 * (uExact - res) / uExact)
            formatString = '{:>20s}{:>5d}{:>3s}{:>2d}{:>15.5e}{:>15.5e}{:>15.2f}'
            print(
                formatString.format(shellType, numEle, " x ", numEle, res,
                                    uExact, err))

    tol = 5.0
    if abs(100 * (uExact - res) / uExact) > tol:
        testOK = 1
    else:
        testOK = 0

    assert testOK == 0
Example #26
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
Example #27
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]))
Example #28
0
def run_sensitivity_analysis(ctrlNode,
                             dof,
                             baseNode,
                             SensParam,
                             steps=500,
                             IOflag=False):
    """
    Run load-control sensitivity analysis
    """
    ops.wipeAnalysis()
    start_time = time.time()

    title("Running Load-Control Sensitivity Analysis ...")

    ops.system("BandGeneral")
    ops.numberer("RCM")
    ops.constraints("Transformation")
    ops.test("NormDispIncr", 1.0E-12, 10, 3)
    ops.algorithm("Newton")  # KrylovNewton
    ops.integrator("LoadControl", 1 / steps)
    ops.analysis("Static")
    ops.sensitivityAlgorithm(
        "-computeAtEachStep"
    )  # automatically compute sensitivity at the end of each step

    outputs = {
        "time": np.array([]),
        "disp": np.array([]),
        "force": np.array([]),
    }

    for sens in SensParam:
        outputs[f"sensDisp_{sens}"] = np.array([]),

    for i in range(steps):
        ops.reactions()
        if IOflag:
            print(
                f"Single Cycle Response: Step #{i}, Node #{ctrlNode}: {ops.nodeDisp(ctrlNode, dof):.3f} {LunitTXT} / {-ops.nodeReaction(baseNode, dof):.2f} {FunitTXT}."
            )
        ops.analyze(1)
        tCurrent = ops.getTime()

        outputs["time"] = np.append(outputs["time"], tCurrent)
        outputs["disp"] = np.append(outputs["disp"],
                                    ops.nodeDisp(ctrlNode, dof))
        outputs["force"] = np.append(outputs["force"],
                                     -ops.nodeReaction(baseNode, dof))

        for sens in SensParam:
            # sensDisp(patternTag, paramTag)
            outputs[f"sensDisp_{sens}"] = np.append(
                outputs[f"sensDisp_{sens}"],
                ops.sensNodeDisp(ctrlNode, dof, sens))

    title("Sensitvity Analysis Completed!")
    print(
        f"Analysis elapsed time is {(time.time() - start_time):.3f} seconds.\n"
    )

    return outputs
Example #29
0
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, 'PlaneStress', Ele[i][0])

# condiciones de frontera
boundFix(nNode, Node)

ops.timeSeries('Linear',1)
ops.pattern('Plain',1,1)
fx = 0
fy = -10*kN
ops.load(2, fx, fy)
#for i in range(nNode):
#    if (Node[i][0] == 2):
#        ops.load(i+1, fx, fy)

ops.system('FullGeneral') # probar otros solvers: 'UmfPack' 'SparseSYM'
ops.numberer('Plain')
ops.constraints('Plain')
ops.integrator('LoadControl',1)
ops.algorithm('Linear')
ops.analysis('Static')
ops.analyze(1)

# Desplazamiento
disp = ops.nodeDisp(2,2)
print(disp)
Example #30
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