Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions lib/ModelingToolkitBase/src/problems/odeproblem.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
"""
generate_ODENLStepData(sys, u0, p, mm, nlstep_compile, nlstep_scc)
generate_ODENLStepData(sys, u0, p, mm, nlstep_compile, nlstep_scc; jac = false)

Generate the NLStep data for implicit ODE solvers. This is a stub that throws an error
if called without ModelingToolkit loaded. The actual implementation is provided by
ModelingToolkit when it is loaded.

When `jac = true`, the analytic Jacobian of the teared inner nonlinear system is
generated symbolically and attached to `nlprob.f.jac`, so NonlinearSolve does not
have to recompute it via AD/FD on every Newton iteration.
"""
function generate_ODENLStepData(sys, u0, p, mm, nlstep_compile, nlstep_scc)
function generate_ODENLStepData(sys, u0, p, mm, nlstep_compile, nlstep_scc; jac = false)
error(
"""
`nlstep=true` requires ModelingToolkit.jl to be loaded.
Expand Down Expand Up @@ -65,7 +69,7 @@ Base.@nospecializeinfer @fallback_iip_specialize function SciMLBase.ODEFunction{
_M = concrete_massmatrix(M; sparse, u0)

if nlstep
ode_nlstep = generate_ODENLStepData(sys, u0, p, M, nlstep_compile, nlstep_scc)
ode_nlstep = generate_ODENLStepData(sys, u0, p, M, nlstep_compile, nlstep_scc; jac)
else
ode_nlstep = nothing
end
Expand Down
10 changes: 7 additions & 3 deletions src/systems/solver_nlprob.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
function MTKBase.generate_ODENLStepData(
sys::System, u0, p, mm = calculate_massmatrix(sys),
nlstep_compile::Bool = true, nlstep_scc::Bool = false
nlstep_compile::Bool = true, nlstep_scc::Bool = false;
jac::Bool = false
)
nlsys, outer_tmp, inner_tmp = inner_nlsystem(sys, mm, nlstep_compile)
state = ProblemState(; u = u0, p)
Expand All @@ -15,10 +16,13 @@ function MTKBase.generate_ODENLStepData(
haskey(op, v) && continue
op[v] = getsym(sys, v)(state)
end
# Forward the outer ODEFunction's `jac` flag so the inner teared nonlinear
# problem also carries an analytic Jacobian. This lets NonlinearSolve.jl
# skip the per-iteration AD/FD Jacobian computation on the inner Newton.
nlprob = if nlstep_scc
SCCNonlinearProblem(nlsys, op; build_initializeprob = false)
SCCNonlinearProblem(nlsys, op; build_initializeprob = false, jac)
else
NonlinearProblem(nlsys, op; build_initializeprob = false)
NonlinearProblem(nlsys, op; build_initializeprob = false, jac)
end

subsetidxs = [findfirst(isequal(y), unknowns(sys)) for y in unknowns(nlsys)]
Expand Down
Loading