Module earthquakepy.multidof

Expand source code
#!/usr/bin/env python3

import numpy as np
from scipy.linalg import eigh
from scipy.integrate import solve_ivp


class Mdof:
    """
    CLass for MDOF system.
    """

    def __init__(self, M=None, C=None, K=None):
        """
        Defines MDOF system object using M, C and K matrices.
        """
        if C is None:
            C = np.zeros_like(M)
        if (M is None) or (K is None):
            raise Exception(
                "Incprrect input parameters. You must provide M and K both."
            )

        self.M = M
        self.K = K
        self.C = C

        wn, v = eigh(K, M)
        self.Wn = wn
        self.Phi = v

    def __repr__(self):
        return "MDOF class instance"

    def mdof_grad(self, t, y, tv, f, R):
        M, C, K = self.M, self.C, self.K
        ft = np.array(
            [np.interp(t, tv, f[:, i]) for i in range(np.shape(f)[1])]
        ).reshape((6, 1))

        n = np.shape(M)[0]
        Minv = np.linalg.inv(M)
        A = np.zeros((2 * n, 2 * n))
        A[0:n, n : 2 * n] = np.eye(n)
        A[n : 2 * n, 0:n] = -Minv * K
        A[n : 2 * n, n : 2 * n] = -Minv * C
        x = np.array(y)

        nInputEqs = 3
        for i in range(nInputEqs):
            R[n + i :: nInputEqs, i] = 1

        dy = np.matmul(A, x) + np.matmul(R, ft)
        # print(np.matmul(A, x))
        # print(np.matmul(R, ft))
        # print("A={}\nx={}\nR={}\nft={}\ndy={}".format(A, x, R, ft, dy))

        return dy

    def get_response(self, Ax=None, Ay=None, Az=None, r=None, **kwargs):
        """
        Wrapper around solve_ivp module from scipy.integrate. It supports all the arguments supported by solve_ivp.

        Parameters
        ----------
        Ax: (timeseries objects) timeseries defining loading/base acceleration (default) in X direction

        Ay: (timeseries objects) timeseries defining loading/base acceleration (default) in Y direction

        Az: (timeseries objects) timeseries defining loading/base acceleration (default) in Z direction

        r: (2D array) Influence coefficient matrix of shape (n*m) where n=Total DOFs, m=DOFs per floor (6). DOFs must be ordered as [x, y, z, thetaX, thetaY, thetaZ]

        **kwargs: arguments acceptable to scipy solve_ivp module

        By default the solution will be obtained for duration = 2 * (ts.t duration). This can be changed using t_span argument. Default method : BDF

        Returns
        -------
        MDOF response object
        """
        # # Total DOFs
        # n = np.shape(self.M)[0]
        # # DOFs per floor
        # m = 6

        # # Create input acceleration matrix of size (len(Ax.t), 6)
        # Xg = np.zeros((len(Ax.t), m))

        # # Find earthquakes applied direction
        # if Ax is not None:
        #     Xg[:, 0] = Ax.t
        # if Ay is not None:
        #     Xg[:, 1] = Ay.t
        # if Az is not None:
        #     Xg[:, 2] = Az.t

        # if (Ax is None) and (Ay is None) and (Az is None):
        #     raise Exception("At least one earthquake input must be specified.")

        # # Create influence coefficient matrix R from r
        # R = np.zeros((2*n, m))
        # R[n::, 0:n] = r

        # defaultArgs = {
        #     "t_span": (Ax.t[0], Ax.t[-1]*2),
        #     "y0": np.zeros(m),
        #     "method": "BDF",
        #     "t_eval": None,
        #     "dense_output": False,
        #     "events": None,
        #     "vectorized": True,
        #     "args": (Ax.t, Xg, R),
        #     #"jac": np.array([
        #     #    [0, 1],
        #     #    [-self.k/self.m, -self.c/self.m]
        #     #    ])
        #     }
        # kwargs = {**defaultArgs, **kwargs}

        # res = solve_ivp(self.mdof_grad, **kwargs)
        # return res
        print("Not implemented yet!")

Classes

class Mdof (M=None, C=None, K=None)

CLass for MDOF system.

