From 20d957a51b475b27a44391923acc83c2f5bc93a7 Mon Sep 17 00:00:00 2001 From: Joshua Lampert <51029046+JoshuaLampert@users.noreply.github.com> Date: Mon, 11 Dec 2023 17:12:07 +0100 Subject: [PATCH] Add `SummaryCallback` (#75) * add SummaryCallback with TimerOutputs.jl * format --- Project.toml | 2 + examples/bbm_bbm_1d/bbm_bbm_1d_basic.jl | 3 +- examples/bbm_bbm_1d/bbm_bbm_1d_dg.jl | 3 +- .../bbm_bbm_1d/bbm_bbm_1d_manufactured.jl | 3 +- examples/bbm_bbm_1d/bbm_bbm_1d_relaxation.jl | 3 +- .../bbm_bbm_variable_bathymetry_1d_basic.jl | 3 +- ...able_bathymetry_1d_dg_upwind_relaxation.jl | 3 +- ...bm_bbm_variable_bathymetry_1d_dingemans.jl | 3 +- ...bbm_variable_bathymetry_1d_manufactured.jl | 3 +- ...m_bbm_variable_bathymetry_1d_relaxation.jl | 3 +- ...ariable_bathymetry_1d_upwind_relaxation.jl | 3 +- ...bm_variable_bathymetry_1d_well_balanced.jl | 3 +- .../svaerd_kalisch_1d_dingemans.jl | 3 +- .../svaerd_kalisch_1d_dingemans_cg.jl | 3 +- .../svaerd_kalisch_1d_dingemans_relaxation.jl | 3 +- .../svaerd_kalisch_1d_dingemans_upwind.jl | 3 +- .../svaerd_kalisch_1d_manufactured.jl | 3 +- .../svaerd_kalisch_1d_well_balanced.jl | 3 +- src/DispersiveShallowWater.jl | 3 +- src/callbacks_step/analysis.jl | 123 +++++++++--------- src/callbacks_step/callbacks_step.jl | 1 + src/callbacks_step/relaxation.jl | 46 +++---- src/callbacks_step/summary.jl | 53 ++++++++ src/equations/bbm_bbm_1d.jl | 17 ++- .../bbm_bbm_variable_bathymetry_1d.jl | 16 ++- src/equations/svaerd_kalisch_1d.jl | 68 +++++----- src/semidiscretization.jl | 5 +- src/util.jl | 6 + test/test_unit.jl | 7 + 29 files changed, 250 insertions(+), 148 deletions(-) create mode 100644 src/callbacks_step/summary.jl diff --git a/Project.toml b/Project.toml index fe6feee0..4e7154d3 100644 --- a/Project.toml +++ b/Project.toml @@ -17,6 +17,7 @@ SimpleUnPack = "ce78b400-467f-4804-87d8-8f486da07d0a" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" SummationByPartsOperators = "9f78cca6-572e-554e-b819-917d2f1cf240" +TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" [compat] DiffEqBase = "6.121" @@ -32,4 +33,5 @@ SimpleUnPack = "1.1" SparseArrays = "1" StaticArrays = "1" SummationByPartsOperators = "0.5.41" +TimerOutputs = "0.5" julia = "1.8" diff --git a/examples/bbm_bbm_1d/bbm_bbm_1d_basic.jl b/examples/bbm_bbm_1d/bbm_bbm_1d_basic.jl index f2640569..46dd871b 100644 --- a/examples/bbm_bbm_1d/bbm_bbm_1d_basic.jl +++ b/examples/bbm_bbm_1d/bbm_bbm_1d_basic.jl @@ -28,11 +28,12 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 30.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, velocity, entropy)) -callbacks = CallbackSet(analysis_callback) +callbacks = CallbackSet(analysis_callback, summary_callback) saveat = range(tspan..., length = 100) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/bbm_bbm_1d/bbm_bbm_1d_dg.jl b/examples/bbm_bbm_1d/bbm_bbm_1d_dg.jl index 7d7d6543..d2efe172 100644 --- a/examples/bbm_bbm_1d/bbm_bbm_1d_dg.jl +++ b/examples/bbm_bbm_1d/bbm_bbm_1d_dg.jl @@ -39,11 +39,12 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, tspan = (0.0, 30.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, velocity, entropy)) -callbacks = CallbackSet(analysis_callback) +callbacks = CallbackSet(analysis_callback, summary_callback) saveat = range(tspan..., length = 100) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/bbm_bbm_1d/bbm_bbm_1d_manufactured.jl b/examples/bbm_bbm_1d/bbm_bbm_1d_manufactured.jl index c051cb3e..d2f72423 100644 --- a/examples/bbm_bbm_1d/bbm_bbm_1d_manufactured.jl +++ b/examples/bbm_bbm_1d/bbm_bbm_1d_manufactured.jl @@ -29,11 +29,12 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 1.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, velocity, entropy)) -callbacks = CallbackSet(analysis_callback) +callbacks = CallbackSet(analysis_callback, summary_callback) saveat = range(tspan..., length = 100) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/bbm_bbm_1d/bbm_bbm_1d_relaxation.jl b/examples/bbm_bbm_1d/bbm_bbm_1d_relaxation.jl index 842ea53d..176b4105 100644 --- a/examples/bbm_bbm_1d/bbm_bbm_1d_relaxation.jl +++ b/examples/bbm_bbm_1d/bbm_bbm_1d_relaxation.jl @@ -28,13 +28,14 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 30.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, velocity, entropy)) relaxation_callback = RelaxationCallback(invariant = entropy) # Always put relaxation_callback before analysis_callback to guarantee conservation of the invariant -callbacks = CallbackSet(relaxation_callback, analysis_callback) +callbacks = CallbackSet(relaxation_callback, analysis_callback, summary_callback) saveat = range(tspan..., length = 100) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_basic.jl b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_basic.jl index 1e02e94e..d1a9050f 100644 --- a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_basic.jl +++ b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_basic.jl @@ -28,11 +28,12 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 30.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, velocity, entropy)) -callbacks = CallbackSet(analysis_callback) +callbacks = CallbackSet(analysis_callback, summary_callback) saveat = range(tspan..., length = 100) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_dg_upwind_relaxation.jl b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_dg_upwind_relaxation.jl index b2d19d38..6a0a1114 100644 --- a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_dg_upwind_relaxation.jl +++ b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_dg_upwind_relaxation.jl @@ -38,13 +38,14 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 30.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, velocity, entropy)) relaxation_callback = RelaxationCallback(invariant = entropy) # Always put relaxation_callback before analysis_callback to guarantee conservation of the invariant -callbacks = CallbackSet(relaxation_callback, analysis_callback) +callbacks = CallbackSet(relaxation_callback, analysis_callback, summary_callback) saveat = range(tspan..., length = 100) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_dingemans.jl b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_dingemans.jl index 8a0a25a8..3949dbb4 100644 --- a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_dingemans.jl +++ b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_dingemans.jl @@ -27,11 +27,12 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 70.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, velocity, entropy)) -callbacks = CallbackSet(analysis_callback) +callbacks = CallbackSet(analysis_callback, summary_callback) saveat = range(tspan..., length = 500) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_manufactured.jl b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_manufactured.jl index 12204888..5ae139e2 100644 --- a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_manufactured.jl +++ b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_manufactured.jl @@ -29,11 +29,12 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 1.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, velocity, entropy)) -callbacks = CallbackSet(analysis_callback) +callbacks = CallbackSet(analysis_callback, summary_callback) saveat = range(tspan..., length = 100) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_relaxation.jl b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_relaxation.jl index 25fd604c..54e51350 100644 --- a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_relaxation.jl +++ b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_relaxation.jl @@ -32,13 +32,14 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 30.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, velocity, entropy)) relaxation_callback = RelaxationCallback(invariant = entropy) # Always put relaxation_callback before analysis_callback to guarantee conservation of the invariant -callbacks = CallbackSet(relaxation_callback, analysis_callback) +callbacks = CallbackSet(relaxation_callback, analysis_callback, summary_callback) saveat = range(tspan..., length = 100) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_upwind_relaxation.jl b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_upwind_relaxation.jl index b645b5ce..5891c2a3 100644 --- a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_upwind_relaxation.jl +++ b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_upwind_relaxation.jl @@ -34,13 +34,14 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 30.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, velocity, entropy)) relaxation_callback = RelaxationCallback(invariant = entropy) # Always put relaxation_callback before analysis_callback to guarantee conservation of the invariant -callbacks = CallbackSet(relaxation_callback, analysis_callback) +callbacks = CallbackSet(relaxation_callback, analysis_callback, summary_callback) saveat = range(tspan..., length = 100) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_well_balanced.jl b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_well_balanced.jl index a55e72ee..ad1e1666 100644 --- a/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_well_balanced.jl +++ b/examples/bbm_bbm_variable_bathymetry_1d/bbm_bbm_variable_bathymetry_1d_well_balanced.jl @@ -51,13 +51,14 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 30.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, velocity, entropy, lake_at_rest_error)) # Always put relaxation_callback before analysis_callback to guarantee conservation of the invariant -callbacks = CallbackSet(analysis_callback) +callbacks = CallbackSet(analysis_callback, summary_callback) dt = 0.5 saveat = range(tspan..., length = 100) diff --git a/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans.jl b/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans.jl index b0590626..f1d1b618 100644 --- a/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans.jl +++ b/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans.jl @@ -28,12 +28,13 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 70.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, entropy, entropy_modified)) -callbacks = CallbackSet(analysis_callback) +callbacks = CallbackSet(analysis_callback, summary_callback) saveat = range(tspan..., length = 500) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans_cg.jl b/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans_cg.jl index 25ffc1a8..cc75b757 100644 --- a/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans_cg.jl +++ b/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans_cg.jl @@ -35,12 +35,13 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 70.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, entropy, entropy_modified)) -callbacks = CallbackSet(analysis_callback) +callbacks = CallbackSet(analysis_callback, summary_callback) saveat = range(tspan..., length = 500) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans_relaxation.jl b/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans_relaxation.jl index d84e4a45..aa5b2442 100644 --- a/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans_relaxation.jl +++ b/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans_relaxation.jl @@ -28,6 +28,7 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 70.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, @@ -35,7 +36,7 @@ analysis_callback = AnalysisCallback(semi; interval = 10, entropy_modified)) relaxation_callback = RelaxationCallback(invariant = entropy_modified) # Always put relaxation_callback before analysis_callback to guarantee conservation of the invariant -callbacks = CallbackSet(relaxation_callback, analysis_callback) +callbacks = CallbackSet(relaxation_callback, analysis_callback, summary_callback) saveat = range(tspan..., length = 500) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans_upwind.jl b/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans_upwind.jl index 64e0f4ad..f57eff3b 100644 --- a/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans_upwind.jl +++ b/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_dingemans_upwind.jl @@ -33,13 +33,14 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 70.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, entropy, entropy_modified)) -callbacks = CallbackSet(analysis_callback) +callbacks = CallbackSet(analysis_callback, summary_callback) saveat = range(tspan..., length = 500) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_manufactured.jl b/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_manufactured.jl index 781d4bf3..44c2fc91 100644 --- a/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_manufactured.jl +++ b/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_manufactured.jl @@ -32,11 +32,12 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 1.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, velocity, entropy)) -callbacks = CallbackSet(analysis_callback) +callbacks = CallbackSet(analysis_callback, summary_callback) saveat = range(tspan..., length = 100) sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7, diff --git a/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_well_balanced.jl b/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_well_balanced.jl index ce91e72d..9384b227 100644 --- a/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_well_balanced.jl +++ b/examples/svaerd_kalisch_1d/svaerd_kalisch_1d_well_balanced.jl @@ -50,12 +50,13 @@ semi = Semidiscretization(mesh, equations, initial_condition, solver, # Create `ODEProblem` and run the simulation tspan = (0.0, 10.0) ode = semidiscretize(semi, tspan) +summary_callback = SummaryCallback() analysis_callback = AnalysisCallback(semi; interval = 10, extra_analysis_errors = (:conservation_error,), extra_analysis_integrals = (waterheight_total, momentum, entropy, lake_at_rest_error)) -callbacks = CallbackSet(analysis_callback) +callbacks = CallbackSet(analysis_callback, summary_callback) # Need a very small time step for stability dt = 0.0002 diff --git a/src/DispersiveShallowWater.jl b/src/DispersiveShallowWater.jl index 77b98726..1cd8e0cd 100644 --- a/src/DispersiveShallowWater.jl +++ b/src/DispersiveShallowWater.jl @@ -21,6 +21,7 @@ using SummationByPartsOperators: AbstractDerivativeOperator, periodic_derivative_operator, derivative_order, integrate import SummationByPartsOperators: grid, xmin, xmax +using TimerOutputs: TimerOutputs, TimerOutput, @timeit, print_timer, reset_timer! include("boundary_conditions.jl") include("mesh.jl") @@ -52,7 +53,7 @@ export initial_condition_convergence_test, initial_condition_manufactured, source_terms_manufactured, initial_condition_dingemans -export AnalysisCallback, RelaxationCallback +export AnalysisCallback, RelaxationCallback, SummaryCallback export tstops, errors, integrals end diff --git a/src/callbacks_step/analysis.jl b/src/callbacks_step/analysis.jl index fa7aaa25..0365a83c 100644 --- a/src/callbacks_step/analysis.jl +++ b/src/callbacks_step/analysis.jl @@ -218,74 +218,77 @@ function (analysis_callback::AnalysisCallback)(io, u_ode, integrator, semi) # Source: https://github.com/JuliaLang/julia/blob/b540315cb4bd91e6f3a3e4ab8129a58556947628/base/timing.jl#L86-L97 memory_use = Base.gc_live_bytes() / 2^20 # bytes -> MiB - println(io) - println(io, "─"^100) - println(io, "Simulation running '", get_name(equations), "' with '", - semi.initial_condition, - "'") - println(io, "─"^100) - println(io, - " #timesteps: " * @sprintf("% 14d", iter) * - " " * - " run time: " * @sprintf("%10.8e s", runtime_absolute)) - println(io, - " Δt: " * @sprintf("%10.8e", dt) * - " " * - " └── GC time: " * - @sprintf("%10.8e s (%5.3f%%)", gc_time_absolute, gc_time_percentage)) - println(io, " sim. time: " * @sprintf("%10.8e (%5.3f%%)", t, sim_time_percentage)) - println(io, - " #DOF: " * @sprintf("% 14d", nnodes(semi)) * - " " * - " alloc'd memory: " * @sprintf("%14.3f MiB", memory_use)) - println(io) - - print(io, " Variable: ") - for v in eachvariable(equations) - @printf(io, " %-14s", varnames(prim2prim, equations)[v]) - end - println(io) - - # Calculate L2/Linf errors, which are also returned - l2_error, linf_error = calc_error_norms(u_ode, t, semi) - current_errors = zeros(real(semi), (length(analysis_errors), nvariables(equations))) - current_errors[1, :] = l2_error - current_errors[2, :] = linf_error - print(io, " L2 error: ") - for v in eachvariable(equations) - @printf(io, " % 10.8e", l2_error[v]) - end - println(io) + @timeit timer() "analyze solution" begin + println(io) + println(io, "─"^100) + println(io, "Simulation running '", get_name(equations), "' with '", + semi.initial_condition, + "'") + println(io, "─"^100) + println(io, + " #timesteps: " * @sprintf("% 14d", iter) * + " " * + " run time: " * @sprintf("%10.8e s", runtime_absolute)) + println(io, + " Δt: " * @sprintf("%10.8e", dt) * + " " * + " └── GC time: " * + @sprintf("%10.8e s (%5.3f%%)", gc_time_absolute, gc_time_percentage)) + println(io, + " sim. time: " * @sprintf("%10.8e (%5.3f%%)", t, sim_time_percentage)) + println(io, + " #DOF: " * @sprintf("% 14d", nnodes(semi)) * + " " * + " alloc'd memory: " * @sprintf("%14.3f MiB", memory_use)) + println(io) - print(io, " Linf error: ") - for v in eachvariable(equations) - @printf(io, " % 10.8e", linf_error[v]) - end - println(io) + print(io, " Variable: ") + for v in eachvariable(equations) + @printf(io, " %-14s", varnames(prim2prim, equations)[v]) + end + println(io) - # Conservation error - if :conservation_error in analysis_errors - @unpack initial_state_integrals = analysis_callback - state_integrals = integrate(u_ode, semi) - current_errors[3, :] = abs.(state_integrals - initial_state_integrals) - print(io, " |∫q - ∫q₀|: ") + # Calculate L2/Linf errors, which are also returned + l2_error, linf_error = calc_error_norms(u_ode, t, semi) + current_errors = zeros(real(semi), (length(analysis_errors), nvariables(equations))) + current_errors[1, :] = l2_error + current_errors[2, :] = linf_error + print(io, " L2 error: ") for v in eachvariable(equations) - @printf(io, " % 10.8e", current_errors[3, v]) + @printf(io, " % 10.8e", l2_error[v]) end println(io) - end - push!(errors, current_errors) - # additional integrals - if length(analysis_integrals) > 0 + print(io, " Linf error: ") + for v in eachvariable(equations) + @printf(io, " % 10.8e", linf_error[v]) + end println(io) - println(io, " Integrals: ") - end - current_integrals = zeros(real(semi), length(analysis_integrals)) - analyze_integrals!(io, current_integrals, 1, analysis_integrals, u_ode, t, semi) - push!(integrals, current_integrals) - println(io, "─"^100) + # Conservation error + if :conservation_error in analysis_errors + @unpack initial_state_integrals = analysis_callback + state_integrals = integrate(u_ode, semi) + current_errors[3, :] = abs.(state_integrals - initial_state_integrals) + print(io, " |∫q - ∫q₀|: ") + for v in eachvariable(equations) + @printf(io, " % 10.8e", current_errors[3, v]) + end + println(io) + end + push!(errors, current_errors) + + # additional integrals + if length(analysis_integrals) > 0 + println(io) + println(io, " Integrals: ") + end + current_integrals = zeros(real(semi), length(analysis_integrals)) + analyze_integrals!(io, current_integrals, 1, analysis_integrals, u_ode, t, semi) + push!(integrals, current_integrals) + + println(io, "─"^100) + end return l2_error, linf_error end diff --git a/src/callbacks_step/callbacks_step.jl b/src/callbacks_step/callbacks_step.jl index 08ee4fb8..2b544db7 100644 --- a/src/callbacks_step/callbacks_step.jl +++ b/src/callbacks_step/callbacks_step.jl @@ -8,3 +8,4 @@ end include("relaxation.jl") include("analysis.jl") +include("summary.jl") diff --git a/src/callbacks_step/relaxation.jl b/src/callbacks_step/relaxation.jl index 686025a6..dfc5dd1b 100644 --- a/src/callbacks_step/relaxation.jl +++ b/src/callbacks_step/relaxation.jl @@ -90,31 +90,33 @@ end end energy_old = relaxation_functional(uold, semi) - if (relaxation_functional(convex_combination(gamma_lo, uold, unew), semi) - energy_old) * - (relaxation_functional(convex_combination(gamma_hi, uold, unew), semi) - energy_old) > - 0 - terminate_integration = true - else - gamma = find_zero(g -> relaxation_functional(convex_combination(g, uold, unew), - semi) - - energy_old, (gamma_lo, gamma_hi), AlefeldPotraShi()) - end + @timeit timer() "relaxation" begin + if (relaxation_functional(convex_combination(gamma_lo, uold, unew), semi) - + energy_old) * + (relaxation_functional(convex_combination(gamma_hi, uold, unew), semi) - + energy_old) > 0 + terminate_integration = true + else + gamma = find_zero(g -> relaxation_functional(convex_combination(g, uold, unew), + semi) - + energy_old, (gamma_lo, gamma_hi), AlefeldPotraShi()) + end - if gamma < eps(typeof(gamma)) - terminate_integration = true - end + if gamma < eps(typeof(gamma)) + terminate_integration = true + end - unew .= convex_combination(gamma, uold, unew) - unew_ode = reshape(unew, prod(size(unew))) - DiffEqBase.set_u!(integrator, unew_ode) - if !isapprox(tnew, first(integrator.opts.tstops)) - tgamma = convex_combination(gamma, told, tnew) - DiffEqBase.set_t!(integrator, tgamma) - end + unew .= convex_combination(gamma, uold, unew) + unew_ode = reshape(unew, prod(size(unew))) + DiffEqBase.set_u!(integrator, unew_ode) + if !isapprox(tnew, first(integrator.opts.tstops)) + tgamma = convex_combination(gamma, told, tnew) + DiffEqBase.set_t!(integrator, tgamma) + end - if terminate_integration - terminate!(integrator) + if terminate_integration + terminate!(integrator) + end end - return nothing end diff --git a/src/callbacks_step/summary.jl b/src/callbacks_step/summary.jl new file mode 100644 index 00000000..1a1fbdb0 --- /dev/null +++ b/src/callbacks_step/summary.jl @@ -0,0 +1,53 @@ +""" + SummaryCallback(io::IO = stdout) + +Create and return a callback that prints a human-readable summary of the simulation setup at the +beginning of a simulation and then resets the timer. When the returned callback is executed +directly, the current timer values are shown. +""" +struct SummaryCallback + io::IO + + function SummaryCallback(io::IO = stdout) + function initialize(cb, u, t, integrator) + initialize_summary_callback(cb, u, t, integrator) + end + summary_callback = new(io) + # SummaryCallback is called at end of simulation + condition = (u, t, integrator) -> isfinished(integrator) + DiscreteCallback(condition, summary_callback, + save_positions = (false, false), + initialize = initialize) + end +end + +function Base.show(io::IO, cb::DiscreteCallback{<:Any, <:SummaryCallback}) + @nospecialize cb # reduce precompilation time + + print(io, "SummaryCallback") +end + +function initialize_summary_callback(cb::DiscreteCallback, u, t, integrator) + reset_timer!(timer()) + return nothing +end + +function (cb::SummaryCallback)(integrator) + u_modified!(integrator, false) + cb() +end + +function (summary_callback::SummaryCallback)() + io = summary_callback.io + TimerOutputs.complement!(timer()) + print_timer(io, timer(), title = "DispersiveSWE", + allocations = true, linechars = :unicode, compact = false) + println(io) + return nothing +end + +# Allow calling the callback explicitly +function (cb::DiscreteCallback{Condition, Affect!})() where {Condition, + Affect! <: SummaryCallback} + cb.affect!() +end diff --git a/src/equations/bbm_bbm_1d.jl b/src/equations/bbm_bbm_1d.jl index fa5844aa..3dc986e6 100644 --- a/src/equations/bbm_bbm_1d.jl +++ b/src/equations/bbm_bbm_1d.jl @@ -125,19 +125,22 @@ function rhs!(du_ode, u_ode, t, mesh, equations::BBMBBMEquations1D, initial_cond # energy and mass conservative semidiscretization if solver.D1 isa PeriodicDerivativeOperator || solver.D1 isa UniformPeriodicCoupledOperator - deta[:] = -solver.D1 * (equations.D * v + eta .* v) - dv[:] = -solver.D1 * (equations.gravity * eta + 0.5 * v .^ 2) + @timeit timer() "deta hyperbolic" deta[:]=-solver.D1 * (equations.D * v + eta .* v) + @timeit timer() "dv hyperbolic" dv[:]=-solver.D1 * + (equations.gravity * eta + 0.5 * v .^ 2) elseif solver.D1 isa PeriodicUpwindOperators - deta[:] = -solver.D1.central * (equations.D * v + eta .* v) - dv[:] = -solver.D1.central * (equations.gravity * eta + 0.5 * v .^ 2) + @timeit timer() "deta hyperbolic" deta[:]=-solver.D1.central * + (equations.D * v + eta .* v) + @timeit timer() "dv hyperbolic" dv[:]=-solver.D1.central * + (equations.gravity * eta + 0.5 * v .^ 2) else @error "unknown type of first-derivative operator" end - calc_sources!(dq, q, t, source_terms, equations, solver) + @timeit timer() "source terms" calc_sources!(dq, q, t, source_terms, equations, solver) - deta[:] = invImD2 * deta - dv[:] = invImD2 * dv + @timeit timer() "deta elliptic" deta[:]=invImD2 * deta + @timeit timer() "dv elliptic" dv[:]=invImD2 * dv return nothing end diff --git a/src/equations/bbm_bbm_variable_bathymetry_1d.jl b/src/equations/bbm_bbm_variable_bathymetry_1d.jl index ad63e6a0..990dd70f 100644 --- a/src/equations/bbm_bbm_variable_bathymetry_1d.jl +++ b/src/equations/bbm_bbm_variable_bathymetry_1d.jl @@ -190,19 +190,21 @@ function rhs!(du_ode, u_ode, t, mesh, equations::BBMBBMVariableEquations1D, if solver.D1 isa PeriodicDerivativeOperator || solver.D1 isa UniformPeriodicCoupledOperator - deta[:] = -solver.D1 * (D .* v + eta .* v) - dv[:] = -solver.D1 * (equations.gravity * eta + 0.5 * v .^ 2) + @timeit timer() "deta hyperbolic" deta[:]=-solver.D1 * (D .* v + eta .* v) + @timeit timer() "dv hyperbolic" dv[:]=-solver.D1 * + (equations.gravity * eta + 0.5 * v .^ 2) elseif solver.D1 isa PeriodicUpwindOperators - deta[:] = -solver.D1.minus * (D .* v + eta .* v) - dv[:] = -solver.D1.plus * (equations.gravity * eta + 0.5 * v .^ 2) + @timeit timer() "deta hyperbolic" deta[:]=-solver.D1.minus * (D .* v + eta .* v) + @timeit timer() "dv hyperbolic" dv[:]=-solver.D1.plus * + (equations.gravity * eta + 0.5 * v .^ 2) else @error "unknown type of first-derivative operator" end - calc_sources!(dq, q, t, source_terms, equations, solver) + @timeit timer() "source terms" calc_sources!(dq, q, t, source_terms, equations, solver) - deta[:] = invImDKD * deta - dv[:] = invImD2K * dv + @timeit timer() "deta elliptic" deta[:]=invImDKD * deta + @timeit timer() "dv elliptic" dv[:]=invImD2K * dv return nothing end diff --git a/src/equations/svaerd_kalisch_1d.jl b/src/equations/svaerd_kalisch_1d.jl index cf15d74e..0bc0eb6d 100644 --- a/src/equations/svaerd_kalisch_1d.jl +++ b/src/equations/svaerd_kalisch_1d.jl @@ -183,38 +183,41 @@ function rhs!(du_ode, u_ode, t, mesh, equations::SvaerdKalischEquations1D, dD = view(dq, 3, :) fill!(dD, zero(eltype(dD))) - h = eta .+ D - hv = h .* v - - if solver.D1 isa PeriodicDerivativeOperator || - solver.D1 isa UniformPeriodicCoupledOperator - D1eta = D1_central * eta - D1v = D1_central * v - tmp1 = alpha_hat .* (D1_central * (alpha_hat .* D1eta)) - vD1y = v .* (D1_central * tmp1) - D1vy = D1_central * (v .* tmp1) - yD1v = tmp1 .* D1v - @. tmp2 = tmp1 - hv - mul!(deta, D1_central, tmp2) - elseif solver.D1 isa PeriodicUpwindOperators - D1eta = D1_central * eta - D1v = D1_central * v - tmp1 = alpha_hat .* (solver.D1.minus * (alpha_hat .* (solver.D1.plus * eta))) - vD1y = v .* (solver.D1.minus * tmp1) - D1vy = solver.D1.minus * (v .* tmp1) - yD1v = tmp1 .* (solver.D1.plus * v) - deta[:] = solver.D1.minus * tmp1 - D1_central * hv - else - @error "unknown type of first derivative operator" + @timeit timer() "deta hyperbolic" begin + h = eta .+ D + hv = h .* v + + if solver.D1 isa PeriodicDerivativeOperator || + solver.D1 isa UniformPeriodicCoupledOperator + D1eta = D1_central * eta + D1v = D1_central * v + tmp1 = alpha_hat .* (D1_central * (alpha_hat .* D1eta)) + vD1y = v .* (D1_central * tmp1) + D1vy = D1_central * (v .* tmp1) + yD1v = tmp1 .* D1v + @. tmp2 = tmp1 - hv + mul!(deta, D1_central, tmp2) + elseif solver.D1 isa PeriodicUpwindOperators + D1eta = D1_central * eta + D1v = D1_central * v + tmp1 = alpha_hat .* (solver.D1.minus * (alpha_hat .* (solver.D1.plus * eta))) + vD1y = v .* (solver.D1.minus * tmp1) + D1vy = solver.D1.minus * (v .* tmp1) + yD1v = tmp1 .* (solver.D1.plus * v) + deta[:] = solver.D1.minus * tmp1 - D1_central * hv + else + @error "unknown type of first derivative operator" + end end - hmD1betaD1 = Diagonal(h) - D1betaD1 # split form - dv[:] = -(0.5 * (D1_central * (hv .* v) + hv .* D1v - v .* (D1_central * hv)) + - equations.gravity * h .* D1eta + - 0.5 * (vD1y - D1vy - yD1v) - - 0.5 * D1_central * (gamma_hat .* (solver.D2 * v)) - - 0.5 * solver.D2 * (gamma_hat .* D1v)) + @timeit timer() "dv hyperbolic" begin + dv[:] = -(0.5 * (D1_central * (hv .* v) + hv .* D1v - v .* (D1_central * hv)) + + equations.gravity * h .* D1eta + + 0.5 * (vD1y - D1vy - yD1v) - + 0.5 * D1_central * (gamma_hat .* (solver.D2 * v)) - + 0.5 * solver.D2 * (gamma_hat .* D1v)) + end # no split form # dv[:] = -(D1_central * (hv .* v) - v .* (D1_central * hv)+ @@ -223,8 +226,11 @@ function rhs!(du_ode, u_ode, t, mesh, equations::SvaerdKalischEquations1D, # 0.5 * D1_central * (gamma_hat .* (solver.D2 * v)) - # 0.5 * solver.D2 * (gamma_hat .* D1v)) - calc_sources!(dq, q, t, source_terms, equations, solver) - dv[:] = hmD1betaD1 \ dv + @timeit timer() "source terms" calc_sources!(dq, q, t, source_terms, equations, solver) + @timeit timer() "dv elliptic" begin + hmD1betaD1 = Diagonal(h) - D1betaD1 + dv[:] = hmD1betaD1 \ dv + end return nothing end diff --git a/src/semidiscretization.jl b/src/semidiscretization.jl index eda6bdb5..62f19d8c 100644 --- a/src/semidiscretization.jl +++ b/src/semidiscretization.jl @@ -203,9 +203,8 @@ end function rhs!(du_ode, u_ode, semi::Semidiscretization, t) @unpack mesh, equations, initial_condition, boundary_conditions, solver, source_terms, cache = semi - rhs!(du_ode, u_ode, t, mesh, equations, initial_condition, boundary_conditions, - source_terms, - solver, cache) + @timeit timer() "rhs!" rhs!(du_ode, u_ode, t, mesh, equations, initial_condition, + boundary_conditions, source_terms, solver, cache) return nothing end diff --git a/src/util.jl b/src/util.jl index c15072af..46014d53 100644 --- a/src/util.jl +++ b/src/util.jl @@ -311,6 +311,12 @@ function extract_initial_N(example, kwargs) end end +# Store main timer for global timing of functions +const main_timer = TimerOutput() + +# Always call timer() to hide implementation details +timer() = main_timer + """ @autoinfiltrate @autoinfiltrate condition::Bool diff --git a/test/test_unit.jl b/test/test_unit.jl index 90fa26a7..782f9dfd 100644 --- a/test/test_unit.jl +++ b/test/test_unit.jl @@ -214,6 +214,13 @@ using SparseArrays: sparse, SparseMatrixCSC @test_nowarn display(relaxation_callback) end + @testset "SummaryCallback" begin + summary_callback = SummaryCallback() + @test_nowarn print(summary_callback) + @test_nowarn display(summary_callback) + @test_nowarn summary_callback() + end + @testset "util" begin @test_nowarn get_examples() @test_nowarn trixi_include(default_example(), tspan = (0.0, 0.1))