Modified Morris-Lecar model

Modified Morris-Lecar model

Modified Morris-Lecar model from Dhooge, Govaerts, Kuznetsov (2003):

using Bifurcations
using Bifurcations: special_intervals
using Bifurcations.Codim1
using Bifurcations.Codim2
using Bifurcations.Codim2LimitCycle: FoldLimitCycleProblem
using Bifurcations.Examples: MorrisLecar

using Setfield: @lens
using Plots

Solve continuation of the equilibrium point:

solver = init(
    MorrisLecar.make_prob();
    start_from_nearest_root = true,
    max_branches = 0,
    nominal_angle_rad = 2π * (5 / 360),
)
@time solve!(solver)
Codim1Solver <Continuous>
# sweeps             : 2
# points             : 41
# branches           : 0
# saddle_node        : 2
# hopf               : 1

Plot equilibriums in $(u_1, y)$-space:

plt1 = plot(solver)

Start continuation of Hopf bifurcation

hopf_point, = special_intervals(solver, Codim1.PointTypes.hopf)
1-element Array{Bifurcations.BifurcationsBase.SpecialPointInterval{Bifurcations.BifurcationsBase.Continuous,Bifurcations.Codim1.PointTypes.PointType,StaticArrays.SArray{Tuple{3},Float64,1,3},StaticArrays.SArray{Tuple{2,3},Float64,2,6}},1}:
 SpecialPointInterval <Continuous hopf>
happened between:
  u0 = [0.0407794, 0.306436, 0.0883504]
  u1 = [0.0314239, 0.279715, 0.0601626]

Solve continuation of the Hopf point:

codim2_prob = BifurcationProblem(
    hopf_point,
    solver,
    (@lens _.z),
    (-1.0, 1.0),
)
hopf_solver1 = init(
    codim2_prob;
    nominal_angle_rad = 0.01,
)
@time solve!(hopf_solver1)
Codim2Solver <Continuous>
# sweeps             : 2
# points             : 55
# branches           : 0
# bautin             : 1

Start continuation of fold bifurcation of limit cycle at Bautin bifurcation

bautin_point, = special_intervals(hopf_solver1, Codim2.PointTypes.bautin)
1-element Array{Bifurcations.BifurcationsBase.SpecialPointInterval{Bifurcations.BifurcationsBase.Continuous,Bifurcations.Codim2.PointTypes.PointType,StaticArrays.SArray{Tuple{9},Float64,1,9},StaticArrays.SArray{Tuple{8,9},Float64,2,72}},1}:
 SpecialPointInterval <Continuous bautin>
happened between:
  u0 = [0.0298965, 0.350792, 0.367924, 0.382807, 0.82458, -0.195343, 2.0067, 0.165926, 0.0745246]
  u1 = [0.0295841, 0.35324, 0.367212, 0.382471, 0.824988, -0.19562, 2.01059, 0.169869, 0.0734342]

Construct a problem for fold bifurcation of the limit cycle starting at bautin_point:

flc_prob = FoldLimitCycleProblem(
    bautin_point,
    hopf_solver1;
    period_bound = (0.0, 14.0),  # see below
    num_mesh = 120,
    degree = 4,
)
flc_solver = init(
    flc_prob;
    start_from_nearest_root = true,
    max_branches = 0,
    bidirectional_first_sweep = false,
    nominal_angle_rad = 2π * (5 / 360),
    max_samples = 500,
)
@time solve!(flc_solver)
BifurcationSolver <Continuous>
# sweeps             : 1
# points             : 46
# branches           : 0

Plot the limit cycles at fold bifurcation boundaries:

plt_state_space = plot_state_space(flc_solver)

The continuation was configured to stop just before the period is about to diverge. Note that stopping at larger period requires larger mesh size.

plt_periods = plot(flc_solver, (x=:p1, y=:period))

Start continuation of Saddle-Node bifurcation

sn_point, = special_intervals(solver, Codim1.PointTypes.saddle_node)
2-element Array{Bifurcations.BifurcationsBase.SpecialPointInterval{Bifurcations.BifurcationsBase.Continuous,Bifurcations.Codim1.PointTypes.PointType,StaticArrays.SArray{Tuple{3},Float64,1,3},StaticArrays.SArray{Tuple{2,3},Float64,2,6}},1}:
 SpecialPointInterval <Continuous saddle_node>
happened between:
  u0 = [-0.0311873, 0.140701, -0.0206357]
  u1 = [-0.0373, 0.130813, -0.0205553]
  
 SpecialPointInterval <Continuous saddle_node>
happened between:
  u0 = [-0.23318, 0.00999542, 0.0828906]
  u1 = [-0.247815, 0.00818325, 0.0832351]

Going back to the original continuation of the equilibrium, let's start continuation of one of the saddle-node bifurcation:

sn_prob = BifurcationProblem(
    sn_point,
    solver,
    (@lens _.z),
    (-1.0, 1.0),
)
sn_solver = init(
    sn_prob;
    nominal_angle_rad = 0.01,
    max_samples = 1000,
    start_from_nearest_root = true,
)
@time solve!(sn_solver)
Codim2Solver <Continuous>
# sweeps             : 2
# points             : 385
# branches           : 0
# cusp               : 1
# bogdanov_takens    : 1

Switching to continuation of Hopf bifurcation at Bogdanov-Takens bifurcation

hopf_prob2 = BifurcationProblem(
    special_intervals(sn_solver, Codim2.PointTypes.bogdanov_takens)[1],
    sn_solver,
)
hopf_solver2 = init(hopf_prob2)
@time solve!(hopf_solver2)
Codim2Solver <Continuous>
# sweeps             : 2
# points             : 11
# branches           : 0
# bogdanov_takens    : 1

Phase diagram

plt2 = plot()
for s in [hopf_solver1, flc_solver, sn_solver, hopf_solver2]
    plot!(plt2, s)
end
plot!(plt2, ylim=(0.03, 0.15), xlim=(-0.05, 0.2))