Get Started with Efficient BVP solving in Julia
When ordinary differential equations has constraints over the time span, we should model the differential equations as a boundary value problem which has the form of:
\[\frac{du}{dt} = f(u, p, t) \\ g(u(a),u(b)) = 0\]
BoundaryValueDiffEq.jl addresses three types of BVProblem.
- General boundary value problems:, i.e., differential equations with constraints applied over the time span. This is a system where you would like to obtain the solution of the differential equations and make sure the solution satisfy the boundary conditions simutanously.
- General second order boundary value problems, i.e., differential equations with constraints for both solution and derivative of solution applied over time span. This is a system where you would like to obtain the solution of the differential equations and make sure the solution satisfy the boundary conditions simutanously.
- Boundary value differential-algebraic equations, i.e., apart from constraints applied over the time span, BVDAE has additional algebraic equations which state the algebraic relationship of different states in BVDAE.
Solving Linear two-point boundary value problem
Consider the linear two-point boundary value problem from standard BVP test problem.
using BoundaryValueDiffEq
function f!(du, u, p, t)
du[1] = u[2]
du[2] = u[1]
return
end
function bc!(res, u, p, t)
res[1] = u(0.0)[1] - 1
res[2] = u(1.0)[1]
return
end
tspan = (0.0, 1.0)
u0 = [0.0, 0.0]
prob = BVProblem(f!, bc!, u0, tspan)
sol = solve(prob, MIRK4(), dt = 0.01)retcode: Success
Interpolation: MIRK Order 4 Interpolation
t: 101-element Vector{Float64}:
0.0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
⋮
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99
1.0
u: 101-element Vector{Vector{Float64}}:
[1.0000000000000002, -1.3130352855093994]
[0.9869194287214476, -1.3031007711534117]
[0.9739375502081996, -1.2932965679604564]
[0.961053066261587, -1.2836216955020445]
[0.9482646884224784, -1.2740751862828676]
[0.9355711378424326, -1.264656085644049]
[0.9229711451558134, -1.255363451667674]
[0.9104634503528526, -1.246196355082602]
[0.8980468026536467, -1.2371538791715353]
[0.8857199603830783, -1.2282351196793475]
⋮
[0.06814608517899787, -0.8536425188086404]
[0.059612925049218654, -0.8530037290807472]
[0.05108572626162192, -0.8524502404365982]
[0.04256363608922266, -0.8519819975268682]
[0.034045802315902034, -0.8515989535268759]
[0.025531373151184485, -0.8513010701319021]
[0.01701949714505822, -0.851088317553359]
[0.008509323102829352, -0.8509606745158118]
[1.888963463549682e-15, -0.8509181282548499]Since this problem only has constraints at the start and end of the time span, we can directly use TwoPointBVProblem:
function f!(du, u, p, t)
du[1] = u[2]
du[2] = u[1]
return
end
function bca!(res, ua, p)
res[1] = ua[1] - 1
return
end
function bcb!(res, ub, p)
res[1] = ub[1]
return
end
tspan = (0.0, 1.0)
u0 = [0.0, 0.0]
prob = TwoPointBVProblem(
f!, (bca!, bcb!), u0, tspan, bcresid_prototype = (zeros(1), zeros(1))
)
sol = solve(prob, MIRK4(), dt = 0.01)retcode: Success
Interpolation: MIRK Order 4 Interpolation
t: 101-element Vector{Float64}:
0.0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
⋮
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99
1.0
u: 101-element Vector{Vector{Float64}}:
[1.0, -1.3130352855093863]
[0.9869194287214468, -1.3031007711533988]
[0.9739375502081986, -1.2932965679604438]
[0.9610530662615859, -1.2836216955020319]
[0.9482646884224767, -1.2740751862828552]
[0.9355711378424306, -1.264656085644036]
[0.9229711451558111, -1.2553634516676615]
[0.9104634503528498, -1.2461963550825896]
[0.8980468026536435, -1.237153879171523]
[0.8857199603830749, -1.2282351196793353]
⋮
[0.06814608517899479, -0.8536425188086307]
[0.0596129250492158, -0.8530037290807374]
[0.051085726261619085, -0.8524502404365886]
[0.04256363608921999, -0.8519819975268585]
[0.03404580231589969, -0.8515989535268664]
[0.02553137315118217, -0.8513010701318926]
[0.017019497145056007, -0.8510883175533496]
[0.008509323102827404, -0.850960674515802]
[0.0, -0.85091812825484]Solving second order boundary value problem
Consirder the test problem from example problems in MIRKN paper Muir and Adams [1].
\[\begin{align*} y_1'(x) &= y_2(x),\\ ε y_2'(x) &= -y_1(x) y_2'(x) - y_3(x) y_3'(x), \\ ε y_3'(x) &= y_1'(x) y_3(x) - y_1(x) y_3'(x) \end{align*}\]
with initial conditions:
\[\begin{align*} y_1(0) &= y_1'(0) = y_1(1) = y_1'(1) = 0, \\ y_3(0) &= -1, \\ y_3(1) &=1 \end{align*}\]
using BoundaryValueDiffEqMIRKN
function f!(ddu, du, u, p, t)
ε = 0.1
ddu[1] = u[2]
ddu[2] = (-u[1] * du[2] - u[3] * du[3]) / ε
ddu[3] = (du[1] * u[3] - u[1] * du[3]) / ε
return
end
function bc!(res, du, u, p, t)
res[1] = u(0.0)[1]
res[2] = u(1.0)[1]
res[3] = u(0.0)[3] + 1
res[4] = u(1.0)[3] - 1
res[5] = du(0.0)[1]
res[6] = du(1.0)[1]
return
end
u0 = [1.0, 1.0, 1.0]
tspan = (0.0, 1.0)
prob = SecondOrderBVProblem(f!, bc!, u0, tspan)
sol = solve(prob, MIRKN4(), dt = 0.01)retcode: Success
Interpolation: 1st order linear
t: 101-element Vector{Float64}:
0.0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
⋮
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99
1.0
u: 101-element Vector{RecursiveArrayTools.ArrayPartition{Float64, Tuple{Vector{Float64}, Vector{Float64}}}}:
([0.0, 0.332894023156958, -1.0], [0.0, -4.010483700884779, 2.0236677823390985])
([1.5984690703048272e-5, 0.293794186609831, -0.9797638577347598], [0.0031317717463644427, -3.8101677065840116, 2.02350899168225])
([6.136532189363588e-5, 0.2566769583280866, -0.9595307801446122], [0.00588249244461684, -3.6139647793072855, 2.023062062423978])
([0.00013242982733332128, 0.22150113124597434, -0.939303437900239], [0.008271782264850052, -3.4218896565078647, 2.0223685705331866])
([0.00022566027980827215, 0.18822536664928907, -0.9190841026599386], [0.010318848622478977, -3.23395398192032, 2.021466768925303])
([0.0003377287575029482, 0.15680822360096383, -0.8988746795140786], [0.012042485011375694, -3.0501666045811384, 2.020391744067036])
([0.00046549320012739755, 0.12720818547409438, -0.8786767378817363], [0.013461070116636064, -2.87053385845286, 2.0191755689450877])
([0.0006059932574530525, 0.09938368378241115, -0.8584915408955731], [0.014592567179008758, -2.695059823442804, 2.0178474524597827])
([0.0007564461326415884, 0.07329311949028493, -0.838320073310437], [0.015454523584878243, -2.5237465686096745, 2.016433885293567])
([0.0009142424224993007, 0.048894881976431596, -0.8181630679707326], [0.016064070657474474, -2.35659437834834, 2.01495878229478])
⋮
([-0.0007564462683575229, -0.07329317370684821, 0.8383200245258973], [0.015454527178535878, -2.5237462679076486, 2.01643449257847])
([-0.0006059933598936757, -0.0993837350647005, 0.8584914981899895], [0.014592570245303756, -2.6950595385210625, 2.0178480609060236])
([-0.0004654932744225575, -0.12720823401581421, 0.8786767012650246], [0.013461072684001653, -2.870533596393183, 2.01917617822382])
([-0.000337728808508998, -0.1568082696637007, 0.8988746489931869], [0.01204248710596376, -3.050166371882654, 2.0203923539134263])
([-0.00022566031213418715, -0.188225410556951, 0.9190840782394801], [0.010318850267509633, -3.233953784565617, 2.0214673791367828])
([-0.00013242984537305033, -0.2215011733802805, 0.9393034195830932], [0.008271783480012168, -3.421889500106908, 2.022369180964326])
([-6.136532986425008e-5, -0.25667699912586883, 0.9595307679324545], [0.00588249324550522, -3.6139646693137646, 2.023062672977649])
([-1.5984692688421936e-5, -0.29379422656277565, 0.9797638516284849], [0.0031317721439322213, -3.81016764856163, 2.023509602296991])
([0.0, -0.3328940628140731, 1.0], [0.0, -4.0104837007750795, 2.0236683929729495])Solving semi-explicit boundary value differential-algebraic equations
Consider the nonlinear semi-explicit DAE of index at most 2 in COLDAE paper Ascher and Spiteri [2]
\[\begin{align*} x_1' &= (ε+ x_2 - \sin(t)) y + \cos(t) \\ x_2' &= \cos(t) \\ x_3' &= y \\ 0 &= [x_1-p_1(t)] \left(y - e^t\right) \end{align*}\]
with boundary conditions
\[\begin{align*} x_1(0) &= 0, \\ x_3(0) &= 1, \\ x_2(1) &= \sin(1) \end{align*}\]
using BoundaryValueDiffEqAscher
function f!(du, u, p, t)
du[1] = (1 + u[2] - sin(t)) * u[4] + cos(t)
du[2] = cos(t)
du[3] = u[4]
du[4] = (u[1] - sin(t)) * (u[4] - exp(t))
return
end
function bc!(res, u, p, t)
res[1] = u(0.0)[1]
res[2] = u(0.0)[3] - 1
res[3] = u(1.0)[2] - sin(1.0)
return
end
u0 = [0.0, 0.0, 0.0, 0.0]
tspan = (0.0, 1.0)
mass_matrix = [1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 0]
fun = BVPFunction(f!, bc!; mass_matrix)
prob = BVProblem(fun, u0, tspan)
sol = solve(prob, Ascher4(), dt = 0.01)retcode: Success
Interpolation: Ascher collocation polynomial
t: 101-element Vector{Float64}:
0.0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
⋮
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99
1.0
u: 101-element Vector{Vector{Float64}}:
[0.0, -1.0946105133413653e-15, 1.0, 2.3859784841767702e-12]
[0.009999833334166673, 0.00999983333416558, 1.0, 4.5429100182399863e-13]
[0.01999866669333309, 0.019998666693332005, 0.9999999999999999, 2.5994856720622157e-13]
[0.029995500202495674, 0.029995500202494595, 1.0000000000000002, 1.8348465441313787e-13]
[0.03998933418663418, 0.039989334186633106, 1.0000000000000002, 1.4261426496333798e-13]
[0.04997916927067836, 0.04997916927067729, 1.0000000000000002, 1.1706991913340566e-13]
[0.05996400647944464, 0.05996400647944357, 1.0000000000000002, 9.871047989198557e-14]
[0.06994284733753282, 0.06994284733753175, 1.0000000000000002, 8.67308571627503e-14]
[0.07991469396917274, 0.07991469396917168, 1.0000000000000002, 7.609865476048423e-14]
[0.0898785491980111, 0.08987854919801005, 0.9999999999999999, 6.928010351746274e-14]
⋮
[0.7956016200363661, 0.7956016200363659, 0.9999999999999989, 1.0403922059013811e-14]
[0.8016199408837773, 0.8016199408837771, 0.9999999999999989, 1.0116821062803834e-14]
[0.8075581004051144, 0.8075581004051141, 0.9999999999999989, 1.0179218072266523e-14]
[0.813415504789374, 0.8134155047893736, 0.9999999999999989, 1.0557389983973713e-14]
[0.8191915683009985, 0.8191915683009982, 0.9999999999999989, 9.844951466653356e-15]
[0.8248857133384503, 0.82488571333845, 0.999999999999999, 9.710681586607396e-15]
[0.8304973704919707, 0.8304973704919704, 0.999999999999999, 9.436938759619721e-15]
[0.8360259786005207, 0.8360259786005204, 0.999999999999999, 9.015056010453568e-15]
[0.8414709848078967, 0.8414709848078964, 0.999999999999999, -1.2225781890436722e-14]