Linear response
This module currently has two goals. One is calculating the Jacobian, used to obtain stability and approximate (but inexpensive) the linear response of steady states. The other is calculating the full response matrix as a function of frequency; this is more accurate but more expensive.
Stability and response from the Jacobian
The simplest way to extract the linear response of a steady state is to evaluate the Jacobian of the harmonic equations. Each of its eigenvalues $\lambda$ describes a Lorentzian peak in the response; $\text{Re}[\lambda]$ gives its center and $\text{Im}[\lambda]$ its width. Transforming the harmonic variables into the non-rotating frame (that is, inverting the harmonic ansatz) then gives the response as it would be observed in an experiment.
The advantage of this method is that for a given parameter set, only one matrix diagonalization is needed to fully describe the response spectrum. However, the method is inaccurate for response frequencies far from the frequencies used in the harmonic ansatz (it relies on the response oscillating slowly in the rotating frame).
The Jacobian is also used to evaluate stability of the solutions.
HarmonicBalance.LinearResponse.get_Jacobian — Functionget_Jacobian(eom)
Obtain the symbolic Jacobian matrix of eom (either a HarmonicEquation or a DifferentialEquation).
HarmonicBalance.LinearResponse.plot_jacobian_spectrum — Functionplot_jacobian_spectrum(res::Result,
nat_var::Num;
Ω_range,
branch::Int,
y_offset::String="0.0",
x_scale=1.0,
y_scale=1.0,
logscale=false)Make a 1D plot of the response spectrum of res for the natural variable nat_var. Performs one matrix diagonalization for each element of Ω_range. This method is faster than plot_response but results in errors where the noise frequency is far from the frequency of the harmonic variables.
Behind the scenes, the spectra are stored using the dedicated structs Lorentzian and JacobianSpectrum.
HarmonicBalance.LinearResponse.JacobianSpectrum — Typemutable struct JacobianSpectrumHolds a set of Lorentzian objects belonging to a variable.
Fields
peaks::Vector{HarmonicBalance.LinearResponse.Lorentzian}
Constructor
JacobianSpectrum(res::Result; index::Int, branch::Int)HarmonicBalance.LinearResponse.Lorentzian — Typestruct LorentzianHolds the three parameters of a Lorentzian peak, defined as A / sqrt((ω-ω0)² + Γ²).
Fields
ω0::Float64Γ::Float64A::Float64
The full response matrix
To recover the response spectra accurately. Unlike for the Jacobian, here we must evaluate in every point.
HarmonicBalance.LinearResponse.ResponseMatrix — Typestruct ResponseMatrixHolds the compiled response matrix of a system.
Fields
matrix::Matrix{Function}The response matrix (compiled).
symbols::Vector{Symbolics.Num}Any symbolic variables in
matrixto be substituted at evaluation.ωs::Vector{Symbolics.Num}The frequencies of the harmonic variables underlying
matrix. These are needed to transform the harmonic variables to the non-rotating frame.
HarmonicBalance.LinearResponse.get_response — Functionget_response(rmat::HarmonicBalance.LinearResponse.ResponseMatrix, s::Dict{Symbolics.Num, ComplexF64}, Ω) -> Any
For rmat and a solution dictionary s, calculate the total response to a perturbative force at frequency Ω.
HarmonicBalance.LinearResponse.get_response_matrix — Functionget_response_matrix(diff_eq::DifferentialEquation, freq::Num; order=2)Obtain the symbolic linear response matrix of a diff_eq corresponding to a perturbation frequency freq. This routine cannot accept a HarmonicEquation since there, some time-derivatives are already dropped. order denotes the highest differential order to be considered.
HarmonicBalance.LinearResponse.plot_response — Functionplot_response(res::Result, Ω_range; branch, logscale)
Plot the linear response of a solution branch of res for the frequencies Ω_range.
This method takes n^2 matrix inversions for n elements of Ω_range. It therefore takes longer than plot_jacobian_spectrum (which is (O(n))) but is also valid far from resonance.