Skip to content

Commit

Permalink
Feature: Checkpointing for T8codeMesh (#1980)
Browse files Browse the repository at this point in the history
* Switching to t8_cmesh_new_brick_{2,3}d.

* Backup.

* Add save callback to elixir.

* Backup.

* Refined code. Make it work in parallel.

* Added support for parallelt8codemesh save solution callback.

* Applied formatter.

* Updated examples and tests.

* Applied formatter.

* Minor adjustments.

* Code refinement. Enabled partitioning after mesh loading.

* Applied formatter and fixed typos.

* Removed commented out section.

* Added missing union type member.

* Switching from UInt64 to UInt128 in global interface/mortar id computation.

* Switching from UInt64 to UInt128 in global interface/mortar id computation (II).

* Adding more tests.

* Applied formatter.

* Removed Printf.

* Incorporated review comments and code polish.

* Applied formatter.

* Fixed typos.

* Update examples/t8code_2d_dgsem/elixir_advection_restart.jl

Co-authored-by: Joshua Lampert <[email protected]>

* Update examples/t8code_2d_dgsem/elixir_advection_restart_amr.jl

Co-authored-by: Joshua Lampert <[email protected]>

* Update examples/t8code_3d_dgsem/elixir_advection_restart.jl

Co-authored-by: Joshua Lampert <[email protected]>

* Update src/meshes/mesh_io.jl

Co-authored-by: Joshua Lampert <[email protected]>

* Update examples/t8code_3d_dgsem/elixir_advection_restart.jl

Co-authored-by: Joshua Lampert <[email protected]>

* Update src/meshes/t8code_mesh.jl

Co-authored-by: Joshua Lampert <[email protected]>

* Update src/meshes/t8code_mesh.jl

Co-authored-by: Joshua Lampert <[email protected]>

* Removing last test in t8code 2D MPI to investigate problems in Github CI.

* Refactored a bit.

* Applied formatter.

* Removed commented code.

* Added LOG_LEVEL variable.

* Added t8code interface simplfication and stitched memory leak.

* Applied formatter.

* Simplifying finailze behavior for T8codeMesh.

* Addeing finalize call to T8codeMesh examples.

* Applied formatter.

* typo

* Aktualisieren von Project.toml

* Set MPI.jl compat version to 0.20.6

add_finalize_hook!() required

* bump MPI.jl compat version

* Update T8code.

* replace  t8_geom_get_dimension by t8_cmesh_get_dimension

* temporarily set negative volume test to broken

* no broken for test_throws

* need a boolean return value

* no dim in t8_geometry_linear_new anymore

* Fixed typo.

* Ironing out minor issues.

---------

Co-authored-by: Johannes Markert <[email protected]>
Co-authored-by: Joshua Lampert <[email protected]>
Co-authored-by: Hendrik Ranocha <[email protected]>
Co-authored-by: Benedict Geihe <[email protected]>
Co-authored-by: Benedict <[email protected]>
  • Loading branch information
6 people authored Nov 5, 2024
1 parent 16c6f17 commit 91eaaf6
Show file tree
Hide file tree
Showing 41 changed files with 1,034 additions and 154 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ IfElse = "0.1"
LinearAlgebra = "1"
LinearMaps = "2.7, 3.0"
LoopVectorization = "0.12.151"
MPI = "0.20"
MPI = "0.20.6"
Makie = "0.19, 0.20"
MuladdMacro = "0.2.2"
NLsolve = "4.5.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ analysis_callback = AnalysisCallback(semi, interval = analysis_interval,

alive_callback = AliveCallback(analysis_interval = analysis_interval)

save_solution = SaveSolutionCallback(interval = 100,
save_initial_solution = true,
save_final_solution = true,
solution_variables = cons2prim)

amr_controller = ControllerThreeLevel(semi,
TrixiExtension.IndicatorSolutionIndependent(semi),
base_level = 4,
Expand All @@ -124,12 +129,20 @@ amr_controller = ControllerThreeLevel(semi,
amr_callback = AMRCallback(semi, amr_controller,
interval = 5,
adapt_initial_condition = true,
adapt_initial_condition_only_refine = true)
adapt_initial_condition_only_refine = true,
dynamic_load_balancing = false)
# We disable `dynamic_load_balancing` for now, since t8code does not support
# partitioning for coarsening yet. That is, a complete family of elements always
# stays on rank and is not split up due to partitioning. Without this feature
# dynamic AMR simulations are not perfectly deterministic regarding to
# convergent tests. Once this feature is available in t8code load balancing is
# enabled again.

stepsize_callback = StepsizeCallback(cfl = 1.6)

callbacks = CallbackSet(summary_callback,
analysis_callback, alive_callback,
save_solution,
amr_callback, stepsize_callback);

###############################################################################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ analysis_callback = AnalysisCallback(semi, interval = analysis_interval,

alive_callback = AliveCallback(analysis_interval = analysis_interval)

save_restart = SaveRestartCallback(interval = 100,
save_final_restart = true)

save_solution = SaveSolutionCallback(interval = 100,
save_initial_solution = true,
save_final_solution = true,
solution_variables = cons2prim)

amr_controller = ControllerThreeLevel(semi, IndicatorMax(semi, variable = first),
base_level = 1,
med_level = 2, med_threshold = 0.1,
Expand All @@ -62,12 +70,19 @@ amr_callback = AMRCallback(semi, amr_controller,
interval = 5,
adapt_initial_condition = true,
adapt_initial_condition_only_refine = true,
dynamic_load_balancing = true)
dynamic_load_balancing = false)
# We disable `dynamic_load_balancing` for now, since t8code does not support
# partitioning for coarsening yet. That is, a complete family of elements always
# stays on rank and is not split up due to partitioning. Without this feature
# dynamic AMR simulations are not perfectly deterministic regarding to
# convergent tests. Once this feature is available in t8code load balancing is
# enabled again.

stepsize_callback = StepsizeCallback(cfl = 0.7)

callbacks = CallbackSet(summary_callback,
analysis_callback, alive_callback,
save_restart, save_solution,
amr_callback, stepsize_callback)

###############################################################################
Expand Down
89 changes: 89 additions & 0 deletions examples/t8code_2d_dgsem/elixir_advection_extended.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@

using OrdinaryDiffEq
using Trixi

###############################################################################
# semidiscretization of the linear advection equation

advection_velocity = (0.2, -0.7)
equations = LinearScalarAdvectionEquation2D(advection_velocity)

initial_condition = initial_condition_convergence_test

# BCs must be passed as Dict
boundary_condition = BoundaryConditionDirichlet(initial_condition)
boundary_conditions = Dict(:x_neg => boundary_condition,
:x_pos => boundary_condition,
:y_neg => boundary_condition,
:y_pos => boundary_condition)

# Create DG solver with polynomial degree = 3 and (local) Lax-Friedrichs/Rusanov flux as surface flux
solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs)

# The initial condition is 2-periodic
coordinates_min = (-1.5, 1.3) # minimum coordinates (min(x), min(y))
coordinates_max = (0.5, 5.3) # maximum coordinates (max(x), max(y))

trees_per_dimension = (19, 37)

# Create curved mesh with 19 x 37 elements
mesh = T8codeMesh(trees_per_dimension, polydeg = 3,
coordinates_min = coordinates_min, coordinates_max = coordinates_max,
periodicity = false)

# A semidiscretization collects data structures and functions for the spatial discretization
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,
boundary_conditions = boundary_conditions)

