コード例 #1
0
ファイル: veloz.py プロジェクト: adesam01/fempy
def fe_solve(exo_io, runid, control, X, connect, elements, fixnodes,
             tractions, nforces, nproc=1):
    """ 2D and 3D Finite Element Code

    Currently configured to run either plane strain in 2D or general 3D but
    could easily be modified for plane stress or axisymmetry.

    Parameters
    ----------
    control : array_like, (i,)
        control[0] -> time integration scheme
        control[1] -> number of steps
        control[2] -> Newton tolerance
        control[3] -> maximum Newton iterations
        control[4] -> relax
        control[5] -> starting time
        control[6] -> termination time
        control[7] -> time step multiplier

    X : array like, (i, j,)
        Nodal coordinates
        X[i, j] -> jth coordinate of ith node for i=1...nnode, j=1...ncoord

    connect : array_like, (i, j,)
        Nodal connections
        connect[i, j] -> jth node on  on the ith element

    elements : array_like, (i,)
        Element class for each element

    fixnodes : array_like, (i, j,)
        List of prescribed displacements at nodes
            fixnodes[i, 0] -> Node number
            fixnodes[i, 1] -> Displacement component (x: 0, y: 1, or z: 2)
            fixnodes[i, 2] -> Value of the displacement

    tractions : array_like, (i, j,)
        List of element tractions
            tractions[i, 0] -> Element number
            tractions[i, 1] -> face number
            tractions[i, 2:] -> Components of traction as a function of time

    Returns
    -------
    retval : init
        0 on completion
        failure otherwise

    Notes
    -----
    Original code was adapted from [1].

    References
    ----------
    1. solidmechanics.org

    """
    # Local Variables
    # ---------------
    # du : array_like, (i,)
    #     Nodal displacements.
    #     Let wij be jth displacement component at ith node. Then du
    #     contains [w00, w01, w10, w11, ...] for 2D
    #     and [w00, w01, w02, w10, w11, w12, ...) for 3D

    # dw : array_like, (i,)
    #     Correction to nodal displacements.

    # K : array_like, (i, j,)
    #     Global stiffness matrix. Stored as
    #              [K_1111 K_1112 K_1121 K_1122...
    #               K_1211 K_1212 K_1221 K_1222...
    #               K_2111 K_2112 K_2121 K_2122...]
    #     for 2D problems and similarly for 3D problems

    # F : array_like, (i, )
    #     Force vector.
    #     Currently only includes contribution from tractions acting on
    #     element faces (body forces are neglected)
    # R : array_like, (i, )
    #     Volume contribution to residual
    # b : array_like (i, )
    #     RHS of equation system

    # number of processors
    nproc = np.amin([mp.cpu_count(), nproc, elements.size])

    # Set up timing and logging
    t0 = time.time()
    logger = Logger(runid)

    # Problem dimensions
    dim = elements[0].ndof
    nelems = elements.shape[0]
    nnode = X.shape[0]
    ndof = elements[0].ndof
    ncoord = elements[0].ncoord

    # Setup kinematic variables
    u = np.zeros((2, nnode * ndof))
    v = np.zeros((2, nnode * ndof))
    a = np.zeros((2, nnode * ndof))

    #  Simulation setup
    tint, nsteps, tol, maxit, relax, tstart, tterm, dtmult = control
    nsteps, maxit = int(nsteps), int(maxit)
    t = tstart
    dt = (tterm - tstart) / float(nsteps) * dtmult

    # Newmark parameters
    b = [.5, 0.]

    # Global mass, find only once
    M = global_mass(X, elements, connect, nproc)

    # Determine initial accelerations
    du = np.diff(u, axis=0)[0]
    K = global_stiffness(0., 1., X, elements, connect, du, nproc)
    findstiff = False
    F = global_traction(
        0., 1., X, elements, connect, tractions, nforces, du)
    apply_dirichlet_bcs(ndof, nnode, 0., fixnodes, u[0], du, 1., K, F, M)
    a[0] = np.linalg.solve(M, -np.dot(K, u[0]) + F)

    logger.write_intro("Explicit", runid, nsteps, tol, maxit, relax, tstart,
                       tterm, ndof, nelems, nnode))

    for step in range(nsteps):

        err1 = 1.
        t += dt

        logger.write(
            "Step {0:.5f}, Time: {1}, Time step: {2}".format(step + 1, t, dt))

        # --- Update the state of each element to end of step
        du = np.diff(u, axis=0)[0]
        update_element_states(dt, X, elements, connect, du)


        # --- Get global quantities
        K = global_stiffness(
            t, dt, X, elements, connect, du, nproc)