def run(out_folder):

    osi = o3.OpenSeesInstance(ndm=2, ndf=2, state=3)
    x_centre = 0.0
    y_centre = 0.0
    top_node = o3.node.Node(osi, x_centre, y_centre)
    o3db = connect_to_db_and_obj_holder('db/truss_ops')
    # o3db = O3ObjectDatabase()
    o3db.add_obj(top_node, 'top_node')
    bot_nodes = []
    sf_eles = []

    o3.Mass(osi, top_node, 10, 10)

    fy = 500
    k = 1.0e4
    b = 0.1
    pro_params = [5, 0.925, 0.15]
    # sf_mat = o3.uniaxial_material.SteelMPF(osi, fy, fy, k, b, b, params=pro_params)
    sf_mat = o3.uniaxial_material.Elastic(osi, k)

    diff_pos = 0.5
    depth = 1
    bot_nodes.append(o3.node.Node(osi, x_centre - diff_pos, y_centre - depth))
    o3.Fix2DOF(osi, bot_nodes[0], o3.cc.FIXED, o3.cc.FIXED)
    bot_nodes.append(o3.node.Node(osi, x_centre + diff_pos, y_centre - depth))
    o3.Fix2DOF(osi, bot_nodes[1], o3.cc.FIXED, o3.cc.FIXED)

    sf_eles.append(
        o3.element.Truss(osi, [top_node, bot_nodes[0]], big_a=1.0, mat=sf_mat))
    sf_eles.append(
        o3.element.Truss(osi, [top_node, bot_nodes[1]], big_a=1.0, mat=sf_mat))
    o3db.add_objs(sf_eles, 'sf_eles')
    save_db_state_and_objs(1, o3db)
