def RunPushoverAnalysis(Px,Py):


    # create TimeSeries
    op.timeSeries("Linear", 1)
    
    # create a plain load pattern
    op.pattern("Plain", 1, 1)
    
    # Create the nodal load - command: load nodeID xForce yForce
    op.load(4, Px, Py, 0.)
    
    # create SOE
    op.system("BandSPD")
    # create DOF number
    op.numberer("RCM")
    # create constraint handler
    op.constraints("Plain")
    
    # create integrator
    op.integrator("LoadControl", 1.0)
    
    # create algorithm
    op.algorithm("Newton")
    
    # create analysis object
    op.analysis("Static")
    
    # perform the analysis
    op.initialize() 
    
    
    ok = op.analyze(1)
Пример #2
0
def analysis(P, du, steps, tol, max_iter):

    tsTag = 1
    ops.timeSeries('Linear', tsTag)

    pattTag = 1
    ops.pattern('Plain', pattTag, tsTag)

    ops.load(2, *P)

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

    ops.constraints('Plain')
    ops.numberer('RCM')
    ops.system('BandGeneral')
    ops.test('NormUnbalance', tol, max_iter)
    ops.algorithm('Newton')

    ops.integrator('DisplacementControl', 2, 2, du, max_iter)

    ops.analysis('Static')

    ops.analyze(steps)

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

    opsplt.plot_model()

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

    ops.wipe()
Пример #3
0
def PDelta_analysis(Nnodes, P, steps, tol, max_iter):

    tsTag = 1
    ops.timeSeries('Linear', tsTag)

    pattTag = 1
    ops.pattern('Plain', pattTag, tsTag)

    ops.load(Nnodes, *P)

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

    ops.constraints('Plain')
    ops.numberer('RCM')
    ops.system('BandGeneral')
    ops.test('NormUnbalance', tol, max_iter)
    ops.algorithm('Newton')

    temp = 1 / steps
    ops.integrator('LoadControl', temp)

    ops.analysis('Static')

    ops.analyze(steps)

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

    opsplt.plot_model('nodes')

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

    ops.wipe()
Пример #4
0
def PointLoad_analysis(Nnodes, P, tol, max_iter):

    tsTag = 10
    ops.timeSeries('Linear', tsTag)

    pattTag = 10
    ops.pattern('Plain', pattTag, tsTag)

    ops.load(Nnodes, *P)

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

    ops.constraints('Plain')
    ops.numberer('RCM')
    ops.system('BandGeneral')
    ops.test('NormUnbalance', tol, max_iter)
    ops.algorithm('Newton')

    ops.integrator('LoadControl', 1)

    ops.analysis('Static')

    ops.analyze(1)

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

    ops.wipe()
Пример #5
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
Пример #6
0
 def buildLinearAnalysis(gamma, beta):
     # do analysis
     ops.constraints('Plain')
     ops.numberer('Plain')
     ops.algorithm('Linear')
     ops.integrator('Newmark', gamma, beta)
     ops.system('ProfileSPD')
     ops.analysis('Transient')
Пример #7
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
Пример #8
0
def analysis_plain():
    ''' analysis create
    '''
    ops.constraints('Plain')
    ops.numberer('Plain')
    ops.system('BandGeneral')
    ops.test('EnergyIncr', 1.0e-6, 200)
    ops.algorithm('KrylovNewton')
    ops.integrator('DisplacementControl', 5, 3, -0.1)
    ops.analysis('Static')
    ops.analyze(100)
    logger.info("analysis created")
Пример #9
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 #")
Пример #10
0
def analysis_rigid():
    ''' for rigid
    '''
    ops.constraints('Lagrange')
    ops.numberer('Plain')
    ops.system('BandGeneral')
    ops.test('EnergyIncr', 1.0e-6, 200)
    ops.algorithm('Newton')
    ops.integrator('LoadControl', 1e-2)
    ops.analysis('Static')
    ops.analyze(100)
    logger.info("analysis created")
Пример #11
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
def run_gravity_analysis(steps=10):
    """
    Run gravity analysis (in 10 steps)
    """
    ops.wipeAnalysis()
    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.analyze(steps)
    title("Gravity Analysis Completed!")
    # Set the gravity loads to be constant & reset the time in the domain
    ops.loadConst("-time", 0.0)
    ops.wipeAnalysis()
Пример #13
0
def analysis_plain_load(test_tol=1.0e-12, test_iter=1000, incr=0.1, num_incr=11):
    ''' @analysis create in load control
        @default parameter:
            test_tol=1.0e-6, test_iter=1000,
            incr=0.1, num_incr=101
    '''
    logger.info("test_tol = %f, test_iter = %f, incr = %f, num_incr = %f",
                test_tol, test_iter, incr, num_incr)
    ops.constraints('Plain')
    ops.numberer('Plain')
    ops.system('BandGeneral')
    ops.test('EnergyIncr', test_tol, test_iter,)
    ops.algorithm('KrylovNewton')
    ops.integrator('LoadControl', incr)
    ops.analysis('Static')
    ops.analyze(num_incr)
    logger.info("load control analysis created")
