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.plot_jacobian_spectrumFunction
plot_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.

source

Behind the scenes, the spectra are stored using the dedicated structs Lorentzian and JacobianSpectrum.

HarmonicBalance.LinearResponse.JacobianSpectrumType
mutable struct JacobianSpectrum

Holds a set of Lorentzian objects belonging to a variable.

Fields

  • peaks::Vector{HarmonicBalance.LinearResponse.Lorentzian}

Constructor

JacobianSpectrum(res::Result; index::Int, branch::Int)
source

The full response matrix

To recover the response spectra accurately. Unlike for the Jacobian, here we must evaluate in every point.

HarmonicBalance.LinearResponse.ResponseMatrixType
struct ResponseMatrix

Holds the compiled response matrix of a system.

Fields

  • matrix::Matrix{Function}

    The response matrix (compiled).

  • symbols::Vector{Symbolics.Num}

    Any symbolic variables in matrix to 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.

source
HarmonicBalance.LinearResponse.get_responseFunction
get_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 Ω.

source
HarmonicBalance.LinearResponse.get_response_matrixFunction
get_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.

source
HarmonicBalance.LinearResponse.plot_responseFunction
plot_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.

source