1
- struct NewtonRaphson{CS, AD, DT , L} <: AbstractNewtonAlgorithm{CS, AD}
2
- diff_type :: DT
1
+ struct NewtonRaphson{CS, AD, FDT , L, P, ST, CJ} < :
2
+ AbstractNewtonAlgorithm{CS, AD, FDT, ST, CJ}
3
3
linsolve:: L
4
+ precs:: P
4
5
end
5
6
6
- function NewtonRaphson (; autodiff = true , chunk_size = 12 , diff_type = Val{:forward },
7
- linsolve = DEFAULT_LINSOLVE)
8
- NewtonRaphson {chunk_size, autodiff, typeof(diff_type), typeof(linsolve)} (diff_type,
9
- linsolve)
7
+ function NewtonRaphson (; chunk_size = Val {0} (), autodiff = Val {true} (),
8
+ standardtag = Val {true} (), concrete_jac = nothing ,
9
+ diff_type = Val{:forward }, linsolve = nothing , precs = DEFAULT_PRECS)
10
+ NewtonRaphson{_unwrap_val (chunk_size), _unwrap_val (autodiff), diff_type,
11
+ typeof (linsolve), typeof (precs), _unwrap_val (standardtag),
12
+ _unwrap_val (concrete_jac)}(linsolve, precs)
10
13
end
11
14
12
15
mutable struct NewtonRaphsonCache{ufType, L, jType, uType, JC}
@@ -17,10 +20,64 @@ mutable struct NewtonRaphsonCache{ufType, L, jType, uType, JC}
17
20
jac_config:: JC
18
21
end
19
22
23
+ function dolinsolve (precs:: P , linsolve; A = nothing , linu = nothing , b = nothing ,
24
+ du = nothing , u = nothing , p = nothing , t = nothing ,
25
+ weight = nothing , solverdata = nothing ,
26
+ reltol = nothing ) where {P}
27
+ A != = nothing && (linsolve = LinearSolve. set_A (linsolve, A))
28
+ b != = nothing && (linsolve = LinearSolve. set_b (linsolve, b))
29
+ linu != = nothing && (linsolve = LinearSolve. set_u (linsolve, linu))
30
+
31
+ Plprev = linsolve. Pl isa LinearSolve. ComposePreconditioner ? linsolve. Pl. outer :
32
+ linsolve. Pl
33
+ Prprev = linsolve. Pr isa LinearSolve. ComposePreconditioner ? linsolve. Pr. outer :
34
+ linsolve. Pr
35
+
36
+ _Pl, _Pr = precs (linsolve. A, du, u, p, nothing , A != = nothing , Plprev, Prprev,
37
+ solverdata)
38
+ if (_Pl != = nothing || _Pr != = nothing )
39
+ _weight = weight === nothing ?
40
+ (linsolve. Pr isa Diagonal ? linsolve. Pr. diag : linsolve. Pr. inner. diag) :
41
+ weight
42
+ Pl, Pr = wrapprecs (_Pl, _Pr, _weight)
43
+ linsolve = LinearSolve. set_prec (linsolve, Pl, Pr)
44
+ end
45
+
46
+ linres = if reltol === nothing
47
+ solve (linsolve; reltol)
48
+ else
49
+ solve (linsolve; reltol)
50
+ end
51
+
52
+ return linres
53
+ end
54
+
55
+ function wrapprecs (_Pl, _Pr, weight)
56
+ if _Pl != = nothing
57
+ Pl = LinearSolve. ComposePreconditioner (LinearSolve. InvPreconditioner (Diagonal (_vec (weight))),
58
+ _Pl)
59
+ else
60
+ Pl = LinearSolve. InvPreconditioner (Diagonal (_vec (weight)))
61
+ end
62
+
63
+ if _Pr != = nothing
64
+ Pr = LinearSolve. ComposePreconditioner (Diagonal (_vec (weight)), _Pr)
65
+ else
66
+ Pr = Diagonal (_vec (weight))
67
+ end
68
+ Pl, Pr
69
+ end
70
+
20
71
function alg_cache (alg:: NewtonRaphson , f, u, p, :: Val{true} )
21
72
uf = JacobianWrapper (f, p)
22
- linsolve = alg. linsolve (Val{:init }, f, u)
23
73
J = false .* u .* u'
74
+
75
+ linprob = LinearProblem (W, _vec (zero (u)); u0 = _vec (zero (u)))
76
+ Pl, Pr = wrapprecs (alg. precs (W, nothing , u, p, nothing , nothing , nothing , nothing ,
77
+ nothing )... , weight)
78
+ linsolve = init (linprob, alg. linsolve, alias_A = true , alias_b = true ,
79
+ Pl = Pl, Pr = Pr)
80
+
24
81
du1 = zero (u)
25
82
tmp = zero (u)
26
83
if alg_autodiff (alg)
@@ -47,9 +104,12 @@ function perform_step(solver::NewtonImmutableSolver, alg::NewtonRaphson, ::Val{t
47
104
@unpack J, linsolve, du1 = cache
48
105
calc_J! (J, solver, cache)
49
106
# u = u - J \ fu
50
- linsolve (du1, J, fu, true )
107
+ linsolve = dolinsolve (alg. precs, solver. linsolve, A = J, b = fu, u = du1,
108
+ p = p, reltol = solver. tol)
109
+ @set! cache. linsolve = linsolve
51
110
@. u = u - du1
52
111
f (fu, u, p)
112
+
53
113
if solver. internalnorm (solver. fu) < solver. tol
54
114
@set! solver. force_stop = true
55
115
end
0 commit comments