Skip to content

Commit

Permalink
More improvements to Klement
Browse files Browse the repository at this point in the history
  • Loading branch information
avik-pal committed Dec 7, 2023
1 parent 2a2d7fc commit 60b408c
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 71 deletions.
2 changes: 1 addition & 1 deletion src/NonlinearSolve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function SciMLBase.reinit!(cache::AbstractNonlinearSolveCache{iip}, u0 = get_u(c
get_u(cache), p, get_fu(cache), Val(iip))
end

hasfield(typeof(cache), :uf) && (cache.uf.p = p)
hasfield(typeof(cache), :uf) && cache.uf !== nothing && (cache.uf.p = p)

Check warning on line 84 in src/NonlinearSolve.jl

View check run for this annotation

Codecov / codecov/patch

src/NonlinearSolve.jl#L84

Added line #L84 was not covered by tests

cache.abstol = abstol
cache.reltol = reltol
Expand Down
60 changes: 39 additions & 21 deletions src/broyden.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Sadly `Broyden` is taken up by SimpleNonlinearSolve.jl
"""
GeneralBroyden(; max_resets = 3, linesearch = nothing, reset_tolerance = nothing,
init_jacobian::Val = Val(:identity), autodiff = nothing, alpha = 1.0)
GeneralBroyden(; max_resets = 100, linesearch = nothing, reset_tolerance = nothing,
init_jacobian::Val = Val(:identity), autodiff = nothing, alpha = nothing)
An implementation of `Broyden` with resetting and line search.
## Arguments
- `max_resets`: the maximum number of resets to perform. Defaults to `3`.
- `max_resets`: the maximum number of resets to perform. Defaults to `100`.
- `reset_tolerance`: the tolerance for the reset check. Defaults to
`sqrt(eps(real(eltype(u))))`.
Expand All @@ -16,11 +16,15 @@ An implementation of `Broyden` with resetting and line search.
used here directly, and they will be converted to the correct `LineSearch`. It is
recommended to use [LiFukushimaLineSearch](@ref) -- a derivative free linesearch
specifically designed for Broyden's method.
- `alpha_initial`: If `init_jacobian` is set to `Val(:identity)`, then the initial
Jacobian inverse is set to be `(αI)⁻¹`. Defaults to `1.0`.
- `init_jacobian`: the method to use for initializing the jacobian. Defaults to using the
identity matrix (`Val(:identitiy)`). Alternatively, can be set to `Val(:true_jacobian)`
to use the true jacobian as initialization.
- `alpha`: If `init_jacobian` is set to `Val(:identity)`, then the initial Jacobian
inverse is set to be `(αI)⁻¹`. Defaults to `nothing` which implies
`α = max(norm(u), 1) / (2 * norm(fu))`.
- `init_jacobian`: the method to use for initializing the jacobian. Defaults to
`Val(:identity)`. Choices include:
+ `Val(:identity)`: Identity Matrix.
+ `Val(:true_jacobian)`: True Jacobian. This is a good choice for differentiable
problems.
- `autodiff`: determines the backend used for the Jacobian. Note that this argument is
ignored if an analytical Jacobian is passed, as that will be used instead. Defaults to
`nothing` which means that a default is selected according to the problem specification!
Expand All @@ -29,39 +33,45 @@ An implementation of `Broyden` with resetting and line search.
+ `Val(:good_broyden)`: Good Broyden's Update Rule
+ `Val(:bad_broyden)`: Bad Broyden's Update Rule
+ `Val(:diagonal)`: Only update the diagonal of the Jacobian. This algorithm may be
useful for specific problems, but whether it will work may depend strongly on the
problem.
+ `Val(:exciting_mixing)`: Update the diagonal of the Jacobian. This is based off
SciPy's implementation of Broyden's method. This algorithm may be useful for
specific problems, but whether it will work may depend strongly on the problem.
"""
@concrete struct GeneralBroyden{IJ, UR, CJ, AD} <: AbstractNewtonAlgorithm{CJ, AD}
ad::AD
max_resets::Int
reset_tolerance
linesearch
inv_alpha
alpha
end

function __alg_print_modifiers(alg::GeneralBroyden{IJ, UR}) where {IJ, UR}
modifiers = String[]
IJ !== :identity && push!(modifiers, "init_jacobian = :$(IJ)")
UR !== :good_broyden && push!(modifiers, "update_rule = :$(UR)")
alg.inv_alpha != 1 && push!(modifiers, "alpha = $(1 / alg.inv_alpha)")
alg.alpha !== nothing && push!(modifiers, "alpha = $(alg.alpha)")
return modifiers

Check warning on line 56 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L51-L56

Added lines #L51 - L56 were not covered by tests
end

function set_ad(alg::GeneralBroyden{IJ, UR, CJ}, ad) where {IJ, UR, CJ}
return GeneralBroyden{IJ, UR, CJ}(ad, alg.max_resets, alg.reset_tolerance,

Check warning on line 60 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L59-L60

Added lines #L59 - L60 were not covered by tests
alg.linesearch, alg.inv_alpha)
alg.linesearch, alg.alpha)
end

