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