%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from jupyterthemes import jtplot ; jtplot.style()
np.random.seed(1969-7-20)
We simulate a dynamic testing, using a low sampled, random error affected sequence of frequencies to compute a random error affected sequence of dynamic amplification factors for $\zeta=3.5\%$.
N = 51
b = np.linspace(0.5, 1.5, N) + (np.random.random(N)-0.5)/100
z = 0.035
D = 1/np.sqrt((1-b*b)**2+(2*z*b)**2) * (1 + (np.random.random(N)-0.5)/100)
print('max of curve', max(D), '\tmax approx.', 1/2/z, '\texact', 1/2/z/np.sqrt(1-z*z))
plt.plot(b, D) ; plt.ylim((0, 15)) ; plt.grid(1);
We find the reference response value using the measured maximum value and plot a zone around the max value, using a reference line at $D_\text{max}/\sqrt2$
Dmax = max(D)
D2 = Dmax/np.sqrt(2)
plt.plot(b, D, 'k-*')
plt.yticks((D2, Dmax))
plt.xlim((0.9, 1.1))
plt.grid(1)
We plot 2 ranges around the crossings with the reference value
plt.plot(b, D)
plt.yticks((D2, Dmax))
plt.xlim((0.950, 0.965))
plt.grid(1)
plt.show()
plt.plot(b, D)
plt.yticks((D2, Dmax))
plt.xlim((1.025, 1.040))
plt.grid(1);
My estimates for the half-power frequencies are $f_1 = 0.962$ and $f_2 = 1.034$, and using these values in the half-power formula gives us our estimate of $\zeta$.
f1 = 0.962
f2 = 1.034
print(z, '%.6f'%((f2-f1)/(f2+f1)))