function GeneralBroyden(; max_resets = 3, linesearch = nothing, reset_tolerance = nothing,
init_jacobian::Val = Val(:identity), autodiff = nothing, alpha = 1.0,
function GeneralBroyden(; max_resets = 100, linesearch = nothing, reset_tolerance = nothing,

Check warning on line 64 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L64

Added line #L64 was not covered by tests
init_jacobian::Val = Val(:identity), autodiff = nothing, alpha = nothing,
update_rule = Val(:good_broyden))
UR = _unwrap_val(update_rule)
@assert UR (:good_broyden, :bad_broyden)
@assert UR (:good_broyden, :bad_broyden, :diagonal, :exciting_mixing)
IJ = _unwrap_val(init_jacobian)
@assert IJ (:identity, :true_jacobian)

Check warning on line 70 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L67-L70

Added lines #L67 - L70 were not covered by tests
linesearch = linesearch isa LineSearch ? linesearch : LineSearch(; method = linesearch)
CJ = IJ === :true_jacobian
return GeneralBroyden{IJ, UR, CJ}(autodiff, max_resets, reset_tolerance, linesearch,

Check warning on line 73 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L72-L73

Added lines #L72 - L73 were not covered by tests
1 / alpha)
alpha)
end

@concrete mutable struct GeneralBroydenCache{iip, IJ, UR} <:
Expand All @@ -78,6 +88,8 @@ end
uf
J⁻¹
J⁻¹dfu
inv_alpha
alpha_initial
force_stop::Bool
resets::Int
max_resets::Int
Expand Down Expand Up @@ -105,6 +117,8 @@ function SciMLBase.__init(prob::NonlinearProblem{uType, iip}, alg_::GeneralBroyd
fu = evaluate_f(prob, u)
@bb du = copy(u)

inv_alpha = __initial_inv_alpha(alg_.alpha, u, fu, internalnorm)

Check warning on line 120 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L120

Added line #L120 was not covered by tests

if IJ === :true_jacobian
alg = get_concrete_algorithm(alg_, prob)
uf, _, J, fu_cache, jac_cache, du = jacobian_caches(alg, f, u, p, Val(iip);

Check warning on line 124 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L122-L124

Added lines #L122 - L124 were not covered by tests
Expand All @@ -114,7 +128,7 @@ function SciMLBase.__init(prob::NonlinearProblem{uType, iip}, alg_::GeneralBroyd
alg = alg_
@bb du = similar(u)
uf, fu_cache, jac_cache = nothing, nothing, nothing
J⁻¹ = __init_identity_jacobian(u, fu, alg.inv_alpha)
J⁻¹ = __init_identity_jacobian(u, fu, inv_alpha)

Check warning on line 131 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L128-L131

Added lines #L128 - L131 were not covered by tests
end

reset_tolerance = alg.reset_tolerance === nothing ? sqrt(eps(real(eltype(u)))) :
Expand All @@ -131,9 +145,9 @@ function SciMLBase.__init(prob::NonlinearProblem{uType, iip}, alg_::GeneralBroyd
kwargs...)

return GeneralBroydenCache{iip, IJ, UR}(f, alg, u, u_cache, du, fu, fu_cache, dfu, p,

Check warning on line 147 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L147

Added line #L147 was not covered by tests
uf, J⁻¹, J⁻¹dfu, false, 0, alg.max_resets, maxiters, internalnorm,
ReturnCode.Default, abstol, reltol, reset_tolerance, reset_check, jac_cache, prob,
NLStats(1, 0, 0, 0, 0),
uf, J⁻¹, J⁻¹dfu, inv_alpha, alg.alpha, false, 0, alg.max_resets, maxiters,
internalnorm, ReturnCode.Default, abstol, reltol, reset_tolerance, reset_check,
jac_cache, prob, NLStats(1, 0, 0, 0, 0),
init_linesearch_cache(alg.linesearch, f, u, p, fu, Val(iip)), tc_cache, trace)
end

Expand Down Expand Up @@ -167,7 +181,9 @@ function perform_step!(cache::GeneralBroydenCache{iip, IJ, UR}) where {iip, IJ,
if IJ === :true_jacobian
cache.J⁻¹ = inv(jacobian!!(cache.J⁻¹, cache))

Check warning on line 182 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L181-L182

Added lines #L181 - L182 were not covered by tests
else
cache.J⁻¹ = __reinit_identity_jacobian!!(cache.J⁻¹, cache.alg.inv_alpha)
cache.inv_alpha = __initial_inv_alpha(cache.inv_alpha, cache.alpha_initial,

Check warning on line 184 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L184

Added line #L184 was not covered by tests
cache.u, cache.fu, cache.internalnorm)
cache.J⁻¹ = __reinit_identity_jacobian!!(cache.J⁻¹, cache.inv_alpha)

Check warning on line 186 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L186

Added line #L186 was not covered by tests
end
cache.resets += 1
else
Expand All @@ -194,7 +210,9 @@ function perform_step!(cache::GeneralBroydenCache{iip, IJ, UR}) where {iip, IJ,
end

function __reinit_internal!(cache::GeneralBroydenCache; kwargs...)
cache.J⁻¹ = __reinit_identity_jacobian!!(cache.J⁻¹, cache.alg.inv_alpha)
cache.inv_alpha = __initial_inv_alpha(cache.inv_alpha, cache.alpha_initial, cache.u,

Check warning on line 213 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L213

Added line #L213 was not covered by tests
cache.fu, cache.internalnorm)
cache.J⁻¹ = __reinit_identity_jacobian!!(cache.J⁻¹, cache.inv_alpha)

Check warning on line 215 in src/broyden.jl

View check run for this annotation

Codecov / codecov/patch

src/broyden.jl#L215

Added line #L215 was not covered by tests
cache.resets = 0
return nothing
end
5 changes: 3 additions & 2 deletions src/default.jl
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,9 @@ function FastShortcutNonlinearPolyalg(; concrete_jac = nothing, linsolve = nothi
TrustRegion(; concrete_jac, linsolve, precs,
radius_update_scheme = RadiusUpdateSchemes.Bastin, adkwargs...))
else
algs = (GeneralKlement(; linsolve, precs),
GeneralBroyden(),
algs = (GeneralBroyden(),

Check warning on line 251 in src/default.jl

View check run for this annotation

Codecov / codecov/patch

src/default.jl#L251

Added line #L251 was not covered by tests
GeneralBroyden(; init_jacobian = Val(:true_jacobian)),
GeneralKlement(; linsolve, precs),
NewtonRaphson(; concrete_jac, linsolve, precs, adkwargs...),
NewtonRaphson(; concrete_jac, linsolve, precs, linesearch = BackTracking(),
adkwargs...),
Expand Down
96 changes: 65 additions & 31 deletions src/klement.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
"""
GeneralKlement(; max_resets = 5, linsolve = nothing, linesearch = nothing,
precs = DEFAULT_PRECS)
GeneralKlement(; max_resets = 100, linsolve = nothing, linesearch = nothing,
precs = DEFAULT_PRECS, alpha = true, init_jacobian::Val = Val(:identity),
autodiff = nothing)
An implementation of `Klement` with line search, preconditioning and customizable linear
solves.
solves. It is recommended to use `Broyden` for most problems over this.
## Keyword Arguments
- `max_resets`: the maximum number of resets to perform. Defaults to `5`.
- `max_resets`: the maximum number of resets to perform. Defaults to `100`.
- `linsolve`: the [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) used for the
linear solves within the Newton method. Defaults to `nothing`, which means it uses the
LinearSolve.jl default algorithm choice. For more information on available algorithm
Expand All @@ -19,10 +21,18 @@ solves.
- `linesearch`: the line search algorithm to use. Defaults to [`LineSearch()`](@ref),
which means that no line search is performed. Algorithms from `LineSearches.jl` can be
used here directly, and they will be converted to the correct `LineSearch`.
- `init_jacobian`: the method to use for initializing the jacobian. Defaults to using the
identity matrix (`Val(:identitiy)`). Alternatively, can be set to `Val(:true_jacobian)`
to use the true jacobian as initialization. (Our tests suggest it is a good idea to
to initialize with an identity matrix)
- `alpha`: If `init_jacobian` is set to `Val(:identity)`, then the initial Jacobian
inverse is set to be `αI`. Defaults to `1`. Can be set to `nothing` which implies
`α = max(norm(u), 1) / (2 * norm(fu))`.
- `init_jacobian`: the method to use for initializing the jacobian. Defaults to
`Val(:identity)`. Choices include:
+ `Val(:identity)`: Identity Matrix.
+ `Val(:true_jacobian)`: True Jacobian. Our tests suggest that this is not very
stable. Instead using `Broyden` with `Val(:true_jacobian)` gives faster and more
reliable convergence.
+ `Val(:true_jacobian_diagonal)`: Diagonal of True Jacobian. This is a good choice for
differentiable problems.
- `autodiff`: determines the backend used for the Jacobian. Note that this argument is
ignored if an analytical Jacobian is passed, as that will be used instead. Defaults to
`nothing` which means that a default is selected according to the problem specification!
Expand All @@ -34,32 +44,30 @@ solves.
linsolve
precs
linesearch
alpha
end

function __alg_print_modifiers(::GeneralKlement{IJ}) where {IJ}
function __alg_print_modifiers(alg::GeneralKlement{IJ}) where {IJ}
modifiers = String[]
IJ !== :identity && push!(modifiers, "init_jacobian = :$(IJ)")
alg.alpha !== nothing && push!(modifiers, "alpha = $(alg.alpha)")
return modifiers

Check warning on line 54 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L50-L54

Added lines #L50 - L54 were not covered by tests
end

function set_linsolve(alg::GeneralKlement{IJ, CS}, linsolve) where {IJ, CS}
return GeneralKlement{IJ, CS}(alg.ad, alg.max_resets, linsolve, alg.precs,
alg.linesearch)
end

function set_ad(alg::GeneralKlement{IJ, CS}, ad) where {IJ, CS}
return GeneralKlement{IJ, CS}(ad, alg.max_resets, alg.linsolve, alg.precs,
alg.linesearch)
function set_ad(alg::GeneralKlement{IJ, CJ}, ad) where {IJ, CJ}
return GeneralKlement{IJ, CJ}(ad, alg.max_resets, alg.linsolve, alg.precs,

Check warning on line 58 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L57-L58

Added lines #L57 - L58 were not covered by tests
alg.linesearch, alg.alpha)
end

function GeneralKlement(; max_resets::Int = 5, linsolve = nothing,
function GeneralKlement(; max_resets::Int = 100, linsolve = nothing, alpha = true,

Check warning on line 62 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L62

Added line #L62 was not covered by tests
linesearch = nothing, precs = DEFAULT_PRECS, init_jacobian::Val = Val(:identity),
autodiff = nothing)
IJ = _unwrap_val(init_jacobian)
@assert IJ (:identity, :true_jacobian)
@assert IJ (:identity, :true_jacobian, :true_jacobian_diagonal)

Check warning on line 66 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L65-L66

Added lines #L65 - L66 were not covered by tests
linesearch = linesearch isa LineSearch ? linesearch : LineSearch(; method = linesearch)
CJ = IJ === :true_jacobian
return GeneralKlement{IJ, CJ}(autodiff, max_resets, linsolve, precs, linesearch)
CJ = IJ !== :identity
return GeneralKlement{IJ, CJ}(autodiff, max_resets, linsolve, precs, linesearch,

Check warning on line 69 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L68-L69

Added lines #L68 - L69 were not covered by tests
alpha)
end

@concrete mutable struct GeneralKlementCache{iip, IJ} <: AbstractNonlinearSolveCache{iip}
Expand All @@ -79,6 +87,8 @@ end
J_cache_2
Jdu
Jdu_cache
alpha
alpha_initial
resets
force_stop
maxiters::Int
Expand All @@ -102,15 +112,23 @@ function SciMLBase.__init(prob::NonlinearProblem{uType, iip}, alg_::GeneralKleme
u = __maybe_unaliased(u0, alias_u0)
fu = evaluate_f(prob, u)

alpha = __initial_alpha(alg_.alpha, u, fu, internalnorm)

Check warning on line 115 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L115

Added line #L115 was not covered by tests

if IJ === :true_jacobian
alg = get_concrete_algorithm(alg_, prob)
uf, _, J, fu_cache, jac_cache, du = jacobian_caches(alg, f, u, p, Val(iip);

Check warning on line 119 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L117-L119

Added lines #L117 - L119 were not covered by tests
lininit = Val(false))
elseif IJ === :true_jacobian_diagonal
alg = get_concrete_algorithm(alg_, prob)
uf, _, J_cache, fu_cache, jac_cache, du = jacobian_caches(alg, f, u, p, Val(iip);

Check warning on line 123 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L121-L123

Added lines #L121 - L123 were not covered by tests
lininit = Val(false))
J = __diag(J_cache)
elseif IJ === :identity

Check warning on line 126 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L125-L126

Added lines #L125 - L126 were not covered by tests
alg = alg_
@bb du = similar(u)
uf, fu_cache, jac_cache = nothing, nothing, nothing
J = one.(u) # Identity Init Jacobian for Klement maintains a Diagonal Structure
@bb J .*= alpha

Check warning on line 131 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L128-L131

Added lines #L128 - L131 were not covered by tests
else
error("Invalid `init_jacobian` value")

Check warning on line 133 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L133

Added line #L133 was not covered by tests
end
Expand All @@ -133,13 +151,14 @@ function SciMLBase.__init(prob::NonlinearProblem{uType, iip}, alg_::GeneralKleme
@bb J_cache_2 = similar(J)
@bb Jdu_cache = similar(fu)

Check warning on line 152 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L149-L152

Added lines #L149 - L152 were not covered by tests
else
J_cache, J_cache_2, Jdu_cache = nothing, nothing, nothing
IJ === :identity && (J_cache = nothing)
J_cache_2, Jdu_cache = nothing, nothing

Check warning on line 155 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L154-L155

Added lines #L154 - L155 were not covered by tests
end

return GeneralKlementCache{iip, IJ}(f, alg, u, u_cache, fu, fu_cache, fu_cache_2, du, p,

Check warning on line 158 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L158

Added line #L158 was not covered by tests
uf, linsolve, J, J_cache, J_cache_2, Jdu, Jdu_cache, 0, false, maxiters,
internalnorm,
ReturnCode.Default, abstol, reltol, prob, jac_cache, NLStats(1, 0, 0, 0, 0),
uf, linsolve, J, J_cache, J_cache_2, Jdu, Jdu_cache, alpha, alg.alpha, 0, false,
maxiters, internalnorm, ReturnCode.Default, abstol, reltol, prob, jac_cache,
NLStats(1, 0, 0, 0, 0),
init_linesearch_cache(alg.linesearch, f, u, p, fu, Val(iip)), tc_cache, trace)
end

Expand All @@ -150,6 +169,12 @@ function perform_step!(cache::GeneralKlementCache{iip, IJ}) where {iip, IJ}
if IJ === :true_jacobian
cache.stats.nsteps == 0 && (cache.J = jacobian!!(cache.J, cache))
ill_conditioned = __is_ill_conditioned(cache.J)
elseif IJ === :true_jacobian_diagonal
if cache.stats.nsteps == 0
cache.J_cache = jacobian!!(cache.J_cache, cache)
cache.J = __get_diagonal!!(cache.J, cache.J_cache)

Check warning on line 175 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L169-L175

Added lines #L169 - L175 were not covered by tests
end
ill_conditioned = __is_ill_conditioned(cache.J)
elseif IJ === :identity
ill_conditioned = __is_ill_conditioned(cache.J)

Check warning on line 179 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L177-L179

Added lines #L177 - L179 were not covered by tests
end
Expand All @@ -162,13 +187,18 @@ function perform_step!(cache::GeneralKlementCache{iip, IJ}) where {iip, IJ}
end
if IJ === :true_jacobian && cache.stats.nsteps != 0
cache.J = jacobian!!(cache.J, cache)
else
cache.J = __reinit_identity_jacobian!!(cache.J)
elseif IJ === :true_jacobian_diagonal && cache.stats.nsteps != 0
cache.J_cache = jacobian!!(cache.J_cache, cache)
cache.J = __get_diagonal!!(cache.J, cache.J_cache)
elseif IJ === :identity
cache.alpha = __initial_alpha(cache.alpha, cache.alpha_initial, cache.u,

Check warning on line 194 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L188-L194

Added lines #L188 - L194 were not covered by tests
cache.fu, cache.internalnorm)
cache.J = __reinit_identity_jacobian!!(cache.J, cache.alpha)

Check warning on line 196 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L196

Added line #L196 was not covered by tests
end
cache.resets += 1
end

if IJ === :identity
if cache.J isa AbstractVector || cache.J isa Number
@bb @. cache.du = cache.fu / cache.J

Check warning on line 202 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L201-L202

Added lines #L201 - L202 were not covered by tests
else
# u = u - J \ fu
Expand All @@ -193,13 +223,15 @@ function perform_step!(cache::GeneralKlementCache{iip, IJ}) where {iip, IJ}

# Update the Jacobian
@bb cache.du .*= -1
if IJ === :identity
if cache.J isa AbstractVector || cache.J isa Number
@bb @. cache.Jdu = (cache.J^2) * (cache.du^2)
@bb @. cache.J += ((cache.fu - cache.fu_cache_2 - cache.J * cache.du) /

Check warning on line 228 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L226-L228

Added lines #L226 - L228 were not covered by tests
ifelse(iszero(cache.Jdu), T(1e-5), cache.Jdu)) * cache.du *
(cache.J^2)
else
@bb cache.J_cache .= cache.J' .^ 2
# Klement Updates to the Full Jacobian don't work for most problems, we should
# probably be using the Broyden Update Rule here
@bb @. cache.J_cache = cache.J' ^ 2
@bb @. cache.Jdu = cache.du^2
@bb cache.Jdu_cache = cache.J_cache × vec(cache.Jdu)
@bb cache.Jdu = cache.J × vec(cache.du)
Expand All @@ -217,7 +249,9 @@ function perform_step!(cache::GeneralKlementCache{iip, IJ}) where {iip, IJ}
end

function __reinit_internal!(cache::GeneralKlementCache; kwargs...)
cache.J = __reinit_identity_jacobian!!(cache.J)
cache.alpha = __initial_alpha(cache.alpha, cache.alpha_initial, cache.u, cache.fu,

Check warning on line 252 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L252

Added line #L252 was not covered by tests
cache.internalnorm)
cache.J = __reinit_identity_jacobian!!(cache.J, cache.alpha)

Check warning on line 254 in src/klement.jl

View check run for this annotation

Codecov / codecov/patch

src/klement.jl#L254

Added line #L254 was not covered by tests
cache.resets = 0
return nothing
end
Loading

0 comments on commit 60b408c

Please sign in to comment.