Skip to content

Commit 70b9884

Browse files
Prevent first Newton iteration to be skipped (#236)
* Add final log for Newton * Create output path for debug monitor * Redirect call in debug monitor * Revert time integration message. Unfortunately the message is before dt is changed. * Add option to opt out early when hitting machine precision.
1 parent cf9dc68 commit 70b9884

2 files changed

Lines changed: 27 additions & 15 deletions

File tree

src/solver/logging.jl

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function integration_step_monitor(integrator::SciMLBase.DEIntegrator, progress_m
1919
# (; id) = progress_monitor
2020
(; tprev, t, dt, iter) = integrator
2121
# push!(msgs, id => "$id: integrating on [$t, $(t+dt)] with Δt=$dt.")
22-
@logmsg LogLevel(-100) "Integrating on [$tprev, $t]." iter=iter Δt=dt _group=:timeintegration
22+
@logmsg LogLevel(-100) "Integrating on [$t, $(t+dt)]." iter=iter Δt=dt tprev=tprev _group=:timeintegration
2323
end
2424

2525
function integration_finalize_monitor(integrator, progress_monitor::DefaultProgressMonitor)
@@ -39,15 +39,24 @@ function nonlinear_step_monitor(nlcache, time, f, u, progress_monitor::DefaultPr
3939
resnorm = norm(nlcache.residual)
4040
normΔu = norm(linear_solver_cache.u)
4141
if stats === nothing
42-
@logmsg LogLevel(-100) "Nonlinear solve step" iter=iter resnorm=resnorm normΔu=normΔu _group=:nlsolve
42+
@logmsg LogLevel(-100) "Nonlinear solve step" time=time iter=iter resnorm=resnorm normΔu=normΔu _group=:nlsolve
4343
else
44-
@logmsg LogLevel(-100) "Nonlinear solve step" iter=iter stats=stats _group=:nlsolve
44+
@logmsg LogLevel(-100) "Nonlinear solve step" time=time iter=iter resnorm=resnorm normΔu=normΔu stats=stats _group=:nlsolve
4545
end
4646
end
4747

4848
function nonlinear_finalize_monitor(nlcache, time, f, progress_monitor::DefaultProgressMonitor)
4949
# (; id, msgs) = progress_monitor
50-
# push!(msgs, id => "$id: done.")
50+
(; iter, linear_solver_cache) = nlcache
51+
stats = hasproperty(linear_solver_cache.cacheval, :stats) ? linear_solver_cache.cacheval.stats : nothing
52+
# push!(msgs, id => "$id: $(nlcache.iter)\n\t||r||=$(norm(nlcache.residual)) ||Δu||=$(norm(linear_solver_cache.u))\n\t$stats")
53+
resnorm = norm(nlcache.residual)
54+
normΔu = norm(linear_solver_cache.u)
55+
if stats === nothing
56+
@logmsg LogLevel(-100) "Nonlinear solve converged" time=time iter=iter resnorm=resnorm normΔu=normΔu _group=:nlsolve
57+
else
58+
@logmsg LogLevel(-100) "Nonlinear solve converged" time=time iter=iter resnorm=resnorm normΔu=normΔu stats=stats _group=:nlsolve
59+
end
5160
end
5261

5362
#
@@ -71,12 +80,14 @@ end
7180
function nonlinear_step_monitor(cache, time, f, u, monitor::VTKNewtonMonitor)
7281
nonlinear_step_monitor(cache,time,f,u,monitor.inner_monitor)
7382

83+
mkpath(monitor.outdir)
7484
VTKGridFile(joinpath(monitor.outdir, "newton-monitor-t=$time-i=$(cache.iter).vtu"), f.dh) do vtk
7585
write_solution(vtk, f.dh, u)
7686
write_solution(vtk, f.dh, cache.linear_solver_cache.b, "_residual")
7787
write_solution(vtk, f.dh, cache.linear_solver_cache.u, "_increment")
7888
end
7989
end
8090

81-
function nonlinear_finalize_monitor(nlcache, time, f, progress_monitor::VTKNewtonMonitor)
91+
function nonlinear_finalize_monitor(nlcache, time, f, monitor::VTKNewtonMonitor)
92+
nonlinear_finalize_monitor(nlcache, time,f, monitor.inner_monitor)
8293
end

src/solver/nonlinear/newton_raphson.jl

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ function setup_solver_cache(f::AbstractSemidiscreteBlockedFunction, solver::Newt
6868
NewtonRaphsonSolverCache(op, residual, solver, inner_cache, T[], 0)
6969
end
7070

71-
function nlsolve!(u::AbstractVector, f::AbstractSemidiscreteFunction, cache::NewtonRaphsonSolverCache, t)
71+
function nlsolve!(u::AbstractVector{T}, f::AbstractSemidiscreteFunction, cache::NewtonRaphsonSolverCache, t) where T
7272
@unpack op, residual, linear_solver_cache, Θks = cache
7373
monitor = cache.parameters.monitor
7474
cache.iter = -1
@@ -84,10 +84,8 @@ function nlsolve!(u::AbstractVector, f::AbstractSemidiscreteFunction, cache::New
8484
linear_solver_cache.isfresh = true # Notify linear solver that we touched the system matrix
8585

8686
residualnorm = residual_norm(cache, f)
87-
if residualnorm < cache.parameters.tol
88-
if cache.iter == 1
89-
push!(Θks, 0.0)
90-
end
87+
if residualnorm < cache.parameters.tol && cache.iter > 0
88+
push!(Θks, 0.0)
9189
break
9290
elseif cache.iter > cache.parameters.max_iter
9391
push!(Θks,Inf)
@@ -116,17 +114,20 @@ function nlsolve!(u::AbstractVector, f::AbstractSemidiscreteFunction, cache::New
116114
else
117115
push!(Θks, Θk)
118116
end
117+
# Try to prevent oversolving when we really just wanted to force the solve to happen once.
118+
if cache.iter == 1 && residualnormprev < eps(T) && residualnorm < eps(T) && incrementnorm < eps(T) && incrementnormprev < eps(T)
119+
break
120+
end
119121
if cache.parameters.enforce_monotonic_convergence && Θk 1.0
120122
@debug "Newton-Raphson diverged. Aborting. ||r|| = $residualnorm" _group=:nlsolve
121123
return false
122124
end
123-
124-
# Late out on second iteration
125-
if residualnorm < cache.parameters.tol
126-
break
127-
end
128125
end
129126

127+
# if incrementnorm < cache.parameters.tol
128+
# break
129+
# end
130+
130131
residualnormprev = residualnorm
131132
incrementnormprev = incrementnorm
132133
end

0 commit comments

Comments
 (0)