@@ -2,6 +2,7 @@ export NewtonsMethod, KrylovMethod
22export JacobianFreeJVP, ForwardDiffJVP, ForwardDiffStepSize
33export ForwardDiffStepSize1, ForwardDiffStepSize2, ForwardDiffStepSize3
44export ForcingTerm, ConstantForcing, EisenstatWalkerForcing
5+ export Verbosity
56
67# TODO : Implement AutoDiffJVP after ClimaAtmos's cache is moved from f! to x (so
78# that we only need to define Dual.(x), and not also make_dual(f!)).
@@ -12,6 +13,11 @@ export ForcingTerm, ConstantForcing, EisenstatWalkerForcing
1213# TODO : Consider implementing BroydensMethod, BadBroydensMethod, and other
1314# automatic Jacobian approximations.
1415
16+ abstract type AbstractVerbosity end
17+ struct Verbose <: AbstractVerbosity end
18+ struct Silent <: AbstractVerbosity end
19+ is_verbose (v:: AbstractVerbosity ) = v isa Verbose
20+
1521"""
1622 ForwardDiffStepSize
1723
330336 kwargs = (;),
331337 solve_kwargs = (;),
332338 disable_preconditioner = false,
333- verbose = false ,
339+ verbose = Silent() ,
334340 debugger = nothing,
335341 )
336342
@@ -393,6 +399,7 @@ Base.@kwdef struct KrylovMethod{
393399 A <: Tuple ,
394400 K <: NamedTuple ,
395401 S <: NamedTuple ,
402+ V <: AbstractVerbosity ,
396403 D <: Union{Nothing, KrylovMethodDebugger} ,
397404}
398405 type:: T = Val (Krylov. GmresSolver)
@@ -402,7 +409,7 @@ Base.@kwdef struct KrylovMethod{
402409 kwargs:: K = (;)
403410 solve_kwargs:: S = (;)
404411 disable_preconditioner:: Bool = false
405- verbose:: Bool = false
412+ verbose:: V = Silent ()
406413 debugger:: D = nothing
407414end
408415
423430
424431function solve_krylov! (alg:: KrylovMethod , cache, Δx, x, f!, f, n, j = nothing )
425432 (; jacobian_free_jvp, forcing_term, solve_kwargs) = alg
426- (; disable_preconditioner, verbose, debugger) = alg
433+ (; disable_preconditioner, debugger) = alg
427434 type = solver_type (alg)
428435 (; jacobian_free_jvp_cache, forcing_term_cache, solver, debugger_cache) = cache
429436 jΔx! (jΔx, Δx) =
@@ -435,7 +442,7 @@ function solve_krylov!(alg::KrylovMethod, cache, Δx, x, f!, f, n, j = nothing)
435442 ldiv = true
436443 atol = zero (eltype (Δx))
437444 rtol = get_rtol! (forcing_term, forcing_term_cache, f, n)
438- verbose = Int (verbose)
445+ verbose = Int (is_verbose (alg . verbose) )
439446 Krylov. solve! (solver, opj, f; M, ldiv, atol, rtol, verbose, solve_kwargs... )
440447 iter = solver. stats. niter
441448 if ! solver. stats. solved
463470 update_j = UpdateEvery(NewNewtonIteration),
464471 krylov_method = nothing,
465472 convergence_checker = nothing,
466- verbose = false ,
473+ verbose = Silent() ,
467474 )
468475
469476Solves the equation `f(x) = 0`, using the Jacobian (or an approximation of the
@@ -538,12 +545,13 @@ Base.@kwdef struct NewtonsMethod{
538545 U <: UpdateSignalHandler ,
539546 K <: Union{Nothing, KrylovMethod} ,
540547 C <: Union{Nothing, ConvergenceChecker} ,
548+ V <: AbstractVerbosity ,
541549}
542550 max_iters:: Int = 1
543551 update_j:: U = UpdateEvery (NewNewtonIteration)
544552 krylov_method:: K = nothing
545553 convergence_checker:: C = nothing
546- verbose:: Bool = false
554+ verbose:: V = Silent ()
547555end
548556
549557function allocate_cache (alg:: NewtonsMethod , x_prototype, j_prototype = nothing )
@@ -571,7 +579,7 @@ function solve_newton!(alg::NewtonsMethod, cache, x, f!, j! = nothing)
571579 # Update x[n] with Δx[n - 1], and exit the loop if Δx[n] is not needed.
572580 n > 0 && (x .- = Δx)
573581 if n == max_iters && isnothing (convergence_checker)
574- verbose && @info " Newton iteration $n : ‖x‖ = $(norm (x)) , ‖Δx‖ = N/A"
582+ is_verbose ( verbose) && @info " Newton iteration $n : ‖x‖ = $(norm (x)) , ‖Δx‖ = N/A"
575583 break
576584 end
577585
@@ -589,7 +597,7 @@ function solve_newton!(alg::NewtonsMethod, cache, x, f!, j! = nothing)
589597 else
590598 solve_krylov! (krylov_method, krylov_method_cache, Δx, x, f!, f, n, j)
591599 end
592- verbose && @info " Newton iteration $n : ‖x‖ = $(norm (x)) , ‖Δx‖ = $(norm (Δx)) "
600+ is_verbose ( verbose) && @info " Newton iteration $n : ‖x‖ = $(norm (x)) , ‖Δx‖ = $(norm (Δx)) "
593601
594602 # Check for convergence if necessary.
595603 if ! isnothing (convergence_checker)
0 commit comments