Continuation of limit cycles of the van der Pol oscillator

# Continuation of limit cycles of the van der Pol oscillator

``````using Bifurcations
using Bifurcations: LimitCycleProblem
using Bifurcations.Examples.DuffingVanDerPol

using Plots
using OrdinaryDiffEq: Tsit5, remake``````

Create an `ODEProblem` and solve it:

``````ode = remake(
DuffingVanDerPol.ode,
p = DuffingVanDerPol.DuffingVanDerPolParam(
d = 0.1,
),
u0 = [1.0, 1.8],
tspan = (0.0, 90),
)
sol = solve(ode, Tsit5())

plt_ode = plot(sol, vars=1, tspan=(70, 90))`````` Let's find a point (approximately) on the limit cycle and its period:

``````using Roots: find_zero
t0 = find_zero((t) -> sol(t) - 1, (80, 83))
t1 = find_zero((t) -> sol(t) - 1, (t0 + 3, t0 + 7))
x0 = sol(t0)
@assert all(isapprox.(x0, sol(t1); rtol=1e-2))
x0``````
``````2-element Array{Float64,1}:
1.000000000000025
1.822900836879164``````

Then a `LimitCycleProblem` can be constructed from the `ode`.

``````num_mesh = 50
degree = 5
t_domain = (0.01, 4.0)  # so that it works with this `num_mesh` / `degree`
prob = LimitCycleProblem(
ode, DuffingVanDerPol.param_axis, t_domain,
num_mesh, degree;
x0 = x0,
l0 = t1 - t0,
de_args = [Tsit5()],
)``````

As the limit cycle is only approximately specified, solver option `start_from_nearest_root = true` must be passed to start continuation:

``````solver = init(
prob;
start_from_nearest_root = true,
max_branches = 0,
)
@time solve!(solver)``````
``````BifurcationSolver <Continuous>
# sweeps             : 2
# points             : 35
# branches           : 1
# saddle_node        : 1
``````

By default, `plot_state_space` plots limit cycles colored by its period:

``plt_lc = plot_state_space(solver)``
{"ft_lang_label":"__label__en","ft_lang_prob":0.5863763,"math_prob":0.9974085,"size":1481,"snap":"2022-40-2023-06","text_gpt3_token_len":506,"char_repetition_ratio":0.109004736,"word_repetition_ratio":0.018518519,"special_character_ratio":0.34571236,"punctuation_ratio":0.22426471,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9993555,"pos_list":[0,1,2,3,4],"im_url_duplicate_count":[null,1,null,1,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2022-10-01T00:53:22Z\",\"WARC-Record-ID\":\"<urn:uuid:2eb1a3b7-26ce-45f2-a9d5-75adb3bed01e>\",\"Content-Length\":\"5728\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:3cd6ec5d-ce84-4760-8920-0cc2f57f450b>\",\"WARC-Concurrent-To\":\"<urn:uuid:b9fdac1c-af95-4331-bca3-d00acc047b8b>\",\"WARC-IP-Address\":\"185.199.109.153\",\"WARC-Target-URI\":\"https://tkf.github.io/Bifurcations.jl/dev/examples/van_der_pol/\",\"WARC-Payload-Digest\":\"sha1:4EY6CQDOUJUTXWHCFAISNRN2WZY6GF2S\",\"WARC-Block-Digest\":\"sha1:46ZT6RLIOKLOO2HEFYHSFOLV6TDMQKDV\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2022/CC-MAIN-2022-40/CC-MAIN-2022-40_segments_1664030335514.65_warc_CC-MAIN-20221001003954-20221001033954-00423.warc.gz\"}"}