A differential-algebraic equation is defined by an implicit function f(du,u,p,t)=0
. All of the controls are the same as the other examples, except here you define a function which returns the residuals for each part of the equation to define the DAE. The initial value u0
and the initial derivative du0
are required, though they do not necessarily have to satisfy f
(known as inconsistent initial conditions). The methods will automatically find consistent initial conditions. In order for this to occur, differential_vars
must be set. This vector states which of the variables are differential (have a derivative term), with false
meaning that the variable is purely algebraic.
This example shows how to solve the Robertson equation:
<- function (du,u,p,t) {
f = - 0.04*u[1] + 1e4*u[2]*u[3] - du[1]
resid1 = + 0.04*u[1] - 3e7*u[2]^2 - 1e4*u[2]*u[3] - du[2]
resid2 = u[1] + u[2] + u[3] - 1.0
resid3 c(resid1,resid2,resid3)
}<- c(1.0, 0, 0)
u0 <- c(-0.04, 0.04, 0.0)
du0 <- c(0.0,100000.0)
tspan <- c(TRUE,TRUE,FALSE)
differential_vars <- de$DAEProblem(f,du0,u0,tspan,differential_vars=differential_vars)
prob <- de$solve(prob)
sol <- as.data.frame(t(sapply(sol$u,identity)))
udf ::plot_ly(udf, x = sol$t, y = ~V1, type = 'scatter', mode = 'lines') %>%
plotly::add_trace(y = ~V2) %>%
plotly::add_trace(y = ~V3) plotly
Additionally, an in-place JIT compiled form for f
can be used to enhance the speed:
= JuliaCall::julia_eval("function f(out,du,u,p,t)
f out[1] = - 0.04u[1] + 1e4*u[2]*u[3] - du[1]
out[2] = + 0.04u[1] - 3e7*u[2]^2 - 1e4*u[2]*u[3] - du[2]
out[3] = u[1] + u[2] + u[3] - 1.0
end")
<- c(1.0, 0, 0)
u0 <- c(-0.04, 0.04, 0.0)
du0 <- c(0.0,100000.0)
tspan <- c(TRUE,TRUE,FALSE)
differential_vars ::julia_assign("du0", du0)
JuliaCall::julia_assign("u0", u0)
JuliaCall::julia_assign("p", p)
JuliaCall::julia_assign("tspan", tspan)
JuliaCall::julia_assign("differential_vars", differential_vars)
JuliaCall= JuliaCall::julia_eval("DAEProblem(f, du0, u0, tspan, p, differential_vars=differential_vars)")
prob = de$solve(prob) sol