admin管理员组文章数量:1201992
Background:
Antiresonance is the phenomenon when the amplitude of a system (say an oscillator) shows a significant dip. Here is an article in Wikipedia discussing the same in a coupled system. The article contains an analytical treatment of the system suggesting the existence of antiresonance.
Motivation:
The following equation describes another system where I'm trying to look for the same phenomena.
x'' + 2 Γ x' + f0^2( 1 + λ sin(2ft) ) x = F sin(ft)
where the constants denote the following.
Γ: Damping coefficient
f0: Natural frequency
f: Driving frequently
F: Strength of the drive
λ: Strength of the parametric drive
Implementing a similar treatment, one can show that the above system too exhibits antiresonance. (My derivation can be found here.)
I want to test this numerically by solving the differential equation and obtaining plots similar to the ones depicted in the article (the first image of the article). Therefore, my question is how do I generate the response numerically that will capture the dip?
Attempt:
I've successfully obtained responses of damped driven (periodically and stochastically) oscillators in the past by computing their Power Spectral Density (PSD). Numerically, to achieve that, one has to take a fast Fourier transform (FFT) of the solution x(t). I followed that same route here, solved the equation for x(t), and plotted the PSD by FFTing the solution.
Here is the code that does the above.
import numpy as np
from matplotlib import pyplot as plt
from scipy.fft import fft, fftfreq
G=0.6 #Gamma
Om=3 #Omega_zero
L=0.5 #Lambda
F=1 #Forcing
Og=2 #Drive_Freq
N=1000000
tf=50
ti=0
dt=(tf-ti)/N
t=np.linspace(ti, tf, N)
u=np.empty(N, dtype=float)
v=np.empty(N, dtype=float)
u[0]=1
v[0]=0
for i in range(N-1):
u[i+1]= u[i] + v[i]*dt
v[i+1]= v[i] - 2*G*v[i]*dt - (2*np.pi*Om)**2 *u[i]*dt - (2*np.pi*Om)**2 *L*np.sin(2*np.pi*2*Og*t[i])*u[i]*dt + F*np.sin(2*np.pi*Og*t[i])*dt
slice_index=int(20/dt) #Take the steady state part
U=u[slice_index:]
X_f = fft(U)
frequencies = fftfreq(len(U), dt)
psd = np.abs(X_f)**2
positive_freqs = frequencies[frequencies > 0]
plt.plot(positive_freqs, psd[frequencies > 0])
However, I only obtain a peak at f=2, the driving frequency, and no dip anywhere. In fact, no choices of parameters showed a dip.
Question:
Am I computing the response wrong? If so, how to do it? Why does PSD fail to capture it?
Background:
Antiresonance is the phenomenon when the amplitude of a system (say an oscillator) shows a significant dip. Here is an article in Wikipedia discussing the same in a coupled system. The article contains an analytical treatment of the system suggesting the existence of antiresonance.
Motivation:
The following equation describes another system where I'm trying to look for the same phenomena.
x'' + 2 Γ x' + f0^2( 1 + λ sin(2ft) ) x = F sin(ft)
where the constants denote the following.
Γ: Damping coefficient
f0: Natural frequency
f: Driving frequently
F: Strength of the drive
λ: Strength of the parametric drive
Implementing a similar treatment, one can show that the above system too exhibits antiresonance. (My derivation can be found here.)
I want to test this numerically by solving the differential equation and obtaining plots similar to the ones depicted in the article (the first image of the article). Therefore, my question is how do I generate the response numerically that will capture the dip?
Attempt:
I've successfully obtained responses of damped driven (periodically and stochastically) oscillators in the past by computing their Power Spectral Density (PSD). Numerically, to achieve that, one has to take a fast Fourier transform (FFT) of the solution x(t). I followed that same route here, solved the equation for x(t), and plotted the PSD by FFTing the solution.
Here is the code that does the above.
import numpy as np
from matplotlib import pyplot as plt
from scipy.fft import fft, fftfreq
G=0.6 #Gamma
Om=3 #Omega_zero
L=0.5 #Lambda
F=1 #Forcing
Og=2 #Drive_Freq
N=1000000
tf=50
ti=0
dt=(tf-ti)/N
t=np.linspace(ti, tf, N)
u=np.empty(N, dtype=float)
v=np.empty(N, dtype=float)
u[0]=1
v[0]=0
for i in range(N-1):
u[i+1]= u[i] + v[i]*dt
v[i+1]= v[i] - 2*G*v[i]*dt - (2*np.pi*Om)**2 *u[i]*dt - (2*np.pi*Om)**2 *L*np.sin(2*np.pi*2*Og*t[i])*u[i]*dt + F*np.sin(2*np.pi*Og*t[i])*dt
slice_index=int(20/dt) #Take the steady state part
U=u[slice_index:]
X_f = fft(U)
frequencies = fftfreq(len(U), dt)
psd = np.abs(X_f)**2
positive_freqs = frequencies[frequencies > 0]
plt.plot(positive_freqs, psd[frequencies > 0])
However, I only obtain a peak at f=2, the driving frequency, and no dip anywhere. In fact, no choices of parameters showed a dip.
Question:
Am I computing the response wrong? If so, how to do it? Why does PSD fail to capture it?
Share Improve this question edited Jan 21 at 13:52 Sourin Dey asked Jan 21 at 13:42 Sourin DeySourin Dey 557 bronze badges 3- Anti-resonance can happen with only one oscillator ? – rehaqds Commented Jan 21 at 16:15
- @rehaqds Yes. The parametric drive (as in the question) will interfere with the external drive, causing antiresonance. – Sourin Dey Commented Jan 21 at 19:00
- You are looking at the response for one forcing frequency. To see a damped frequency you would need to either sweep the frequencies, or force with a broadband input signal (Gaussian white noise is often a reasonable choice) – Jody Klymak Commented Jan 22 at 21:17
1 Answer
Reset to default 2A log-log plot reveals a sharp drop at 5Hz, and again at ~18Hz. You can switch to logarithmic axes using plt.xscale('log')
.
For solving ODEs, scipy.integrate
has various solvers that might capture temporal dynamics more accurately.
I think it's worth trying your method out on a system for which you know the derivation and values to be correct (e.g. the article you referenced). Once it's confirmed to be working on a simpler reference system, you can try it on your experimental system. I find that breaking it down like that helps with troubleshooting and validation.
#... code from OP
plt.plot(positive_freqs, psd[frequencies > 0])
plt.xscale('log')
plt.yscale('log')
plt.grid(visible=True, which='both', lw=0.5, color='gray', linestyle=':')
plt.gcf().set_size_inches(10, 3)
plt.xlim(0.1, 200)
plt.xlabel('frequency/Hz')
plt.ylabel('PSD')
FYI, you might like to see this answer that also uses a finite-difference approach, but in 2D.
本文标签: pythonAlternatives to Power Spectral Density for Response of an OscillatorStack Overflow
版权声明:本文标题:python - Alternatives to Power Spectral Density for Response of an Oscillator - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738630601a2103719.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论