Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restart HyperbolicParabolic with SplitODEProblem #2156

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion examples/tree_1d_dgsem/elixir_advection_diffusion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,12 @@ analysis_callback = AnalysisCallback(semi, interval = 100)
# The AliveCallback prints short status information in regular intervals
alive_callback = AliveCallback(analysis_interval = 100)

# The SaveRestartCallback allows to save a file from which a Trixi.jl simulation can be restarted
save_restart = SaveRestartCallback(interval = 100,
save_final_restart = true)

# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver
callbacks = CallbackSet(summary_callback, analysis_callback, alive_callback)
callbacks = CallbackSet(summary_callback, analysis_callback, alive_callback, save_restart)

###############################################################################
# run the simulation
Expand Down
30 changes: 30 additions & 0 deletions examples/tree_1d_dgsem/elixir_advection_diffusion_restart.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

using OrdinaryDiffEq
using Trixi

###############################################################################
# create a restart file

elixir_file = "elixir_advection_diffusion.jl"
trixi_include(@__MODULE__, joinpath(@__DIR__, elixir_file))

###############################################################################
# initialize the ODE

restart_file = "restart_000000018.h5"
restart_filename = joinpath("out", restart_file)
tspan = (load_time(restart_filename), 2.0)

ode = semidiscretize(semi, tspan, restart_filename);
DanielDoehring marked this conversation as resolved.
Show resolved Hide resolved

# Do not save restart files here
callbacks = CallbackSet(summary_callback, analysis_callback, alive_callback)

###############################################################################
# run the simulation

sol = solve(ode, KenCarp4(autodiff = false), abstol = time_abs_tol, reltol = time_int_tol,
save_everystep = false, callback = callbacks)

