Skip to content

First frequency sweep

This example computes forward and backward synthetic frequency-sweep curves for a one-degree-of-freedom Duffing oscillator. It is the shortest complete Poscidyn workflow: build the physical pieces, create one solver, then call its method.

import jax.numpy as jnp
import matplotlib.pyplot as plt
import poscidyn

# q¨ + (omega_0 / Q) q˙ + omega_0² q + b q³ = f_d cos(omega t)
oscillator = poscidyn.NonlinearOscillator(
    omega_0=jnp.array([1.0]),
    Q=jnp.array([80.0]),
    a=jnp.zeros((1, 1, 1)),
    b=jnp.array([[[[0.2]]]]),
)
excitation = poscidyn.DirectHarmonicExcitation(
    f_d=jnp.array([0.002]),
    lambdas=jnp.array([1.0]),
)

solver = poscidyn.TimeIntegration(
    oscillator=oscillator,
    excitation=excitation,
    response_measure=poscidyn.Demodulation(
        multiples=(1.0,),
        modal_contributions=jnp.array([1.0]),
    ),
    multistart=poscidyn.LinearResponse(n_init_cond=8, random_seed=0),
    n_time_steps=64,
    periods_to_retain=2,
    max_steps=4096,
    rtol=1e-5,
    atol=1e-7,
)

result = solver.frequency_sweep(jnp.linspace(0.8, 1.2, 100))

frequency = result.frequency
forward = jnp.squeeze(result.forward.total.amplitude)
backward = jnp.squeeze(result.backward.total.amplitude)

plt.plot(frequency, forward, label="forward")
plt.plot(frequency, backward, "--", label="backward")
plt.xlabel("Drive frequency")
plt.ylabel("Response amplitude")
plt.legend()
plt.show()

result.forward and result.backward contain the selected synthetic-sweep branches. total is the weighted modal superposition; modal retains an individual result for each mode. With Demodulation, a singleton harmonic axis remains in the output, hence jnp.squeeze in this one-mode, one-harmonic plot.

The calculation first integrates each frequency from several initial conditions. It then selects a path through those candidates; it does not run a traditional continuation algorithm. Read the workflow and limitations before changing numerical settings or drawing branch-level conclusions.

Next: configure a time response, or learn how to interpret sweep results.