Пример #14
0
def analysis_plain_disp(test_tol=1.0e-3, test_iter=1000, nodeTag=0, dof=1, disp_incr=1, num_incr=10):
    ''' @analysis create in displacement control\n
        @default parameter:
            test_tol=1.0e-3, test_iter=1000,
            nodeTag=0, dof=1, disp_incr=1, num_incr=10
    '''
    logger.info("test_tol = %f, test_iter = %f, nodeTag = %d, dof = %d, disp_incr = %f, num_incr = %f",
                test_tol, test_iter, nodeTag, dof, disp_incr, num_incr)
    ops.constraints('Plain')
    ops.numberer('Plain')
    ops.system('BandGeneral')
    ops.test('EnergyIncr', test_tol, test_iter)
    ops.algorithm('KrylovNewton')
    ops.integrator('DisplacementControl', nodeTag, dof, disp_incr)
    ops.analysis('Static')
    ops.analyze(num_incr)
    logger.info("displacemen control analysis created")
Пример #15
0
def MomentCurvature(secTag, axialLoad, maxK, numIncr=100):

    # Define two nodes at (0,0)
    ops.node(1, 0.0, 0.0)
    ops.node(2, 0.0, 0.0)

    # Fix all degrees of freedom except axial and bending
    ops.fix(1, 1, 1, 1)
    ops.fix(2, 0, 1, 0)

    # Define element
    #                             tag ndI ndJ  secTag
    ops.element('zeroLengthSection', 1, 1, 2, secTag)

    # Define constant axial load
    ops.timeSeries('Constant', 1)
    ops.pattern('Plain', 1, 1)
    ops.load(2, axialLoad, 0.0, 0.0)

    # Define analysis parameters
    ops.integrator('LoadControl', 0.0)
    ops.system('SparseGeneral', '-piv')
    ops.test('NormUnbalance', 1e-9, 10)
    ops.numberer('Plain')
    ops.constraints('Plain')
    ops.algorithm('Newton')
    ops.analysis('Static')

    # Do one analysis for constant axial load
    ops.analyze(1)

    # Define reference moment
    ops.timeSeries('Linear', 2)
    ops.pattern('Plain', 2, 2)
    ops.load(2, 0.0, 0.0, 1.0)

    # Compute curvature increment
    dK = maxK / numIncr

    # Use displacement control at node 2 for section analysis
    ops.integrator('DisplacementControl', 2, 3, dK, 1, dK, dK)

    # Do the section analysis
    ops.analyze(numIncr)
Пример #16
0
def ops_gravity():
    ops.recorder('Node', '-file', 'output\\gravity_disp.out',
                 '-nodeRange', 651, 663,  '-time', '-dof',  3, 'disp')
    ops.recorder('Node', '-file', 'output\\gravity_reaction.out',
                 '-nodeRange', 651, 663,  '-time', '-dof',  3, 'reaction')
    ops.timeSeries('Linear', 1)
    ops.pattern('Plain', 1, 1)
    load: float = [0, 0, (gravity_load + dead_load) / 13, 0, 0, 0]
    for i in range(651, 664):
        ops.load(i, *load)
    ops.constraints('Plain')
    ops.numberer('Plain')
    ops.system('BandGen')
    ops.test('NormDispIncr', 1.0, 1000)
    ops.algorithm('Newton')
    ops.integrator('LoadControl', 0.01)
    ops.analysis('Static')
    ok = ops.analyze(100)
    logger.info("gravity analyze result is %s", ok == 0)
def PushoverDcF(Nsteps):
    
    ControlNode = 4
    ControlNodeDof = 1
    dForce = 1.*kN
    du = 0.00001*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.load(ControlNode, dForce, 0., 0.)
    
    
    # Define Analysis Options
    # create SOE
    op.system("BandGeneral")
    # create DOF number
    op.numberer("Plain")
    # create constraint handler
    op.constraints("Transformation")
    # create integrator
    op.integrator("DisplacementControl", ControlNode, ControlNodeDof, du)
    # create algorithm
    op.algorithm("Newton")
    # create analysis object
    op.analysis("Static")

    # Create Test
    op.test('NormDispIncr', 1.*10**-11, 50)
    
    # Run Analysis
    
    op.record()
    
    ok = op.analyze(Nsteps)
    def analyse(self, num_incr):
        '''
        Analyse the system.
        
        Args:
            num_incr: An integer number of load increments.
            return_node_disp: 
        '''

        ops.constraints('Transformation')
        ops.numberer('RCM')
        ops.system('BandGeneral')
        ops.test('NormUnbalance', 2e-8, num_incr)
        ops.algorithm('Newton')
        ops.integrator('LoadControl', 1 / num_incr)
        ops.record()

        ops.analysis('Static')
        ok = ops.analyze(num_incr)

        # Report analysis status
        if ok == 0: print("Analysis done.")
        else: print("Convergence issue.")