# Print the timer summary
summary_callback()
21 changes: 13 additions & 8 deletions src/semidiscretization/semidiscretization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,18 @@ function calc_error_norms(u_ode, t, analyzer, semi::AbstractSemidiscretization,
end

"""
semidiscretize(semi::AbstractSemidiscretization, tspan)
semidiscretize(semi::AbstractSemidiscretization, tspan;
reset_threads=true)
DanielDoehring marked this conversation as resolved.
Show resolved Hide resolved

Wrap the semidiscretization `semi` as an ODE problem in the time interval `tspan`
that can be passed to `solve` from the [SciML ecosystem](https://diffeq.sciml.ai/latest/).

Optionally reset Polyester.jl threads. See
https://github.com/trixi-framework/Trixi.jl/issues/1583
https://github.com/JuliaSIMD/Polyester.jl/issues/30
"""
function semidiscretize(semi::AbstractSemidiscretization, tspan;
reset_threads = true)
# Optionally reset Polyester.jl threads. See
# https://github.com/trixi-framework/Trixi.jl/issues/1583
# https://github.com/JuliaSIMD/Polyester.jl/issues/30
if reset_threads
Polyester.reset_threads!()
end
Expand All @@ -102,18 +104,21 @@ function semidiscretize(semi::AbstractSemidiscretization, tspan;
end

"""
semidiscretize(semi::AbstractSemidiscretization, tspan, restart_file::AbstractString)
semidiscretize(semi::AbstractSemidiscretization, tspan,
restart_file::AbstractString;
reset_threads=true)

Wrap the semidiscretization `semi` as an ODE problem in the time interval `tspan`
that can be passed to `solve` from the [SciML ecosystem](https://diffeq.sciml.ai/latest/).
The initial condition etc. is taken from the `restart_file`.

Optionally reset Polyester.jl threads. See
https://github.com/trixi-framework/Trixi.jl/issues/1583
https://github.com/JuliaSIMD/Polyester.jl/issues/30
"""
function semidiscretize(semi::AbstractSemidiscretization, tspan,
restart_file::AbstractString;
reset_threads = true)
# Optionally reset Polyester.jl threads. See
# https://github.com/trixi-framework/Trixi.jl/issues/1583
# https://github.com/JuliaSIMD/Polyester.jl/issues/30
if reset_threads
Polyester.reset_threads!()
end
Expand Down
45 changes: 41 additions & 4 deletions src/semidiscretization/semidiscretization_hyperbolic_parabolic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -267,19 +267,21 @@ function compute_coefficients!(u_ode, t, semi::SemidiscretizationHyperbolicParab
end

"""
semidiscretize(semi::SemidiscretizationHyperbolicParabolic, tspan)
semidiscretize(semi::SemidiscretizationHyperbolicParabolic, tspan;
reset_threads=true)

Wrap the semidiscretization `semi` as a split ODE problem in the time interval `tspan`
that can be passed to `solve` from the [SciML ecosystem](https://diffeq.sciml.ai/latest/).
The parabolic right-hand side is the first function of the split ODE problem and
will be used by default by the implicit part of IMEX methods from the
SciML ecosystem.

Optionally reset Polyester.jl threads. See
https://github.com/trixi-framework/Trixi.jl/issues/1583
https://github.com/JuliaSIMD/Polyester.jl/issues/30
"""
function semidiscretize(semi::SemidiscretizationHyperbolicParabolic, tspan;
reset_threads = true)
# Optionally reset Polyester.jl threads. See
# https://github.com/trixi-framework/Trixi.jl/issues/1583
# https://github.com/JuliaSIMD/Polyester.jl/issues/30
if reset_threads
Polyester.reset_threads!()
end
Expand All @@ -295,6 +297,41 @@ function semidiscretize(semi::SemidiscretizationHyperbolicParabolic, tspan;
return SplitODEProblem{iip}(rhs_parabolic!, rhs!, u0_ode, tspan, semi)
end

"""
semidiscretize(semi::SemidiscretizationHyperbolicParabolic, tspan,
restart_file::AbstractString;
reset_threads=true)

Wrap the semidiscretization `semi` as a split ODE problem in the time interval `tspan`
that can be passed to `solve` from the [SciML ecosystem](https://diffeq.sciml.ai/latest/).
The parabolic right-hand side is the first function of the split ODE problem and
will be used by default by the implicit part of IMEX methods from the
SciML ecosystem.

The initial condition etc. is taken from the `restart_file`.

Optionally reset Polyester.jl threads. See
https://github.com/trixi-framework/Trixi.jl/issues/1583
https://github.com/JuliaSIMD/Polyester.jl/issues/30
"""
function semidiscretize(semi::SemidiscretizationHyperbolicParabolic, tspan,
restart_file::AbstractString;
reset_threads = true)
if reset_threads
Polyester.reset_threads!()
end

u0_ode = load_restart_file(semi, restart_file)
# TODO: MPI, do we want to synchronize loading and print debug statements, e.g. using
# mpi_isparallel() && MPI.Barrier(mpi_comm())
# See https://github.com/trixi-framework/Trixi.jl/issues/328
iip = true # is-inplace, i.e., we modify a vector when calling rhs_parabolic!, rhs!
# Note that the IMEX time integration methods of OrdinaryDiffEq.jl treat the
# first function implicitly and the second one explicitly. Thus, we pass the
# stiffer parabolic function first.
return SplitODEProblem{iip}(rhs_parabolic!, rhs!, u0_ode, tspan, semi)
end

function rhs!(du_ode, u_ode, semi::SemidiscretizationHyperbolicParabolic, t)
@unpack mesh, equations, boundary_conditions, source_terms, solver, cache = semi

Expand Down
15 changes: 15 additions & 0 deletions test/test_parabolic_1d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@ isdir(outdir) && rm(outdir, recursive = true)
end
end

@trixi_testset "TreeMesh1D: elixir_advection_diffusion_restart.jl" begin
@test_trixi_include(joinpath(examples_dir(), "tree_1d_dgsem",
"elixir_advection_diffusion_restart.jl"),
l2=[1.0671615777620987e-5],
linf=[3.861509422325993e-5])
# Ensure that we do not have excessive memory allocations
# (e.g., from type instabilities)
let
t = sol.t[end]
u_ode = sol.u[end]
du_ode = similar(u_ode)
@test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000
end
end

@trixi_testset "TreeMesh1D: elixir_advection_diffusion.jl (AMR)" begin
@test_trixi_include(joinpath(examples_dir(), "tree_1d_dgsem",
"elixir_advection_diffusion.jl"),
Expand Down
Loading