Defines MDOF system object using M, C and K matrices.

Expand source code
class Mdof:
    """
    CLass for MDOF system.
    """

    def __init__(self, M=None, C=None, K=None):
        """
        Defines MDOF system object using M, C and K matrices.
        """
        if C is None:
            C = np.zeros_like(M)
        if (M is None) or (K is None):
            raise Exception(
                "Incprrect input parameters. You must provide M and K both."
            )

        self.M = M
        self.K = K
        self.C = C

        wn, v = eigh(K, M)
        self.Wn = wn
        self.Phi = v

    def __repr__(self):
        return "MDOF class instance"

    def mdof_grad(self, t, y, tv, f, R):
        M, C, K = self.M, self.C, self.K
        ft = np.array(
            [np.interp(t, tv, f[:, i]) for i in range(np.shape(f)[1])]
        ).reshape((6, 1))

        n = np.shape(M)[0]
        Minv = np.linalg.inv(M)
        A = np.zeros((2 * n, 2 * n))
        A[0:n, n : 2 * n] = np.eye(n)
        A[n : 2 * n, 0:n] = -Minv * K
        A[n : 2 * n, n : 2 * n] = -Minv * C
        x = np.array(y)

        nInputEqs = 3
        for i in range(nInputEqs):
            R[n + i :: nInputEqs, i] = 1

        dy = np.matmul(A, x) + np.matmul(R, ft)
        # print(np.matmul(A, x))
        # print(np.matmul(R, ft))
        # print("A={}\nx={}\nR={}\nft={}\ndy={}".format(A, x, R, ft, dy))

        return dy

    def get_response(self, Ax=None, Ay=None, Az=None, r=None, **kwargs):
        """
        Wrapper around solve_ivp module from scipy.integrate. It supports all the arguments supported by solve_ivp.

        Parameters
        ----------
        Ax: (timeseries objects) timeseries defining loading/base acceleration (default) in X direction

        Ay: (timeseries objects) timeseries defining loading/base acceleration (default) in Y direction

        Az: (timeseries objects) timeseries defining loading/base acceleration (default) in Z direction

        r: (2D array) Influence coefficient matrix of shape (n*m) where n=Total DOFs, m=DOFs per floor (6). DOFs must be ordered as [x, y, z, thetaX, thetaY, thetaZ]

        **kwargs: arguments acceptable to scipy solve_ivp module

        By default the solution will be obtained for duration = 2 * (ts.t duration). This can be changed using t_span argument. Default method : BDF

        Returns
        -------
        MDOF response object
        """
        # # Total DOFs
        # n = np.shape(self.M)[0]
        # # DOFs per floor
        # m = 6

        # # Create input acceleration matrix of size (len(Ax.t), 6)
        # Xg = np.zeros((len(Ax.t), m))

        # # Find earthquakes applied direction
        # if Ax is not None:
        #     Xg[:, 0] = Ax.t
        # if Ay is not None:
        #     Xg[:, 1] = Ay.t
        # if Az is not None:
        #     Xg[:, 2] = Az.t

        # if (Ax is None) and (Ay is None) and (Az is None):
        #     raise Exception("At least one earthquake input must be specified.")

        # # Create influence coefficient matrix R from r
        # R = np.zeros((2*n, m))
        # R[n::, 0:n] = r

        # defaultArgs = {
        #     "t_span": (Ax.t[0], Ax.t[-1]*2),
        #     "y0": np.zeros(m),
        #     "method": "BDF",
        #     "t_eval": None,
        #     "dense_output": False,
        #     "events": None,
        #     "vectorized": True,
        #     "args": (Ax.t, Xg, R),
        #     #"jac": np.array([
        #     #    [0, 1],
        #     #    [-self.k/self.m, -self.c/self.m]
        #     #    ])
        #     }
        # kwargs = {**defaultArgs, **kwargs}

        # res = solve_ivp(self.mdof_grad, **kwargs)
        # return res
        print("Not implemented yet!")

Methods

def get_response(self, Ax=None, Ay=None, Az=None, r=None, **kwargs)

Wrapper around solve_ivp module from scipy.integrate. It supports all the arguments supported by solve_ivp.

