using ODEInterface
@ODEInterface.import_huge

# We look at (again) the boundary value problem (see, ex6.jl)
#
#                       sin⁴(x)
#    ε⋅y'(x) = sin²(x)-λ──────  ;   y(-π/2)=y(π/2)=1
#                         y
#
# Here ε is given (e.g. ε=0.1) and λ is an unknown parameter.
#
# We use bvpm2 and a "homotopy": starting with ε=0.1, using this
# solution as start-guess for smaller ε.

a, b = -pi / 2, pi / 2

found_pyplot = true
try
    using PyPlot
catch
    found_pyplot = false
end

global ε = nothing
global ε_old = nothing
global sol_old = nothing

function rhs(x, y, p, f)
    return f[1] = (sin(x)^2 - p[1] * sin(x)^4 / y[1]) / ε
end

function Drhs(x, y, p, dfdy, dfdp)
    dfdy[1, 1] = (p[1] * sin(x)^4 / y[1]^2) / ε
    return dfdp[1, 1] = (-sin(x)^4 / y[1]) / ε
end

function bc(ya, yb, p, bca, bcb)
    bca[1] = ya[1] - 1.0
    return bcb[1] = yb[1] - 1.0
end

function Dbc(ya, yb, dya, dyb, p, dpa, dpb)
    dya[1, 1] = 1.0
    dyb[1, 1] = 1.0
    dpa[1, 1] = 0.0
    return dpb[1, 1] = 0.0
end

opt = OptionsODE(
    "example 7",
    OPT_RTOL => 1.0e-6,
    OPT_METHODCHOICE => 4,
)
xx = collect(linspace(a, b, 400));

initial_guess = Bvpm2()
bvpm2_init(initial_guess, 1, 1, collect(linspace(a, b, 20)), [0.5], [1.0])

sol = nothing
for ε in [0.1, 0.05, 0.02, 0.01]
    guess = sol_old !== nothing ? sol_old : initial_guess
    sol, retcode, stats = bvpm2_solve(guess, rhs, bc, opt, Drhs = Drhs, Dbc = Dbc)
    @printf("ε=%g, retcode=%i\n", ε, retcode)
    @assert retcode ≥ 0
    zz_new = evalSolution(sol, xx)
    if sol_old === nothing
        zz_old = copy(zz_new); zz_old[1, :] = 0.5
    else
        zz_old = evalSolution(sol_old, xx)
        bvpm2_destroy(sol_old)
    end
    if found_pyplot
        plot(xx, zz_old[1, :], xx, zz_new[1, :]);grid(true)
    end
    sol_old = sol; ε_old = ε
end

xx = collect(linspace(a, b, 9))
zz = evalSolution(sol, xx)
println("Solution at some points:")

display([ xx' ; zz[1, :]' ])
println()

bvpm2_destroy(initial_guess)
bvpm2_destroy(sol)

# vim:syn=julia:cc=79:fdm=indent:
