@muladd begin
"""
AliveCallback(analysis_interval=0, alive_interval=analysis_interval÷10)
Inexpensive callback showing that a simulation is still running by printing
some information such as the current time to the screen every `alive_interval`
time steps. If `analysis_interval ≂̸ 0`, the output is omitted every
`analysis_interval` time steps.
"""
mutable struct AliveCallback
start_time::Float64
alive_interval::Int
analysis_interval::Int
end
function AliveCallback(; analysis_interval = 0,
alive_interval = analysis_interval ÷ 10)
alive_callback = AliveCallback(0.0, alive_interval, analysis_interval)
DiscreteCallback(alive_callback, alive_callback,
save_positions = (false, false),
initialize = initialize!)
end
function Base.show(io::IO, cb::DiscreteCallback{<:Any, <:AliveCallback})
@nospecialize cb
alive_callback = cb.affect!
print(io, "AliveCallback(alive_interval=", alive_callback.alive_interval, ")")
end
function Base.show(io::IO, ::MIME"text/plain",
cb::DiscreteCallback{<:Any, <:AliveCallback})
@nospecialize cb
if get(io, :compact, false)
show(io, cb)
else
alive_callback = cb.affect!
setup = [
"interval" => alive_callback.alive_interval
]
summary_box(io, "AliveCallback", setup)
end
end
function initialize!(cb::DiscreteCallback{Condition, Affect!}, u, t,
integrator) where {Condition, Affect! <: AliveCallback}
alive_callback = cb.affect!
alive_callback.start_time = time_ns()
return nothing
end
function (alive_callback::AliveCallback)(u, t, integrator)
@unpack alive_interval, analysis_interval = alive_callback
return alive_interval > 0 && ((integrator.stats.naccept % alive_interval == 0 &&
(analysis_interval == 0 ||
integrator.stats.naccept % analysis_interval != 0)) ||
isfinished(integrator))
end
function (alive_callback::AliveCallback)(integrator)
if isfinished(integrator) && mpi_isroot()
println("─"^100)
println("Trixi.jl simulation finished. Final time: ", integrator.t,
" Time steps: ", integrator.stats.naccept, " (accepted), ",
integrator.iter, " (total)")
println("─"^100)
println()
elseif mpi_isroot()
t = integrator.t
t_initial = first(integrator.sol.prob.tspan)
t_final = last(integrator.sol.prob.tspan)
sim_time_percentage = (t - t_initial) / (t_final - t_initial) * 100
runtime_absolute = 1.0e-9 * (time_ns() - alive_callback.start_time)
println(rpad(@sprintf("#timesteps: %6d │ Δt: %.4e │ sim. time: %.4e (%5.3f%%)",
integrator.stats.naccept, integrator.dt, t,
sim_time_percentage), 71) *
@sprintf("│ run time: %.4e s", runtime_absolute))
end
u_modified!(integrator, false)
return nothing
end
end