###############################################################################
# ODE solvers, callbacks etc.

# Create ODE problem with time span from 0.0 to 1.0
tspan = (0.0, 1.0)
ode = semidiscretize(semi, tspan);

# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup
# and resets the timers
summary_callback = SummaryCallback()

# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results
analysis_interval = 100
analysis_callback = AnalysisCallback(semi, interval = analysis_interval,
extra_analysis_integrals = (entropy, energy_total))

# The AliveCallback prints short status information in regular intervals
alive_callback = AliveCallback(analysis_interval = analysis_interval)

# 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)

# The SaveSolutionCallback allows to save the solution to a file in regular intervals
save_solution = SaveSolutionCallback(interval = 100,
save_initial_solution = true,
save_final_solution = true,
solution_variables = cons2prim)

# The StepsizeCallback handles the re-calculation of the maximum Δt after each time step
stepsize_callback = StepsizeCallback(cfl = 1.6)

# 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,
save_restart, save_solution,
stepsize_callback)

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

# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks
sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false),
dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
save_everystep = false, callback = callbacks);

# Print the timer summary
summary_callback()

# Finalize `T8codeMesh` to make sure MPI related objects in t8code are
# released before `MPI` finalizes.
!isinteractive() && finalize(mesh)
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,16 @@ summary_callback = SummaryCallback()
# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results
analysis_callback = AnalysisCallback(semi, interval = 100)