Пример #19
0
    def __init__(self):
        # AIが取れるアクションの設定
        self.action = np.array([
            0, 0.02, 0.03, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1
        ])
        self.naction = len(self.action)

        self.beta = 1 / 4

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

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

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

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

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

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

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

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

        # Define the dynamic analysis
        load_tag_dynamic = 1
        pattern_tag_dynamic = 1

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

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

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

        # Run the dynamic analysis

        op.wipeAnalysis()

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

        tol = 1.0e-10
        iterations = 10
        op.test('EnergyIncr', tol, iterations, 0, 2)
        self.i_pre = 0
        self.i = 0
        self.i_next = 0
        self.time = 0
        self.analysis_time = (len(self.values) - 1) * self.dt
        self.dis = 0
        self.vel = 0
        self.acc = 0
        self.a_acc = 0
        self.force = 0
        self.resp = {
            "time": [],
            "dis": [],
            "acc": [],
            "a_acc": [],
            "vel": [],
            "force": [],
        }
        self.done = False
Пример #20
0
WzBeam = Weight / LBeam
op.timeSeries('Linear', 1)
op.pattern('Plain', 1, 1)
op.eleLoad('-ele', 3, '-type', '-beamUniform', -WzBeam, 0.0, 0.0)

#op.load(2, 0.0, -PCol, 0.0)

Tol = 1e-8  # convergence tolerance for test
NstepGravity = 10
DGravity = 1 / NstepGravity
op.integrator('LoadControl',
              DGravity)  # determine the next time step for an analysis
op.numberer(
    'Plain'
)  # renumber dof's to minimize band-width (optimization), if you want to
op.system('BandGeneral'
          )  # how to store and solve the system of equations in the analysis
op.constraints('Plain')  # how it handles boundary conditions
op.test(
    'NormDispIncr', Tol, 6
)  # determine if convergence has been achieved at the end of an iteration step
op.algorithm(
    'Newton'
)  # use Newton's solution algorithm: updates tangent stiffness at every iteration
op.analysis('Static')  # define type of analysis static or transient
op.analyze(NstepGravity)  # apply gravity

op.loadConst('-time',
             0.0)  #maintain constant gravity loads and reset time to zero
