In [1]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')
In [2]:
# time and frequency vectors
t = np.arange(0, 30, 0.002)
f = np.arange(2, 45, 2**(1.0/6.0)) #frequency change by 1/6 octave
# relative damping factor
dz = 0.05
In [3]:
# omega
w1 = 2*np.pi*f[1]
# acceleration response calculation
a1 = np.exp(-dz*w1*t) * (2*dz*np.cos(w1*np.sqrt(1-dz**2)*t) + (1-2*dz**2)/np.sqrt(1-dz**2)*np.sin(w1*np.sqrt(1-dz**2)*t))
# omega
w2 = 2*np.pi*f[-1]
# acceleration response calculation
a2 = np.exp(-dz*w2*t) * (2*dz*np.cos(w2*np.sqrt(1-dz**2)*t) + (1-2*dz**2)/np.sqrt(1-dz**2)*np.sin(w2*np.sqrt(1-dz**2)*t))
plt.figure(figsize=(12,5))
plt.subplot(121)
plt.plot(t, a1, label='Frequency ' + str(f[1]))
plt.xlabel('Time [s]')
plt.ylabel('Acceleration [m/s2]')
plt.legend()
plt.xlim(0, 5)
plt.subplot(122)
plt.plot(t, a2, label='Frequency ' + str(f[-1]))
plt.xlabel('Time [s]')
plt.ylabel('Acceleration [m/s2]')
plt.legend()
plt.xlim(0, 1)
plt.tight_layout();
In [4]:
# wholistic approach
# omega
w = 2*np.pi*f
A = np.empty((len(t), len(f)))
for j in range(len(w)):
for i in range(len(t)):
A[i,j] = np.exp(-dz*w[j]*t[i]) * (2*dz*np.cos(w[j]*np.sqrt(1-dz**2)*t[i]) +
(1-2*dz**2)/np.sqrt(1-dz**2)*np.sin(w[j]*np.sqrt(1-dz**2)*t[i]))
plt.figure(figsize=(12,6))
plt.plot(t,A)
plt.xlabel('Time [s]')
plt.ylabel('Acceleration [m/s2]')
plt.xlim(0, 2);
In [5]:
a_max =[]
for i in range(A.shape[1]):
a_max.append(max(np.abs(A[:,i])))
plt.figure(figsize=(12,6))
plt.semilogx(f, a_max, marker='.', linestyle='none')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Acceleration [m/s2]')
plt.ylim(0.8, 1);
In [6]:
#Aux variables definition
ZPA = 0.4
#Amplitudes
AA = [np.random.random()*ZPA for k in f]
#Random angle
fi = [np.random.random()*np.pi/2 for k in f]
# excitation for frequency range
B = np.empty((len(t), len(f)))
for j in range(len(w)):
for i in range(len(t)):
B[i,j] = AA[j]*np.sin(w[j]*t[i] + fi[j])
# sum across columns (per frequency)
C = np.sum(B, axis=1)
In [7]:
plt.figure(figsize=(12,10))
plt.subplot(211)
plt.plot(t, C, color='orange')
plt.xlabel('Time [s]')
plt.ylabel('Acceleration [g]')
plt.subplot(212)
plt.plot(t, C, color='green')
plt.xlabel('Time [s]')
plt.ylabel('Acceleration [g]')
plt.xlim(0,2)
plt.ylim(-2,2)
plt.tight_layout();
In [8]:
window = np.hamming(len(C))
window2 = np.bartlett(len(C))
window3 = np.blackman(len(C))
window4 = np.hanning(len(C))
window5 = np.kaiser(len(C), beta=3.5)
In [9]:
plt.figure(figsize=(12,6))
plt.plot(t, window, label='hamming')
plt.plot(t, window2, label='barlett')
plt.plot(t, window3, label='blackman')
plt.plot(t, window4, label='hanning')
plt.plot(t, window5, label='kaiser')
plt.legend();
In [10]:
plt.figure(figsize=(12,10))
plt.plot(t, C*window5, color='orange', alpha=0.35)
plt.plot(t, C*window, alpha=0.35)
plt.xlabel('Time [s]')
plt.ylabel('Acceleration [g]');
In [11]:
# definition of parameters
# spring constant [N/m]
k = 40
# mass [kg]
m = 2
# damping
c = 5
# frequency
f1 = np.arange(0, 45, 0.001)
# angular frequency
omega = 2*np.pi*f1
In [12]:
# frequency response function (FRF)
H = 1 / (-omega**2*m + 1j*omega*c + k)
In [13]:
plt.figure(figsize=(10,8))
plt.subplot(211)
plt.semilogx(omega, np.abs(H))
plt.axvline(np.sqrt(k/m), color='grey', linestyle='--')
plt.axvline(np.sqrt(k/m - (c/(2*m))**2), color='orange', linestyle='--')
plt.xlabel('angular frequency [rad/s]')
plt.ylabel('H(omega)')
plt.subplot(212)
plt.semilogx(omega, np.angle(H)*360/(2*np.pi))
plt.xlabel('angular frequency [rad/s]')
plt.ylabel('Phase{H}')
plt.tight_layout()
In [14]:
1/k
Out[14]:
In [15]:
omega_0 = np.sqrt(k/m)
omega_0
Out[15]:
In [16]:
sigma = c / (2*m)
omega_d = np.sqrt(omega_0**2 - sigma**2)
omega_d
Out[16]:
Modal parameter model (because in reality mass, spring constant and damping coefficient are not known)
In [17]:
# examplary data from testing
# modal constant
C = 1.4
# resonance frequency (undamped nat freq)
omega_00 = 2*np.pi*5.8
# damping
dzeta = 6.6/100
# damped natural freq
omega_d = omega_00 * np.sqrt(1 - dzeta**2)
# residue
R = -1j* C * 0.54
R_con = np.conj(R)
# sigma
sigma = np.sqrt(omega_00**2 - omega_d**2)
# pole location
p = -sigma + 1j*omega_d
p_con = np.conj(p)
In [18]:
# frequency response function FRF
H2 = R / (1j*omega - p) + R_con / (1j*omega - p_con)
In [19]:
plt.figure(figsize=(10,8))
plt.subplot(211)
plt.semilogx(omega, np.abs(H2))
plt.axvline(omega_d, color='grey', linestyle='--')
#plt.axvline(np.sqrt(k/m - (c/(2*m))**2), color='orange', linestyle='--')
plt.xlabel('angular frequency [rad/s]')
plt.ylabel('H(omega)')
plt.subplot(212)
plt.semilogx(omega, np.angle(H2)*360/(2*np.pi))
plt.xlabel('angular frequency [rad/s]')
plt.ylabel('Phase{H}')
plt.tight_layout()
In [20]:
omega_d, omega_00
Out[20]:
In [30]:
# approach by SP institute with correction based on literature
f0 = omega_00/(2*np.pi)
H3 = C * (f0**2 - f1**2 - 1j*2*dzeta*f0*f1) / ((f0**2 - f1**2)**2 + (2*dzeta*f0*f1)**2)
# as written in the materials from SP
H4 = C * (f0**2 + 1j*2*dzeta*f0*f1) / (f0**2 - f1**2 + 1j*2*dzeta*f0*f1)
In [25]:
max(abs(H2)), max(abs(H3)), max(abs(H4)), R
Out[25]:
In [28]:
plt.figure(figsize=(10,8))
plt.subplot(211)
plt.semilogx(omega, np.abs(H2), label='B&K')
plt.semilogx(omega, np.abs(H3), label='SP mod')
plt.axvline(omega_d, color='grey', linestyle='--')
#plt.axvline(np.sqrt(k/m - (c/(2*m))**2), color='orange', linestyle='--')
plt.xlabel('angular frequency [rad/s]')
plt.ylabel('H(omega)')
plt.legend()
plt.subplot(212)
plt.semilogx(omega, np.angle(H2)*360/(2*np.pi))
plt.semilogx(omega, np.angle(H3)*360/(2*np.pi))
plt.axvline(omega_d, color='grey', linestyle='--')
plt.xlabel('angular frequency [rad/s]')
plt.ylabel('Phase{H}')
plt.tight_layout()
In [29]:
plt.figure(figsize=(10,8))
plt.subplot(211)
plt.semilogx(omega, np.abs(H3), label='SP mod')
plt.semilogx(omega, np.abs(H4), label='SP')
plt.axvline(omega_d, color='grey', linestyle='--')
#plt.axvline(np.sqrt(k/m - (c/(2*m))**2), color='orange', linestyle='--')
plt.xlabel('angular frequency [rad/s]')
plt.ylabel('H(omega)')
plt.legend()
plt.subplot(212)
plt.semilogx(omega, np.angle(H3)*360/(2*np.pi))
plt.semilogx(omega, np.angle(H4)*360/(2*np.pi))
plt.axvline(omega_d, color='grey', linestyle='--')
plt.xlabel('angular frequency [rad/s]')
plt.ylabel('Phase{H}')
plt.tight_layout()
In [ ]: