コード例 #1
0
ファイル: drx_numba.py プロジェクト: lidiatanasova/compas
def drx_numba(network, factor=1.0, tol=0.1, steps=10000, summary=0, update=False):
    """ Run Numba accelerated dynamic relaxation analysis.

    Parameters
    ----------
    network : obj
        Network to analyse.
    factor : float
        Convergence factor.
    tol : float
        Tolerance value.
    steps : int
        Maximum number of steps.
    summary : int
        Print summary at end (1:yes or 0:no).
    update : bool
        Update the co-ordinates of the Network.

    Returns
    -------
    array
        Vertex co-ordinates.
    array
        Edge forces.
    array
        Edge lengths.
    """
    # Setup
    tic1 = time()
    args = _args(network, factor, summary, steps, tol)
    toc1 = time() - tic1

    # Solver
    tic2 = time()
    tol, steps, summary, m, n, u, v, X, f0, l0, k0, ind_c, ind_t, B, P, S, rows, cols, vals, nv, M, factor, V, inds, indi, indf, EIx, EIy, beams, C = args
    drx_solver_numba(tol, steps, summary, m, n, u, v, X, f0, l0, k0, ind_c, ind_t, B, P, S, rows, cols, vals, nv,
                     M, factor, V, inds, indi, indf, EIx, EIy, beams)
    _, l = uvw_lengths(C, X)  # noqa: E741
    f = f0 + k0 * (l.ravel() - l0)
    toc2 = time() - tic2

    # Summary
    if summary:
        print('\n\nNumba DR -------------------')
        print('Setup time: {0:.3f} s'.format(toc1))
        print('Solver time: {0:.3f} s'.format(toc2))
        print('----------------------------------')

    # Update
    if update:
        k_i = network.key_index()
        uv_i = network.uv_index()
        for key in network.vertices():
            x, y, z = X[k_i[key], :]
            network.set_vertex_attributes(key, 'xyz', [x, y, z])
        for uv in network.edges():
            i = uv_i[uv]
            network.set_edge_attribute(uv, 'f', float(f[i]))

    return X, f, l
コード例 #2
0
ファイル: drx_numpy.py プロジェクト: elidim/compas
def drx_solver_numpy(tol, steps, factor, C, Ct, X, M, k0, l0, f0, ind_c, ind_t,
                     P, S, B, V, refresh, beams, inds, indi, indf, EIx, EIy,
                     callback, **kwargs):
    """ NumPy and SciPy dynamic relaxation solver.

    Parameters
    ----------
    tol : float
        Tolerance value.
    steps : int
        Maximum number of steps.
    factor : float
        Convergence factor.
    C : array
        Connectivity matrix.
    Ct : array
        Transposed connectivity matrix.
    X : array
        Nodal co-ordinates.
    M : array
        Mass matrix.
    k0 : array
        Initial edge axial stiffnesses.
    l0 : array
        Initial edge lengths.
    f0 : array
        Initial edge forces.
    ind_c : list
        Indices of compression only edges.
    ind_t : list
        Indices of tension only edges.
    P : array
        Nodal loads Px, Py, Pz.
    S : array
        Shear forces Sx, Sy, Sz.
    B : array
        Constraint conditions Bx, By, Bz.
    V : array
        Nodal velocities Vx, Vy, Vz.
    refresh : int
        Update progress every n steps.
    beams : int
        Beam data flag 1 or 0.
    inds : array
        Indices of beam element start nodes.
    indi : array
        Indices of beam element intermediate nodes.
    indf : array
        Indices of beam element finish nodes beams.
    EIx : array
        Nodal EIx flexural stiffnesses.
    EIy : array
        Nodal EIy flexural stiffnesses.
    callback : obj
        Callback function.

    Returns
    -------
    array
        Vertex co-ordinates.
    array
        Edge forces.
    array
        Edge lengths.

    """

    res = 1000 * tol
    ts, Uo = 0, 0
    M = factor * tile(M.reshape((-1, 1)), (1, 3))

    while (ts <= steps) and (res > tol):

        uvw, l = uvw_lengths(C, X)
        f = f0 + k0 * (l.ravel() - l0)

        if ind_t:
            f[ind_t] *= f[ind_t] > 0
        if ind_c:
            f[ind_c] *= f[ind_c] < 0

        if beams:
            S = _beam_shear(S, X, inds, indi, indf, EIx, EIy)

        q = f[:, newaxis] / l
        qt = tile(q, (1, 3))
        R = (P - S - Ct.dot(uvw * qt)) * B
        res = mean(normrow(R))

        V += R / M
        Un = sum(M * V**2)
        if Un < Uo:
            V *= 0
        Uo = Un

        X += V

        if refresh:
            if (ts % refresh == 0) or (res < tol):
                print('Step:{0} Residual:{1:.3f}'.format(ts, res))
                if callback:
                    callback(X, **kwargs)

        ts += 1

    return X, f, l