print('Model Built')
Пример #21
0
def get_inelastic_response(fb, asig, extra_time=0.0, xi=0.05, analysis_dt=0.001):
    """
    Run seismic analysis of a nonlinear FrameBuilding

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

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

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

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

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

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

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

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

    l_hinge = fb.bay_lengths[0] * 0.1

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

    # Define beams and columns

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

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

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

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

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

    # Define the dynamic analysis
    load_tag_dynamic = 1
    pattern_tag_dynamic = 1

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

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

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

    # Run the dynamic analysis

    op.wipeAnalysis()

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

    return outputs
Пример #22
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
Пример #23
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]))
Пример #24
0
def ModalAnalysis3D(numEigen):
    """
    |-----------------------------------------------------------------------|
    |                                                                       |
    |    Modal Analysis of 3D systems                                       |
    |                                                                       |
    |    Author: Volkan Ozsarac                                             |
    |    Affiliation: University School for Advanced Studies IUSS Pavia     |
    |    Earthquake Engineering PhD Candidate                               |
    |                                                                       |
    |-----------------------------------------------------------------------|
    """
    import numpy as np
    import openseespy.opensees as op
    import time
    import sys

    print('Extracting the mass matrix, ignore the following warnings...\n')
    op.wipeAnalysis()
    op.system('FullGeneral')
    op.analysis('Transient')

    # Extract the Mass Matrix
    op.integrator('GimmeMCK',1.0,0.0,0.0)
    op.analyze(1,0.0) 
    time.sleep(0.5) 
    # Number of equations in the model
    N = op.systemSize() # Has to be done after analyze
    Mmatrix = op.printA('-ret') # Or use op.printA('-file','M.out')
    Mmatrix = np.array(Mmatrix) # Convert the list to an array
    Mmatrix.shape = (N,N) # Make the array an NxN matrix
    print('\nExtracted the mass matrix, ignore the previous warnings...')

    # Rerrange the mass matrix in accordance with nodelist order from getNodeTags()
    DOFs = [] # These are the idx of all the DOFs used in the extract mass matrix, order is rearranged
    used = {} # Save here the nodes and their associated dofs used in global mass matrix
    lx = np.zeros([N,1]) # influence vector (x)
    ly = np.zeros([N,1]) # influence vector (y)
    lz = np.zeros([N,1]) # influence vector (z)
    lrx = np.zeros([N,1]) # influence vector (rx)
    lry = np.zeros([N,1]) # influence vector (ry)
    lrz = np.zeros([N,1]) # influence vector (rz)

    idx = 0 # index
    NDF = 6 # NDF is number of DOFs/node
    for node in op.getNodeTags():
        used[node] = []
        for j in range(NDF): 
            temp = op.nodeDOFs(node)[j]
            if temp not in DOFs and temp >=0:
                DOFs.append(op.nodeDOFs(node)[j])
                used[node].append(j+1)
                if j == 0: lx[idx,0] = 1
                if j == 1: ly[idx,0] = 1
                if j == 2: lz[idx,0] = 1
                if j == 3: lrx[idx,0] = 1
                if j == 4: lry[idx,0] = 1
                if j == 5: lrz[idx,0] = 1
                idx += 1

    Mmatrix = Mmatrix[DOFs,:][:,DOFs] 

    op.wipeAnalysis()
    listSolvers = ['-genBandArpack','-fullGenLapack','-symmBandLapack']
    ok = 1  

    for s in listSolvers:
        print("Using %s as solver..." % s[1:])
        try:
            eigenValues = op.eigen(s,numEigen)
            catchOK = 0
            ok = 0
        except: 
            catchOK = 1

        if catchOK==0:
            for i in range(numEigen):
                if eigenValues[i] < 0: ok = 1
            if ok==0: 
                print('Eigenvalue analysis is completed.')
                break

    if ok!=0:
        print("Error on Modal Analysis...")
        sys.exit()
    else:  
        Lamda = np.asarray(eigenValues)
        Omega = Lamda**0.5
        T = 2*np.pi/Omega
        f = 1/T

    print('Modal properties for the first %d modes:' % numEigen)
    Mx = []; My = []; Mz = []; Mrx = []; Mry = []; Mrz = []
    dofs = ['x','y','z','rx','ry','rz']
    print('Mode| T [sec] | f [Hz] | \u03C9 [rad/sec] | Mx [%] | My [%] | Mz [%] | \u2211Mx [%] | \u2211My [%] | \u2211Mz [%]')

    for mode in range(1,numEigen+1): # Although Mrx, Mry and Mrz are calculated, I am not printing these
        idx = 0
        phi = np.zeros([N,1])
        for node in used:
            for dof in used[node]:
                phi[idx,0]=op.nodeEigenvector(node,mode,dof)
                idx += 1
        
        for dof in dofs:
            l = eval('l'+dof)
            Mtot = l.T@Mmatrix@l   # Total mass in specified global dof
            Mn = phi.T@Mmatrix@phi # Modal mass in specified global dof
            Ln = phi.T@Mmatrix@l   # Effective modal mass in specified global dof
            Mnstar = Ln**2/Mn/Mtot*100 # Normalised effective modal mass participating [%], in specified global dof
            eval('M'+dof).append(Mnstar[0,0]) # Save the modal mass for the specified dof
        
        print('%3s |%7s  |%6s  |%9s    |%6s  |%6s  |%6s  |%7s  |%7s  |%7s' \
              % ("{:.0f}".format(mode), "{:.3f}".format(T[mode-1]), "{:.3f}".format(f[mode-1]), "{:.2f}".format(Omega[mode-1]), \
                  "{:.2f}".format(Mx[mode-1]), "{:.2f}".format(My[mode-1]), "{:.2f}".format(Mz[mode-1]), \
                  "{:.2f}".format(sum(Mx)), "{:.2f}".format(sum(My)), "{:.2f}".format(sum(Mz))))

    Mtot = lx.T@Mmatrix@lx; Mtot = Mtot[0,0]
def NSProcedure(ndm, ndf, NbaysX, NbaysZ, NStr, XbayL, ZbayL, StoryH, lon, lat,
                SHL, Vso, gamma_soil, nu_soil, Re, fpc, Ec, gamma_conc, fy, E0,
                bsteel, ColTransfType, BeamEffFact, ColEffFact, g, Qsd, Ql,
                Qlr, EMs, R, Ie, StrType, BldTypCo, BldTypCm, DsgnType, dirs,
                directory):

    # The Nonlinear Static Procdure is executed in order to get responses
    # of a defined building.

    import openseespy.opensees as ops
    import OPSDefsMOD as OPSDMOD
    import OPSDefsAN as OPSDAN
    from timeit import default_timer as timer
    import ASCE716Seismic as ASCE716
    import ASCE4117
    import matplotlib.pyplot as plt
    import pickle
    import numpy as np

    for mm in range(len(NbaysX)):
        for nn in range(len(NStr)):
            for oo in range(len(Vso)):

                Teff = np.zeros(
                    (len(dirs)
                     ))  # [s][LIST] effective lateral period of building.

                for ii in range(len(dirs)):

                    time_o = timer()

                    # Some previous definitions
                    # ----------------------------
                    if DsgnType in ('conv_dsgn'):
                        flex = 'no'
                    elif DsgnType in ('ssi_dsgn'):
                        flex = 'yes'

                    # SiteClass = ASCE716.detSiteClass(Vso[oo])

                    # Unpicklin' some stored parameters from design process.
                    # ------------------------------------------------------
                    workpath = directory + '\\RegularDesign\\' + str(NbaysX[mm])+'BayX'+str(NbaysZ)+\
                        'BayZ'+str(NStr[nn])+'FLRS'+str(Vso[oo])+'.pickle'

                    with open(workpath, 'rb') as f:
                        ColDims, Colreinf, XBDims, XBreinf, ZBDims, ZBreinf, _, _, _, _, _, _, _, _, _, _ = pickle.load(
                            f)

                    # Calculation of height vector
                    # ------------------------------
                    if flex in ('Y', 'YES', 'Yes', 'yES', 'yes', 'y'):
                        # [m][LIST] with level height starting from first level or from base if foundation flexibility is included.
                        hx = [0.0001]
                    else:
                        hx = []

                    for i in range(NStr[nn]):
                        hx.append((i + 1) * StoryH)

                    # Plan Dimensions of Building
                    B = NbaysZ * ZbayL  # [m] short side of building plan.
                    L = NbaysX[mm] * XbayL  # [m] long side of building plan.

                    # Determination of MCEr spectral acceleration parameters
                    # ------------------------------------------------------
                    (Sxs, Sx1) = ASCE4117.detSxi(lon, lat, Vso[oo], SHL)

                    # MODELING OF THE STRUCTURE USING OPENSEESPY
                    # ===========================================
                    ops.wipe()
                    OPSDMOD.ModelGen(ndm, ndf)
                    OPSDMOD.NodeGen(NbaysX[mm], NbaysZ, XbayL, ZbayL, StoryH,
                                    NStr[nn], flex)
                    OPSDMOD.MastNodeGen(NbaysX[mm],
                                        NbaysZ,
                                        XbayL,
                                        ZbayL,
                                        StoryH,
                                        NStr[nn],
                                        flex,
                                        coords=0)
                    OPSDMOD.SPConstGen(NbaysX[mm], NbaysZ, flex)
                    OPSDMOD.MPConstGen(NbaysX[mm], NbaysZ, NStr[nn], flex)
                    OPSDMOD.MatGenRCB(fpc, Ec, fy, E0, bsteel)
                    # OPSDMOD.GeomTransGen(ColTransfType,XBD=[min(XBDims[:,0]),min(XBDims[:,1])],\
                    #                      ZBD=[min(ZBDims[:,0]),min(ZBDims[:,1])],\
                    #                          ColD=[min(ColDims[:,0]),min(ColDims[:,1])])
                    OPSDMOD.GeomTransGen(
                        ColTransfType,
                        ColD=[min(ColDims[:, 0]),
                              min(ColDims[:, 1])])
                    # OPSDMOD.GeomTransGen(ColTransfType)

                    if flex in ('Y', 'YES', 'Yes', 'yES', 'yes', 'y'):
                        # Interface elements generation for foundation flexibility considerations.
                        # =========================================================================
                        # Materials generation: stiffness constants accounting for soil flexibility.
                        # ---------------------------------------------------------------------------
                        OPSDMOD.FoundFlexMaterials(NbaysX[mm],NbaysZ,XbayL,ZbayL,Sxs,Vso[oo],gamma_soil,nu_soil,B,L,Re,\
                                                   D=0,omega_soil=0,analtype='lat')
                        # Zero-Length elements creation for connecting base nodes.
                        OPSDMOD.FoundFlexZLElements(NbaysX[mm], NbaysZ, XbayL,
                                                    ZbayL, B, L, Re)

                    OPSDMOD.ElementGen(NbaysX[mm],NbaysZ,XbayL,ZbayL,NStr[nn],StoryH,XBDims,ZBDims,\
                                               ColDims,BeamEffFact,ColEffFact,Ec,fy,EMs,\
                                                   XBreinf,ZBreinf,Colreinf,N=5,rec=0.0654,nuconc=0.2,dbar=0.025)
                    [Wx,MassInputMatr] = \
                        OPSDMOD.LumpedMassGen(NbaysX[mm],NbaysZ,XBDims,ZBDims,ColDims,gamma_conc,g,XbayL,ZbayL,NStr[nn],StoryH,Qsd,flex)
                    W = sum(Wx)  # [kN] total weight of the building

                    # GRAVITY LOADS APPLIED TO MODEL ACCORDINGO TO ASCE4117
                    # ======================================================
                    # According to ASCE4117 Section 7.2.2, equation (7-3), the combination
                    # of gravitational loads mus be as follows:
                    #       Qg = Qd + 0.25*Ql + Qs      (7-3)
                    OPSDMOD.DeadLoadGen(NbaysX[mm], NbaysZ, NStr[nn], XBDims,
                                        ZBDims, ColDims, gamma_conc)
                    OPSDMOD.SuperDeadLoadGen(NbaysX[mm], NbaysZ, NStr[nn],
                                             XbayL, ZbayL, Qsd)
                    OPSDMOD.LiveLoadGen(NbaysX[mm], NbaysZ, NStr[nn], XbayL,
                                        ZbayL, 0.25 * Ql, 0.25 * Qlr)

                    # GRAVITY-LOADS-CASE ANALYSIS.
                    # ============================
                    ops.system('ProfileSPD')
                    ops.constraints('Transformation')
                    ops.numberer('RCM')
                    ops.test('NormDispIncr', 1.0e-4, 100)
                    ops.algorithm('KrylovNewton')
                    ops.integrator('LoadControl', 1)
                    ops.analysis('Static')
                    ops.analyze(1)
                    # Vertical reactions Calculation for verification.
                    # ------------------------------------------------
                    ops.reactions()
                    YReact = 0
                    for i in range((NbaysX[mm] + 1) * (NbaysZ + 1)):
                        if flex in ('Y', 'YES', 'Yes', 'yES', 'yes', 'y'):
                            YReact += ops.nodeReaction(int(i + 1), 2)
                        else:
                            YReact += ops.nodeReaction(int(i + 1 + 1e4), 2)

                    # ==========================================================================
                    # MODAL ANALYSIS FOR DETERMINING FUNDAMENTAL PERIOD AND ITS DIRECTION.
                    # ==========================================================================
                    (T, Tmaxver,
                     Mast) = OPSDAN.ModalAnalysis(NStr[nn], B, L, Wx, flex)
                    print(T)
                    # ==================
                    # PUSHOVER ANALYSIS
                    # ==================
                    # Lateral Force used for analysis
                    # --------------------------------
                    # Using functions from ASCE716Seismic Module.
                    (_,_,_,_,_,_,_,_,_,_,_,FxF,_,_,_) = \
                        ASCE716.ELFP(Sxs,Sx1,Vso[oo],Wx,R,Ie,hx,StrType,T[0,ii])

                    # Aplication of forces to the model.
                    # ----------------------------------
                    ops.loadConst('-time', 0.0)
                    MdeShape = OPSDMOD.POForceGen(NStr[nn], FxF, dirs[ii],
                                                  flex)

                    # =============================================
                    # First Execution of the analysis and output results.
                    # =============================================
                    (results1,dtg1,tgfactor1) = \
                        OPSDAN.POAnalysisProc(lon,lat,Vso[oo],SHL,NbaysX[mm],NbaysZ,\
                                              NStr[nn],StoryH,R,Ie,BldTypCo,BldTypCm,\
                                                  T[0,ii],W,dirs[ii],flex,\
                                                      DispIncr=0,beta=0.05,TL=8.,Tf=6.0,Npts=500,Vy=0,Te=0)  # [Disp,Force]

                    # =====================================================
                    # Determining the first approximation of values of Vy
                    # and calculation of effective fundamental period for NSP
                    # =====================================================
                    (Delta_y, V_y, Delta_d, V_d, Ke, alpha1, alpha2) = \
                        ASCE4117.IFDC(dtg1,results1)

                    Ki = Mast[ii] * 4 * np.pi**2 / T[
                        0,
                        ii]**2  # [kN/m] elastic lateral stiffness of the building.
                    Teff[ii] = T[0, ii] * (
                        Ki / Ke
                    )**0.5  # [s] effctive fundamental period of building.

                    # =============================================
                    # Second Execution of the analysis and output results.
                    # =============================================
                    ops.wipe()
                    OPSDMOD.ModelGen(ndm, ndf)
                    OPSDMOD.NodeGen(NbaysX[mm], NbaysZ, XbayL, ZbayL, StoryH,
                                    NStr[nn], flex)
                    OPSDMOD.MastNodeGen(NbaysX[mm],
                                        NbaysZ,
                                        XbayL,
                                        ZbayL,
                                        StoryH,
                                        NStr[nn],
                                        flex,
                                        coords=0)
                    OPSDMOD.SPConstGen(NbaysX[mm], NbaysZ, flex)
                    OPSDMOD.MPConstGen(NbaysX[mm], NbaysZ, NStr[nn], flex)
                    OPSDMOD.MatGenRCB(fpc, Ec, fy, E0, bsteel)
                    # OPSDMOD.GeomTransGen(ColTransfType,XBD=[min(XBDims[:,0]),min(XBDims[:,1])],\
                    #                      ZBD=[min(ZBDims[:,0]),min(ZBDims[:,1])],\
                    #                          ColD=[min(ColDims[:,0]),min(ColDims[:,1])])
                    OPSDMOD.GeomTransGen(
                        ColTransfType,
                        ColD=[min(ColDims[:, 0]),
                              min(ColDims[:, 1])])
                    # OPSDMOD.GeomTransGen(ColTransfType)

                    if flex in ('Y', 'YES', 'Yes', 'yES', 'yes', 'y'):
                        # Interface elements generation for foundation flexibility considerations.
                        # =========================================================================
                        # Materials generation: stiffness constants accounting for soil flexibility.
                        # ---------------------------------------------------------------------------
                        OPSDMOD.FoundFlexMaterials(NbaysX[mm],NbaysZ,XbayL,ZbayL,Sxs,Vso[oo],gamma_soil,nu_soil,B,L,Re,\
                                                   D=0,omega_soil=0,analtype='lat')
                        # Zero-Length elements creation for connecting base nodes.
                        OPSDMOD.FoundFlexZLElements(NbaysX[mm], NbaysZ, XbayL,
                                                    ZbayL, B, L, Re)

                    OPSDMOD.ElementGen(NbaysX[mm],NbaysZ,XbayL,ZbayL,NStr[nn],StoryH,XBDims,ZBDims,\
                                               ColDims,BeamEffFact,ColEffFact,Ec,fy,EMs,\
                                                   XBreinf,ZBreinf,Colreinf,N=5,rec=0.0654,nuconc=0.2,dbar=0.025)
                    [Wx,MassInputMatr] = \
                        OPSDMOD.LumpedMassGen(NbaysX[mm],NbaysZ,XBDims,ZBDims,ColDims,gamma_conc,g,XbayL,ZbayL,NStr[nn],StoryH,Qsd,flex)
                    W = sum(Wx)  # [kN] total weight of the building
                    # GRAVITY LOADS APPLIED TO MODEL ACCORDINGO TO ASCE4117
                    # ======================================================
                    OPSDMOD.DeadLoadGen(NbaysX[mm], NbaysZ, NStr[nn], XBDims,
                                        ZBDims, ColDims, gamma_conc)
                    OPSDMOD.SuperDeadLoadGen(NbaysX[mm], NbaysZ, NStr[nn],
                                             XbayL, ZbayL, Qsd)
                    OPSDMOD.LiveLoadGen(NbaysX[mm], NbaysZ, NStr[nn], XbayL,
                                        ZbayL, 0.25 * Ql, 0.25 * Qlr)

                    # GRAVITY-LOADS-CASE ANALYSIS.
                    # ============================
                    ops.system('ProfileSPD')
                    ops.constraints('Transformation')
                    ops.numberer('RCM')
                    ops.test('NormDispIncr', 1.0e-4, 100)
                    ops.algorithm('KrylovNewton')
                    ops.integrator('LoadControl', 1)
                    ops.analysis('Static')
                    ops.analyze(1)
                    # ==================
                    # PUSHOVER ANALYSIS
                    # ==================
                    # Lateral Force used for analysis
                    # --------------------------------
                    # Using functions from ASCE716Seismic Module.
                    (_,_,_,_,_,_,_,_,_,_,_,FxF,_,_,_) = \
                        ASCE716.ELFP(Sxs,Sx1,Vso[oo],Wx,R,Ie,hx,StrType,Teff[ii])

                    # Aplication of forces to the model.
                    # ----------------------------------
                    ops.loadConst('-time', 0.0)
                    MdeShape = OPSDMOD.POForceGen(NStr[nn], FxF, dirs[ii],
                                                  flex)

                    # =============================================
                    # First Execution of the analysis and output results.
                    # =============================================
                    (results2,dtg2,tgfactor2) = \
                        OPSDAN.POAnalysisProc(lon,lat,Vso[oo],SHL,NbaysX[mm],NbaysZ,\
                                              NStr[nn],StoryH,R,Ie,BldTypCo,BldTypCm,\
                                                  T[0,ii],W,dirs[ii],flex,\
                                                      DispIncr=0,beta=0.05,TL=8.,Tf=6.0,Npts=500,Vy=0,Te=Teff[ii])  # [Disp,Force].

                    # =====================================================
                    # Determining the "exact"  values of Vy
                    # and calculation of effective fundamental period for NSP
                    # =====================================================
                    (Delta_y, V_y, Delta_d, V_d, Ke, alpha1, alpha2) = \
                        ASCE4117.IFDC(dtg1,results2)

                    Ki = Mast[ii] * 4 * np.pi**2 / T[
                        0,
                        ii]**2  # [kN/m] elastic lateral stiffness of the building.
                    Teff[ii] = T[0, ii] * (
                        Ki / Ke
                    )**0.5  # [s] effctive fundamental period of building.

                    ttime = timer() - time_o
                    print(f'Elapsed Time {round(ttime/60,2)} [m]')

                    plt.figure()
                    plt.plot(results2[:, 0], results2[:, 1])
                    plt.grid()

                    print('The mode shape is:')
                    print(MdeShape)

    return (results1, results2), (dtg1, dtg2), (tgfactor1,
                                                tgfactor2), (tgfactor1 * dtg1,
                                                             tgfactor2 * dtg2)
Пример #26
0
tf = 0.2 * s
fr = 10 * Hz
prd = 1 / fr
ops.timeSeries('Trig', 1, ti, tf, prd)
# https://openseespydoc.readthedocs.io/en/latest/src/pathTs.html
ops.pattern('UniformExcitation', 1, 1, '-accel', 1)
# https://openseespydoc.readthedocs.io/en/latest/src/uniformExcitation.html

# amortiguamiento de rayleigh
ops.rayleigh(*setRayParam(0.05, 0.05, 0.2, 20))

# analysis commands
ops.constraints('Plain')
ops.numberer('Plain')
ops.system('UmfPack')
ops.algorithm('Linear')
ops.integrator('Newmark', 0.5, 0.25)
ops.analysis('Transient')

# analisis
# ops.analyze(400,0.001)
ops.start()
for i in range(400):
    ops.analyze(1, 0.001)
    print(i)
ops.stop()

# Grafico de la deformada
fig = plt.figure(figsize=(25, 5))
opsv.plot_defo(500)
plt.show()
Пример #27
0
def analisis_opensees(path, permutaciones):  #helper, #win
    ops.wipe()

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

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

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

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

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

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

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

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

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

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

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

        #win.ui.progressBar.setValue(15)

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

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

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

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

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

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

                    yCoord = (yCoord + sElemY[k])

                count = (count + nNodeY[k])

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        count = 0
        alpha = 1.5e-6

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

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

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

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

        #win.ui.progressBar.setValue(25)

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

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

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

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

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

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

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

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

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

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

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

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

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

        #win.ui.progressBar.setValue(35)

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

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

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

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

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

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

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

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

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

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

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

        #win.ui.progressBar.setValue(40)

        # update materials to consider plastic behavior

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

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

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

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

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

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

            break

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

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

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

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

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

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

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

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

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

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

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

        # objeto de serie temporal para el historial de fuerza

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

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

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

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

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

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

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

            ops.analyze(remStep, dT)

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

                ops.analyze(remStep, dT)

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

    ops.wipe()
Пример #28
0
def Analysis_Proc(Num: int, Node: int, dof: int, Dincr: float):
    '''
      brief KrylovNewton → Newton -SecantNewton → ModifiedNewton → NewtonWithLineSearch → BGFS → Broyden\n
      pararm Num the number of analyze step\n
      return analyze if successful return 0
      if NOT successful return < 0\n
    '''
    for step in range(1, Num + 1):
        logger.info("No. %d of Cyclic. Anaylsis KrylovNewton..", step)
        ops.algorithm('KrylovNewton')
        ops.integrator("DisplacementControl", Node, dof, Dincr)
        ops.analysis("Static")
        ok = ops.analyze(1)

        if ok != 0:
            logger.info("No. %d of Cyclic. Anaylsis Trying SecantNewton ..",
                        step)
            ops.algorithm('SecantNewton')
            ops.integrator("DisplacementControl", Node, dof, Dincr)
            ops.analysis("Static")
            ok = ops.analyze(1)

        if ok != 0:
            logger.info(
                "NO. %d of Cyclic. Anaylsis Trying NewtonLineSearch ..", step)
            ops.algorithm('NewtonLineSearch', True, False, True, False, 0.8,
                          1000, 0.1, 10.0)
            ops.integrator("DisplacementControl", Node, dof, Dincr)
            ops.analysis("Static")
            ok = ops.analyze(1)

        if ok != 0:
            logger.info("No. %d of Cyclic. Anaylsis Trying PeriodicNewton ..",
                        step)
            ops.algorithm('PeriodicNewton')
            ops.integrator("DisplacementControl", Node, dof, Dincr)
            ops.analysis("Static")
            ok = ops.analyze(1)

        if ok != 0:
            logger.info(
                "NO. %d of Cyclic. Anaylsis Trying NewtonWithLineSearch ..",
                step)
            ops.algorithm('NewtonLineSearch')
            ops.integrator("DisplacementControl", Node, dof, Dincr)
            ops.analysis("Static")
            ok = ops.analyze(1)

        if ok != 0:
            logger.info("No. %d of Cyclic. Anaylsis Trying BFGS ..", step)
            ops.algorithm('BFGS', True, False, 10000000)
            ops.integrator("DisplacementControl", Node, dof, Dincr)
            ops.analysis("Static")
            ok = ops.analyze(1)

        if ok != 0:
            logger.info("No. %d of Cyclic. Anaylsis Trying Broyden ..", step)
            ops.algorithm('Broyden')
            ops.integrator("DisplacementControl", Node, dof, Dincr)
            ops.analysis("Static")
            ok = ops.analyze(1)

        if ok != 0:
            logger.info("No. $step of Cyclic. Analysis Convergence Failure!")
Пример #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)
Пример #30
0
# create numberer object
ops.numberer('Plain')

# create convergence test object
ops.test('PFEM', 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 10, 3, 1, 2)

# create algorithm object
ops.algorithm('Newton')

# create integrator object
ops.integrator('PFEM', 0.5, 0.25)

# create SOE object
ops.system('PFEM')
# ops.system('PFEM', '-mumps) Linux version can use mumps

# create analysis object
ops.analysis('PFEM', dtmax, dtmin, b2)

# analysis
while ops.getTime() < totaltime:

    # analysis
    if ops.analyze() < 0:
        break

    ops.remesh()

print("==========================================")