@@ -16,7 +16,7 @@ function SciMLBase.solve(prob::NonlinearProblem,
1616 x = float (prob. u0)
1717 fₙ = f (x)
1818 T = eltype (x)
19- J = ArrayInterfaceCore . zeromatrix (x) + I
19+ J = init_J (x)
2020
2121 if SciMLBase. isinplace (prob)
2222 error (" Klement currently only supports out-of-place nonlinear problems" )
@@ -30,8 +30,19 @@ function SciMLBase.solve(prob::NonlinearProblem,
3030 xₙ₋₁ = x
3131 fₙ₋₁ = fₙ
3232 for _ in 1 : maxiters
33- xₙ = xₙ₋₁ - inv (J) * fₙ₋₁
33+ tmp = J \ fₙ₋₁
34+ xₙ = xₙ₋₁ - tmp
3435 fₙ = f (xₙ)
36+
37+ iszero (fₙ) &&
38+ return SciMLBase. build_solution (prob, alg, xₙ, fₙ;
39+ retcode = ReturnCode. Success)
40+
41+ if isapprox (xₙ, xₙ₋₁, atol = atol, rtol = rtol)
42+ return SciMLBase. build_solution (prob, alg, xₙ, fₙ;
43+ retcode = ReturnCode. Success)
44+ end
45+
3546 Δxₙ = xₙ - xₙ₋₁
3647 Δfₙ = fₙ - fₙ₋₁
3748
@@ -41,19 +52,11 @@ function SciMLBase.solve(prob::NonlinearProblem,
4152 k = (Δfₙ - J * Δxₙ) ./ denominator
4253 J += (k * Δxₙ' .* J) * J
4354
44- # Prevent inverting singular matrix
45- if det (J) ≈ 0
46- J = ArrayInterfaceCore . zeromatrix (x) + I
55+ # Singularity test
56+ if cond (J) > 1e9
57+ J = init_J (xₙ)
4758 end
4859
49- iszero (fₙ) &&
50- return SciMLBase. build_solution (prob, alg, xₙ, fₙ;
51- retcode = ReturnCode. Success)
52-
53- if isapprox (xₙ, xₙ₋₁, atol = atol, rtol = rtol)
54- return SciMLBase. build_solution (prob, alg, xₙ, fₙ;
55- retcode = ReturnCode. Success)
56- end
5760 xₙ₋₁ = xₙ
5861 fₙ₋₁ = fₙ
5962 end
0 commit comments