Пример #2
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
    o3.Fix3DOF(osi, top_node, o3.cc.FREE, o3.cc.FIXED, o3.cc.FIXED)
    o3.Fix3DOF(osi, bot_node, o3.cc.FIXED, o3.cc.FIXED, o3.cc.FIXED)
    # Set out-of-plane DOFs to be slaved
    o3.EqualDOF(osi, top_node, bot_node, [o3.cc.Y, o3.cc.DOF2D_ROTZ])

    # nodal mass (weight / g):
    o3.Mass(osi, top_node, 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
    values = list(-1 * motion)  # should be negative
    acc_series = o3.time_series.Path(osi, dt, values)
    o3.pattern.UniformExcitation(osi, o3.cc.X, accel_series=acc_series)

    # set damping based on first eigen mode
    angular_freq2 = o3.get_eigen(osi, solver='fullGenLapack', n=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

    o3.wipe_analysis(osi)
    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": [], "force": []}
    o3.record(osi)
    curr_time = o3.get_time(osi)
    while curr_time < analysis_time:
        outputs["time"].append(curr_time)
        outputs["rel_disp"].append(o3.get_node_disp(osi, top_node, o3.cc.X))
        outputs["rel_accel"].append(o3.get_node_accel(osi, top_node, o3.cc.X))
        o3.gen_reactions(osi)
        outputs["force"].append(-o3.get_node_reaction(
            osi, bot_node, o3.cc.X))  # Negative since diff node
        o3.analyze(osi, 1, analysis_dt)
        curr_time = o3.get_time(osi)
    o3.wipe(osi)
    for item in outputs:
        outputs[item] = np.array(outputs[item])

    return outputs
Пример #3
0
def get_response(bd, asig, dtype, l_ph):
    """
    Compute the response of a nonlinear lollipop on a foundation with linear/nonlinear soil
    Units are N, m, s

    :param bd:
        SDOF building object
    :param asig:
        Acceleration signal object
    :return:
    """
    osi = o3.OpenSeesInstance(ndm=2, state=3)

    # Establish nodes
    top_ss_node = o3.node.Node(osi, 0, bd.h_eff)
    bot_ss_node = o3.node.Node(osi, 0, 0)

    # Fix bottom node
    o3.Fix3DOF(osi, bot_ss_node, o3.cc.FIXED, o3.cc.FIXED, o3.cc.FIXED)

    # nodal mass (weight / g):
    o3.Mass(osi, top_ss_node, bd.mass_eff, 0.0, 0)

    # Define a column element with a plastic hinge at base
    transf = o3.geom_transf.Linear2D(osi, [])  # can change for P-delta effects
    area = 1.0
    e_mod = 200.0e9
    iz = bd.k_eff * bd.h_eff ** 3 / (3 * e_mod)
    ele_nodes = [bot_ss_node, top_ss_node]

    # Superstructure element
    vert_ele = o3.element.ElasticBeamColumn2D(osi, ele_nodes, area=area, e_mod=e_mod, iz=iz, transf=transf)

    omega = 2 * np.pi / bd.t_fixed

    # define superstructure damping using rotational spring approach from Millen et al. (2017) to avoid double damping
    if dtype == 'rot_dashpot':
        cxx = bd.xi * 2 * np.sqrt(bd.mass_eff * bd.k_eff)
        equiv_c_rot = cxx * (2.0 / 3) ** 2 * bd.h_eff ** 2
        ss_rot_dashpot_mat = o3.uniaxial_material.Viscous(osi, equiv_c_rot, alpha=1.)
        sfi_dashpot_ele = o3.element.TwoNodeLink(osi, [bot_ss_node, top_ss_node], mats=[ss_rot_dashpot_mat],
                                            dirs=[o3.cc.DOF2D_ROTZ])
    elif dtype == 'horz_dashpot':
        cxx = bd.xi * 2 * np.sqrt(bd.mass_eff * bd.k_eff)
        ss_rot_dashpot_mat = o3.uniaxial_material.Viscous(osi, cxx, alpha=1.)
        sfi_dashpot_ele = o3.element.ZeroLength(osi, [bot_ss_node, top_ss_node], mats=[ss_rot_dashpot_mat],
                                            dirs=[o3.cc.X])
    else:
        beta_k = 2 * bd.xi / omega
        o3.rayleigh.Rayleigh(osi, 0, 0, beta_k_init=beta_k, beta_k_comm=0.0)


    # Define the input motion for the dynamic analysis
    acc_series = o3.time_series.Path(osi, dt=asig.dt, values=-asig.values)  # should be negative
    o3.pattern.UniformExcitation(osi, dir=o3.cc.X, accel_series=acc_series)
    print('loaded gm')
    o3.wipe_analysis(osi)

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

    o3.test_check.NormDispIncr(osi, tol=1.0e-6, max_iter=10)
    analysis_time = asig.time[-1]
    analysis_dt = 0.001

    # define outputs of analysis
    od = {
        "time": o3.recorder.TimeToArrayCache(osi),
        "rel_deck_disp": o3.recorder.NodeToArrayCache(osi, top_ss_node, [o3.cc.DOF2D_X], 'disp'),
        "deck_accel": o3.recorder.NodeToArrayCache(osi, top_ss_node, [o3.cc.DOF2D_X], 'accel'),
        "deck_rot": o3.recorder.NodeToArrayCache(osi, top_ss_node, [o3.cc.DOF2D_ROTZ], 'disp'),
        "chord_rots": o3.recorder.ElementToArrayCache(osi, vert_ele, arg_vals=['chordRotation']),
        "col_forces": o3.recorder.ElementToArrayCache(osi, vert_ele, arg_vals=['force']),
    }
    if dtype in ['rot_dashpot', 'horz_dashpot']:
        od['dashpot_force'] = o3.recorder.ElementToArrayCache(osi, sfi_dashpot_ele, arg_vals=['force'])

    o3.analyze(osi, int(analysis_time / analysis_dt), analysis_dt)

    o3.wipe(osi)

    for item in od:
        od[item] = od[item].collect()
    od['col_shear'] = -od['col_forces'][:, 0]
    od['col_moment'] = od['col_forces'][:, 2]
    od['hinge_rotation'] = od['chord_rots'][:, 1]
    od['hinge_rotation1'] = -od['chord_rots'][:, 2]
    del od['col_forces']
    del od['chord_rots']

    return od
def run_analysis(asig, period, xi, f_yield, etype):
    # Load a ground motion

    # Define inelastic SDOF
    mass = 1.0

    r_post = 0.0

    # Initialise OpenSees instance
    osi = o3.OpenSeesInstance(ndm=2, state=0)

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

    # Fix bottom node
    o3.Fix3DOF(osi, top_node, o3.cc.FREE, o3.cc.FIXED, o3.cc.FIXED)
    o3.Fix3DOF(osi, bot_node, o3.cc.FIXED, o3.cc.FIXED, o3.cc.FIXED)
    # Set out-of-plane DOFs to be slaved
    o3.EqualDOF(osi, top_node, bot_node, [o3.cc.Y, o3.cc.ROTZ])

    # nodal mass (weight / g):
    o3.Mass(osi, top_node, mass, 0., 0.)

    # Define material
    k_spring = 4 * np.pi**2 * mass / period**2
    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

    # Define the dynamic analysis
    acc_series = o3.time_series.Path(osi, dt=asig.dt, values=-1 *
                                     asig.values)  # should be negative
    o3.pattern.UniformExcitation(osi, dir=o3.cc.X, accel_series=acc_series)

    # set damping based on first eigen mode
    angular_freqs = np.array(o3.get_eigen(osi, solver='fullGenLapack',
                                          n=1))**0.5
    beta_k = 2 * xi / angular_freqs[0]
    print('angular_freqs: ', angular_freqs)
    periods = 2 * np.pi / angular_freqs

    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
    o3.wipe_analysis(osi)

    # Run the dynamic analysis
    o3.constraints.Transformation(osi)
    o3.test_check.NormDispIncr(osi, tol=1.0e-6, max_iter=35, p_flag=0)
    o3.numberer.RCM(osi)
    if etype == 'implicit':
        o3.algorithm.Newton(osi)
        o3.system.SparseGeneral(osi)
        o3.integrator.Newmark(osi, gamma=0.5, beta=0.25)
        analysis_dt = 0.01
    else:
        o3.algorithm.Linear(osi, factor_once=True)
        o3.system.FullGeneral(osi)
        if etype == 'newmark_explicit':
            o3.integrator.NewmarkExplicit(osi, gamma=0.6)
            explicit_dt = periods[0] / np.pi / 32
        elif etype == 'central_difference':
            o3.integrator.CentralDifference(osi)
            o3.opy.integrator('HHTExplicit')
            explicit_dt = periods[0] / np.pi / 16  # 0.5 is a factor of safety
        elif etype == 'explicit_difference':
            o3.integrator.ExplicitDifference(osi)
            explicit_dt = periods[0] / np.pi / 32
        else:
            raise ValueError(etype)
        print('explicit_dt: ', explicit_dt)
        analysis_dt = explicit_dt
    o3.analysis.Transient(osi)

    analysis_time = asig.time[-1]

    outputs = {
        "time": [],
        "rel_disp": [],
        "rel_accel": [],
        "rel_vel": [],
        "force": []
    }

    while o3.get_time(osi) < analysis_time:
        o3.analyze(osi, 1, analysis_dt)
        curr_time = o3.get_time(osi)
        outputs["time"].append(curr_time)
        outputs["rel_disp"].append(o3.get_node_disp(osi, top_node, o3.cc.X))
        outputs["rel_vel"].append(o3.get_node_vel(osi, top_node, o3.cc.X))
        outputs["rel_accel"].append(o3.get_node_accel(osi, top_node, o3.cc.X))
        o3.gen_reactions(osi)
        outputs["force"].append(-o3.get_node_reaction(
            osi, bot_node, o3.cc.X))  # Negative since diff node
    o3.wipe(osi)
    for item in outputs:
        outputs[item] = np.array(outputs[item])
    return outputs
def run(out_folder):

    osi = o3.OpenSeesInstance(ndm=2, ndf=2, state=3)
    x_centre = 0.0
    y_centre = 0.0
    top_node = o3.node.Node(osi, x_centre, y_centre)
    fd_area = 1
    fd_e_mod = 1e9
    fd_iz = 1e6
    top_nodes = []
    bot_nodes = []
    sf_eles = []
    fd_eles = []

    o3.Mass(osi, top_node, 10, 10)

    fy = 500
    k = 1.0e4
    b = 0.1
    pro_params = [5, 0.925, 0.15]
    sf_mat = o3.uniaxial_material.SteelMPF(osi,
                                           fy,
                                           fy,
                                           k,
                                           b,
                                           b,
                                           params=pro_params)

    diff_pos = 0.5
    depth = 1
    bot_nodes.append(o3.node.Node(osi, x_centre - diff_pos, y_centre - depth))
    o3.Fix2DOF(osi, bot_nodes[0], o3.cc.FIXED, o3.cc.FIXED)
    bot_nodes.append(o3.node.Node(osi, x_centre + diff_pos, y_centre - depth))
    o3.Fix2DOF(osi, bot_nodes[1], o3.cc.FIXED, o3.cc.FIXED)

    top_nodes.append(o3.node.Node(osi, x_centre, y_centre))

    sf_eles.append(
        o3.element.Truss(osi, [top_nodes[0], bot_nodes[0]],
                         big_a=1.0,
                         mat=sf_mat))
    sf_eles.append(
        o3.element.Truss(osi, [top_nodes[0], bot_nodes[1]],
                         big_a=1.0,
                         mat=sf_mat))

    o3.EqualDOF(osi,
                top_node,
                top_nodes[0],
                dofs=[o3.cc.DOF2D_X, o3.cc.DOF2D_Y])

    ts0 = o3.time_series.Linear(osi, factor=1)
    o3.pattern.Plain(osi, ts0)
    o3.Load(osi, top_node, [100, -500])

    o3.constraints.Transformation(osi)
    o3.test_check.NormDispIncr(osi, tol=1.0e-6, max_iter=35, p_flag=0)
    o3.algorithm.Newton(osi)
    o3.numberer.RCM(osi)
    o3.system.FullGeneral(osi)
    n_steps_gravity = 15
    d_gravity = 1. / n_steps_gravity
    o3.integrator.LoadControl(osi, d_gravity, num_iter=10)
    # o3.rayleigh.Rayleigh(osi, a0, a1, 0.0, 0.0)
    o3.analysis.Static(osi)
    o3r = o3.results.Results2D(cache_path=out_folder, dynamic=True)
    o3r.pseudo_dt = 0.1
    o3r.start_recorders(osi, dt=0.1)
    nr = o3.recorder.NodeToArrayCache(osi, top_node,
                                      [o3.cc.DOF2D_X, o3.cc.DOF2D_Y], 'disp')
    er = o3.recorder.ElementToArrayCache(osi, sf_eles[0], arg_vals=['force'])
    for i in range(n_steps_gravity):
        o3.analyze(osi, num_inc=1)
    o3.load_constant(osi, time=0.0)
    import o3seespy.extensions
    o3.extensions.to_py_file(osi, 'ofile.py')
    print('init_disp: ', o3.get_node_disp(osi, top_node, o3.cc.DOF2D_Y))
    print('init_disp: ', o3.get_node_disp(osi, top_nodes[0], o3.cc.DOF2D_Y))
    print('init_disp: ', o3.get_node_disp(osi, top_nodes[-1], o3.cc.DOF2D_Y))
    o3.wipe(osi)
    o3r.save_to_cache()
    # o3r.coords = o3.get_all_node_coords(osi)
    # o3r.ele2node_tags = o3.get_all_ele_node_tags_as_dict(osi)
    data = nr.collect()
    edata = er.collect()
    # bf, sps = plt.subplots(nrows=2)
    # sps[0].plot(data[:, 0])
    # sps[0].plot(data[:, 1])
    # sps[1].plot(edata[:, 0])
    # # sps[0].plot(data[1])
    # plt.show()
    o3r.load_from_cache()
    o3plot.replot(o3r)
def run(show=0):
    # Load a ground motion
    record_filename = 'test_motion_dt0p01.txt'
    asig = eqsig.load_asig(ap.MODULE_DATA_PATH + 'gms/' + record_filename,
                           m=0.5)

    # Define inelastic SDOF
    period = 1.0
    xi = 0.05
    mass = 1.0
    f_yield = 1.5  # Reduce this to make it nonlinear
    r_post = 0.0

    # Initialise OpenSees instance
    osi = o3.OpenSeesInstance(ndm=2, state=0)

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

    # Fix bottom node
    o3.Fix3DOF(osi, top_node, o3.cc.FREE, o3.cc.FIXED, o3.cc.FIXED)
    o3.Fix3DOF(osi, bot_node, o3.cc.FIXED, o3.cc.FIXED, o3.cc.FIXED)
    # Set out-of-plane DOFs to be slaved
    o3.EqualDOF(osi, top_node, bot_node, [o3.cc.Y, o3.cc.ROTZ])

    # nodal mass (weight / g):
    o3.Mass(osi, top_node, mass, 0., 0.)

    # Define material
    k_spring = 4 * np.pi**2 * mass / period**2
    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

    # Define the dynamic analysis
    acc_series = o3.time_series.Path(osi, dt=asig.dt, values=-1 *
                                     asig.values)  # should be negative
    o3.pattern.UniformExcitation(osi, dir=o3.cc.X, accel_series=acc_series)

    # set damping based on first eigen mode
    angular_freq = o3.get_eigen(osi, solver='fullGenLapack', n=1)[0]**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
    o3.wipe_analysis(osi)

    # Run the dynamic analysis
    o3.algorithm.Newton(osi)
    o3.system.SparseGeneral(osi)
    o3.numberer.RCM(osi)
    o3.constraints.Transformation(osi)
    o3.integrator.Newmark(osi, gamma=0.5, beta=0.25)
    o3.analysis.Transient(osi)

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

    while o3.get_time(osi) < analysis_time:
        o3.analyze(osi, 1, analysis_dt)
        curr_time = o3.get_time(osi)
        outputs["time"].append(curr_time)
        outputs["rel_disp"].append(o3.get_node_disp(osi, top_node, o3.cc.X))
        outputs["rel_vel"].append(o3.get_node_vel(osi, top_node, o3.cc.X))
        outputs["rel_accel"].append(o3.get_node_accel(osi, top_node, o3.cc.X))
        o3.gen_reactions(osi)
        outputs["force"].append(-o3.get_node_reaction(
            osi, bot_node, o3.cc.X))  # Negative since diff node
    o3.wipe(osi)
    for item in outputs:
        outputs[item] = np.array(outputs[item])

    if show:
        import matplotlib.pyplot as plt
        plt.plot(outputs['time'], outputs['rel_disp'], label='o3seespy')
        periods = np.array([period])

        # Compare closed form elastic solution
        from eqsig import sdof
        resp_u, resp_v, resp_a = sdof.response_series(motion=asig.values,
                                                      dt=asig.dt,
                                                      periods=periods,
                                                      xi=xi)
        plt.plot(asig.time, resp_u[0], ls='--', label='Elastic')
        plt.legend()
        plt.show()
Пример #7
0
def get_elastic_response(mass, k_spring, 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 motion: array_like,
        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, state=3)

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

    # Fix bottom node
    o3.Fix3DOF(osi, top_node, o3.cc.FREE, o3.cc.FIXED, o3.cc.FREE)
    o3.Fix3DOF(osi, bot_node, o3.cc.FIXED, o3.cc.FIXED, o3.cc.FIXED)
    # Set out-of-plane DOFs to be slaved
    o3.EqualDOF(osi, top_node, bot_node, [o3.cc.Y])

    # nodal mass (weight / g):
    o3.Mass(osi, top_node, mass, 0., 0.)

    # Define material
    transf = o3.geom_transf.Linear2D(osi, [])
    area = 1.0
    e_mod = 1.0e6
    iz = k_spring * height ** 3 / (3 * e_mod)
    ele_nodes = [bot_node, top_node]

    ele = o3.element.ElasticBeamColumn2D(osi, ele_nodes, area=area, e_mod=e_mod, iz=iz, transf=transf)
    # Define the dynamic analysis
    acc_series = o3.time_series.Path(osi, dt=dt, values=-motion)  # should be negative
    o3.pattern.UniformExcitation(osi, dir=o3.cc.X, accel_series=acc_series)

    # set damping based on first eigen mode
    angular_freq = o3.get_eigen(osi, solver='fullGenLapack', n=1)[0] ** 0.5
    response_period = 2 * np.pi / angular_freq
    print('response_period: ', response_period)
    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

    o3.wipe_analysis(osi)

    o3.algorithm.Newton(osi)
    o3.system.SparseGeneral(osi)
    o3.numberer.RCM(osi)
    o3.constraints.Transformation(osi)
    o3.integrator.Newmark(osi, 0.5, 0.25)
    o3.analysis.Transient(osi)
    o3.extensions.to_py_file(osi, 'simple.py')

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

    while o3.get_time(osi) < analysis_time:

        o3.analyze(osi, 1, analysis_dt)
        curr_time = o3.get_time(osi)
        outputs["time"].append(curr_time)
        outputs["rel_disp"].append(o3.get_node_disp(osi, top_node, o3.cc.X))
        outputs["rel_vel"].append(o3.get_node_vel(osi, top_node, o3.cc.X))
        outputs["rel_accel"].append(o3.get_node_accel(osi, top_node, o3.cc.X))
        o3.gen_reactions(osi)
        outputs["force"].append(o3.get_ele_response(osi, ele, 'force'))
    o3.wipe(osi)
    for item in outputs:
        outputs[item] = np.array(outputs[item])

    return outputs
Пример #8
0
def get_response(bd, asig, l_ph):
    """
    Compute the response of a nonlinear lollipop on a foundation with linear/nonlinear soil
    Units are N, m, s

    :param bd:
        SDOF building object
    :param asig:
        Acceleration signal object
    :return:
    """
    osi = o3.OpenSeesInstance(ndm=2, state=3)

    # Establish nodes
    top_ss_node = o3.node.Node(osi, 0, bd.h_eff)
    bot_ss_node = o3.node.Node(osi, 0, 0)

    # Fix bottom node
    o3.Fix3DOF(osi, bot_ss_node, o3.cc.FIXED, o3.cc.FIXED, o3.cc.FIXED)

    # nodal mass (weight / g):
    o3.Mass(osi, top_ss_node, bd.mass_eff, 0.0, 0)

    # Define a column element with a plastic hinge at base
    transf = o3.geom_transf.Linear2D(osi, [])  # can change for P-delta effects
    area = 1.0
    e_mod = 200.0e9
    iz = bd.k_eff * bd.h_eff**3 / (3 * e_mod)
    ele_nodes = [bot_ss_node, top_ss_node]

    # Superstructure element
    elastic_sect = o3.section.Elastic2D(osi, e_mod, area, iz)
    integ = o3.beam_integration.HingeMidpoint(osi, elastic_sect, l_ph,
                                              elastic_sect, l_ph, elastic_sect)
    vert_ele = o3.element.ForceBeamColumn(osi, ele_nodes, transf, integ)

    omega = 2 * np.pi / bd.t_fixed

    beta_k = 2 * bd.xi / omega
    o3.rayleigh.Rayleigh(osi, 0, 0, beta_k_init=beta_k, beta_k_comm=0.0)

    # Define the input motion for the dynamic analysis
    acc_series = o3.time_series.Path(osi, dt=asig.dt,
                                     values=-asig.values)  # should be negative
    o3.pattern.UniformExcitation(osi, dir=o3.cc.X, accel_series=acc_series)
    print('loaded gm')
    o3.wipe_analysis(osi)

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

    o3.test_check.NormDispIncr(osi, tol=1.0e-6, max_iter=10)
    analysis_time = asig.time[-1]
    analysis_dt = 0.001

    # define outputs of analysis
    od = {
        "time":
        o3.recorder.TimeToArrayCache(osi),
        "rel_deck_disp":
        o3.recorder.NodeToArrayCache(osi, top_ss_node, [o3.cc.DOF2D_X],
                                     'disp'),
        "deck_accel":
        o3.recorder.NodeToArrayCache(osi, top_ss_node, [o3.cc.DOF2D_X],
                                     'accel'),
        "deck_rot":
        o3.recorder.NodeToArrayCache(osi, top_ss_node, [o3.cc.DOF2D_ROTZ],
                                     'disp'),
        "chord_rots":
        o3.recorder.ElementToArrayCache(osi,
                                        vert_ele,
                                        arg_vals=['chordRotation']),
        "col_forces":
        o3.recorder.ElementToArrayCache(osi, vert_ele, arg_vals=['force']),
    }

    o3.analyze(osi, int(analysis_time / analysis_dt), analysis_dt)

    o3.wipe(osi)

    for item in od:
        od[item] = od[item].collect()
    od['col_shear'] = -od['col_forces'][:, 0]
    od['col_moment'] = od['col_forces'][:, 2]
    od['hinge_rotation'] = od['chord_rots'][:, 1]
    od['hinge_rotation1'] = -od['chord_rots'][:, 2]
    del od['col_forces']
    del od['chord_rots']

    return od
def gen_response(period, xi, asig, etype, fos_for_dt=None):

    # Define inelastic SDOF
    mass = 1.0
    f_yield = 1.5  # Reduce this to make it nonlinear
    r_post = 0.0

    # Initialise OpenSees instance
    osi = o3.OpenSeesInstance(ndm=2, state=0)

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

    # Fix bottom node
    o3.Fix3DOF(osi, top_node, o3.cc.FREE, o3.cc.FIXED, o3.cc.FIXED)
    o3.Fix3DOF(osi, bot_node, o3.cc.FIXED, o3.cc.FIXED, o3.cc.FIXED)
    # Set out-of-plane DOFs to be slaved
    o3.EqualDOF(osi, top_node, bot_node, [o3.cc.Y, o3.cc.ROTZ])

    # nodal mass (weight / g):
    o3.Mass(osi, top_node, mass, 0., 0.)

    # Define material
    k_spring = 4 * np.pi**2 * mass / period**2
    # bilinear_mat = o3.uniaxial_material.Steel01(osi, fy=f_yield, e0=k_spring, b=r_post)
    mat = o3.uniaxial_material.Elastic(osi, e_mod=k_spring)

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

    # Define the dynamic analysis

    # Define the dynamic analysis
    acc_series = o3.time_series.Path(osi, dt=asig.dt, values=-1 *
                                     asig.values)  # should be negative
    o3.pattern.UniformExcitation(osi, dir=o3.cc.X, accel_series=acc_series)

    # set damping based on first eigen mode
    angular_freq = o3.get_eigen(osi, solver='fullGenLapack', n=1)[0]**0.5
    period = 2 * np.pi / angular_freq
    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)

    o3.set_time(osi, 0.0)
    # Run the dynamic analysis
    o3.wipe_analysis(osi)

    # Run the dynamic analysis
    o3.numberer.RCM(osi)
    o3.system.FullGeneral(osi)
    if etype == 'central_difference':
        o3.algorithm.Linear(osi, factor_once=True)
        o3.integrator.CentralDifference(osi)
        explicit_dt = 2 / angular_freq / fos_for_dt
        analysis_dt = explicit_dt
    elif etype == 'implicit':
        o3.algorithm.Newton(osi)
        o3.integrator.Newmark(osi, gamma=0.5, beta=0.25)
        analysis_dt = 0.001
    else:
        raise ValueError()
    o3.constraints.Transformation(osi)
    o3.analysis.Transient(osi)

    o3.test_check.EnergyIncr(osi, tol=1.0e-10, max_iter=10)
    analysis_time = asig.time[-1]

    outputs = {
        "time": [],
        "rel_disp": [],
        "rel_accel": [],
        "rel_vel": [],
        "force": []
    }
    rec_dt = 0.002
    n_incs = int(analysis_dt / rec_dt)
    n_incs = 1
    while o3.get_time(osi) < analysis_time:
        o3.analyze(osi, n_incs, analysis_dt)
        curr_time = o3.get_time(osi)
        outputs["time"].append(curr_time)
        outputs["rel_disp"].append(o3.get_node_disp(osi, top_node, o3.cc.X))
        outputs["rel_vel"].append(o3.get_node_vel(osi, top_node, o3.cc.X))
        outputs["rel_accel"].append(o3.get_node_accel(osi, top_node, o3.cc.X))
        o3.gen_reactions(osi)
        outputs["force"].append(-o3.get_node_reaction(
            osi, bot_node, o3.cc.X))  # Negative since diff node
    o3.wipe(osi)
    for item in outputs:
        outputs[item] = np.array(outputs[item])
    return outputs