<jupyter_start><jupyter_text>Multi Degree of Freedom Systems Equation of Motion$[M] \{ \ddot{x}(t) \} + [C] \{ \dot{x}(t) \} + [K] \{ x(t) \} = \{ f(t) \} $or$m_{ij} \ddot{x}_j(t) + c \dot{x}_j(t) + k_{ij} x_j(t) = f_i(t), \qquad i = 1, 2, \ldots, n $Typically, the mass matrix $[M]$ is a diagonal matrix and the stiffness matrix $[K]$ is a symmetric matrix. Usually, $[M]$, $[C]$ and $[K]$ are coupled and it is not possible to solve the $n$ simultaneous differential equations independent of each other. It is possible to uncouple the equations of motion so that each differential equation then contains only one unknown and thus determine the response. Orthogonality of Normal ModesThe equation of motion for undamped free vibration is:$[M] \{ \ddot{x}(t) \} + [K] \{ x(t) \} = \{ 0 \}$Response under free vibration is harmonic, therefore $\{x(t) \} = \{ X \} \cos \omega t$. Then, $\{ \ddot{x}(t) \} = -\omega^2 \{ X \} \cos \omega t$.$-\omega^2 [M] \{ X \} + [K] \{ X \} = \{ 0 \}$$\omega^2 [M] \{ X \} = [K] \{ X \}$$ [D] \{ X \} = \lambda \{ X \}$where $[D] = [K]^{-1}$ and $\lambda = \frac{1}{\omega^2}$. This is the eigenvalue problem. Solution to the eigenvalue problem consists of finding the $n$ eigenvalues $\lambda_i$ and for each eigenvalue, a corresponding eigenvector $\{ X^{(k)} \}$, such that the above eigenvalue equation is satisfied. In structural dynamics, each eigenvalue corresponds to a natural frequency $\omega_i = \frac{1}{\sqrt{\lambda_i}}$ and each eigenvector is called a mode shape vector of that natural mode.Thus, an MDOF system with $n$ degrees of freedom has $n$ natural frequencies and $n$ mode shape vectors. Each mode shape vector is a column vector, and when arranged columnwise in order of the natural frequencies in increasing order, the resulting matrix is called the mode shape matrix $[X] = [ \{X^{(1)}\} \{X^{(2)}\} \cdots \{X^{(n)}\}]$Considering mode $i$, the above eigenvalue equation can be written as:$\omega_i^2 [M] \{X^{(i)}\} = [K] \{X^{(i)}\}$Similarly, for mode $j$$\omega_j^2 [M] \{X^{(j)}\} = [K] \{X^{(j)}\}$Pre-multiplying the first with $\{X^{(j)}\}^T$ and the second with $\{X^{(i)}\}^T$, and noting the fact that $[M]$ is a diagonal matrix and $[K]$ is a symmetric matrix, we get:$\omega_i^2 \{ X^{(j)}\}^T [M] \{X^{(i)}\} = \{ X^{(j)}\}^T [K] \{X^{(i)}\} \equiv \{ X^{(i)}\}^T [K] \{X^{(j)}\}$$\omega_i^2 \{ X^{(i)}\}^T [M] \{X^{(j)}\} \equiv \omega_i^2 \{ X^{(j)}\}^T [M] \{X^{(i)}\} = \{ X^{(i)}\}^T [K] \{X^{(j)}\}$Subtracting one from the other, we get:$ \left( \omega_i^2 - \omega_j^2 \right) \{ X^{(j)}\}^T [M] \{X^{(i)}\} = 0$Since two distinct modes usually have distinct frequencies, $\left( \omega_i^2 - \omega_j^2 \right) \neq 0$, which implies that $\{ X^{(j)}\}^T [M] \{X^{(i)}\} = 0$. Since $[X]$ represents the relative amplitudes of the different degrees of freedom when the system is vibrating in one of it snormal modes, the absolute value of the mode shape vector is not important. That is, the mode shape vector can be scaled without affecting the eigenvalue equation.If the mode shape matrix $[X]$ is scaled in such a way that $[X]^T [M] [X] = [I]$, then the mode shape matrix is said to be ortho-normalized. The corresponding matrix multiplication product is then $[X]^T [K] [X] = [\nwarrow \omega^2 \searrow]$, a diagonal matrix with diagonal elements equal to $\omega_i^2$.<jupyter_code>import numpy as np
import scipy.linalg as LA

# Assemble mass matrix
def calc_m(m):
    return np.diag(m)

# Assemble stiffness matrix
def calc_k(k):
    n = len(k)
    K = np.diag(k[:-1]) + np.diag(k[1:]) - np.diag(k[1:-1], 1) - np.diag(k[1:-1], -1)
    return K

# Main function

# Input data
k = np.array([1, 1, 1, 0], dtype=float)
m = np.array([1, 1, 1], dtype=float)

# Assemble mass and stiffness matrices
M = calc_m(m)
K = calc_k(k)
print "Mass Matrix [M]"
print M
print "Stiffness Matrix [K]"
print K
D = np.dot(LA.inv(K), M)
print "Dynamic Matrix [D]"
print D

# Solve eigenvalue problem
lam, X = LA.eig(D)
print "Natural Frequencies:", 1.0 / np.sqrt(abs(lam))

print "Mode Shape Matrix"
print X
print "[X]' [M] [X]"
print np.dot(X.T, np.dot(M, X))