# The SaveSolutionCallback allows to save the solution to a file in regular intervals
save_solution = SaveSolutionCallback(interval = 100,
solution_variables = cons2prim)

# The StepsizeCallback handles the re-calculation of the maximum Δt after each time step
stepsize_callback = StepsizeCallback(cfl = 1.6)

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

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

using OrdinaryDiffEq
using Trixi

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

elixir_file = "elixir_advection_extended.jl"
restart_file = "restart_000000021.h5"

trixi_include(@__MODULE__, joinpath(@__DIR__, elixir_file))

###############################################################################
# adapt the parameters that have changed compared to "elixir_advection_extended.jl"

# Note: If you get a restart file from somewhere else, you need to provide
# appropriate setups in the elixir loading a restart file

restart_filename = joinpath("out", restart_file)
mesh = load_mesh(restart_filename)

semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,
boundary_conditions = boundary_conditions)

tspan = (load_time(restart_filename), 2.0)
dt = load_dt(restart_filename)
ode = semidiscretize(semi, tspan, restart_filename);

# Do not overwrite the initial snapshot written by elixir_advection_extended.jl.
save_solution.condition.save_initial_solution = false

integrator = init(ode, CarpenterKennedy2N54(williamson_condition = false),
dt = dt, # solve needs some value here but it will be overwritten by the stepsize_callback
save_everystep = false, callback = callbacks, maxiters = 100_000);

# Get the last time index and work with that.
load_timestep!(integrator, restart_filename)

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

sol = solve!(integrator)
summary_callback() # print the timer summary

# Finalize `T8codeMesh` to make sure MPI related objects in t8code are
# released before `MPI` finalizes.
!isinteractive() && finalize(mesh)
66 changes: 66 additions & 0 deletions examples/t8code_2d_dgsem/elixir_advection_restart_amr.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

using OrdinaryDiffEq
using Trixi

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

elixir_file = "elixir_advection_extended.jl"
restart_file = "restart_000000021.h5"

trixi_include(@__MODULE__, joinpath(@__DIR__, elixir_file))

###############################################################################
# adapt the parameters that have changed compared to "elixir_advection_extended.jl"

# Note: If you get a restart file from somewhere else, you need to provide
# appropriate setups in the elixir loading a restart file

restart_filename = joinpath("out", restart_file)
mesh = load_mesh(restart_filename)

semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,
boundary_conditions = boundary_conditions)

tspan = (load_time(restart_filename), 2.0)
dt = load_dt(restart_filename)
ode = semidiscretize(semi, tspan, restart_filename);

# Do not overwrite the initial snapshot written by elixir_advection_extended.jl.
save_solution.condition.save_initial_solution = false

# Add AMR callback
amr_controller = ControllerThreeLevel(semi, IndicatorMax(semi, variable = first),
base_level = 0,
med_level = 0, med_threshold = 0.8,
max_level = 1, max_threshold = 1.2)
amr_callback = AMRCallback(semi, amr_controller,
interval = 5,
adapt_initial_condition = true,
adapt_initial_condition_only_refine = true,
dynamic_load_balancing = false)
# We disable `dynamic_load_balancing` for now, since t8code does not support
# partitioning for coarsening yet. That is, a complete family of elements always
# stays on rank and is not split up due to partitioning. Without this feature
# dynamic AMR simulations are not perfectly deterministic regarding to
# convergent tests. Once this feature is available in t8code load balancing is
# enabled again.