Parameters

Ax : (timeseries objects) timeseries defining loading/base acceleration (default) in X direction
 
Ay : (timeseries objects) timeseries defining loading/base acceleration (default) in Y direction
 
Az : (timeseries objects) timeseries defining loading/base acceleration (default) in Z direction
 
r : (2D array) Influence coefficient matrix of shape (n*m) where n=Total DOFs, m=DOFs per floor (6). DOFs must be ordered as [x, y, z, thetaX, thetaY, thetaZ]
 
**kwargs : arguments acceptable to scipy solve_ivp module
 

By default the solution will be obtained for duration = 2 * (ts.t duration). This can be changed using t_span argument. Default method : BDF

Returns

MDOF response object
 
Expand source code
def get_response(self, Ax=None, Ay=None, Az=None, r=None, **kwargs):
    """
    Wrapper around solve_ivp module from scipy.integrate. It supports all the arguments supported by solve_ivp.

    Parameters
    ----------
    Ax: (timeseries objects) timeseries defining loading/base acceleration (default) in X direction

    Ay: (timeseries objects) timeseries defining loading/base acceleration (default) in Y direction

    Az: (timeseries objects) timeseries defining loading/base acceleration (default) in Z direction

    r: (2D array) Influence coefficient matrix of shape (n*m) where n=Total DOFs, m=DOFs per floor (6). DOFs must be ordered as [x, y, z, thetaX, thetaY, thetaZ]

    **kwargs: arguments acceptable to scipy solve_ivp module

    By default the solution will be obtained for duration = 2 * (ts.t duration). This can be changed using t_span argument. Default method : BDF

    Returns
    -------
    MDOF response object
    """
    # # Total DOFs
    # n = np.shape(self.M)[0]
    # # DOFs per floor
    # m = 6

    # # Create input acceleration matrix of size (len(Ax.t), 6)
    # Xg = np.zeros((len(Ax.t), m))

    # # Find earthquakes applied direction
    # if Ax is not None:
    #     Xg[:, 0] = Ax.t
    # if Ay is not None:
    #     Xg[:, 1] = Ay.t
    # if Az is not None:
    #     Xg[:, 2] = Az.t

    # if (Ax is None) and (Ay is None) and (Az is None):
    #     raise Exception("At least one earthquake input must be specified.")

    # # Create influence coefficient matrix R from r
    # R = np.zeros((2*n, m))
    # R[n::, 0:n] = r

    # defaultArgs = {
    #     "t_span": (Ax.t[0], Ax.t[-1]*2),
    #     "y0": np.zeros(m),
    #     "method": "BDF",
    #     "t_eval": None,
    #     "dense_output": False,
    #     "events": None,
    #     "vectorized": True,
    #     "args": (Ax.t, Xg, R),
    #     #"jac": np.array([
    #     #    [0, 1],
    #     #    [-self.k/self.m, -self.c/self.m]
    #     #    ])
    #     }
    # kwargs = {**defaultArgs, **kwargs}

    # res = solve_ivp(self.mdof_grad, **kwargs)
    # return res
    print("Not implemented yet!")
def mdof_grad(self, t, y, tv, f, R)
Expand source code
def mdof_grad(self, t, y, tv, f, R):
    M, C, K = self.M, self.C, self.K
    ft = np.array(
        [np.interp(t, tv, f[:, i]) for i in range(np.shape(f)[1])]
    ).reshape((6, 1))

    n = np.shape(M)[0]
    Minv = np.linalg.inv(M)
    A = np.zeros((2 * n, 2 * n))
    A[0:n, n : 2 * n] = np.eye(n)
    A[n : 2 * n, 0:n] = -Minv * K
    A[n : 2 * n, n : 2 * n] = -Minv * C
    x = np.array(y)

    nInputEqs = 3
    for i in range(nInputEqs):
        R[n + i :: nInputEqs, i] = 1

    dy = np.matmul(A, x) + np.matmul(R, ft)
    # print(np.matmul(A, x))
    # print(np.matmul(R, ft))
    # print("A={}\nx={}\nR={}\nft={}\ndy={}".format(A, x, R, ft, dy))

    return dy