for i in range(len(X)):
    X[:,i] = X[:,i] / X[0,i]
print "Mode Shape Matrix"
print X<jupyter_output>Mass Matrix [M]
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]
Stiffness Matrix [K]
[[ 2. -1.  0.]
 [-1.  2. -1.]
 [ 0. -1.  1.]]
Dynamic Matrix [D]
[[ 1.  1.  1.]
 [ 1.  2.  2.]
 [ 1.  2.  3.]]
Natural Frequencies: [ 0.44504187  1.2469796   1.80193774]
Mode Shape Matrix
[[-0.32798528 -0.73697623  0.59100905]
 [-0.59100905 -0.32798528 -0.73697623]
 [-0.73697623  0.59100905  0.32798528]]
[X]' [M] [X]
[[  1.00000000e+00   1.11022302e-16  -5.55111512e-17]
 [  1.11022302e-16   1.00000000e+00   6.38378239e-16]
 [ -5.55111512e-17   6.38378239e-16   1.00000000e+00]]
Mode Shape Matrix
[[ 1.          1.          1.        ]
 [ 1.80193774  0.44504187 -1.2469796 ]
 [ 2.2469796  -0.80193774  0.55495813]]<jupyter_text>Undamped Forced Vibration of MDOF Systems - Modal AnalysisEquation of motion of an undamped MDOF systems is:    $[M] \{ \ddot{x} \} + [K] \{ x \} = \{ f(t) \} $    Let $\{ x(t) \} = q_1(t) \{ X^{(1)} \} + q_2(t) \{ X^{(2)} + \cdots + q_n(t) \{ X^{(n)} \} = $where $\{ X^{(k)} \}$ is independent of time and represents the amplitude of vibration of each degree of freedom when the system is vibrating in the $k^{th}$ normal mode. Then, $\{ x \} = [X]\{ q(t) \}$ and $\{ \ddot{x} \} = \{ X \} \{ \ddot{q}(t) \}$ because $\{ X \}$ is independent of time.The equation of motion can now be written as:$[M][X] \{ \ddot{q}(t) \} + [K] [X] \{ q(t) \} = \{ f(t) \}$Pre-multiplying both sides with $[X]^{T}$$[X]^{T} [M] [X] \{ \ddot{q}(t) \} + [X]^{T} [K] [X] = [X]^{T} \{F(t) \}$If the normal modes are ortho-normalized, then $[X]^{T}[M][X] = [I]$ and $[X]^{T}[K][X] = [\nwarrow \omega^2 \searrow]$. Let $\{ Q(t) \} = [X]^{T} \{ F(t) \}$ be the generalized force vector, then:$\{ \ddot{q}(t) \} + [\nwarrow \omega^2 \searrow] \{ q(t) \} = \{ Q(t) \}$The equations are now in terms of the generalized coordinates $\{ q(t) \}$ and are uncoupled. Each uncoupled equation is:$\ddot{q}_i (t) + \omega_i^2 q_i (t) = Q_i(t) \qquad i = 1,2,\ldots,n$The equations can first be solved for $\{ q(t) \}$ and the response can then be obtained as $\{ x(t) \} = [X] \{ q(t) \}$.<jupyter_code>m = np.array([10, 1], dtype=float)
k = np.array([30, 5, 0], dtype=float)
M = calc_m(m)
K = calc_k(k)
print "Mass Matrix"
print M
print "Stiffness Matrix"
print K
D = np.dot(LA.inv(K), M)
print "Dynamic Matrix [D]"
print D

# Solve eigenvalue problem
lam, X = LA.eig(D)
print "Natural Frequencies:", 1.0 / np.sqrt(abs(lam))

print "Mode Shape Matrix"
print X
for i in range(len(X)):
    X[:,i] = X[:,i] / X[0,i]
print "Mode Shape Matrix"
print X
XMX = np.dot(X.T, np.dot(M, X))
print "[X]' [M] [X]"
print XMX

for i in range(len(XMX)):
    X[:,i] = X[:,i] / np.sqrt(XMX[i,i])
print X
print "[X]' [M] [X]"
print np.dot(X.T, np.dot(M, X))<jupyter_output>Mass Matrix
[[ 10.   0.]
 [  0.   1.]]
Stiffness Matrix
[[ 35.  -5.]
 [ -5.   5.]]
Dynamic Matrix [D]
[[ 0.33333333  0.03333333]
 [ 0.33333333  0.23333333]]
Natural Frequencies: [ 1.58113883  2.44948974]
Mode Shape Matrix
[[ 0.4472136  -0.19611614]
 [ 0.89442719  0.98058068]]
Mode Shape Matrix
[[ 1.  1.]
 [ 2. -5.]]
[X]' [M] [X]
[[ 14.   0.]
 [  0.  35.]]
[[ 0.26726124  0.16903085]
 [ 0.53452248 -0.84515425]]
[X]' [M] [X]
[[  1.00000000e+00  -5.55111512e-17]
 [ -5.55111512e-17   1.00000000e+00]]
{'fraction_non_alphanumeric': 0.21579651941097724, 'fraction_numerical': 0.07242302543507363, 'mean_word_length': 3.3562682215743442, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 9, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '254943', 'license': 'CC0-1.0', 'n_tokens_mistral': 3265, 'n_tokens_neox': 2854, 'n_words': 958, 'path': 'str_dyn_modal_analysis.ipynb', 'repo_name': 'satish-annigeri/Notebooks', 'size': '7470'}