6
6
(uf:: JacobianWrapper )(u) = uf. f (u, uf. p)
7
7
(uf:: JacobianWrapper )(res, u) = uf. f (res, u, uf. p)
8
8
9
- # function sparsity_colorvec(f, x)
10
- # sparsity = f.sparsity
11
- # colorvec = DiffEqBase.has_colorvec(f) ? f.colorvec :
12
- # (isnothing(sparsity) ? (1:length(x)) : matrix_colors(sparsity))
13
- # sparsity, colorvec
14
- # end
9
+ # FIXME : This is a deviation from older versions. Previously if sparsity and colorvec were
10
+ # provided we would use a sparse AD. Right now it requires an explicit specification
11
+ sparsity_detection_alg (f, ad) = NoSparsityDetection ()
12
+ function sparsity_detection_alg (f, ad:: AbstractSparseADType )
13
+ if f. sparsity === nothing
14
+ if f. jac_prototype === nothing
15
+ return SymbolicsSparsityDetection ()
16
+ else
17
+ jac_prototype = f. jac_prototype
18
+ end
19
+ else
20
+ jac_prototype = f. sparsity
21
+ end
22
+
23
+ if SciMLBase. has_colorvec (f)
24
+ return PrecomputedJacobianColorvec (; jac_prototype, f. colorvec,
25
+ partition_by_rows = ad isa ADTypes. AbstractSparseReverseMode)
26
+ else
27
+ return JacPrototypeSparsityDetection (; jac_prototype)
28
+ end
29
+ end
15
30
16
31
# NoOp for Jacobian if it is not a Abstract Array -- For eg, JacVec Operator
17
32
jacobian!! (J, _) = J
@@ -41,14 +56,13 @@ function jacobian_caches(alg::AbstractNonlinearSolveAlgorithm, f, u, p,
41
56
needs_concrete_A (alg. linsolve)))))
42
57
alg_wants_jac = (concrete_jac (alg) === nothing && concrete_jac (alg))
43
58
44
- fu = zero (u) # TODO : Use Prototype
59
+ # 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)
45
62
if ! has_analytic_jac && (linsolve_needs_jac || alg_wants_jac)
46
- # TODO : We need an Upstream Mode to allow using known sparsity and colorvec
47
- # TODO : We can use the jacobian prototype here
48
- sd = typeof (alg. ad) <: AbstractSparseADType ? SymbolicsSparsityDetection () :
49
- NoSparsityDetection ()
63
+ sd = sparsity_detection_alg (f, alg. ad)
50
64
jac_cache = iip ? sparse_jacobian_cache (alg. ad, sd, uf, fu, u) :
51
- sparse_jacobian_cache (alg. ad, sd, uf, u; fx= fu)
65
+ sparse_jacobian_cache (alg. ad, sd, uf, u; fx = fu)
52
66
else
53
67
jac_cache = nothing
54
68
end
@@ -60,12 +74,12 @@ function jacobian_caches(alg::AbstractNonlinearSolveAlgorithm, f, u, p,
60
74
if has_analytic_jac
61
75
iip ? undefmatrix (u) : nothing
62
76
else
63
- f. jac_prototype === nothing ? __init_𝒥 (jac_cache) : f. jac_prototype
77
+ f. jac_prototype === nothing ? init_jacobian (jac_cache) : f. jac_prototype
64
78
end
65
79
end
66
80
67
- # FIXME : Assumes same sized `u` and `fu` -- Incorrect Assumption for Levenberg
68
- linprob = LinearProblem (J, _vec (zero (u)) ; u0 = _vec (zero (u) ))
81
+ du = zero (u)
82
+ linprob = LinearProblem (J, _vec (fu) ; u0 = _vec (du ))
69
83
70
84
weight = similar (u)
71
85
recursivefill! (weight, true )
@@ -74,5 +88,5 @@ function jacobian_caches(alg::AbstractNonlinearSolveAlgorithm, f, u, p,
74
88
nothing )... , weight)
75
89
linsolve = init (linprob, alg. linsolve; alias_A = true , alias_b = true , Pl, Pr)
76
90
77
- return uf, linsolve, J, fu, jac_cache
91
+ return uf, linsolve, J, fu, jac_cache, du
78
92
end
0 commit comments