コード例 #3
0
def drx_solver(tol, steps, factor, C, Ct, X, ks, l0, f0, ind_c, ind_t, P, S, B,
               M, V, refresh, beams, inds, indi, indf, EIx, EIy, callback,
               **kwargs):
    """ NumPy and SciPy dynamic relaxation solver.

    Parameters:
        tol (float): Tolerance limit.
        steps (int): Maximum number of steps.
        factor (float): Convergence factor.
        C (array): Connectivity matrix.
        Ct (array): Transposed connectivity matrix.
        X (array): Nodal co-ordinates.
        ks (array): Initial edge axial stiffnesses.
        l0 (array): Initial edge lengths.
        f0 (array): Initial edge forces.
        ind_c (list): Indices of compression only edges.
        ind_t (list): Indices of tension only edges.
        P (array): Nodal loads Px, Py, Pz.
        S (array): Shear forces Sx, Sy, Sz.
        B (array): Constraint conditions.
        M (array): Mass matrix.
        V (array): Nodal velocities Vx, Vy, Vz.
        refresh (int): Update progress every n steps.
        beams (bool): Dictionary of beam information.
        inds (list): Indices of beam element start nodes.
        indi (list): Indices of beam element intermediate nodes.
        indf (list): Indices of beam element finish nodes beams.
        EIx (array): Nodal EIx flexural stiffnesses.
        EIy (array): Nodal EIy flexural stiffnesses.
        callback (obj): Callback function.

    Returns:
        array: Updated nodal co-ordinates.
        array: Updated forces.
        array: Updated lengths.
    """
    res = 1000 * tol
    ts, Uo = 0, 0
    M = factor * tile(M, (1, 3))
    while (ts <= steps) and (res > tol):
        uvw, l = uvw_lengths(C, X)
        f = f0 + ks * (l - l0)
        if ind_t:
            f[ind_t] *= f[ind_t] > 0
        if ind_c:
            f[ind_c] *= f[ind_c] < 0
        if beams:
            S = _beam_shear(S, X, inds, indi, indf, EIx, EIy)
        q = f / l
        qt = tile(q, (1, 3))
        R = (P - S - Ct.dot(uvw * qt)) * B
        res = mean(normrow(R))
        V += R / M
        Un = sum(M * V**2)
        if Un < Uo:
            V *= 0
        Uo = Un
        X += V
        if refresh:
            if (ts % refresh == 0) or (res < tol):
                print('Step:{0} Residual:{1:.3g}'.format(ts, res))
                if callback:
                    callback(X, **kwargs)
        ts += 1
    return X, f, l
コード例 #4
0
def drx_numba(network,
              factor=1.0,
              tol=0.1,
              steps=10000,
              summary=0,
              update=False):
    """ Run Numba accelerated dynamic relaxation analysis.

    Parameters
    ----------
        network (obj): Network to analyse.
        factor (float): Convergence factor.
        tol (float): Tolerance value.
        steps (int): Maximum number of steps.
        summary (int): Print summary at end.
        update (bool): Update the co-ordinates of the Network.

    Returns
    -------
        array: Vertex co-ordinates.
        array: Edge forces.
        array: Edge lengths.
    """

    # Setup

    tic1 = time()
    X, B, P, Pn, S, V, E, A, C, Ct, f0, l0, ind_c, ind_t, u, v, M, ks = _create_arrays(
        network)
    try:
        inds, indi, indf, EIx, EIy = _beam_data(network)
        inds = array(inds)
        indi = array(indi)
        indf = array(indf)
        EIx = EIx.ravel()
        EIy = EIy.ravel()
        beams = 1
    except AttributeError:
        z0, z1 = array([0]), array([0.])
        inds, indi, indf, EIx, EIy = z0, z0, z0, z1, z1
        beams = 0

    # Arrays

    f0_ = f0.ravel()
    ks_ = ks.ravel()
    l0_ = l0.ravel()
    M_ = M.ravel()
    if not ind_c:
        ind_c = [-1]
    if not ind_t:
        ind_t = [-1]
    ind_c = array(ind_c)
    ind_t = array(ind_t)
    rows, cols, vals = find(Ct)
    toc1 = time() - tic1

    # Solver

    tic2 = time()
    X = drx_solver(tol, steps, factor, u, v, X, ks_, l0_, f0_, ind_c, ind_t,
                   rows, cols, vals, P, S, B, M_, summary, inds, indi, indf,
                   EIx, EIy, beams)
    _, l = uvw_lengths(C, X)
    f = f0 + ks * (l - l0)
    toc2 = time() - tic2

    # Summary

    if summary:
        print('\n\nNumba DR -------------------')
        print('Setup time: {0:.3g}s'.format(toc1))
        print('Solver time: {0:.3g}s'.format(toc2))
        print('----------------------------------')

    # Update

    if update:

        i_k = network.index_key()
        for i in sorted(list(network.vertices()), key=int):
            x, y, z = X[i, :]
            network.set_vertex_attributes(i_k[i], {'x': x, 'y': y, 'z': z})

        uv_i = network.uv_index()
        for edge in network.edges():
            i = uv_i[edge]
            network.set_edge_attribute(edge, 'f', float(f[i]))

    return X, f, l