callbacks_ext = CallbackSet(amr_callback, callbacks.discrete_callbacks...)

integrator = init(ode, CarpenterKennedy2N54(williamson_condition = false),
dt = dt, # solve needs some value here but it will be overwritten by the stepsize_callback
save_everystep = false, callback = callbacks_ext, maxiters = 100_000);

# Get the last time index and work with that.
load_timestep!(integrator, restart_filename)

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

sol = solve!(integrator)
summary_callback() # print the timer summary

# Finalize `T8codeMesh` to make sure MPI related objects in t8code are
# released before `MPI` finalizes.
!isinteractive() && finalize(mesh)
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,18 @@ summary_callback = SummaryCallback()
# prints the results.
analysis_callback = AnalysisCallback(semi, interval = 100)

# The SaveSolutionCallback allows to save the solution to a file in regular intervals
save_solution = SaveSolutionCallback(interval = 100,
solution_variables = cons2prim)

# The StepsizeCallback handles the re-calculation of the maximum Δt after each
# time step.
stepsize_callback = StepsizeCallback(cfl = 1.4)

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

###############################################################################
# Run the simulation.
Expand Down
6 changes: 6 additions & 0 deletions examples/t8code_2d_dgsem/elixir_euler_free_stream.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,16 @@ analysis_callback = AnalysisCallback(semi, interval = analysis_interval)

alive_callback = AliveCallback(analysis_interval = analysis_interval)

save_solution = SaveSolutionCallback(interval = 100,
save_initial_solution = true,
save_final_solution = true,
solution_variables = cons2prim)

stepsize_callback = StepsizeCallback(cfl = 2.0)

callbacks = CallbackSet(summary_callback,
analysis_callback, alive_callback,
save_solution,
stepsize_callback)

###############################################################################
Expand Down
5 changes: 5 additions & 0 deletions examples/t8code_2d_dgsem/elixir_euler_sedov.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,16 @@ analysis_callback = AnalysisCallback(semi, interval = analysis_interval)

alive_callback = AliveCallback(analysis_interval = analysis_interval)

save_solution = SaveSolutionCallback(interval = 300,
save_initial_solution = true,
save_final_solution = true)

stepsize_callback = StepsizeCallback(cfl = 0.5)

callbacks = CallbackSet(summary_callback,
analysis_callback,
alive_callback,
save_solution,
stepsize_callback)

###############################################################################
Expand Down
6 changes: 6 additions & 0 deletions examples/t8code_2d_dgsem/elixir_euler_shockcapturing_ec.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,17 @@ analysis_callback = AnalysisCallback(semi, interval = analysis_interval)

alive_callback = AliveCallback(analysis_interval = analysis_interval)

save_solution = SaveSolutionCallback(interval = 100,
save_initial_solution = true,
save_final_solution = true,
solution_variables = cons2prim)

stepsize_callback = StepsizeCallback(cfl = 1.0)

callbacks = CallbackSet(summary_callback,
analysis_callback,
alive_callback,
save_solution,
stepsize_callback)

###############################################################################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,19 @@ analysis_callback = AnalysisCallback(semi, interval = analysis_interval)

alive_callback = AliveCallback(analysis_interval = analysis_interval)

save_restart = SaveRestartCallback(interval = 100,
save_final_restart = true)

save_solution = SaveSolutionCallback(interval = 100,
save_initial_solution = true,
save_final_solution = true,
solution_variables = cons2prim)

stepsize_callback = StepsizeCallback(cfl = 0.8)

callbacks = CallbackSet(summary_callback,
analysis_callback, alive_callback,
save_restart, save_solution,
stepsize_callback)
###############################################################################
# run the simulation
Expand Down
Loading

0 comments on commit 91eaaf6

Please sign in to comment.