@@ -178,7 +178,7 @@ function NonlinearSolveBase.nonlinearsolve_forwarddiff_solve(
178178
179179 Jₚ = NonlinearSolveBase. nonlinearsolve_∂f_∂p (ad_prob, fn, uu, p)
180180 Jᵤ = NonlinearSolveBase. nonlinearsolve_∂f_∂u (ad_prob, fn, uu, p)
181- z = - Jᵤ \ Jₚ
181+ z = - _forwarddiff_implicit_solve (Jᵤ, Jₚ)
182182 pp = prob. p
183183 sumfun = ((z, p),) -> map (Base. Fix2 (* , ForwardDiff. partials (p)), z)
184184
@@ -222,6 +222,22 @@ function NonlinearSolveBase.nonlinearsolve_∂f_∂u(prob, f::F, u, p) where {F}
222222 return ForwardDiff. jacobian (Base. Fix2 (f, p), u)
223223end
224224
225+ _forwarddiff_implicit_solve (A:: Number , B) = A \ B
226+
227+ function _forwarddiff_implicit_solve (A, B)
228+ Utils. is_extension_loaded (Val (:LinearSolve )) || return A \ B
229+
230+ T = promote_type (typeof (oneunit (eltype (A)) / oneunit (eltype (A))), eltype (B))
231+ u = similar (B, T, size (B))
232+ lincache = NonlinearSolveBase. construct_linear_solver (
233+ nothing , nothing , A, B, u, nothing ;
234+ stats = SciMLBase. NLStats (0 , 0 , 0 , 0 , 0 ), verbose = false
235+ )
236+ linres = lincache ()
237+ linres. success || error (" Linear solve failed while differentiating a nonlinear solve." )
238+ return linres. u
239+ end
240+
225241function NonlinearSolveBase. nonlinearsolve_dual_solution (
226242 u:: Number , partials,
227243 :: Union{<:AbstractArray{<:Dual{T, V, P}}, Dual{T, V, P}}
@@ -302,7 +318,7 @@ function CommonSolve.solve!(cache::NonlinearSolveForwardDiffCache)
302318 Jₚ = NonlinearSolveBase. nonlinearsolve_∂f_∂p (ad_prob, fn, uu, cache. values_p)
303319 Jᵤ = NonlinearSolveBase. nonlinearsolve_∂f_∂u (ad_prob, fn, uu, cache. values_p)
304320
305- z_arr = - Jᵤ \ Jₚ
321+ z_arr = - _forwarddiff_implicit_solve (Jᵤ, Jₚ)
306322
307323 sumfun = ((z, p),) -> map (zᵢ -> zᵢ * ForwardDiff. partials (p), z)
308324 if cache. p isa Number
0 commit comments