Skip to content

Optimization based solvers #350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 32 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
53dc9f2
Optimization based solvers
ErikQQY Jul 14, 2025
9b7ff46
Fix some typos
ErikQQY Jul 14, 2025
1cc250d
Don't fail other solvers
ErikQQY Jul 14, 2025
5931430
Fix unrelated failings
ErikQQY Jul 14, 2025
fac21aa
Fix more concrete solve algorithm
ErikQQY Jul 15, 2025
f9cd33f
Add default cost
ErikQQY Jul 17, 2025
c694c26
Nested FIRK should work with optimization solvers
ErikQQY Jul 17, 2025
93ea85a
More docstrings
ErikQQY Jul 18, 2025
54943e8
Proper assert
ErikQQY Jul 18, 2025
5c21462
Expanded FIRK should work
ErikQQY Jul 18, 2025
ce2b3e0
Fix Aqua error
ErikQQY Jul 18, 2025
3b905c9
Fix typo in compat
ErikQQY Jul 18, 2025
a041b90
Shooting and MultipleShooting work fine
ErikQQY Jul 20, 2025
b7f5762
MIRKN work fine
ErikQQY Jul 21, 2025
130da34
All solvers should be done
ErikQQY Jul 21, 2025
d7e4ef4
Fix kwargs issue with shooting
ErikQQY Jul 21, 2025
9901afb
Fix inplace assert in multiple shooting
ErikQQY Jul 21, 2025
f710cd7
Fix inplace assert in single shooting
ErikQQY Jul 21, 2025
5cc940a
Merge branch 'master' into qqy/bvp_opt
ErikQQY Jul 21, 2025
81da921
Use correct setup in FIRK testing
ErikQQY Jul 22, 2025
4d677c7
Unify testing environment
ErikQQY Jul 23, 2025
66a6b89
Fix ensemble test for FIRK
ErikQQY Jul 23, 2025
44d556f
Fix more FIRK tests
ErikQQY Jul 24, 2025
2237f70
Fix FIRK on simple pendulum
ErikQQY Jul 24, 2025
318f015
Set default abstol for nonlinear solving in shooting
ErikQQY Jul 24, 2025
ebc6dca
Fix kwargs issue with Shooting
ErikQQY Jul 24, 2025
3137c0b
Fix multiple shooting only use inplace problem constructor
ErikQQY Jul 24, 2025
3d0dc52
Fix typo
ErikQQY Jul 24, 2025
f16dc9a
Use proper Jacobian algorithm
ErikQQY Jul 24, 2025
ed84cb0
Fix internal solver
ErikQQY Jul 25, 2025
15eb2de
Fix nested FIRK testing
ErikQQY Jul 25, 2025
db1bddd
Fix shooting in manifold tests
ErikQQY Jul 25, 2025
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
3 changes: 2 additions & 1 deletion docs/src/basics/solve.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- `controller`: Error controller for collocation methods, default as `DefectControl()`, more controller options in [Error Control Adaptivity](@ref error_control).
- `defect_threshold`: Monitor of the size of defect norm. Defaults to `0.1`.
- `odesolve_kwargs`: OrdinaryDiffEq.jl solvers kwargs for passing to ODE solving in shooting methods. For more information, see the documentation for OrdinaryDiffEq: [Common Solver Options](https://docs.sciml.ai/DiffEqDocs/latest/basics/common_solver_opts/).
- `nlsolve_kwargs`: NonlinearSolve.jl solvers kwargs for passing to nonlinear solving in collocation methods and shooting methods. For more information, see the documentation for NonlinearSolve: [Commom Solver Options](https://docs.sciml.ai/NonlinearSolve/stable/basics/solve/). The default absolute tolerance of nonlinear solving in collocaio
- `nlsolve_kwargs`: NonlinearSolve.jl solvers kwargs for passing to nonlinear solving in collocation methods and shooting methods. For more information, see the documentation for NonlinearSolve: [Commom Solver Options](https://docs.sciml.ai/NonlinearSolve/stable/basics/solve/). The default internal nonlinear solver is [customized polyalgorithm](https://github.com/SciML/BoundaryValueDiffEq.jl/blob/master/lib/BoundaryValueDiffEqCore/src/default_nlsolve.jl) and the default absolute tolerance of nonlinear solving in collocation methods is `1e-6`.
- `optimize_kwargs`: Optimization.jl solvers kwargs for passing to optimizing in collocation methods and shooting methods. For more information, see the documentation for Optimization: [Commom Solver Options](https://docs.sciml.ai/Optimization/stable/API/solve/). The internal optimization solver should be specified and the default absolute tolerance of optimization problem solving in collocation methods is `1e-6`.
- `verbose`: Toggles whether warnings are thrown when the solver exits early. Defaults to `true`.
- `ensemblealg`: Whether `MultipleShooting` uses multithreading, default as `EnsembleThreads()`. For more information, see the documentation for OrdinaryDiffEq: [EnsembleAlgorithms](https://docs.sciml.ai/DiffEqDocs/latest/features/ensemble/#EnsembleAlgorithms).
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ using AlmostBlockDiagonals: AlmostBlockDiagonals, IntermediateAlmostBlockDiagona
using BoundaryValueDiffEqCore: AbstractBoundaryValueDiffEqAlgorithm,
AbstractBoundaryValueDiffEqCache, BVPJacobianAlgorithm,
__extract_problem_details, concrete_jacobian_algorithm,
__Fix3, __concrete_nonlinearsolve_algorithm,
__Fix3, __concrete_solve_algorithm,
__internal_nlsolve_problem, __vec, __vec_f, __vec_f!,
__vec_bc, __vec_bc!, __extract_mesh, get_dense_ad,
__get_bcresid_prototype, __split_kwargs,
__default_nonsparse_ad
__get_bcresid_prototype, __split_kwargs, __concrete_kwargs,
__default_nonsparse_ad, __construct_internal_problem

using ConcreteStructs: @concrete
using DiffEqBase: DiffEqBase
Expand Down
6 changes: 5 additions & 1 deletion lib/BoundaryValueDiffEqAscher/src/algorithms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ for stage in (1, 2, 3, 4, 5, 6, 7)
- `nlsolve`: Internal Nonlinear solver. Any solver which conforms to the SciML
`NonlinearProblem` interface can be used. Note that any autodiff argument for
the solver will be ignored and a custom jacobian algorithm will be used.
- `optimize`: Internal Optimization solver. Any solver which conforms to the SciML
`OptimizationProblem` interface can be used. Note that any autodiff argument for
the solver will be ignored and a custom jacobian algorithm will be used.
- `max_num_subintervals`: Number of maximal subintervals, default as 3000.
- `zeta`: side condition points, should always be provided.

Expand Down Expand Up @@ -46,8 +49,9 @@ for stage in (1, 2, 3, 4, 5, 6, 7)
}
```
"""
@kwdef struct $(alg){N, J <: BVPJacobianAlgorithm} <: AbstractAscher
@kwdef struct $(alg){N, O, J <: BVPJacobianAlgorithm} <: AbstractAscher
nlsolve::N = nothing
optimize::O = nothing
zeta::Vector{Float64} = nothing
jac_alg::J = BVPJacobianAlgorithm()
max_num_subintervals::Int = 3000
Expand Down
24 changes: 14 additions & 10 deletions lib/BoundaryValueDiffEqAscher/src/ascher.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
TU
valstr
nlsolve_kwargs
optimize_kwargs
kwargs
end

Expand All @@ -60,7 +61,8 @@ end

function SciMLBase.__init(
prob::BVProblem, alg::AbstractAscher; dt = 0.0, controller = GlobalErrorControl(),
adaptive = true, abstol = 1e-4, nlsolve_kwargs = (; abstol = abstol), kwargs...)
adaptive = true, abstol = 1e-4, nlsolve_kwargs = (; abstol = abstol),
optimize_kwargs = (; abstol = abstol), kwargs...)
(; tspan, p) = prob
_, T, ncy, n, u0 = __extract_problem_details(prob; dt, check_positive_dt = true)
t₀, t₁ = tspan
Expand Down Expand Up @@ -147,9 +149,9 @@ function SciMLBase.__init(
g = build_almost_block_diagonals(zeta, ncomp, mesh, T)
cache = AscherCache{iip, T}(
prob, f, jac, bc, bcjac, k, copy(mesh), mesh, mesh_dt, ncomp, ny, p, zeta,
fixpnt, alg, prob.problem_type, bcresid_prototype, residual, zval, yval,
gval, err, g, w, v, lz, ly, dmz, delz, deldmz, dqdmz, dmv, pvtg, pvtw, TU,
valst, nlsolve_kwargs, (; abstol, dt, adaptive, controller, kwargs...))
fixpnt, alg, prob.problem_type, bcresid_prototype, residual, zval, yval, gval,
err, g, w, v, lz, ly, dmz, delz, deldmz, dqdmz, dmv, pvtg, pvtw, TU, valst,
nlsolve_kwargs, optimize_kwargs, (; abstol, dt, adaptive, controller, kwargs...))
return cache
end

Expand All @@ -176,8 +178,10 @@ function __perform_ascher_iteration(
cache::AscherCache{iip, T}, abstol, adaptive::Bool) where {iip, T}
info::ReturnCode.T = ReturnCode.Success
nlprob = __construct_nlproblem(cache)
nlsolve_alg = __concrete_nonlinearsolve_algorithm(nlprob, cache.alg.nlsolve)
nlsol = __solve(nlprob, nlsolve_alg; cache.nlsolve_kwargs...)
solve_alg = __concrete_solve_algorithm(nlprob, cache.alg.nlsolve, cache.alg.optimize)
kwargs = __concrete_kwargs(
cache.alg.nlsolve, cache.alg.optimize, cache.nlsolve_kwargs, cache.optimize_kwargs)
nlsol = solve(nlprob, solve_alg; kwargs...)
error_norm = 2 * abstol
info = nlsol.retcode

Expand All @@ -203,7 +207,7 @@ function __perform_ascher_iteration(
__expand_cache_for_error!(cache)

_nlprob = __construct_nlproblem(cache)
nlsol = __solve(_nlprob, nlsolve_alg; cache.nlsolve_kwargs...)
nlsol = solve(_nlprob, solve_alg; kwargs...)

error_norm = error_estimate!(cache)
if norm(error_norm) > abstol
Expand Down Expand Up @@ -346,9 +350,9 @@ function __construct_nlproblem(cache::AscherCache{iip, T}) where {iip, T}
jac_prototype, u, diffmode, jac_cache, loss, cache.p)
end

nlf = NonlinearFunction{iip}(
loss; jac = jac, resid_prototype = resid_prototype, jac_prototype = jac_prototype)
return __internal_nlsolve_problem(cache.prob, similar(lz), lz, nlf, lz, cache.p)
return __construct_internal_problem(
cache.prob, alg, loss, jac, jac_prototype, resid_prototype,
lz, cache.p, cache.ncomp, length(cache.mesh))
end

function __ascher_mpoint_jacobian!(J, x, diffmode, diffcache, loss, resid, p)
Expand Down
2 changes: 1 addition & 1 deletion lib/BoundaryValueDiffEqAscher/src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ end
return nothing
end

@views function recursive_flatten!(y::Vector, x::Vector{Vector{T}}) where {T}
@views function recursive_flatten!(y::AbstractArray, x::Vector{Vector{T}}) where {T}
i = 0
for xᵢ in x
copyto!(y[(i + 1):(i + length(xᵢ))], xᵢ)
Expand Down
2 changes: 1 addition & 1 deletion lib/BoundaryValueDiffEqCore/src/BoundaryValueDiffEqCore.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ include("utils.jl")
include("algorithms.jl")
include("abstract_types.jl")
include("alg_utils.jl")
include("default_nlsolve.jl")
include("default_internal_solve.jl")
include("calc_errors.jl")

function SciMLBase.__solve(prob::AbstractBVProblem,
Expand Down
9 changes: 9 additions & 0 deletions lib/BoundaryValueDiffEqCore/src/algorithms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,12 @@ function Base.show(io::IO, alg::AbstractBoundaryValueDiffEqAlgorithm)
print(io, join(modifiers, ", "))
print(io, ")")
end

# Check what's the internal solver, nonlinear or optimization?
function __internal_solver(alg::AbstractBoundaryValueDiffEqAlgorithm)
# We don't allow both `nlsolve` and `optimize` to be specified at the same time
(isnothing(alg.nlsolve) && isnothing(alg.optimize)) &&
error("Either `nlsolve` or `optimize` must be specified in the algorithm, but not both.")
isnothing(alg.nlsolve) && return alg.optimize
isnothing(alg.optimize) && return alg.nlsolve
end
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,28 @@ function __FastShortcutNonlinearPolyalg(::Type{T} = Float64; concrete_jac = noth
return NonlinearSolvePolyAlgorithm(algs)
end

@inline __concrete_nonlinearsolve_algorithm(prob, alg) = alg
@inline function __concrete_nonlinearsolve_algorithm(prob, ::Nothing)
"""
__concrete_solve_algorithm(prob, nlsolve_alg, optimize_alg)

Automatic solver choosing according to the input solver.
If none of the solvers are specified, we use nonlinear solvers from NonlinearSolve.jl.
If both of the nonlinear solver and optimization solver are specified, we throw an error.
If only one of the nonlinear solver and optimization solver is specified, we use that solver.
"""
@inline __concrete_solve_algorithm(prob, alg) = alg
@inline __concrete_solve_algorithm(prob, alg, ::Nothing) = alg
@inline __concrete_solve_algorithm(prob, ::Nothing, alg) = alg
@inline __concrete_solve_algorithm(prob,
alg1,
alg2) = error("Both `nlsolve` and `optimize` are specified in the algorithm, but only one of them is allowed. Please specify only one of them.")
@inline function __concrete_solve_algorithm(prob, ::Nothing)
if prob isa NonlinearLeastSquaresProblem
return __FastShortcutBVPCompatibleNLLSPolyalg(eltype(prob.u0))
else
return __FastShortcutBVPCompatibleNonlinearPolyalg(eltype(prob.u0))
end
end
@inline function __concrete_solve_algorithm(prob, ::Nothing, ::Nothing)
if prob isa NonlinearLeastSquaresProblem
return __FastShortcutBVPCompatibleNLLSPolyalg(eltype(prob.u0))
else
Expand Down
125 changes: 124 additions & 1 deletion lib/BoundaryValueDiffEqCore/src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,19 @@ end
return NonlinearProblem(args...; kwargs...)
end

# Construct the internal OptimizationProblem
@inline function __internal_optimization_problem(
::BVProblem{uType, tType, iip}, args...; kwargs...) where {uType, tType, iip}
prob = OptimizationProblem(args...; kwargs...)
return prob
end

@inline function __internal_optimization_problem(::SecondOrderBVProblem{uType, tType, iip},
args...; kwargs...) where {uType, tType, iip}
prob = OptimizationProblem(args...; kwargs...)
return prob
end

# Handling Initial Guesses
"""
__extract_u0(u₀, t₀)
Expand Down Expand Up @@ -563,10 +576,17 @@ end
end

# Construct BVP Solution
function __build_solution(prob::AbstractBVProblem, odesol, nlsol)
function __build_solution(
prob::AbstractBVProblem, odesol, nlsol::SciMLBase.NonlinearSolution)
retcode = ifelse(SciMLBase.successful_retcode(nlsol), odesol.retcode, nlsol.retcode)
return SciMLBase.solution_new_original_retcode(odesol, nlsol, retcode, nlsol.resid)
end
function __build_solution(
prob::AbstractBVProblem, odesol, optsol::SciMLBase.OptimizationSolution)
retcode = ifelse(SciMLBase.successful_retcode(optsol), odesol.retcode, optsol.retcode)
return SciMLBase.solution_new_original_retcode(
odesol, optsol, retcode, zeros(length(first(odesol)))) # Need a patch in SciMLBase
end

# Fix3
@concrete struct __Fix3
Expand Down Expand Up @@ -600,3 +620,106 @@ end
function __split_kwargs(; abstol, adaptive, controller, kwargs...)
return ((abstol, adaptive, controller), (; abstol, adaptive, kwargs...))
end

@inline __concrete_kwargs(nlsolve,
::Nothing,
nlsolve_kwargs,
optimize_kwargs) = (
nlsolve_kwargs..., alias = SciMLBase.NonlinearAliasSpecifier(alias_u0 = true))
@inline __concrete_kwargs(::Nothing, optimize, nlsolve_kwargs, optimize_kwargs) = (;) # Doesn't support for now
@inline __concrete_kwargs(::Nothing,
::Nothing,
nlsolve_kwargs,
optimize_kwargs) = (
nlsolve_kwargs..., alias = SciMLBase.NonlinearAliasSpecifier(alias_u0 = true))

## Optimization solver related utils ##

@inline __default_cost(::Nothing) = (x, p) -> 0.0
@inline __default_cost(f) = f
@inline __default_cost(fun::BVPFunction) = __default_cost(fun.cost)

"""
__construct_internal_problem

Constructs the internal problem based on the type of the boundary value problem and the
algorithm used. It returns either a `NonlinearProblem` or an `OptimizationProblem`.
"""
function __construct_internal_problem(prob::AbstractBVProblem, alg, loss, jac,
jac_prototype, resid_prototype, y, p, M::Int, N::Int)
T = eltype(y)
# multiple shooting always use iip
iip = SciMLBase.isinplace(prob)
if !isnothing(alg.nlsolve) || (isnothing(alg.nlsolve) && isnothing(alg.optimize))
nlf = NonlinearFunction{iip}(loss; jac = jac, resid_prototype = resid_prototype,
jac_prototype = jac_prototype)
return __internal_nlsolve_problem(prob, resid_prototype, y, nlf, y, p)
else
optf = OptimizationFunction{true}(__default_cost(prob.f), AutoFiniteDiff(), # Need to investigate the ForwardDiff dual problem
cons = loss,
cons_j = jac, cons_jac_prototype = jac_prototype)
lcons = zeros(T, N*M)
ucons = zeros(T, N*M)
return __internal_optimization_problem(
prob, optf, y, p; lcons = lcons, ucons = ucons)
end
end

function __construct_internal_problem(prob::TwoPointBVProblem, alg, loss, jac,
jac_prototype, resid_prototype, y, p, M::Int, N::Int)
T = eltype(y)
iip = SciMLBase.isinplace(prob)
if !isnothing(alg.nlsolve) || (isnothing(alg.nlsolve) && isnothing(alg.optimize))
nlf = NonlinearFunction{iip}(loss; jac = jac, resid_prototype = resid_prototype,
jac_prototype = jac_prototype)
return __internal_nlsolve_problem(prob, resid_prototype, y, nlf, y, p)
else
optf = OptimizationFunction{true}(
__default_cost(prob.f), get_dense_ad(alg.jac_alg.diffmode),
cons = loss, cons_j = jac, cons_jac_prototype = jac_prototype)
lcons = zeros(T, N*M)
ucons = zeros(T, N*M)

return __internal_optimization_problem(
prob, optf, y, p; lcons = lcons, ucons = ucons)
end
end
# Multiple shooting only use inplace version internal problem constructor
function __construct_internal_problem(prob, alg, loss, jac, jac_prototype,
resid_prototype, y, p, M::Int, N::Int, ::Nothing)
T = eltype(y)
if !isnothing(alg.nlsolve) || (isnothing(alg.nlsolve) && isnothing(alg.optimize))
nlf = NonlinearFunction{true}(loss; jac = jac, resid_prototype = resid_prototype,
jac_prototype = jac_prototype)
return __internal_nlsolve_problem(prob, resid_prototype, y, nlf, y, p)
else
optf = OptimizationFunction{true}(
__default_cost(prob.f), get_dense_ad(alg.jac_alg.diffmode),
cons = loss, cons_j = jac, cons_jac_prototype = jac_prototype)
lcons = zeros(T, N*M)
ucons = zeros(T, N*M)

return __internal_optimization_problem(
prob, optf, y, p; lcons = lcons, ucons = ucons)
end
end
function __construct_internal_problem(
prob::TwoPointBVProblem, alg, loss, jac, jac_prototype,
resid_prototype, y, p, M::Int, N::Int, ::Nothing)
T = eltype(y)
iip = SciMLBase.isinplace(prob)
if !isnothing(alg.nlsolve) || (isnothing(alg.nlsolve) && isnothing(alg.optimize))
nlf = NonlinearFunction{iip}(loss; jac = jac, resid_prototype = resid_prototype,
jac_prototype = jac_prototype)
return __internal_nlsolve_problem(prob, resid_prototype, y, nlf, y, p)
else
optf = OptimizationFunction{true}(
__default_cost(prob.f), get_dense_ad(alg.jac_alg.nonbc_diffmode),
cons = loss, cons_j = jac, cons_jac_prototype = jac_prototype)
lcons = zeros(T, N*M)
ucons = zeros(T, N*M)

return __internal_optimization_problem(
prob, optf, y, p; lcons = lcons, ucons = ucons)
end
end
11 changes: 6 additions & 5 deletions lib/BoundaryValueDiffEqFIRK/src/BoundaryValueDiffEqFIRK.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,24 @@ using BandedMatrices: BandedMatrix, Ones
using BoundaryValueDiffEqCore: AbstractBoundaryValueDiffEqAlgorithm,
AbstractBoundaryValueDiffEqCache, BVPJacobianAlgorithm,
recursive_flatten, recursive_flatten!, recursive_unflatten!,
__concrete_nonlinearsolve_algorithm, diff!, EvalSol,
__concrete_solve_algorithm, diff!, EvalSol,
concrete_jacobian_algorithm, eval_bc_residual, interval,
eval_bc_residual!, get_tmp, __maybe_matmul!, __resize!,
__extract_problem_details, __initial_guess, nodual_value,
__maybe_allocate_diffcache, __restructure_sol,
__get_bcresid_prototype, __vec, __vec_f, __vec_f!, __vec_bc,
__vec_bc!, recursive_flatten_twopoint!,
__vec_bc!, recursive_flatten_twopoint!, __concrete_kwargs,
__internal_nlsolve_problem, __extract_mesh, __extract_u0,
__default_coloring_algorithm, __maybe_allocate_diffcache,
__restructure_sol, __get_bcresid_prototype, safe_similar,
__vec, __vec_f, __vec_f!, __vec_bc, __vec_bc!, __cache_trait,
recursive_flatten_twopoint!, __internal_nlsolve_problem,
__extract_mesh, __extract_u0, DiffCacheNeeded,
NoDiffCacheNeeded, __has_initial_guess,
__initial_guess_length, __initial_guess_on_mesh,
__flatten_initial_guess, __build_solution, __Fix3,
__split_kwargs, _sparse_like, get_dense_ad
__construct_internal_problem, __initial_guess_length,
__initial_guess_on_mesh, __flatten_initial_guess,
__build_solution, __Fix3, __split_kwargs, _sparse_like,
get_dense_ad, __internal_optimization_problem

using ConcreteStructs: @concrete
using DiffEqBase: DiffEqBase
Expand Down
8 changes: 4 additions & 4 deletions lib/BoundaryValueDiffEqFIRK/src/adaptivity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ end
end
τ = (t - mesh[j])

nest_nlsolve_alg = __concrete_nonlinearsolve_algorithm(nest_prob, alg.nlsolve)
nest_nlsolve_alg = __concrete_solve_algorithm(nest_prob, alg.nlsolve)
nestprob_p = zeros(T, cache.M + 2)

yᵢ = copy(cache.y[j].du)
Expand Down Expand Up @@ -152,7 +152,7 @@ end
end
τ = (t - mesh[j])

nest_nlsolve_alg = __concrete_nonlinearsolve_algorithm(nest_prob, alg.nlsolve)
nest_nlsolve_alg = __concrete_solve_algorithm(nest_prob, alg.nlsolve)
nestprob_p = zeros(T, cache.M + 2)

yᵢ = copy(cache.y[j])
Expand Down Expand Up @@ -457,7 +457,7 @@ end
(; f, mesh, mesh_dt, defect, ITU, nest_prob, alg) = cache
(; q_coeff, τ_star) = ITU

nlsolve_alg = __concrete_nonlinearsolve_algorithm(nest_prob, cache.alg.nlsolve)
nlsolve_alg = __concrete_solve_algorithm(nest_prob, cache.alg.nlsolve)
nestprob_p = zeros(T, cache.M + 2)

for i in 1:(length(mesh) - 1)
Expand Down Expand Up @@ -509,7 +509,7 @@ end
(; f, mesh, mesh_dt, defect, ITU, nest_prob, alg) = cache
(; q_coeff, τ_star) = ITU

nlsolve_alg = __concrete_nonlinearsolve_algorithm(nest_prob, cache.alg.nlsolve)
nlsolve_alg = __concrete_solve_algorithm(nest_prob, cache.alg.nlsolve)
nestprob_p = zeros(T, cache.M + 2)

for i in 1:(length(mesh) - 1)
Expand Down
Loading
Loading