@@ -36,12 +36,16 @@ function jacobian!!(J::Union{AbstractMatrix{<:Number}, Nothing}, cache)
36
36
@unpack f, uf, u, p, jac_cache, alg, fu2 = cache
37
37
iip = isinplace (cache)
38
38
if iip
39
- has_jac (f) ? f. jac (J, u, p) : sparse_jacobian! (J, alg. ad, jac_cache, uf, fu2, u)
39
+ has_jac (f) ? f. jac (J, u, p) :
40
+ sparse_jacobian! (J, alg. ad, jac_cache, uf, fu2, _maybe_mutable (u, alg. ad))
40
41
else
41
- return has_jac (f) ? f. jac (u, p) : sparse_jacobian! (J, alg. ad, jac_cache, uf, u)
42
+ return has_jac (f) ? f. jac (u, p) :
43
+ sparse_jacobian! (J, alg. ad, jac_cache, uf, _maybe_mutable (u, alg. ad))
42
44
end
43
- return nothing
45
+ return J
44
46
end
47
+ # Scalar case
48
+ jacobian!! (:: Number , cache) = last (value_derivative (cache. uf, cache. u))
45
49
46
50
# Build Jacobian Caches
47
51
function jacobian_caches (alg:: AbstractNonlinearSolveAlgorithm , f, u, p,
@@ -54,15 +58,16 @@ function jacobian_caches(alg::AbstractNonlinearSolveAlgorithm, f, u, p,
54
58
linsolve_needs_jac = (concrete_jac (alg) === nothing &&
55
59
(! haslinsolve || (haslinsolve && (alg. linsolve === nothing ||
56
60
needs_concrete_A (alg. linsolve)))))
57
- alg_wants_jac = (concrete_jac (alg) = == nothing && concrete_jac (alg))
61
+ alg_wants_jac = (concrete_jac (alg) ! == nothing && concrete_jac (alg))
58
62
59
63
# NOTE: The deepcopy is needed here since we are using the resid_prototype elsewhere
60
- fu = f. resid_prototype === nothing ? (iip ? zero (u) : f (u, p)) :
61
- deepcopy (f. resid_prototype)
64
+ fu = f. resid_prototype === nothing ? (iip ? _mutable_zero (u) : _mutable ( f (u, p) )) :
65
+ (iip ? deepcopy (f . resid_prototype) : f. resid_prototype)
62
66
if ! has_analytic_jac && (linsolve_needs_jac || alg_wants_jac)
63
67
sd = sparsity_detection_alg (f, alg. ad)
64
- jac_cache = iip ? sparse_jacobian_cache (alg. ad, sd, uf, fu, u) :
65
- sparse_jacobian_cache (alg. ad, sd, uf, u; fx = fu)
68
+ ad = alg. ad
69
+ jac_cache = iip ? sparse_jacobian_cache (ad, sd, uf, fu, _maybe_mutable (u, ad)) :
70
+ sparse_jacobian_cache (ad, sd, uf, _maybe_mutable (u, ad); fx = fu)
66
71
else
67
72
jac_cache = nothing
68
73
end
@@ -78,7 +83,7 @@ function jacobian_caches(alg::AbstractNonlinearSolveAlgorithm, f, u, p,
78
83
end
79
84
end
80
85
81
- du = zero (u)
86
+ du = _mutable_zero (u)
82
87
linprob = LinearProblem (J, _vec (fu); u0 = _vec (du))
83
88
84
89
weight = similar (u)
@@ -90,3 +95,11 @@ function jacobian_caches(alg::AbstractNonlinearSolveAlgorithm, f, u, p,
90
95
91
96
return uf, linsolve, J, fu, jac_cache, du
92
97
end
98
+
99
+ # # Special Handling for Scalars
100
+ function jacobian_caches (alg:: AbstractNonlinearSolveAlgorithm , f, u:: Number , p,
101
+ :: Val{false} )
102
+ # NOTE: Scalar `u` assumes scalar output from `f`
103
+ uf = JacobianWrapper (f, p)
104
+ return uf, nothing , u, nothing , nothing , u
105
+ end
0 commit comments