3
3
precs = DEFAULT_PRECS, alpha_initial = 1e-3, adkwargs...)
4
4
5
5
An implementation of PseudoTransient method that is used to solve steady state problems in an accelerated manner. It uses an adaptive time-stepping to
6
- integrate an initial value of nonlinear problem until sufficient accuracy in the desired steady-state is achieved to switch over to Newton's method and
6
+ integrate an initial value of nonlinear problem until sufficient accuracy in the desired steady-state is achieved to switch over to Newton's method and
7
7
gain a rapid convergence. This implementation specifically uses "switched evolution relaxation" SER method. For detail information about the time-stepping and algorithm,
8
- please see the paper: [Coffey, Todd S. and Kelley, C. T. and Keyes, David E. (2003), Pseudotransient Continuation and Differential-Algebraic Equations,
8
+ please see the paper: [Coffey, Todd S. and Kelley, C. T. and Keyes, David E. (2003), Pseudotransient Continuation and Differential-Algebraic Equations,
9
9
SIAM Journal on Scientific Computing,25, 553-569.](https://doi.org/10.1137/S106482750241044X)
10
10
11
11
### Keyword Arguments
@@ -27,7 +27,7 @@ SIAM Journal on Scientific Computing,25, 553-569.](https://doi.org/10.1137/S1064
27
27
preconditioners. For more information on specifying preconditioners for LinearSolve
28
28
algorithms, consult the
29
29
[LinearSolve.jl documentation](https://docs.sciml.ai/LinearSolve/stable/).
30
- - `alpha_initial` : the initial pseudo time step. it defaults to 1e-3. If it is small,
30
+ - `alpha_initial` : the initial pseudo time step. it defaults to 1e-3. If it is small,
31
31
you are going to need more iterations to converge but it can be more stable.
32
32
"""
33
33
@concrete struct PseudoTransient{CJ, AD} <: AbstractNewtonAlgorithm{CJ, AD}
52
52
f
53
53
alg
54
54
u
55
+ u_prev
55
56
fu1
56
57
fu2
57
58
du
67
68
internalnorm
68
69
retcode:: ReturnCode.T
69
70
abstol
71
+ reltol
70
72
prob
71
73
stats:: NLStats
74
+ termination_condition
75
+ tc_storage
72
76
end
73
77
74
78
isinplace (:: PseudoTransientCache{iip} ) where {iip} = iip
75
79
76
80
function SciMLBase. __init (prob:: NonlinearProblem{uType, iip} , alg_:: PseudoTransient ,
77
81
args... ;
78
- alias_u0 = false , maxiters = 1000 , abstol = 1e-6 , internalnorm = DEFAULT_NORM,
82
+ alias_u0 = false , maxiters = 1000 , abstol = nothing , reltol = nothing ,
83
+ termination_condition = nothing , internalnorm = DEFAULT_NORM,
79
84
linsolve_kwargs = (;),
80
85
kwargs... ) where {uType, iip}
81
86
alg = get_concrete_algorithm (alg_, prob)
@@ -93,16 +98,30 @@ function SciMLBase.__init(prob::NonlinearProblem{uType, iip}, alg_::PseudoTransi
93
98
alpha = convert (eltype (u), alg. alpha_initial)
94
99
res_norm = internalnorm (fu1)
95
100
96
- return PseudoTransientCache {iip} (f, alg, u, fu1, fu2, du, p, alpha, res_norm, uf,
101
+ abstol, reltol, termination_condition = _init_termination_elements (abstol,
102
+ reltol,
103
+ termination_condition,
104
+ eltype (u))
105
+
106
+ mode = DiffEqBase. get_termination_mode (termination_condition)
107
+
108
+ storage = mode ∈ DiffEqBase. SAFE_TERMINATION_MODES ? NLSolveSafeTerminationResult () :
109
+ nothing
110
+
111
+ return PseudoTransientCache {iip} (f, alg, u, copy (u), fu1, fu2, du, p, alpha, res_norm,
112
+ uf,
97
113
linsolve, J, jac_cache, false , maxiters, internalnorm, ReturnCode. Default, abstol,
98
- prob, NLStats (1 , 0 , 0 , 0 , 0 ))
114
+ reltol,
115
+ prob, NLStats (1 , 0 , 0 , 0 , 0 ), termination_condition, storage)
99
116
end
100
117
101
118
function perform_step! (cache:: PseudoTransientCache{true} )
102
- @unpack u, fu1, f, p, alg, J, linsolve, du, alpha = cache
119
+ @unpack u, u_prev, fu1, f, p, alg, J, linsolve, du, alpha, tc_storage = cache
103
120
jacobian!! (J, cache)
104
121
J_new = J - (1 / alpha) * I
105
122
123
+ termination_condition = cache. termination_condition (tc_storage)
124
+
106
125
# u = u - J \ fu
107
126
linres = dolinsolve (alg. precs, linsolve; A = J_new, b = _vec (fu1), linu = _vec (du),
108
127
p, reltol = cache. abstol)
@@ -114,7 +133,10 @@ function perform_step!(cache::PseudoTransientCache{true})
114
133
cache. alpha *= cache. res_norm / new_norm
115
134
cache. res_norm = new_norm
116
135
117
- new_norm < cache. abstol && (cache. force_stop = true )
136
+ termination_condition (fu1, u, u_prev, cache. abstol, cache. reltol) &&
137
+ (cache. force_stop = true )
138
+
139
+ @. u_prev = u
118
140
cache. stats. nf += 1
119
141
cache. stats. njacs += 1
120
142
cache. stats. nsolve += 1
@@ -123,7 +145,10 @@ function perform_step!(cache::PseudoTransientCache{true})
123
145
end
124
146
125
147
function perform_step! (cache:: PseudoTransientCache{false} )
126
- @unpack u, fu1, f, p, alg, linsolve, alpha = cache
148
+ @unpack u, u_prev, fu1, f, p, alg, linsolve, alpha, tc_storage = cache
149
+
150
+ tc_storage = cache. tc_storage
151
+ termination_condition = cache. termination_condition (tc_storage)
127
152
128
153
cache. J = jacobian!! (cache. J, cache)
129
154
# u = u - J \ fu
@@ -141,7 +166,9 @@ function perform_step!(cache::PseudoTransientCache{false})
141
166
new_norm = cache. internalnorm (fu1)
142
167
cache. alpha *= cache. res_norm / new_norm
143
168
cache. res_norm = new_norm
144
- new_norm < cache. abstol && (cache. force_stop = true )
169
+ termination_condition (fu1, cache. u, u_prev, cache. abstol, cache. reltol) &&
170
+ (cache. force_stop = true )
171
+ cache. u_prev = @. cache. u
145
172
cache. stats. nf += 1
146
173
cache. stats. njacs += 1
147
174
cache. stats. nsolve += 1
167
194
168
195
function SciMLBase. reinit! (cache:: PseudoTransientCache{iip} , u0 = cache. u; p = cache. p,
169
196
alpha_new,
170
- abstol = cache. abstol, maxiters = cache. maxiters) where {iip}
197
+ abstol = cache. abstol, reltol = cache. reltol,
198
+ termination_condition = cache. termination_condition,
199
+ maxiters = cache. maxiters) where {iip}
171
200
cache. p = p
172
201
if iip
173
202
recursivecopy! (cache. u, u0)
@@ -177,9 +206,17 @@ function SciMLBase.reinit!(cache::PseudoTransientCache{iip}, u0 = cache.u; p = c
177
206
cache. u = u0
178
207
cache. fu1 = cache. f (cache. u, p)
179
208
end
209
+
210
+ termination_condition = _get_reinit_termination_condition (cache,
211
+ abstol,
212
+ reltol,
213
+ termination_condition)
214
+
180
215
cache. alpha = convert (eltype (cache. u), alpha_new)
181
216
cache. res_norm = cache. internalnorm (cache. fu1)
182
217
cache. abstol = abstol
218
+ cache. reltol = reltol
219
+ cache. termination_condition = termination_condition
183
220
cache. maxiters = maxiters
184
221
cache. stats. nf = 1
185
222
cache. stats. nsteps = 1
0 commit comments