Nonlinear laser model
The following model is taken from [Pusuluri]:
\[\left\{\begin{aligned} \dot{\beta} & =-\sigma \beta+g p_{23}, \\ \dot{p}_{21} & =-p_{21}-\beta p_{31}+a D_{21}, \\ \dot{p}_{23} & =-p_{23}+\beta D_{23}-a p_{31}, \\ \dot{p}_{31} & =-p_{31}+\beta p_{21}+a p_{23}, \\ \dot{D}_{21} & =-b\left(D_{21}-D_{21}^0\right)-4 a p_{21}-2 \beta p_{23}, \\ \dot{D}_{23} & =-b\left(D_{23}-D_{23}^0\right)-2 a p_{21}-4 \beta p_{23}, \end{aligned}\right.\]
It is easy to encode the ODE as follows
using Revise, Plots
using BifurcationKit
using HclinicBifurcationKit
const BK = BifurcationKit
record_from_solution(x, p; k...) = (D₂₃ = x[6], β = x[1],)
####################################################################################################
function OPL!(dz, u, p, t = 0)
(;b, σ, g, a, D₂₁⁰, D₂₃⁰) = p
β, p₂₁, p₂₃, p₃₁, D₂₁, D₂₃ = u
dz[1] = -σ * β + g * p₂₃
dz[2] = -p₂₁ - β * p₃₁ + a * D₂₁
dz[3] = -p₂₃ + β * D₂₃ - a * p₃₁
dz[4] = -p₃₁ + β * p₂₁ + a * p₂₃
dz[5] = -b * (D₂₁ - D₂₁⁰) - 4a * p₂₁ - 2β * p₂₃
dz[6] = -b * (D₂₃ - D₂₃⁰) - 2a * p₂₁ - 4β * p₂₃
dz
end
par_OPL = (b = 1.2, σ = 2.0, g=50., a = 1., D₂₁⁰ = -1., D₂₃⁰ = 0.)
z0 = zeros(6)
prob = BK.BifurcationProblem(OPL!, z0, par_OPL, (@optic _.a); record_from_solution)
We first compute the branch of equilibria
opts_br = ContinuationPar(p_min = -1., p_max = 8., ds = 0.001, dsmax = 0.06, n_inversion = 6, nev = 6)
br = continuation(prob, PALC(), opts_br; normC = norminf)
plot(br, plotfold=true)
br2 = continuation(re_make(prob; u0 = [1.6931472491037485, -0.17634826359471437, 0.06772588996414994, -0.23085768742546342, -0.5672243219935907, -0.09634826359471438]), PALC(), opts_br; normC = norminf)
scene = plot(br, br2)
Codimension 2 bifurcations
sn_br = continuation(br, 1, (@optic _.b), ContinuationPar(opts_br, detect_bifurcation = 1, max_steps = 80) ;
detect_codim2_bifurcation = 2,
start_with_eigen = true,
bothside = true,
)
show(sn_br)
hopf_br = continuation(br, 2, (@optic _.b), ContinuationPar(opts_br, detect_bifurcation = 1, max_steps = 140),
detect_codim2_bifurcation = 2,
bothside = true,
)
hopf_br2 = continuation(br2, 1, (@optic _.b), ContinuationPar(opts_br, detect_bifurcation = 1, max_steps = 140),
detect_codim2_bifurcation = 2,
bothside = true,
)
show(hopf_br2)
┌ Warning: [Codim 2 Hopf - Finalizer] The Hopf curve seems to be close to a BT point: ω ≈ 1.9480996957042472e-16. Stopping computations at (-1.1888807173990747, -1.3000236804649769e-18). If the BT point is not detected, try lowering Newton tolerance or dsmax.
└ @ BifurcationKit ~/.julia/packages/BifurcationKit/RaJtn/src/codim2/MinAugHopf.jl:466
┌ Warning: More than one Event was detected bt-bp. We call the continuous event to save data in the branch.
└ @ BifurcationKit ~/.julia/packages/BifurcationKit/RaJtn/src/events/EventDetection.jl:348
┌ Warning: [Codim 2 Hopf - Finalizer] The Hopf curve seems to be close to a BT point: ω ≈ 1.4745706480588852e-17. Stopping computations at (-1.5468233549487838, -2.889089079658572e-19). If the BT point is not detected, try lowering Newton tolerance or dsmax.
└ @ BifurcationKit ~/.julia/packages/BifurcationKit/RaJtn/src/codim2/MinAugHopf.jl:466
┌─ Curve type: HopfCont
├─ Number of points: 57
├─ Type of vectors: Vector{Float64}
├─ Parameters (:a, :b)
├─ Parameter b starts at -2.889089079658572e-19, ends at 1.34897480907086
├─ Algo: PALC
└─ Special points:
- # 1, endpoint at b ≈ -0.00000000, step = 0
- # 2, bt at b ≈ -0.00000000 ∈ (-0.00000000, +0.00000000), |δp|=4e-13, [converged], δ = ( 0, 0), step = 0
- # 3, bt at b ≈ +0.00000000 ∈ (-0.00000000, +0.00000000), |δp|=4e-13, [ guessL], δ = ( 0, 0), step = 1
- # 4, gh at b ≈ +1.06366729 ∈ (+1.06366729, +1.06367897), |δp|=1e-05, [converged], δ = ( 0, 0), step = 28
- # 5, bt at b ≈ +1.34897481 ∈ (+1.34897481, +1.34897481), |δp|=6e-10, [converged], δ = ( 0, 0), step = 56
- # 6, endpoint at b ≈ +1.34897481, step = 56
# plot(sn_br, vars = (:a, :b), branchlabel = "SN", )
plot(hopf_br, branchlabel = "Hopf", vars = (:a, :b))
plot!(hopf_br2, branchlabel = "Hopf", vars = (:a, :b))
ylims!(0,1.5)
Branch of homoclinic orbits with Orthogonal Collocation
# plotting function
function plotPO(x, p; k...)
xtt = BK.get_periodic_orbit(p.prob, x, set(getparams(p.prob), BK.getlens(p.prob), p.p))
plot!(xtt.t, xtt[1,:]; markersize = 2, k...)
plot!(xtt.t, xtt[6,:]; k...)
scatter!(xtt.t, xtt[1,:]; markersize = 1, legend = false, k...)
end
# record function
function recordPO(x, p; k...)
xtt = BK.get_periodic_orbit(p.prob, x, set(getparams(p.prob), BK.getlens(p.prob), p.p))
period = BK.getperiod(p.prob, x, p.p)
return (max = maximum(xtt[6,:]), min = minimum(xtt[6,:]), period = period, )
end
# newton parameters
optn_po = NewtonPar(verbose = true, tol = 1e-8, max_iterations = 25)
# continuation parameters
opts_po_cont = ContinuationPar(dsmax = 0.05, ds= 0.001, dsmin = 1e-4, p_max = 6.8, p_min=-5., max_steps = 100, newton_options = (@set optn_po.tol = 1e-8), detect_bifurcation = 0, plot_every_step = 3)
br_coll = continuation(
br2, 1,
opts_po_cont,
PeriodicOrbitOCollProblem(20, 4; meshadapt = true, update_section_every_step = 2);
ampfactor = 1., δp = 0.0015,
verbosity = 2, plot = true,
alg = PALC(tangent = Bordered()),
record_from_solution = recordPO,
plot_solution = (x, p; k...) -> begin
plotPO(x, p; k...)
## add previous branch
plot!(br, subplot=1, putbifptlegend = false)
plot!(br2, subplot=1, putbifptlegend = false)
end,
finalise_solution = (z, tau, step, contResult; prob = nothing, kwargs...) -> begin
# limit the period
return z.u[end] < 150
true
end,
normC = norminf)
_sol = get_periodic_orbit(br_coll, length(br_coll))
BK.plot(_sol.t, _sol.u'; marker = :d, markersize = 1,title = "Last periodic orbit on branch")
probhom, solh = generate_hom_problem(
setproperties(br_coll.prob.prob, meshadapt=true, K = 100),
br_coll.sol[end].x.sol,
BK.setparam(br_coll, br_coll.sol[end].p),
BK.getlens(br_coll);
update_every_step = 4,
verbose = true,
# ϵ0 = 1e-7, ϵ1 = 1e-7, # WORK BEST
# ϵ0 = 1e-8, ϵ1 = 1e-5, # maxT = 70,
t0 = 0., t1 = 120.,
# freeparams = ((@optic _.T), (@optic _.ϵ1),)
# freeparams = ((@optic _.T), (@optic _.ϵ0)),
freeparams = ((@optic _.ϵ0), (@optic _.ϵ1)), # WORK BEST
# freeparams = ((@optic _.T),),
testOrbitFlip = false,
testInclinationFlip = false
)
#####
_sol = get_homoclinic_orbit(probhom, solh, BK.getparams(probhom);)
BK.plot(_sol.t, _sol.u'; marker = :d, markersize = 1,title = "Guess for homoclinic orbit")
optn_hom = NewtonPar(verbose = true, tol = 1e-10, max_iterations = 5)
optc_hom = ContinuationPar(newton_options = optn_hom, ds = -1e-4, dsmin = 1e-5, detect_bifurcation = 0, detect_event = 2, p_min = -1.01, dsmax = 4e-2, p_max = 1.5, max_steps = 100)
br_hom_c = continuation(
deepcopy(probhom), solh, (@optic _.b),
PALC(tangent = Bordered()),
optc_hom;
verbosity = 1, plot = true,
normC = norminf,
plot_solution = (x,p;k...) -> begin
𝐇𝐨𝐦 = p.prob
par0 = set(BK.getparams(𝐇𝐨𝐦), BK.getlens(𝐇𝐨𝐦), x.x[end][1])
par0 = set(par0, (@optic _.b), p.p)
sol = get_homoclinic_orbit(𝐇𝐨𝐦, x, par0)
m = (𝐇𝐨𝐦.bvp isa PeriodicOrbitOCollProblem && 𝐇𝐨𝐦.bvp.meshadapt) ? :d : :none
plot!(sol.t, sol[:,:]',subplot=3, markersize = 1, marker=m)
end,
)
# plot(sn_br, vars = (:a, :b), branchlabel = "SN", )
plot(hopf_br, branchlabel = "AH₀", vars = (:a, :b))
plot!(hopf_br2, branchlabel = "AH₁₂", vars = (:a, :b))
plot!(br_hom_c, branchlabel = "H₀", vars = (:a, :b))
ylims!(0.1,1.5)
Branch of homoclinic orbits with Multiple Shooting
using DifferentialEquations
probsh = ODEProblem(OPL!, copy(z0), (0., 1000.), par_OPL; abstol = 1e-12, reltol = 1e-10)
# newton parameters
optn_po = NewtonPar(verbose = true, tol = 1e-8, max_iterations = 25)
# continuation parameters
opts_po_cont = ContinuationPar(dsmax = 0.075, ds= -0.001, dsmin = 1e-4, p_max = 6.8, p_min=-5., max_steps = 130, newton_options = (@set optn_po.tol = 1e-8), tol_stability = 1e-4, detect_bifurcation = 0)
br_sh = continuation(
br2, 1,
opts_po_cont,
ShootingProblem(8, probsh, Rodas5P(); parallel = true, abstol = 1e-13, reltol = 1e-11);
ampfactor = 1., δp = 0.0015,
verbosity = 2, plot = true,
record_from_solution = recordPO,
callback_newton = BK.cbMaxNorm(1e0),
plot_solution = (x, p; k...) -> begin
plotPO(x, p; k...)
## add previous branch
# plot!(br, subplot=1, putbifptlegend = false)
end,
finalise_solution = (z, tau, step, contResult; prob = nothing, kwargs...) -> begin
# limit the period
return z.u[end] < 100
true
end,
normC = norminf)
_sol = get_periodic_orbit(br_sh.prob.prob, br_sh.sol[end].x, BK.setparam(br_sh, br_sh.sol[end].p))
plot(_sol.t, _sol[1:3,:]')
# homoclinic
probhom, solh = generate_hom_problem(
br_sh.prob.prob, br_sh.sol[end].x,
BK.setparam(br_sh, br_sh.sol[end].p),
BK.getlens(br_sh);
verbose = true,
update_every_step = 4,
# ϵ0 = 1e-6, ϵ1 = 1e-5,
t0 = 75, t1 = 25,
# freeparams = ((@optic _.T), (@optic _.ϵ1),)
# freeparams = ((@optic _.T), (@optic _.ϵ0)),
# freeparams = ((@optic _.ϵ0), (@optic _.ϵ1)), # WORK BEST
freeparams = ((@optic _.T),),
)
_sol = get_homoclinic_orbit(probhom, solh, BK.getparams(probhom); saveat=.1)
plot(plot(_sol[1,:], _sol[2,:]), plot(_sol.t, _sol[1:4,:]'))
optn_hom = NewtonPar(verbose = true, tol = 1e-9, max_iterations = 7)
optc_hom = ContinuationPar(newton_options = optn_hom, ds = -1e-4, dsmin = 1e-6, max_steps = 300, detect_bifurcation = 0, dsmax = 12e-2, plot_every_step = 3, p_max = 7., detect_event = 2, a = 0.9)
br_hom_sh = continuation(
deepcopy(probhom), solh, (@optic _.b),
PALC(),
optc_hom;
verbosity = 3, plot = true,
callback_newton = BK.cbMaxNorm(1e0),
normC = norminf,
plot_solution = (x,p;k...) -> begin
𝐇𝐨𝐦 = p.prob
par0 = set(BK.getparams(𝐇𝐨𝐦), BK.getlens(𝐇𝐨𝐦), x.x[end][1])
par0 = set(par0, (@optic _.b), p.p)
sol = get_homoclinic_orbit(𝐇𝐨𝐦, x, par0)
m = (𝐇𝐨𝐦.bvp isa PeriodicOrbitOCollProblem && 𝐇𝐨𝐦.bvp.meshadapt) ? :d : :none
plot!(sol.t, sol[1:6,:]',subplot=3, markersize = 1, marker=m)
end,
)
_sol = get_homoclinic_orbit(probhom, br_hom_sh.sol[end].x, BK.setparam(br_hom_sh, br_hom_sh.sol[end].p); saveat=.1)
plot(_sol.t, _sol[1:6,:]')
# plot(sn_br, vars = (:a, :b), branchlabel = "SN", )
plot(hopf_br, branchlabel = "AH₀", vars = (:a, :b))
plot!(hopf_br2, branchlabel = "AH₁₂", vars = (:a, :b))
plot!(br_hom_c, branchlabel = "Hc₀", vars = (:a, :b))
plot!(br_hom_sh, branchlabel = "Hsh₀", vars = (:a, :b), linewidth = 3)
ylims!(0,1.5)
References
- Pusuluri
Pusuluri, K, H G E Meijer, and A L Shilnikov. “Homoclinic Puzzles and Chaos in a Nonlinear Laser Model,” n.d.