From df2245e628ff4d060dd1d20db9fe452e25dcce02 Mon Sep 17 00:00:00 2001 From: Warisa Date: Tue, 11 Jun 2024 12:08:24 +0200 Subject: [PATCH 1/8] refactor 2N and 3* --- src/time_integration/methods_2N.jl | 36 +++++++++++++++++++------- src/time_integration/methods_3Sstar.jl | 36 +++++++++++++++++++------- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/time_integration/methods_2N.jl b/src/time_integration/methods_2N.jl index f3b09b01e9..b8a71bfeb7 100644 --- a/src/time_integration/methods_2N.jl +++ b/src/time_integration/methods_2N.jl @@ -104,9 +104,8 @@ function Base.getproperty(integrator::SimpleIntegrator2N, field::Symbol) return getfield(integrator, field) end -# Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1 -function solve(ode::ODEProblem, alg::T; - dt, callback = nothing, kwargs...) where {T <: SimpleAlgorithm2N} +function init(ode::ODEProblem, alg::T; + dt, callback = nothing, kwargs...) where {T <: SimpleAlgorithm2N} u = copy(ode.u0) du = similar(u) u_tmp = similar(u) @@ -129,10 +128,33 @@ function solve(ode::ODEProblem, alg::T; error("unsupported") end - solve!(integrator) + return integrator +end + +# Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1 +function solve(ode::ODEProblem, alg::T; + dt, callback = nothing, kwargs...) where {T <: SimpleAlgorithm2N} + integrator = init(ode, alg, dt = dt, callback = callback; kwargs...) + + # Start actual solve + solve_steps!(integrator) +end + +function solve_steps!(integrator::SimpleIntegrator2N) + @unpack prob = integrator.sol + + integrator.finalstep = false + + @trixi_timeit timer() "main loop" while !integrator.finalstep + step!(integrator) + end # "main loop" timer + + return TimeIntegratorSolution((first(prob.tspan), integrator.t), + (prob.u0, integrator.u), + integrator.sol.prob) end -function solve!(integrator::SimpleIntegrator2N) +function step!(integrator::SimpleIntegrator2N) @unpack prob = integrator.sol @unpack alg = integrator t_end = last(prob.tspan) @@ -186,10 +208,6 @@ function solve!(integrator::SimpleIntegrator2N) terminate!(integrator) end end - - return TimeIntegratorSolution((first(prob.tspan), integrator.t), - (prob.u0, integrator.u), - integrator.sol.prob) end # get a cache where the RHS can be stored diff --git a/src/time_integration/methods_3Sstar.jl b/src/time_integration/methods_3Sstar.jl index 7b70466606..53aebc212a 100644 --- a/src/time_integration/methods_3Sstar.jl +++ b/src/time_integration/methods_3Sstar.jl @@ -171,9 +171,8 @@ function Base.getproperty(integrator::SimpleIntegrator3Sstar, field::Symbol) return getfield(integrator, field) end -# Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1 -function solve(ode::ODEProblem, alg::T; - dt, callback = nothing, kwargs...) where {T <: SimpleAlgorithm3Sstar} +function init(ode::ODEProblem, alg::T; + dt, callback = nothing, kwargs...) where {T <: SimpleAlgorithm3Sstar} u = copy(ode.u0) du = similar(u) u_tmp1 = similar(u) @@ -199,10 +198,33 @@ function solve(ode::ODEProblem, alg::T; error("unsupported") end - solve!(integrator) + return integrator +end + +# Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1 +function solve(ode::ODEProblem, alg::T; + dt, callback = nothing, kwargs...) where {T <: SimpleAlgorithm3Sstar} + integrator = init(ode, alg, dt = dt, callback = callback; kwargs...) + + # Start actual solve + solve_steps!(integrator) +end + +function solve_steps!(integrator::SimpleIntegrator3Sstar) + @unpack prob = integrator.sol + + integrator.finalstep = false + + @trixi_timeit timer() "main loop" while !integrator.finalstep + step!(integrator) + end # "main loop" timer + + return TimeIntegratorSolution((first(prob.tspan), integrator.t), + (prob.u0, integrator.u), + integrator.sol.prob) end -function solve!(integrator::SimpleIntegrator3Sstar) +function step!(integrator::SimpleIntegrator3Sstar) @unpack prob = integrator.sol @unpack alg = integrator t_end = last(prob.tspan) @@ -262,10 +284,6 @@ function solve!(integrator::SimpleIntegrator3Sstar) terminate!(integrator) end end - - return TimeIntegratorSolution((first(prob.tspan), integrator.t), - (prob.u0, integrator.u), - integrator.sol.prob) end # get a cache where the RHS can be stored From fc0c064e6af71d521f56a6af00e8778e49761d61 Mon Sep 17 00:00:00 2001 From: Daniel Doehring Date: Fri, 14 Jun 2024 11:10:36 +0200 Subject: [PATCH 2/8] Apply suggestions from code review Co-authored-by: Hendrik Ranocha --- src/time_integration/methods_2N.jl | 4 ++-- src/time_integration/methods_3Sstar.jl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/time_integration/methods_2N.jl b/src/time_integration/methods_2N.jl index b8a71bfeb7..155fe11226 100644 --- a/src/time_integration/methods_2N.jl +++ b/src/time_integration/methods_2N.jl @@ -137,10 +137,10 @@ function solve(ode::ODEProblem, alg::T; integrator = init(ode, alg, dt = dt, callback = callback; kwargs...) # Start actual solve - solve_steps!(integrator) + solve!(integrator) end -function solve_steps!(integrator::SimpleIntegrator2N) +function solve!(integrator::SimpleIntegrator2N) @unpack prob = integrator.sol integrator.finalstep = false diff --git a/src/time_integration/methods_3Sstar.jl b/src/time_integration/methods_3Sstar.jl index 53aebc212a..91529e2e68 100644 --- a/src/time_integration/methods_3Sstar.jl +++ b/src/time_integration/methods_3Sstar.jl @@ -207,10 +207,10 @@ function solve(ode::ODEProblem, alg::T; integrator = init(ode, alg, dt = dt, callback = callback; kwargs...) # Start actual solve - solve_steps!(integrator) + solve!(integrator) end -function solve_steps!(integrator::SimpleIntegrator3Sstar) +function solve!(integrator::SimpleIntegrator3Sstar) @unpack prob = integrator.sol integrator.finalstep = false From 55260223bdf0a9f1de60ff1cd02ec90f37d0f3ae Mon Sep 17 00:00:00 2001 From: Warisa Date: Mon, 17 Jun 2024 14:21:15 +0200 Subject: [PATCH 3/8] fix the logic of step! --- src/time_integration/methods_2N.jl | 78 +++++++++++----------- src/time_integration/methods_3Sstar.jl | 90 +++++++++++++------------- 2 files changed, 82 insertions(+), 86 deletions(-) diff --git a/src/time_integration/methods_2N.jl b/src/time_integration/methods_2N.jl index 155fe11226..281fa0338d 100644 --- a/src/time_integration/methods_2N.jl +++ b/src/time_integration/methods_2N.jl @@ -160,53 +160,51 @@ function step!(integrator::SimpleIntegrator2N) t_end = last(prob.tspan) callbacks = integrator.opts.callback - integrator.finalstep = false - @trixi_timeit timer() "main loop" while !integrator.finalstep - if isnan(integrator.dt) - error("time step size `dt` is NaN") - end + @assert !integrator.finalstep + if isnan(integrator.dt) + error("time step size `dt` is NaN") + end - # if the next iteration would push the simulation beyond the end time, set dt accordingly - if integrator.t + integrator.dt > t_end || - isapprox(integrator.t + integrator.dt, t_end) - integrator.dt = t_end - integrator.t - terminate!(integrator) - end + # if the next iteration would push the simulation beyond the end time, set dt accordingly + if integrator.t + integrator.dt > t_end || + isapprox(integrator.t + integrator.dt, t_end) + integrator.dt = t_end - integrator.t + terminate!(integrator) + end - # one time step - integrator.u_tmp .= 0 - for stage in eachindex(alg.c) - t_stage = integrator.t + integrator.dt * alg.c[stage] - integrator.f(integrator.du, integrator.u, prob.p, t_stage) - - a_stage = alg.a[stage] - b_stage_dt = alg.b[stage] * integrator.dt - @trixi_timeit timer() "Runge-Kutta step" begin - @threaded for i in eachindex(integrator.u) - integrator.u_tmp[i] = integrator.du[i] - - integrator.u_tmp[i] * a_stage - integrator.u[i] += integrator.u_tmp[i] * b_stage_dt - end + # one time step + integrator.u_tmp .= 0 + for stage in eachindex(alg.c) + t_stage = integrator.t + integrator.dt * alg.c[stage] + integrator.f(integrator.du, integrator.u, prob.p, t_stage) + + a_stage = alg.a[stage] + b_stage_dt = alg.b[stage] * integrator.dt + @trixi_timeit timer() "Runge-Kutta step" begin + @threaded for i in eachindex(integrator.u) + integrator.u_tmp[i] = integrator.du[i] - + integrator.u_tmp[i] * a_stage + integrator.u[i] += integrator.u_tmp[i] * b_stage_dt end end - integrator.iter += 1 - integrator.t += integrator.dt - - # handle callbacks - if callbacks isa CallbackSet - foreach(callbacks.discrete_callbacks) do cb - if cb.condition(integrator.u, integrator.t, integrator) - cb.affect!(integrator) - end - return nothing + end + integrator.iter += 1 + integrator.t += integrator.dt + + # handle callbacks + if callbacks isa CallbackSet + foreach(callbacks.discrete_callbacks) do cb + if cb.condition(integrator.u, integrator.t, integrator) + cb.affect!(integrator) end + return nothing end + end - # respect maximum number of iterations - if integrator.iter >= integrator.opts.maxiters && !integrator.finalstep - @warn "Interrupted. Larger maxiters is needed." - terminate!(integrator) - end + # respect maximum number of iterations + if integrator.iter >= integrator.opts.maxiters && !integrator.finalstep + @warn "Interrupted. Larger maxiters is needed." + terminate!(integrator) end end diff --git a/src/time_integration/methods_3Sstar.jl b/src/time_integration/methods_3Sstar.jl index 91529e2e68..a62787228c 100644 --- a/src/time_integration/methods_3Sstar.jl +++ b/src/time_integration/methods_3Sstar.jl @@ -230,59 +230,57 @@ function step!(integrator::SimpleIntegrator3Sstar) t_end = last(prob.tspan) callbacks = integrator.opts.callback - integrator.finalstep = false - @trixi_timeit timer() "main loop" while !integrator.finalstep - if isnan(integrator.dt) - error("time step size `dt` is NaN") - end + @assert !integrator.finalstep + if isnan(integrator.dt) + error("time step size `dt` is NaN") + end - # if the next iteration would push the simulation beyond the end time, set dt accordingly - if integrator.t + integrator.dt > t_end || - isapprox(integrator.t + integrator.dt, t_end) - integrator.dt = t_end - integrator.t - terminate!(integrator) - end + # if the next iteration would push the simulation beyond the end time, set dt accordingly + if integrator.t + integrator.dt > t_end || + isapprox(integrator.t + integrator.dt, t_end) + integrator.dt = t_end - integrator.t + terminate!(integrator) + end - # one time step - integrator.u_tmp1 .= zero(eltype(integrator.u_tmp1)) - integrator.u_tmp2 .= integrator.u - for stage in eachindex(alg.c) - t_stage = integrator.t + integrator.dt * alg.c[stage] - prob.f(integrator.du, integrator.u, prob.p, t_stage) - - delta_stage = alg.delta[stage] - gamma1_stage = alg.gamma1[stage] - gamma2_stage = alg.gamma2[stage] - gamma3_stage = alg.gamma3[stage] - beta_stage_dt = alg.beta[stage] * integrator.dt - @trixi_timeit timer() "Runge-Kutta step" begin - @threaded for i in eachindex(integrator.u) - integrator.u_tmp1[i] += delta_stage * integrator.u[i] - integrator.u[i] = (gamma1_stage * integrator.u[i] + - gamma2_stage * integrator.u_tmp1[i] + - gamma3_stage * integrator.u_tmp2[i] + - beta_stage_dt * integrator.du[i]) - end + # one time step + integrator.u_tmp1 .= zero(eltype(integrator.u_tmp1)) + integrator.u_tmp2 .= integrator.u + for stage in eachindex(alg.c) + t_stage = integrator.t + integrator.dt * alg.c[stage] + prob.f(integrator.du, integrator.u, prob.p, t_stage) + + delta_stage = alg.delta[stage] + gamma1_stage = alg.gamma1[stage] + gamma2_stage = alg.gamma2[stage] + gamma3_stage = alg.gamma3[stage] + beta_stage_dt = alg.beta[stage] * integrator.dt + @trixi_timeit timer() "Runge-Kutta step" begin + @threaded for i in eachindex(integrator.u) + integrator.u_tmp1[i] += delta_stage * integrator.u[i] + integrator.u[i] = (gamma1_stage * integrator.u[i] + + gamma2_stage * integrator.u_tmp1[i] + + gamma3_stage * integrator.u_tmp2[i] + + beta_stage_dt * integrator.du[i]) end end - integrator.iter += 1 - integrator.t += integrator.dt - - # handle callbacks - if callbacks isa CallbackSet - foreach(callbacks.discrete_callbacks) do cb - if cb.condition(integrator.u, integrator.t, integrator) - cb.affect!(integrator) - end - return nothing + end + integrator.iter += 1 + integrator.t += integrator.dt + + # handle callbacks + if callbacks isa CallbackSet + foreach(callbacks.discrete_callbacks) do cb + if cb.condition(integrator.u, integrator.t, integrator) + cb.affect!(integrator) end + return nothing end + end - # respect maximum number of iterations - if integrator.iter >= integrator.opts.maxiters && !integrator.finalstep - @warn "Interrupted. Larger maxiters is needed." - terminate!(integrator) - end + # respect maximum number of iterations + if integrator.iter >= integrator.opts.maxiters && !integrator.finalstep + @warn "Interrupted. Larger maxiters is needed." + terminate!(integrator) end end From b39a7538ee7a50cae30d4dde06b0798b215e2136 Mon Sep 17 00:00:00 2001 From: Warisa Roongaraya <81345089+warisa-r@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:49:09 +0200 Subject: [PATCH 4/8] Apply suggestions from code review Co-authored-by: Hendrik Ranocha --- src/time_integration/methods_2N.jl | 8 ++++---- src/time_integration/methods_3Sstar.jl | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/time_integration/methods_2N.jl b/src/time_integration/methods_2N.jl index 281fa0338d..afcfe8c320 100644 --- a/src/time_integration/methods_2N.jl +++ b/src/time_integration/methods_2N.jl @@ -104,8 +104,8 @@ function Base.getproperty(integrator::SimpleIntegrator2N, field::Symbol) return getfield(integrator, field) end -function init(ode::ODEProblem, alg::T; - dt, callback = nothing, kwargs...) where {T <: SimpleAlgorithm2N} +function init(ode::ODEProblem, alg::SimpleAlgorithm2N; + dt, callback = nothing, kwargs...) u = copy(ode.u0) du = similar(u) u_tmp = similar(u) @@ -132,8 +132,8 @@ function init(ode::ODEProblem, alg::T; end # Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1 -function solve(ode::ODEProblem, alg::T; - dt, callback = nothing, kwargs...) where {T <: SimpleAlgorithm2N} +function solve(ode::ODEProblem, alg:: SimpleAlgorithm2N; + dt, callback = nothing, kwargs...) integrator = init(ode, alg, dt = dt, callback = callback; kwargs...) # Start actual solve diff --git a/src/time_integration/methods_3Sstar.jl b/src/time_integration/methods_3Sstar.jl index a62787228c..9a6ad09f7f 100644 --- a/src/time_integration/methods_3Sstar.jl +++ b/src/time_integration/methods_3Sstar.jl @@ -171,8 +171,8 @@ function Base.getproperty(integrator::SimpleIntegrator3Sstar, field::Symbol) return getfield(integrator, field) end -function init(ode::ODEProblem, alg::T; - dt, callback = nothing, kwargs...) where {T <: SimpleAlgorithm3Sstar} +function init(ode::ODEProblem, alg:: SimpleAlgorithm3Sstar; + dt, callback = nothing, kwargs...) u = copy(ode.u0) du = similar(u) u_tmp1 = similar(u) @@ -202,8 +202,8 @@ function init(ode::ODEProblem, alg::T; end # Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1 -function solve(ode::ODEProblem, alg::T; - dt, callback = nothing, kwargs...) where {T <: SimpleAlgorithm3Sstar} +function solve(ode::ODEProblem, alg:: SimpleAlgorithm3Sstar; + dt, callback = nothing, kwargs...) integrator = init(ode, alg, dt = dt, callback = callback; kwargs...) # Start actual solve From edb92b0c6f380b5f18fb5800f9a69d5750df21de Mon Sep 17 00:00:00 2001 From: Warisa Date: Tue, 18 Jun 2024 13:23:55 +0200 Subject: [PATCH 5/8] fmt --- docs/literate/make.jl | 42 ++- docs/literate/src/files/DGMulti_1.jl | 70 ++-- docs/literate/src/files/DGMulti_2.jl | 15 +- docs/literate/src/files/DGSEM_FluxDiff.jl | 49 ++- .../src/files/adaptive_mesh_refinement.jl | 38 +- .../src/files/adding_new_parabolic_terms.jl | 85 +++-- .../src/files/adding_new_scalar_equations.jl | 71 ++-- .../files/adding_nonconservative_equation.jl | 81 ++--- .../behind_the_scenes_simulation_setup.jl | 7 - ...scretizationHyperbolic_structure_figure.jl | 106 ++++-- .../src/generate_boundary_figure.jl | 296 +++++++++------ .../src/generate_elements_figure.jl | 179 +++++---- .../src/generate_interfaces_figure.jl | 229 +++++++----- .../src/generate_mortars_figure.jl | 257 ++++++++----- .../src/generate_nodes_figure.jl | 8 +- .../src/generate_treemesh_figure.jl | 53 ++- .../src/rhs_structure_figure.jl | 61 ++-- .../src/semidiscretize_structure_figure.jl | 79 ++-- .../src/files/custom_semidiscretization.jl | 15 +- .../src/files/differentiable_programming.jl | 143 ++++---- .../files/first_steps/create_first_setup.jl | 16 +- .../src/files/first_steps/getting_started.jl | 26 +- docs/literate/src/files/hohqmesh_tutorial.jl | 340 +++++++++--------- .../src/files/non_periodic_boundaries.jl | 41 ++- docs/literate/src/files/p4est_from_gmsh.jl | 7 +- docs/literate/src/files/parabolic_terms.jl | 43 ++- .../src/files/scalar_linear_advection_1d.jl | 105 +++--- docs/literate/src/files/shock_capturing.jl | 82 ++--- .../src/files/structured_mesh_mapping.jl | 80 ++--- .../src/files/subcell_shock_capturing.jl | 2 - docs/literate/src/files/time_stepping.jl | 4 +- docs/literate/src/files/upwind_fdsbp.jl | 11 +- docs/make.jl | 148 ++++---- src/time_integration/methods_2N.jl | 2 +- src/time_integration/methods_3Sstar.jl | 4 +- 35 files changed, 1537 insertions(+), 1258 deletions(-) diff --git a/docs/literate/make.jl b/docs/literate/make.jl index 262a236971..deda425ff3 100644 --- a/docs/literate/make.jl +++ b/docs/literate/make.jl @@ -3,22 +3,22 @@ using Test: @testset import Pkg # Create markdown and notebook files for `file` -function create_files(title, file, repo_src, pages_dir, notebooks_dir; folder="") +function create_files(title, file, repo_src, pages_dir, notebooks_dir; folder = "") notebook_filename = first(splitext(file)) * ".ipynb" if !isempty(folder) notebook_filename = joinpath(folder, notebook_filename) end - binder_logo = "https://mybinder.org/badge_logo.svg" + binder_logo = "https://mybinder.org/badge_logo.svg" nbviewer_logo = "https://img.shields.io/badge/render-nbviewer-f37726" raw_notebook_logo = "https://img.shields.io/badge/raw-notebook-4cc61e" notebook_path = "tutorials/notebooks/$notebook_filename" - binder_url = "https://mybinder.org/v2/gh/trixi-framework/Trixi.jl/tutorial_notebooks?filepath=$notebook_path" + binder_url = "https://mybinder.org/v2/gh/trixi-framework/Trixi.jl/tutorial_notebooks?filepath=$notebook_path" nbviewer_url = "https://nbviewer.jupyter.org/github/trixi-framework/Trixi.jl/blob/tutorial_notebooks/$notebook_path" raw_notebook_url = "https://raw.githubusercontent.com/trixi-framework/Trixi.jl/tutorial_notebooks/$notebook_path" - binder_badge = "# [![]($binder_logo)]($binder_url)" + binder_badge = "# [![]($binder_logo)]($binder_url)" nbviewer_badge = "# [![]($nbviewer_logo)]($nbviewer_url)" raw_notebook_badge = "# [![]($raw_notebook_logo)]($raw_notebook_url)" @@ -28,25 +28,28 @@ function create_files(title, file, repo_src, pages_dir, notebooks_dir; folder="" # available for the latest stable release of Trixi.jl at the time of caching.\n\n" return string("# # $title\n\n", warning, content) end - Literate.notebook(joinpath(repo_src, folder, file), joinpath(notebooks_dir, folder); execute=false, preprocess=preprocess_notebook, credit=false) + Literate.notebook(joinpath(repo_src, folder, file), joinpath(notebooks_dir, folder); + execute = false, preprocess = preprocess_notebook, credit = false) # Generate markdown file function preprocess_docs(content) - return string("# # [$title](@id $(splitext(file)[1]))\n $binder_badge\n $nbviewer_badge\n $raw_notebook_badge\n\n", content) + return string("# # [$title](@id $(splitext(file)[1]))\n $binder_badge\n $nbviewer_badge\n $raw_notebook_badge\n\n", + content) end - Literate.markdown(joinpath(repo_src, folder, file), joinpath(pages_dir, folder); preprocess=preprocess_docs,) + Literate.markdown(joinpath(repo_src, folder, file), joinpath(pages_dir, folder); + preprocess = preprocess_docs,) end # Create tutorials with Literate.jl function create_tutorials(files) - repo_src = joinpath(@__DIR__, "src", "files") + repo_src = joinpath(@__DIR__, "src", "files") - pages_dir = joinpath(@__DIR__, "..", "src", "tutorials") - notebooks_dir = joinpath(pages_dir, "notebooks") + pages_dir = joinpath(@__DIR__, "..", "src", "tutorials") + notebooks_dir = joinpath(pages_dir, "notebooks") - Sys.rm(pages_dir; recursive=true, force=true) + Sys.rm(pages_dir; recursive = true, force = true) - Sys.rm("out"; recursive=true, force=true) + Sys.rm("out"; recursive = true, force = true) # Run tests on all tutorial files @testset "TrixiTutorials" begin @@ -59,7 +62,8 @@ function create_tutorials(files) mod = gensym(filename[j][2][2]) @testset "$(filename[j][2][2])" begin @eval module $mod - include(joinpath($repo_src, $(filename[j][2][1]), $(filename[j][2][2]))) + include(joinpath($repo_src, $(filename[j][2][1]), + $(filename[j][2][2]))) end end end @@ -67,7 +71,7 @@ function create_tutorials(files) mod = gensym(title) @testset "$title" begin @eval module $mod - include(joinpath($repo_src, $filename)) + include(joinpath($repo_src, $filename)) end end end @@ -85,9 +89,10 @@ function create_tutorials(files) end return content end - Literate.markdown(joinpath(repo_src, "index.jl"), pages_dir; name="introduction", preprocess=preprocess_introduction) + Literate.markdown(joinpath(repo_src, "index.jl"), pages_dir; name = "introduction", + preprocess = preprocess_introduction) # Navigation system for makedocs - pages = Any["Introduction" => "tutorials/introduction.md",] + pages = Any["Introduction" => "tutorials/introduction.md"] # Create markdown and notebook files for tutorials for (i, (title, filename)) in enumerate(files) @@ -95,8 +100,9 @@ function create_tutorials(files) if filename isa Vector vector = [] for j in eachindex(filename) - create_files("$i.$j: $title: $(filename[j][1])", filename[j][2][2], repo_src, - pages_dir, notebooks_dir; folder=filename[j][2][1]) + create_files("$i.$j: $title: $(filename[j][1])", filename[j][2][2], + repo_src, + pages_dir, notebooks_dir; folder = filename[j][2][1]) path = "$(filename[j][2][1])/$(splitext(filename[j][2][2])[1]).md" push!(vector, "$i.$j $(filename[j][1])" => "tutorials/$path") diff --git a/docs/literate/src/files/DGMulti_1.jl b/docs/literate/src/files/DGMulti_1.jl index 6c9a5aea93..c3095d8938 100644 --- a/docs/literate/src/files/DGMulti_1.jl +++ b/docs/literate/src/files/DGMulti_1.jl @@ -30,22 +30,22 @@ dg = DGMulti(polydeg = 3, cells_per_dimension = (32, 32) mesh = DGMultiMesh(dg, cells_per_dimension, # initial_refinement_level = 5 - coordinates_min=(-2.0, -2.0), - coordinates_max=( 2.0, 2.0), - periodicity=true) + coordinates_min = (-2.0, -2.0), + coordinates_max = (2.0, 2.0), + periodicity = true) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg, - boundary_conditions=boundary_condition_periodic) + boundary_conditions = boundary_condition_periodic) tspan = (0.0, 0.4) ode = semidiscretize(semi, tspan) -alive_callback = AliveCallback(alive_interval=10) -analysis_callback = AnalysisCallback(semi, interval=100, uEltype=real(dg)) +alive_callback = AliveCallback(alive_interval = 10) +analysis_callback = AnalysisCallback(semi, interval = 100, uEltype = real(dg)) callbacks = CallbackSet(analysis_callback, alive_callback); # Run the simulation with the same time integration algorithm as before. -sol = solve(ode, RDPK3SpFSAL49(), abstol=1.0e-6, reltol=1.0e-6, - callback=callbacks, save_everystep=false); +sol = solve(ode, RDPK3SpFSAL49(), abstol = 1.0e-6, reltol = 1.0e-6, + callback = callbacks, save_everystep = false); #- using Plots pd = PlotData2D(sol) @@ -60,7 +60,6 @@ plot!(getmesh(pd)) # (2021) provides a nice runtime comparison between the different mesh types. On the other hand, # the functions are more general and thus we have more option we can choose from. - # ## Simulation with Gauss nodes # For instance, we can change the approximation type of our simulation. using Trixi, OrdinaryDiffEq @@ -78,28 +77,27 @@ dg = DGMulti(polydeg = 3, cells_per_dimension = (32, 32) mesh = DGMultiMesh(dg, - cells_per_dimension, # initial_refinement_level = 5 - coordinates_min=(-2.0, -2.0), - coordinates_max=( 2.0, 2.0), - periodicity=true) + cells_per_dimension, # initial_refinement_level = 5 + coordinates_min = (-2.0, -2.0), + coordinates_max = (2.0, 2.0), + periodicity = true) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg, - boundary_conditions=boundary_condition_periodic) + boundary_conditions = boundary_condition_periodic) tspan = (0.0, 0.4) ode = semidiscretize(semi, tspan) -alive_callback = AliveCallback(alive_interval=10) -analysis_callback = AnalysisCallback(semi, interval=100, uEltype=real(dg)) +alive_callback = AliveCallback(alive_interval = 10) +analysis_callback = AnalysisCallback(semi, interval = 100, uEltype = real(dg)) callbacks = CallbackSet(analysis_callback, alive_callback); -sol = solve(ode, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, - ode_default_options()..., callback=callbacks); +sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, + ode_default_options()..., callback = callbacks); #- using Plots pd = PlotData2D(sol) plot(pd) - # ## Simulation with triangular elements # Also, we can set another element type. We want to use triangles now. using Trixi, OrdinaryDiffEq @@ -119,21 +117,21 @@ dg = DGMulti(polydeg = 3, cells_per_dimension = (32, 32) mesh = DGMultiMesh(dg, cells_per_dimension, # initial_refinement_level = 5 - coordinates_min=(-2.0, -2.0), - coordinates_max=( 2.0, 2.0), - periodicity=true) + coordinates_min = (-2.0, -2.0), + coordinates_max = (2.0, 2.0), + periodicity = true) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg, - boundary_conditions=boundary_condition_periodic) + boundary_conditions = boundary_condition_periodic) tspan = (0.0, 0.4) ode = semidiscretize(semi, tspan) -alive_callback = AliveCallback(alive_interval=10) -analysis_callback = AnalysisCallback(semi, interval=100, uEltype=real(dg)) +alive_callback = AliveCallback(alive_interval = 10) +analysis_callback = AnalysisCallback(semi, interval = 100, uEltype = real(dg)) callbacks = CallbackSet(analysis_callback, alive_callback); -sol = solve(ode, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, - ode_default_options()..., callback=callbacks); +sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, + ode_default_options()..., callback = callbacks); #- using Plots pd = PlotData2D(sol) @@ -142,7 +140,6 @@ plot(pd) plot(pd["rho"]) plot!(getmesh(pd)) - # ## Triangular meshes on non-Cartesian domains # To use triangular meshes on a non-Cartesian domain, Trixi.jl uses the package [StartUpDG.jl](https://github.com/jlchan/StartUpDG.jl). # The following example is based on [`elixir_euler_triangulate_pkg_mesh.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/dgmulti_2d/elixir_euler_triangulate_pkg_mesh.jl) @@ -157,7 +154,7 @@ source_terms = source_terms_convergence_test # We create the solver `DGMulti` with triangular elements (`Tri()`) as before. dg = DGMulti(polydeg = 3, element_type = Tri(), - approximation_type=Polynomial(), + approximation_type = Polynomial(), surface_flux = flux_lax_friedrichs, volume_integral = VolumeIntegralFluxDifferencing(flux_ranocha)) @@ -168,11 +165,11 @@ meshIO = StartUpDG.triangulate_domain(StartUpDG.RectangularDomainWithHole()); # The pre-defined Triangulate geometry in StartUpDG has integer boundary tags. With [`DGMultiMesh`](@ref) # we assign boundary faces based on these integer boundary tags and create a mesh compatible with Trixi.jl. -mesh = DGMultiMesh(dg, meshIO, Dict(:outer_boundary=>1, :inner_boundary=>2)) +mesh = DGMultiMesh(dg, meshIO, Dict(:outer_boundary => 1, :inner_boundary => 2)) #- boundary_condition_convergence_test = BoundaryConditionDirichlet(initial_condition) boundary_conditions = (; :outer_boundary => boundary_condition_convergence_test, - :inner_boundary => boundary_condition_convergence_test) + :inner_boundary => boundary_condition_convergence_test) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg, source_terms = source_terms, @@ -181,12 +178,12 @@ semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg, tspan = (0.0, 0.2) ode = semidiscretize(semi, tspan) -alive_callback = AliveCallback(alive_interval=20) -analysis_callback = AnalysisCallback(semi, interval=200, uEltype=real(dg)) +alive_callback = AliveCallback(alive_interval = 20) +analysis_callback = AnalysisCallback(semi, interval = 200, uEltype = real(dg)) callbacks = CallbackSet(alive_callback, analysis_callback); -sol = solve(ode, CarpenterKennedy2N54(williamson_condition=false), - dt = 0.5 * estimate_dt(mesh, dg), save_everystep=false, callback=callbacks); +sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false), + dt = 0.5 * estimate_dt(mesh, dg), save_everystep = false, callback = callbacks); #- using Plots pd = PlotData2D(sol) @@ -195,7 +192,6 @@ plot!(getmesh(pd)) # For more information, please have a look in the [StartUpDG.jl documentation](https://jlchan.github.io/StartUpDG.jl/stable/). - # ## Package versions # These results were obtained using the following versions. @@ -205,4 +201,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "StartUpDG", "OrdinaryDiffEq", "Plots"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/DGMulti_2.jl b/docs/literate/src/files/DGMulti_2.jl index 0624856234..c90063c3a0 100644 --- a/docs/literate/src/files/DGMulti_2.jl +++ b/docs/literate/src/files/DGMulti_2.jl @@ -8,8 +8,8 @@ # to the `DGMulti` constructor. For example, the classical second-order FD SBP operator # can be created as using Trixi.SummationByPartsOperators # or add SummationByPartsOperators to your project and use it directly -D = derivative_operator(MattssonNordström2004(), derivative_order=1, accuracy_order=2, - xmin=0.0, xmax=1.0, N=11) +D = derivative_operator(MattssonNordström2004(), derivative_order = 1, accuracy_order = 2, + xmin = 0.0, xmax = 1.0, N = 11) # Here, the arguments `xmin` and `xmax` do not matter beyond setting the real type # used for the operator - they just set a reference element and are rescaled on the # physical elements. The parameter `N` determines the number of finite difference nodes. @@ -20,8 +20,8 @@ D = derivative_operator(MattssonNordström2004(), derivative_order=1, accuracy_o # # You can also use fully periodic single-block FD methods by creating a periodic SBP # operator. For example, a fully periodic FD operator can be constructed as -D = periodic_derivative_operator(derivative_order=1, accuracy_order=2, - xmin=0.0, xmax=1.0, N=11) +D = periodic_derivative_operator(derivative_order = 1, accuracy_order = 2, + xmin = 0.0, xmax = 1.0, N = 11) # An example using such an FD method is implemented in # [`elixir_euler_fdsbp_periodic.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/dgmulti_2d/elixir_euler_fdsbp_periodic.jl). # For all parameters and other calling options, please have a look in the @@ -31,15 +31,14 @@ D = periodic_derivative_operator(derivative_order=1, accuracy_order=2, # method with polynomial degree of `3` (`N=4` Legendre Lobatto nodes on `[0, 1]`) coupled continuously # on a uniform mesh with `Nx=10` elements by setting `approximation_type` to using Trixi.SummationByPartsOperators # or add SummationByPartsOperators to your project and use it directly -D = couple_continuously(legendre_derivative_operator(xmin=0.0, xmax=1.0, N=4), - UniformPeriodicMesh1D(xmin=-1.0, xmax=1.0, Nx=10)) +D = couple_continuously(legendre_derivative_operator(xmin = 0.0, xmax = 1.0, N = 4), + UniformPeriodicMesh1D(xmin = -1.0, xmax = 1.0, Nx = 10)) # To choose a discontinuous coupling (DGSEM), use `couple_discontinuously()` instead of `couple_continuously()`. # For more information and other SBP operators, see the documentations of [StartUpDG.jl](https://jlchan.github.io/StartUpDG.jl/dev/) # and [SummationByPartsOperators.jl](https://ranocha.de/SummationByPartsOperators.jl/stable/). - # ## Package versions # These results were obtained using the following versions. @@ -49,4 +48,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "StartUpDG", "SummationByPartsOperators"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/DGSEM_FluxDiff.jl b/docs/literate/src/files/DGSEM_FluxDiff.jl index a576990026..faafe45812 100644 --- a/docs/literate/src/files/DGSEM_FluxDiff.jl +++ b/docs/literate/src/files/DGSEM_FluxDiff.jl @@ -20,7 +20,6 @@ # J u_t + f(u)_{\xi} = 0, \qquad t\in \mathbb{R}^+, \xi\in [-1,1] # ``` - # ## The weak form of the DGSEM # We consider the so-called discontinuous Galerkin spectral element method (DGSEM) with collocation. # It results from choosing a nodal DG ansatz using $N+1$ Gauss-Lobatto nodes $\xi_i$ in $[-1,1]$ @@ -77,7 +76,6 @@ # ``` # More information about the equivalence you can find in [Kopriva, Gassner (2010)](https://doi.org/10.1007/s10915-010-9372-3). - # ## DGSEM with flux differencing # When using the diagonal SBP property it is possible to rewrite the application of the derivative # operator $D$ in the calculation of the volume integral into a subcell based finite volume type @@ -105,7 +103,6 @@ # flux $f=f_{surface}$ used for the numerical flux $f_{surface}^*$ and the already mentioned volume # flux $f_{vol}$ especially for this formulation. - # This formulation creates a more stable version of DGSEM, because it fulfils entropy stability. # Moreover it allows the construction of entropy conserving discretizations without relying on # exact integration. This is achieved when using a two-point entropy conserving flux function as @@ -113,8 +110,6 @@ # Then, the numerical surface flux can be used to control the dissipation of the discretization and to # guarantee decreasing entropy, i.e. entropy stability. - - # ## [Implementation in Trixi.jl](@id fluxDiffExample) # Now, we have a look at the implementation of DGSEM with flux differencing with [Trixi.jl](https://github.com/trixi-framework/Trixi.jl). using OrdinaryDiffEq, Trixi @@ -158,21 +153,21 @@ initial_condition = initial_condition_weak_blast_wave # We will confirm the entropy conservation property numerically. volume_flux = flux_ranocha # = f_vol -solver = DGSEM(polydeg=3, surface_flux=volume_flux, - volume_integral=VolumeIntegralFluxDifferencing(volume_flux)) +solver = DGSEM(polydeg = 3, surface_flux = volume_flux, + volume_integral = VolumeIntegralFluxDifferencing(volume_flux)) # Now, we implement Trixi.jl's `mesh`, `semi` and `ode` in a simple framework. For more information please # have a look at the documentation, the basic tutorial [introduction to DG methods](@ref scalar_linear_advection_1d) # or some basic elixirs. coordinates_min = (-2.0, -2.0) -coordinates_max = ( 2.0, 2.0) +coordinates_max = (2.0, 2.0) mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level=5, - n_cells_max=10_000, - periodicity=true) + initial_refinement_level = 5, + n_cells_max = 10_000, + periodicity = true) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - boundary_conditions=boundary_condition_periodic) + boundary_conditions = boundary_condition_periodic) ## ODE solvers tspan = (0.0, 0.4) @@ -180,11 +175,11 @@ ode = semidiscretize(semi, tspan); # To analyse the entropy conservation of the approximation, we will use the analysis calllback # implemented in Trixi. It provides some information about the approximation including the entropy change. -analysis_callback = AnalysisCallback(semi, interval=100); +analysis_callback = AnalysisCallback(semi, interval = 100); # We now run the simulation using `flux_ranocha` for both surface and volume flux. -sol = solve(ode, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, - ode_default_options()..., callback=analysis_callback); +sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, + ode_default_options()..., callback = analysis_callback); # A look at the change in entropy $\sum \partial S/\partial U \cdot U_t$ in the analysis callback # confirms that the flux is entropy conserving since the change is about machine precision. @@ -202,34 +197,33 @@ equations = CompressibleEulerEquations2D(gamma) initial_condition = initial_condition_weak_blast_wave volume_flux = flux_ranocha # = f_vol -solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs, - volume_integral=VolumeIntegralFluxDifferencing(volume_flux)) +solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs, + volume_integral = VolumeIntegralFluxDifferencing(volume_flux)) coordinates_min = (-2.0, -2.0) -coordinates_max = ( 2.0, 2.0) +coordinates_max = (2.0, 2.0) mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level=5, - n_cells_max=10_000, - periodicity=true) + initial_refinement_level = 5, + n_cells_max = 10_000, + periodicity = true) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - boundary_conditions=boundary_condition_periodic) + boundary_conditions = boundary_condition_periodic) ## ODE solvers tspan = (0.0, 0.4) ode = semidiscretize(semi, tspan); -analysis_callback = AnalysisCallback(semi, interval=100); +analysis_callback = AnalysisCallback(semi, interval = 100); # We now run the simulation using the volume flux `flux_ranocha` and surface flux `flux_lax_friedrichs`. -sol = solve(ode, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, - ode_default_options()..., callback=analysis_callback); +sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, + ode_default_options()..., callback = analysis_callback); # The change in entropy confirms the expected entropy stability. using Plots plot(sol) - # Of course, you can use more than these two fluxes in Trixi. Here, we will give a short list # of possible fluxes for the compressible Euler equations. # For the volume flux Trixi.jl provides for example [`flux_ranocha`](@ref), [`flux_shima_etal`](@ref), @@ -237,7 +231,6 @@ plot(sol) # As surface flux you can use all volume fluxes and additionally for instance [`flux_lax_friedrichs`](@ref), # [`flux_hll`](@ref), [`flux_hllc`](@ref). - # ## Package versions # These results were obtained using the following versions. @@ -247,4 +240,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/adaptive_mesh_refinement.jl b/docs/literate/src/files/adaptive_mesh_refinement.jl index 46af8f7952..608c415efd 100644 --- a/docs/literate/src/files/adaptive_mesh_refinement.jl +++ b/docs/literate/src/files/adaptive_mesh_refinement.jl @@ -50,7 +50,6 @@ # amr_indicator = IndicatorMax(semi, variable=variable) # ```` - # ### Controllers # The spatial discretization into elements is tree-based for both AMR supporting mesh types `TreeMesh` # and `P4estMesh`. Thus, the higher the level in the tree the higher the level of refinement. @@ -87,7 +86,6 @@ # This controller is for instance used in # [`elixir_euler_astro_jet_amr.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_2d_dgsem/elixir_euler_astro_jet_amr.jl). - # ### Callback # The AMR indicator and controller are added to the simulation through the callback [`AMRCallback`](@ref). # It contains a semidiscretization `semi`, the controller `amr_controller` and the parameters `interval`, @@ -103,7 +101,6 @@ # adapt_initial_condition_only_refine=true) # ```` - # # Exemplary simulation # Here, we want to implement a simple AMR simulation of the 2D linear advection equation for a Gaussian pulse. @@ -114,17 +111,16 @@ advection_velocity = (0.2, -0.7) equations = LinearScalarAdvectionEquation2D(advection_velocity) initial_condition = initial_condition_gauss -solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) +solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) coordinates_min = (-5.0, -5.0) -coordinates_max = ( 5.0, 5.0) +coordinates_max = (5.0, 5.0) mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level=4, - n_cells_max=30_000) + initial_refinement_level = 4, + n_cells_max = 30_000) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver) - tspan = (0.0, 10.0) ode = semidiscretize(semi, tspan); @@ -132,29 +128,29 @@ ode = semidiscretize(semi, tspan); # `IndicatorMax`. As described before, it returns the maximal value of the specified variable # (here the only conserved variable). Therefore, regions with a high maximum are refined. # This is not really useful numerical application, but a nice demonstration example. -amr_indicator = IndicatorMax(semi, variable=first) +amr_indicator = IndicatorMax(semi, variable = first) # These values are transferred to a refinement level with the `ControllerThreeLevel`, such that # every element with maximal value greater than `0.1` is refined once and elements with maximum # above `0.6` are refined twice. amr_controller = ControllerThreeLevel(semi, amr_indicator, - base_level=4, - med_level=5, med_threshold=0.1, - max_level=6, max_threshold=0.6) + base_level = 4, + med_level = 5, med_threshold = 0.1, + max_level = 6, max_threshold = 0.6) amr_callback = AMRCallback(semi, amr_controller, - interval=5, - adapt_initial_condition=true, - adapt_initial_condition_only_refine=true) + interval = 5, + adapt_initial_condition = true, + adapt_initial_condition_only_refine = true) -stepsize_callback = StepsizeCallback(cfl=0.9) +stepsize_callback = StepsizeCallback(cfl = 0.9) callbacks = CallbackSet(amr_callback, stepsize_callback); # Running the simulation. -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); +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); # We plot the solution and add the refined mesh at the end of the simulation. using Plots @@ -162,7 +158,6 @@ pd = PlotData2D(sol) plot(pd) plot!(getmesh(pd)) - # # More examples # Trixi.jl provides many elixirs using AMR. We want to give some examples for different mesh types: # - `elixir_euler_blast_wave_amr.jl` for [`TreeMesh`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_2d_dgsem/elixir_euler_blast_wave_amr.jl) @@ -203,7 +198,6 @@ plot!(getmesh(pd)) # For more information, please have a look at the respective links. - # ## Package versions # These results were obtained using the following versions. @@ -213,4 +207,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/adding_new_parabolic_terms.jl b/docs/literate/src/files/adding_new_parabolic_terms.jl index 209ef62c98..5240a67447 100644 --- a/docs/literate/src/files/adding_new_parabolic_terms.jl +++ b/docs/literate/src/files/adding_new_parabolic_terms.jl @@ -7,7 +7,6 @@ using OrdinaryDiffEq using Trixi - advection_velocity = (1.0, 1.0) equations_hyperbolic = LinearScalarAdvectionEquation2D(advection_velocity); @@ -26,13 +25,15 @@ equations_hyperbolic = LinearScalarAdvectionEquation2D(advection_velocity); # the gradient with respect to a different set of variables; see, for example, the implementation of # [`CompressibleNavierStokesDiffusion2D`](@ref), which can utilize either "primitive" or "entropy" variables. -struct ConstantAnisotropicDiffusion2D{E, T} <: Trixi.AbstractEquationsParabolic{2, 1, GradientVariablesConservative} - diffusivity::T - equations_hyperbolic::E +struct ConstantAnisotropicDiffusion2D{E, T} <: + Trixi.AbstractEquationsParabolic{2, 1, GradientVariablesConservative} + diffusivity::T + equations_hyperbolic::E end -varnames(variable_mapping, equations_parabolic::ConstantAnisotropicDiffusion2D) = - varnames(variable_mapping, equations_parabolic.equations_hyperbolic) +function varnames(variable_mapping, equations_parabolic::ConstantAnisotropicDiffusion2D) + varnames(variable_mapping, equations_parabolic.equations_hyperbolic) +end # Next, we define the viscous flux function. We assume that the mixed hyperbolic-parabolic system # is of the form @@ -46,14 +47,15 @@ varnames(variable_mapping, equations_parabolic::ConstantAnisotropicDiffusion2D) # # Here, we specialize the flux to our new parabolic equation type `ConstantAnisotropicDiffusion2D`. -function Trixi.flux(u, gradients, orientation::Integer, equations_parabolic::ConstantAnisotropicDiffusion2D) - @unpack diffusivity = equations_parabolic - dudx, dudy = gradients - if orientation == 1 - return SVector(diffusivity[1, 1] * dudx + diffusivity[1, 2] * dudy) - else # if orientation == 2 - return SVector(diffusivity[2, 1] * dudx + diffusivity[2, 2] * dudy) - end +function Trixi.flux(u, gradients, orientation::Integer, + equations_parabolic::ConstantAnisotropicDiffusion2D) + @unpack diffusivity = equations_parabolic + dudx, dudy = gradients + if orientation == 1 + return SVector(diffusivity[1, 1] * dudx + diffusivity[1, 2] * dudy) + else # if orientation == 2 + return SVector(diffusivity[2, 1] * dudx + diffusivity[2, 2] * dudy) + end end # ## Defining boundary conditions @@ -76,7 +78,7 @@ end # As an example, let us introduce a Dirichlet boundary condition with constant boundary data. struct BoundaryConditionConstantDirichlet{T <: Real} - boundary_value::T + boundary_value::T end # This boundary condition contains only the field `boundary_value`, which we assume to be some @@ -87,10 +89,13 @@ end # the `Gradient` and `Divergence`. Since the gradient is operating on the solution `u`, the boundary # data should be the value of `u`, and we can directly impose Dirichlet data. -@inline function (boundary_condition::BoundaryConditionConstantDirichlet)(flux_inner, u_inner, normal::AbstractVector, - x, t, operator_type::Trixi.Gradient, +@inline function (boundary_condition::BoundaryConditionConstantDirichlet)(flux_inner, + u_inner, + normal::AbstractVector, + x, t, + operator_type::Trixi.Gradient, equations_parabolic::ConstantAnisotropicDiffusion2D) - return boundary_condition.boundary_value + return boundary_condition.boundary_value end # While the gradient acts on the solution `u`, the divergence acts on the viscous flux ``\bm{\sigma}``. @@ -102,10 +107,13 @@ end # `flux_inner`, which is boundary data for ``\bm{\sigma}`` computed using the "inner" or interior solution. # This way, we supply boundary data for the divergence operation without imposing any additional conditions. -@inline function (boundary_condition::BoundaryConditionConstantDirichlet)(flux_inner, u_inner, normal::AbstractVector, - x, t, operator_type::Trixi.Divergence, +@inline function (boundary_condition::BoundaryConditionConstantDirichlet)(flux_inner, + u_inner, + normal::AbstractVector, + x, t, + operator_type::Trixi.Divergence, equations_parabolic::ConstantAnisotropicDiffusion2D) - return flux_inner + return flux_inner end # ### A note on the choice of gradient variables @@ -130,42 +138,42 @@ using Trixi: SMatrix diffusivity = 5.0e-2 * SMatrix{2, 2}([2 -1; -1 2]) equations_parabolic = ConstantAnisotropicDiffusion2D(diffusivity, equations_hyperbolic); -boundary_conditions_hyperbolic = (; x_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(1.0)), - y_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(2.0)), - y_pos = boundary_condition_do_nothing, - x_pos = boundary_condition_do_nothing) +boundary_conditions_hyperbolic = (; + x_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(1.0)), + y_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(2.0)), + y_pos = boundary_condition_do_nothing, + x_pos = boundary_condition_do_nothing) boundary_conditions_parabolic = (; x_neg = BoundaryConditionConstantDirichlet(1.0), - y_neg = BoundaryConditionConstantDirichlet(2.0), - y_pos = BoundaryConditionConstantDirichlet(0.0), - x_pos = BoundaryConditionConstantDirichlet(0.0)); + y_neg = BoundaryConditionConstantDirichlet(2.0), + y_pos = BoundaryConditionConstantDirichlet(0.0), + x_pos = BoundaryConditionConstantDirichlet(0.0)); -solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) +solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) coordinates_min = (-1.0, -1.0) # minimum coordinates (min(x), min(y)) -coordinates_max = ( 1.0, 1.0) # maximum coordinates (max(x), max(y)) +coordinates_max = (1.0, 1.0) # maximum coordinates (max(x), max(y)) mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level=4, - periodicity=false, n_cells_max=30_000) # set maximum capacity of tree data structure + initial_refinement_level = 4, + periodicity = false, n_cells_max = 30_000) # set maximum capacity of tree data structure initial_condition = (x, t, equations) -> SVector(0.0) semi = SemidiscretizationHyperbolicParabolic(mesh, (equations_hyperbolic, equations_parabolic), initial_condition, solver; - boundary_conditions=(boundary_conditions_hyperbolic, - boundary_conditions_parabolic)) + boundary_conditions = (boundary_conditions_hyperbolic, + boundary_conditions_parabolic)) tspan = (0.0, 2.0) ode = semidiscretize(semi, tspan) callbacks = CallbackSet(SummaryCallback()) time_int_tol = 1.0e-6 -sol = solve(ode, RDPK3SpFSAL49(); abstol=time_int_tol, reltol=time_int_tol, - ode_default_options()..., callback=callbacks); +sol = solve(ode, RDPK3SpFSAL49(); abstol = time_int_tol, reltol = time_int_tol, + ode_default_options()..., callback = callbacks); using Plots plot(sol) - # ## Package versions # These results were obtained using the following versions. @@ -175,5 +183,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode=PKGMODE_MANIFEST) - + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/adding_new_scalar_equations.jl b/docs/literate/src/files/adding_new_scalar_equations.jl index a65b4de7f1..243d379351 100644 --- a/docs/literate/src/files/adding_new_scalar_equations.jl +++ b/docs/literate/src/files/adding_new_scalar_equations.jl @@ -12,8 +12,8 @@ # ## Basic setup using Trixi -struct CubicEquation <: Trixi.AbstractEquations{1 #= number of spatial dimensions =#, - 1 #= number of primary variables, i.e. scalar =#}; +struct CubicEquation <: Trixi.AbstractEquations{1, #= number of spatial dimensions =# + 1} #= number of primary variables, i.e. scalar =# end # We create `CubicEquation` as an empty `struct` since we do not use any parameters @@ -23,7 +23,7 @@ end # Next, we define the physical flux `f(u) = u^3` using the calling structure # used in Trixi.jl. -Trixi.flux(u, orientation, equation::CubicEquation) = u.^3 +Trixi.flux(u, orientation, equation::CubicEquation) = u .^ 3 Trixi.varnames(_, ::CubicEquation) = ("scalar",) # In Trixi.jl, the conserved variables `u` are usually passed as `SVector`s of variables @@ -41,10 +41,10 @@ equation = CubicEquation() initial_condition_sine(x, t, equation::CubicEquation) = SVector(sinpi(x[1])) mesh = TreeMesh(-1.0, 1.0, # min/max coordinates - initial_refinement_level=4, - n_cells_max=10^4) + initial_refinement_level = 4, + n_cells_max = 10^4) -solver = DGSEM(3 #= polynomial degree =#, flux_central) +solver = DGSEM(3, flux_central) #= polynomial degree =# semi = SemidiscretizationHyperbolic(mesh, equation, initial_condition_sine, solver) @@ -67,7 +67,7 @@ callbacks = CallbackSet(summary_callback) ## OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks sol = solve(ode, SSPRK43(); - ode_default_options()..., callback=callbacks); + ode_default_options()..., callback = callbacks); # That's it, you ran your first simulation using your new equation with Trixi.jl! Now, we can plot # the solution at the final time using Plots.jl. @@ -79,20 +79,21 @@ plot(sol) # To avoid these issues, we need to use dissipative numerical fluxes (approximate # Riemann solvers) at interfaces. - # ## Advanced setup # Thus, we add a Godunov's flux for our cubic equation. That is easy for this equation # since the wave speed `f'(u) = 3u^2` is always non-negative. -@inline Trixi.flux_godunov(u_ll, u_rr, orientation, equation::CubicEquation) = flux(u_ll, orientation, equation) +@inline Trixi.flux_godunov(u_ll, u_rr, orientation, equation::CubicEquation) = flux(u_ll, + orientation, + equation) # Let's run the example again but with a dissipative numerical flux at interfaces. # `remake` will recreate the semidiscretization we used before and only change # selected parameters, in this case the `solver`. ## A new setup with dissipation -semi = remake(semi, solver=DGSEM(3, flux_godunov)) +semi = remake(semi, solver = DGSEM(3, flux_godunov)) ode = semidiscretize(semi, tspan) sol = solve(ode, SSPRK43(); ode_default_options()...) plot!(sol) @@ -101,8 +102,9 @@ plot!(sol) # Now let's increase the final time (and also the spatial resolution). ## A larger final time: Nonclassical shocks develop (you can even increase the refinement to 12) -semi = remake(semi, mesh=TreeMesh(-1.0, 1.0, initial_refinement_level=8, n_cells_max=10^5)) -ode = semidiscretize(semi, (0.0, 0.5) #= tspan =#) +semi = remake(semi, + mesh = TreeMesh(-1.0, 1.0, initial_refinement_level = 8, n_cells_max = 10^5)) +ode = semidiscretize(semi, (0.0, 0.5)) #= tspan =# sol = solve(ode, SSPRK43(); ode_default_options()...) plot(sol) @@ -112,14 +114,16 @@ plot(sol) # to define an entropy-conservative numerical flux @inline function Trixi.flux_ec(u_ll, u_rr, orientation, equation::CubicEquation) - return SVector(0.25 * (u_ll[1]^3 + u_ll[1]^2 * u_rr[1] + u_ll[1] * u_rr[1]^2 + u_rr[1]^3)) + return SVector(0.25 * + (u_ll[1]^3 + u_ll[1]^2 * u_rr[1] + u_ll[1] * u_rr[1]^2 + u_rr[1]^3)) end # and use a [`VolumeIntegralFluxDifferencing`](@ref) instead of the standard # [`VolumeIntegralWeakForm`](@ref) in the DGSEM. ## Let's use a provably entropy-dissipative semidiscretization -semi = remake(semi, solver=DGSEM(3, flux_godunov, VolumeIntegralFluxDifferencing(flux_ec))) +semi = remake(semi, + solver = DGSEM(3, flux_godunov, VolumeIntegralFluxDifferencing(flux_ec))) ode = semidiscretize(semi, (0.0, 0.5)) sol = solve(ode, SSPRK43(); ode_default_options()...); plot(sol) @@ -137,7 +141,6 @@ plot(sol) # the 2D scalar "KPP equation" from [Kurganov, Petrova, Popov (2007)](https://doi.org/10.1137/040614189) is # implemented. - # ## Summary of the code # To sum up, here is the complete code that we used (without the callbacks since these create a @@ -150,21 +153,23 @@ module CubicConservationLaw using Trixi -struct CubicEquation <: Trixi.AbstractEquations{1 #= number of spatial dimensions =#, - 1 #= number of primary variables, i.e. scalar =#} +struct CubicEquation <: Trixi.AbstractEquations{1, #= number of spatial dimensions =# + 1} #= number of primary variables, i.e. scalar =# end -@inline Trixi.flux(u, orientation, equation::CubicEquation) = u.^3 +@inline Trixi.flux(u, orientation, equation::CubicEquation) = u .^ 3 Trixi.varnames(_, ::CubicEquation) = ("scalar",) -@inline Trixi.flux_godunov(u_ll, u_rr, orientation, equation::CubicEquation) = flux(u_ll, orientation, equation) +@inline Trixi.flux_godunov(u_ll, u_rr, orientation, equation::CubicEquation) = flux(u_ll, + orientation, + equation) @inline function Trixi.flux_ec(u_ll, u_rr, orientation, equation::CubicEquation) - return SVector(0.25 * (u_ll[1]^3 + u_ll[1]^2 * u_rr[1] + u_ll[1] * u_rr[1]^2 + u_rr[1]^3)) + return SVector(0.25 * + (u_ll[1]^3 + u_ll[1]^2 * u_rr[1] + u_ll[1] * u_rr[1]^2 + u_rr[1]^3)) end end # module - ## Create a simulation setup import .CubicConservationLaw using Trixi @@ -173,13 +178,15 @@ using Plots equation = CubicConservationLaw.CubicEquation() -initial_condition_sine(x, t, equation::CubicConservationLaw.CubicEquation) = SVector(sinpi(x[1])) +function initial_condition_sine(x, t, equation::CubicConservationLaw.CubicEquation) + SVector(sinpi(x[1])) +end mesh = TreeMesh(-1.0, 1.0, # min/max coordinates - initial_refinement_level=4, - n_cells_max=10^4) + initial_refinement_level = 4, + n_cells_max = 10^4) -solver = DGSEM(3 #= polynomial degree =#, flux_central) +solver = DGSEM(3, flux_central) #= polynomial degree =# semi = SemidiscretizationHyperbolic(mesh, equation, initial_condition_sine, solver) @@ -191,28 +198,26 @@ ode = semidiscretize(semi, tspan) sol = solve(ode, SSPRK43(); ode_default_options()...) plot(sol) - ## A new setup with dissipation -semi = remake(semi, solver=DGSEM(3, flux_godunov)) +semi = remake(semi, solver = DGSEM(3, flux_godunov)) ode = semidiscretize(semi, tspan) sol = solve(ode, SSPRK43(); ode_default_options()...) plot!(sol) - ## A larger final time: Nonclassical shocks develop (you can even increase the refinement to 12) -semi = remake(semi, mesh=TreeMesh(-1.0, 1.0, initial_refinement_level=8, n_cells_max=10^5)) +semi = remake(semi, + mesh = TreeMesh(-1.0, 1.0, initial_refinement_level = 8, n_cells_max = 10^5)) ode = semidiscretize(semi, (0.0, 0.5)) sol = solve(ode, SSPRK43(); ode_default_options()...) plot(sol) - ## Let's use a provably entropy-dissipative semidiscretization -semi = remake(semi, solver=DGSEM(3, flux_godunov, VolumeIntegralFluxDifferencing(flux_ec))) +semi = remake(semi, + solver = DGSEM(3, flux_godunov, VolumeIntegralFluxDifferencing(flux_ec))) ode = semidiscretize(semi, (0.0, 0.5)) sol = solve(ode, SSPRK43(); ode_default_options()...) plot(sol) - # ## Package versions # These results were obtained using the following versions. @@ -222,4 +227,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/adding_nonconservative_equation.jl b/docs/literate/src/files/adding_nonconservative_equation.jl index b40e21fb11..798253210e 100644 --- a/docs/literate/src/files/adding_nonconservative_equation.jl +++ b/docs/literate/src/files/adding_nonconservative_equation.jl @@ -40,27 +40,28 @@ import Trixi: varnames, default_analysis_integrals, flux, max_abs_speed_naive, ## Since there is no native support for variable coefficients, we use two ## variables: one for the basic unknown `u` and another one for the coefficient `a` -struct NonconservativeLinearAdvectionEquation <: AbstractEquations{1 #= spatial dimension =#, - 2 #= two variables (u,a) =#} +struct NonconservativeLinearAdvectionEquation <: AbstractEquations{1, #= spatial dimension =# + 2} #= two variables (u,a) =# end -varnames(::typeof(cons2cons), ::NonconservativeLinearAdvectionEquation) = ("scalar", "advection_velocity") +function varnames(::typeof(cons2cons), ::NonconservativeLinearAdvectionEquation) + ("scalar", "advection_velocity") +end default_analysis_integrals(::NonconservativeLinearAdvectionEquation) = () - ## The conservative part of the flux is zero flux(u, orientation, equation::NonconservativeLinearAdvectionEquation) = zero(u) ## Calculate maximum wave speed for local Lax-Friedrichs-type dissipation -function max_abs_speed_naive(u_ll, u_rr, orientation::Integer, ::NonconservativeLinearAdvectionEquation) +function max_abs_speed_naive(u_ll, u_rr, orientation::Integer, + ::NonconservativeLinearAdvectionEquation) _, advection_velocity_ll = u_ll _, advection_velocity_rr = u_rr return max(abs(advection_velocity_ll), abs(advection_velocity_rr)) end - ## We use nonconservative terms have_nonconservative_terms(::NonconservativeLinearAdvectionEquation) = Trixi.True() @@ -73,7 +74,7 @@ have_nonconservative_terms(::NonconservativeLinearAdvectionEquation) = Trixi.Tru function flux_nonconservative(u_mine, u_other, orientation, equations::NonconservativeLinearAdvectionEquation) _, advection_velocity = u_mine - scalar, _ = u_other + scalar, _ = u_other return SVector(advection_velocity * scalar, zero(scalar)) end @@ -105,15 +106,15 @@ end ## Create a uniform mesh in 1D in the interval [-π, π] with periodic boundaries mesh = TreeMesh(-Float64(π), Float64(π), # min/max coordinates - initial_refinement_level=4, n_cells_max=10^4) + initial_refinement_level = 4, n_cells_max = 10^4) ## Create a DGSEM solver with polynomials of degree `polydeg` ## Remember to pass a tuple of the form `(conservative_flux, nonconservative_flux)` ## as `surface_flux` and `volume_flux` when working with nonconservative terms -volume_flux = (flux_central, flux_nonconservative) +volume_flux = (flux_central, flux_nonconservative) surface_flux = (flux_lax_friedrichs, flux_nonconservative) -solver = DGSEM(polydeg=3, surface_flux=surface_flux, - volume_integral=VolumeIntegralFluxDifferencing(volume_flux)) +solver = DGSEM(polydeg = 3, surface_flux = surface_flux, + volume_integral = VolumeIntegralFluxDifferencing(volume_flux)) ## Setup the spatial semidiscretization containing all ingredients semi = SemidiscretizationHyperbolic(mesh, equation, initial_condition_sine, solver) @@ -125,13 +126,13 @@ ode = semidiscretize(semi, tspan) ## Set up some standard callbacks summarizing the simulation setup and computing ## errors of the numerical solution summary_callback = SummaryCallback() -analysis_callback = AnalysisCallback(semi, interval=50) +analysis_callback = AnalysisCallback(semi, interval = 50) callbacks = CallbackSet(summary_callback, analysis_callback) ## OrdinaryDiffEq's `solve` method evolves the solution in time and executes ## the passed callbacks -sol = solve(ode, Tsit5(), abstol=1.0e-6, reltol=1.0e-6, - save_everystep=false, callback=callbacks) +sol = solve(ode, Tsit5(), abstol = 1.0e-6, reltol = 1.0e-6, + save_everystep = false, callback = callbacks) ## Print the timer summary summary_callback() @@ -152,7 +153,7 @@ error_1 = analysis_callback(sol).l2 |> first # simulation again. mesh = TreeMesh(-Float64(π), Float64(π), # min/max coordinates - initial_refinement_level=5, n_cells_max=10^4) + initial_refinement_level = 5, n_cells_max = 10^4) semi = SemidiscretizationHyperbolic(mesh, equation, initial_condition_sine, solver) @@ -160,24 +161,22 @@ tspan = (0.0, 1.0) ode = semidiscretize(semi, tspan); summary_callback = SummaryCallback() -analysis_callback = AnalysisCallback(semi, interval=50) +analysis_callback = AnalysisCallback(semi, interval = 50) callbacks = CallbackSet(summary_callback, analysis_callback); -sol = solve(ode, Tsit5(), abstol=1.0e-6, reltol=1.0e-6, - save_everystep=false, callback=callbacks); +sol = solve(ode, Tsit5(), abstol = 1.0e-6, reltol = 1.0e-6, + save_everystep = false, callback = callbacks); summary_callback() #nb #- error_2 = analysis_callback(sol).l2 |> first -@test isapprox(error_2, 1.860295931682964e-5, rtol=0.05) #src +@test isapprox(error_2, 1.860295931682964e-5, rtol = 0.05) #src #- error_1 / error_2 -@test isapprox(error_1 / error_2, 15.916970234784808, rtol=0.05) #src +@test isapprox(error_1 / error_2, 15.916970234784808, rtol = 0.05) #src # As expected, the new error is roughly reduced by a factor of 16, corresponding # to an experimental order of convergence of 4 (for polynomials of degree 3). - - # ## Summary of the code # Here is the complete code that we used (without the callbacks since these @@ -186,7 +185,6 @@ error_1 / error_2 # That ensures that we can re-create `struct`s defined therein without having to # restart Julia. - # Define new physics module NonconservativeLinearAdvection @@ -197,27 +195,28 @@ import Trixi: varnames, default_analysis_integrals, flux, max_abs_speed_naive, ## Since there is not yet native support for variable coefficients, we use two ## variables: one for the basic unknown `u` and another one for the coefficient `a` -struct NonconservativeLinearAdvectionEquation <: AbstractEquations{1 #= spatial dimension =#, - 2 #= two variables (u,a) =#} +struct NonconservativeLinearAdvectionEquation <: AbstractEquations{1, #= spatial dimension =# + 2} #= two variables (u,a) =# end -varnames(::typeof(cons2cons), ::NonconservativeLinearAdvectionEquation) = ("scalar", "advection_velocity") +function varnames(::typeof(cons2cons), ::NonconservativeLinearAdvectionEquation) + ("scalar", "advection_velocity") +end default_analysis_integrals(::NonconservativeLinearAdvectionEquation) = () - ## The conservative part of the flux is zero flux(u, orientation, equation::NonconservativeLinearAdvectionEquation) = zero(u) ## Calculate maximum wave speed for local Lax-Friedrichs-type dissipation -function max_abs_speed_naive(u_ll, u_rr, orientation::Integer, ::NonconservativeLinearAdvectionEquation) +function max_abs_speed_naive(u_ll, u_rr, orientation::Integer, + ::NonconservativeLinearAdvectionEquation) _, advection_velocity_ll = u_ll _, advection_velocity_rr = u_rr return max(abs(advection_velocity_ll), abs(advection_velocity_rr)) end - ## We use nonconservative terms have_nonconservative_terms(::NonconservativeLinearAdvectionEquation) = Trixi.True() @@ -230,15 +229,13 @@ have_nonconservative_terms(::NonconservativeLinearAdvectionEquation) = Trixi.Tru function flux_nonconservative(u_mine, u_other, orientation, equations::NonconservativeLinearAdvectionEquation) _, advection_velocity = u_mine - scalar, _ = u_other + scalar, _ = u_other return SVector(advection_velocity * scalar, zero(scalar)) end end # module - - ## Create a simulation setup import .NonconservativeLinearAdvection using Trixi @@ -248,7 +245,8 @@ equation = NonconservativeLinearAdvection.NonconservativeLinearAdvectionEquation ## You can derive the exact solution for this setup using the method of ## characteristics -function initial_condition_sine(x, t, equation::NonconservativeLinearAdvection.NonconservativeLinearAdvectionEquation) +function initial_condition_sine(x, t, + equation::NonconservativeLinearAdvection.NonconservativeLinearAdvectionEquation) x0 = -2 * atan(sqrt(3) * tan(sqrt(3) / 2 * t - atan(tan(x[1] / 2) / sqrt(3)))) scalar = sin(x0) advection_velocity = 2 + cos(x[1]) @@ -257,15 +255,15 @@ end ## Create a uniform mesh in 1D in the interval [-π, π] with periodic boundaries mesh = TreeMesh(-Float64(π), Float64(π), # min/max coordinates - initial_refinement_level=4, n_cells_max=10^4) + initial_refinement_level = 4, n_cells_max = 10^4) ## Create a DGSEM solver with polynomials of degree `polydeg` ## Remember to pass a tuple of the form `(conservative_flux, nonconservative_flux)` ## as `surface_flux` and `volume_flux` when working with nonconservative terms -volume_flux = (flux_central, NonconservativeLinearAdvection.flux_nonconservative) +volume_flux = (flux_central, NonconservativeLinearAdvection.flux_nonconservative) surface_flux = (flux_lax_friedrichs, NonconservativeLinearAdvection.flux_nonconservative) -solver = DGSEM(polydeg=3, surface_flux=surface_flux, - volume_integral=VolumeIntegralFluxDifferencing(volume_flux)) +solver = DGSEM(polydeg = 3, surface_flux = surface_flux, + volume_integral = VolumeIntegralFluxDifferencing(volume_flux)) ## Setup the spatial semidiscretization containing all ingredients semi = SemidiscretizationHyperbolic(mesh, equation, initial_condition_sine, solver) @@ -277,19 +275,18 @@ ode = semidiscretize(semi, tspan); ## Set up some standard callbacks summarizing the simulation setup and computing ## errors of the numerical solution summary_callback = SummaryCallback() -analysis_callback = AnalysisCallback(semi, interval=50) +analysis_callback = AnalysisCallback(semi, interval = 50) callbacks = CallbackSet(summary_callback, analysis_callback); ## OrdinaryDiffEq's `solve` method evolves the solution in time and executes ## the passed callbacks -sol = solve(ode, Tsit5(), abstol=1.0e-6, reltol=1.0e-6, - save_everystep=false); +sol = solve(ode, Tsit5(), abstol = 1.0e-6, reltol = 1.0e-6, + save_everystep = false); ## Plot the numerical solution at the final time using Plots: plot plot(sol); - # ## Package versions # These results were obtained using the following versions. @@ -299,4 +296,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/behind_the_scenes_simulation_setup.jl b/docs/literate/src/files/behind_the_scenes_simulation_setup.jl index c93660e9bc..ecb3c94c8d 100644 --- a/docs/literate/src/files/behind_the_scenes_simulation_setup.jl +++ b/docs/literate/src/files/behind_the_scenes_simulation_setup.jl @@ -62,7 +62,6 @@ semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergen # perform the necessary initialization steps. A brief description of the key sub-functions is # provided below. - # - `init_elements(leaf_cell_ids, mesh, equations, dg.basis, RealT, uEltype)` # The fundamental elements for approximating the solution are the leaf @@ -73,14 +72,12 @@ semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergen # coordinates, and maps the Gauss-Lobatto nodes from the 1D interval ``[-1, 1]`` onto each coordinate axis # of every element. - # ![elements_example](https://github.com/trixi-framework/Trixi.jl/assets/119304909/9f486670-b579-4e42-8697-439540c8bbb4) # The visualization of elements with nodes shown here includes spaces between elements, which do # not exist in reality. This spacing is included only for illustrative purposes to underscore the # separation of elements and the independent projection of nodes onto each element. - # - `init_interfaces(leaf_cell_ids, mesh, elements)` # At this point, the elements with nodes have been defined; however, they lack the necessary @@ -102,7 +99,6 @@ semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergen # ![interfaces_example](https://github.com/trixi-framework/Trixi.jl/assets/119304909/bc3b6b02-afbc-4371-aaf7-c7bdc5a6c540) - # - `init_mortars(leaf_cell_ids, mesh, elements, dg.mortar)` # Returning to the consideration of different sizes among adjacent elements, within the @@ -123,7 +119,6 @@ semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergen # ![mortars_example](https://github.com/trixi-framework/Trixi.jl/assets/119304909/43a95a60-3a31-4b1f-8724-14049e7a0481) - # - `init_boundaries(leaf_cell_ids, mesh, elements)` # In order to apply boundary conditions, it is necessary to identify the locations of the @@ -169,7 +164,6 @@ ode = semidiscretize(semi, (0.0, 1.0)); # The `semidiscretize` function involves a deep tree of subsequent calls, with the primary ones # explained below. - # - `allocate_coefficients(mesh, equations, solver, cache)` # To apply initial conditions, a data structure ("container") needs to be generated to store the @@ -198,7 +192,6 @@ ode = semidiscretize(semi, (0.0, 1.0)); # This is possible because, from a storage perspective, they share the same stored data, while # access to this data is provided in different ways. - # - `compute_coefficients!(u, initial_conditions, t, mesh::DG, equations, solver, cache)` # Now the variable `u`, intended to store solutions, has been allocated and wrapped, it is time diff --git a/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/SemidiscretizationHyperbolic_structure_figure.jl b/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/SemidiscretizationHyperbolic_structure_figure.jl index cae7b19d47..3066a0a515 100644 --- a/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/SemidiscretizationHyperbolic_structure_figure.jl +++ b/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/SemidiscretizationHyperbolic_structure_figure.jl @@ -1,64 +1,94 @@ using Plots -plot(Shape([(-2.3,4.5), (2.35,4.5), (2.35,2.5), (-2.3,2.5)]), linecolor="black", fillcolor="white", label=false,linewidth=2, size=(800,600), showaxis=false, grid=false, xlim=(-2.4,2.8), ylim=(-25,5.5)) -annotate!(2.3, 3.5, ("SemidiscretizationHyperbolic(mesh, equations, initial_conditions, solver; source_terms, +plot(Shape([(-2.3, 4.5), (2.35, 4.5), (2.35, 2.5), (-2.3, 2.5)]), linecolor = "black", + fillcolor = "white", label = false, linewidth = 2, size = (800, 600), showaxis = false, + grid = false, xlim = (-2.4, 2.8), ylim = (-25, 5.5)) +annotate!(2.3, 3.5, + ("SemidiscretizationHyperbolic(mesh, equations, initial_conditions, solver; source_terms, boundary_conditions, RealT, uEltype, initial_cache) ", 10, :black, :right)) -annotate!(-2.3, 1.5, ("creates and returns SemidiscretizationHyperbolic object, initialized using a mesh, equations, +annotate!(-2.3, 1.5, + ("creates and returns SemidiscretizationHyperbolic object, initialized using a mesh, equations, initial_conditions, boundary_conditions, source_terms, solver and cache", 9, :black, :left)) -plot!([-1.2,-1.2],[0.6,-2],arrow=true,color=:black,linewidth=2,label="") -plot!([-1.2,-1.4],[0.6,-2],arrow=true,color=:black,linewidth=2,label="") -plot!([-1.2,-1.],[0.6,-2],arrow=true,color=:black,linewidth=2,label="") +plot!([-1.2, -1.2], [0.6, -2], arrow = true, color = :black, linewidth = 2, label = "") +plot!([-1.2, -1.4], [0.6, -2], arrow = true, color = :black, linewidth = 2, label = "") +plot!([-1.2, -1.0], [0.6, -2], arrow = true, color = :black, linewidth = 2, label = "") annotate!(-1, -0.7, ("specialized for mesh and solver types", 9, :black, :left)) -plot!([1.25,1.25],[0.6,-2],arrow=true,color=:black,linewidth=2,label="") -plot!([1.25,1.05],[0.6,-2],arrow=true,color=:black,linewidth=2,label="") -plot!([1.25,1.45],[0.6,-2],arrow=true,color=:black,linewidth=2,label="") +plot!([1.25, 1.25], [0.6, -2], arrow = true, color = :black, linewidth = 2, label = "") +plot!([1.25, 1.05], [0.6, -2], arrow = true, color = :black, linewidth = 2, label = "") +plot!([1.25, 1.45], [0.6, -2], arrow = true, color = :black, linewidth = 2, label = "") annotate!(1.48, -0.7, ("specialized for mesh and boundary_conditions types", 9, :black, :left)) -plot!(Shape([(-2.3,-2), (-0.1,-2), (-0.1,-4), (-2.3,-4)]), linecolor="black", fillcolor="white", label=false,linewidth=2) +plot!(Shape([(-2.3, -2), (-0.1, -2), (-0.1, -4), (-2.3, -4)]), linecolor = "black", + fillcolor = "white", label = false, linewidth = 2) annotate!(-1.2, -3, ("create_cache(mesh::TreeMesh, equations, solver::Dg, RealT, uEltype)", 10, :black, :center)) -plot!([-2.22,-2.22],[-4,-22],arrow=false,color=:black,linewidth=2,label="") +plot!([-2.22, -2.22], [-4, -22], arrow = false, color = :black, linewidth = 2, label = "") -plot!(Shape([(-0.05,-2), (2.6,-2), (2.6,-4), (-0.05,-4)]), linecolor="black", fillcolor="white", label=false,linewidth=2) -annotate!(1.27, -3, ("digest_boundary_conditions(boundary_conditions, - mesh, solver, cache)", 10, :black, :center)) +plot!(Shape([(-0.05, -2), (2.6, -2), (2.6, -4), (-0.05, -4)]), linecolor = "black", + fillcolor = "white", label = false, linewidth = 2) +annotate!(1.27, -3, + ("digest_boundary_conditions(boundary_conditions, + mesh, solver, cache)", 10, :black, :center)) annotate!(2.6, -5, ("if necessary, converts passed boundary_conditions into a suitable form for processing by Trixi.jl", 9, :black, :right)) -plot!(Shape([(-2,-6), (-0.55,-6), (-0.55,-7.1), (-2,-7.1)]), linecolor="black", fillcolor="white", label=false,linewidth=2) +plot!(Shape([(-2, -6), (-0.55, -6), (-0.55, -7.1), (-2, -7.1)]), linecolor = "black", + fillcolor = "white", label = false, linewidth = 2) annotate!(-1.95, -6.5, ("local_leaf_cells(mesh.tree)", 10, :black, :left)) -annotate!(-2, -7.5, ("returns cells for which an element needs to be created (i.e. all leaf cells)", 9, :black, :left)) -plot!([-2.22,-2],[-6.5,-6.5],arrow=true,color=:black,linewidth=2,label="") +annotate!(-2, -7.5, + ("returns cells for which an element needs to be created (i.e. all leaf cells)", + 9, :black, :left)) +plot!([-2.22, -2], [-6.5, -6.5], arrow = true, color = :black, linewidth = 2, label = "") -plot!(Shape([(-2,-9), (1.73,-9), (1.73,-10.1), (-2,-10.1)]), linecolor="black", fillcolor="white", label=false,linewidth=2) -annotate!(-1.95, -9.5, ("init_elements(leaf_cell_ids, mesh, equations, dg.basis, RealT, uEltype)", 10, :black, :left)) -annotate!(-2, -10.5, ("creates and initializes elements, projects Gauss-Lobatto basis onto each of them", 9, :black, :left)) -plot!([-2.22,-2],[-9.5,-9.5],arrow=true,color=:black,linewidth=2,label="") +plot!(Shape([(-2, -9), (1.73, -9), (1.73, -10.1), (-2, -10.1)]), linecolor = "black", + fillcolor = "white", label = false, linewidth = 2) +annotate!(-1.95, -9.5, + ("init_elements(leaf_cell_ids, mesh, equations, dg.basis, RealT, uEltype)", 10, + :black, :left)) +annotate!(-2, -10.5, + ("creates and initializes elements, projects Gauss-Lobatto basis onto each of them", + 9, :black, :left)) +plot!([-2.22, -2], [-9.5, -9.5], arrow = true, color = :black, linewidth = 2, label = "") -plot!(Shape([(-2,-12), (0.4,-12), (0.4,-13.1), (-2,-13.1)]), linecolor="black", fillcolor="white", label=false,linewidth=2) -annotate!(-1.95, -12.5, ("init_interfaces(leaf_cell_ids, mesh, elements)", 10, :black, :left)) -annotate!(-2, -13.5, ("creates and initializes interfaces between each pair of adjacent elements of the same size", 9, :black, :left)) -plot!([-2.22,-2],[-12.5,-12.5],arrow=true,color=:black,linewidth=2,label="") +plot!(Shape([(-2, -12), (0.4, -12), (0.4, -13.1), (-2, -13.1)]), linecolor = "black", + fillcolor = "white", label = false, linewidth = 2) +annotate!(-1.95, -12.5, + ("init_interfaces(leaf_cell_ids, mesh, elements)", 10, :black, :left)) +annotate!(-2, -13.5, + ("creates and initializes interfaces between each pair of adjacent elements of the same size", + 9, :black, :left)) +plot!([-2.22, -2], [-12.5, -12.5], arrow = true, color = :black, linewidth = 2, label = "") -plot!(Shape([(-2,-15), (0.5,-15), (0.5,-16.1), (-2,-16.1)]), linecolor="black", fillcolor="white", label=false,linewidth=2) -annotate!(-1.95, -15.5, ("init_boundaries(leaf_cell_ids, mesh, elements)", 10, :black, :left)) -annotate!(-2, -17, ("creates and initializes boundaries, remembers each boundary element, as well as the coordinates of +plot!(Shape([(-2, -15), (0.5, -15), (0.5, -16.1), (-2, -16.1)]), linecolor = "black", + fillcolor = "white", label = false, linewidth = 2) +annotate!(-1.95, -15.5, + ("init_boundaries(leaf_cell_ids, mesh, elements)", 10, :black, :left)) +annotate!(-2, -17, + ("creates and initializes boundaries, remembers each boundary element, as well as the coordinates of each boundary node", 9, :black, :left)) -plot!([-2.22,-2],[-15.5,-15.5],arrow=true,color=:black,linewidth=2,label="") +plot!([-2.22, -2], [-15.5, -15.5], arrow = true, color = :black, linewidth = 2, label = "") -plot!(Shape([(-1.6,-18), (1.3,-18), (1.3,-19.1), (-1.6,-19.1)]), linecolor="black", fillcolor="white", label=false,linewidth=2) -annotate!(-1.55, -18.5, ("init_mortars(leaf_cell_ids, mesh, elements, dg.mortar)", 10, :black, :left)) -annotate!(-1.6, -20, ("creates and initializes mortars (type of interfaces) between each triple of adjacent coarsened +plot!(Shape([(-1.6, -18), (1.3, -18), (1.3, -19.1), (-1.6, -19.1)]), linecolor = "black", + fillcolor = "white", label = false, linewidth = 2) +annotate!(-1.55, -18.5, + ("init_mortars(leaf_cell_ids, mesh, elements, dg.mortar)", 10, :black, :left)) +annotate!(-1.6, -20, + ("creates and initializes mortars (type of interfaces) between each triple of adjacent coarsened and corresponding small elements", 9, :black, :left)) -plot!([-2.22,-1.6],[-18.5,-18.5],arrow=true,color=:black,linewidth=2,label="") +plot!([-2.22, -1.6], [-18.5, -18.5], arrow = true, color = :black, linewidth = 2, + label = "") annotate!(-2.15, -19, ("2D and 3D", 8, :black, :left)) -plot!(Shape([(-2,-21), (1.5,-21), (1.5,-23.1), (-2,-23.1)]), linecolor="black", fillcolor="white", label=false,linewidth=2) -annotate!(-1.95, -22, ("create_cache(mesh, equations, dg.volume_integral, dg, uEltype) +plot!(Shape([(-2, -21), (1.5, -21), (1.5, -23.1), (-2, -23.1)]), linecolor = "black", + fillcolor = "white", label = false, linewidth = 2) +annotate!(-1.95, -22, + ("create_cache(mesh, equations, dg.volume_integral, dg, uEltype) for 2D and 3D create_cache(mesh, equations, dg.mortar, uEltype)", 10, :black, :left)) -annotate!(-2, -23.5, ("add specialized parts of the cache required to compute the volume integral, etc.", 9, :black, :left)) -plot!([-2.22,-2],[-22,-22],arrow=true,color=:black,linewidth=2,label="") +annotate!(-2, -23.5, + ("add specialized parts of the cache required to compute the volume integral, etc.", + 9, :black, :left)) +plot!([-2.22, -2], [-22, -22], arrow = true, color = :black, linewidth = 2, label = "") -savefig("./SemidiscretizationHyperbolic") \ No newline at end of file +savefig("./SemidiscretizationHyperbolic") diff --git a/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/generate_boundary_figure.jl b/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/generate_boundary_figure.jl index 14475d2133..9083610cfc 100644 --- a/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/generate_boundary_figure.jl +++ b/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/generate_boundary_figure.jl @@ -1,190 +1,268 @@ using Plots function min(coordinates::Vector{Tuple{Float64, Float64}}, i) - min=coordinates[1][i] - for j in coordinates - if min>j[i] - min=j[i] + min = coordinates[1][i] + for j in coordinates + if min > j[i] + min = j[i] + end end - end - return min + return min end function max(coordinates::Vector{Tuple{Float64, Float64}}, i) - max=coordinates[1][i] - for j in coordinates - if maxj[i] - min=j[i] + min = coordinates[1][i] + for j in coordinates + if min > j[i] + min = j[i] + end end - end - return min + return min end function max(coordinates::Vector{Tuple{Float64, Float64}}, i) - max=coordinates[1][i] - for j in coordinates - if maxj[i] - min=j[i] + min = coordinates[1][i] + for j in coordinates + if min > j[i] + min = j[i] + end end - end - return min + return min end function max(coordinates::Vector{Tuple{Float64, Float64}}, i) - max=coordinates[1][i] - for j in coordinates - if maxj[i] - min=j[i] + min = coordinates[1][i] + for j in coordinates + if min > j[i] + min = j[i] + end end - end - return min + return min end function max(coordinates::Vector{Tuple{Float64, Float64}}, i) - max=coordinates[1][i] - for j in coordinates - if max begin - equations_inner = CompressibleEulerEquations2D(first(γ)) - semi_inner = Trixi.remake(semi, equations=equations_inner, uEltype=eltype(γ)) - Trixi.rhs!(du_ode, u0_ode, semi_inner, 0.0) -end, similar(u0_ode), [1.4]); # γ needs to be an `AbstractArray` + equations_inner = CompressibleEulerEquations2D(first(γ)) + semi_inner = Trixi.remake(semi, equations = equations_inner, + uEltype = eltype(γ)) + Trixi.rhs!(du_ode, u0_ode, semi_inner, 0.0) + end, similar(u0_ode), [1.4]); # γ needs to be an `AbstractArray` -round.(extrema(J), sigdigits=2) -@test round.(extrema(J), sigdigits=2) == (-220.0, 220.0) #src +round.(extrema(J), sigdigits = 2) +@test round.(extrema(J), sigdigits = 2) == (-220.0, 220.0) #src # Note that we create a semidiscretization `semi` at first to determine the state `u0_ode` around # which we want to perform the linearization. Next, we wrap the RHS evaluation inside a closure @@ -211,7 +210,6 @@ norm(J[1:4:end]) # Here, we used some knowledge about the internal memory layout of Trixi.jl, an array of structs # with the conserved variables as fastest-varying index in memory. - # ## Differentiating through a complete simulation # It is also possible to differentiate through a complete simulation. As an example, let's differentiate @@ -222,22 +220,23 @@ using Trixi, OrdinaryDiffEq, ForwardDiff, Plots function energy_at_final_time(k) # k is the wave number of the initial condition equations = LinearScalarAdvectionEquation2D(1.0, -0.3) - mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level=3, n_cells_max=10^4) + mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level = 3, + n_cells_max = 10^4) solver = DGSEM(3, flux_lax_friedrichs) initial_condition = (x, t, equation) -> begin - x_trans = Trixi.x_trans_periodic_2d(x - equation.advection_velocity * t) - return SVector(sinpi(k * sum(x_trans))) + x_trans = Trixi.x_trans_periodic_2d(x - equation.advection_velocity * t) + return SVector(sinpi(k * sum(x_trans))) end semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - uEltype=typeof(k)) + uEltype = typeof(k)) ode = semidiscretize(semi, (0.0, 1.0)) - sol = solve(ode, BS3(), save_everystep=false) + sol = solve(ode, BS3(), save_everystep = false) Trixi.integrate(energy_total, sol.u[end], semi) end -k_values = range(0.9, 1.1, length=101) +k_values = range(0.9, 1.1, length = 101) -plot(k_values, energy_at_final_time.(k_values), label="Energy") +plot(k_values, energy_at_final_time.(k_values), label = "Energy") # You see a plot of a curve that resembles a parabola with local maximum around `k = 1.0`. # Why's that? Well, the domain is fixed but the wave number changes. Thus, if the wave number is @@ -249,44 +248,45 @@ plot(k_values, energy_at_final_time.(k_values), label="Energy") # We can compute the discrete derivative of the energy at the final time with respect to the wave # number `k` as follows. -round(ForwardDiff.derivative(energy_at_final_time, 1.0), sigdigits=2) -@test round(ForwardDiff.derivative(energy_at_final_time, 1.0), sigdigits=2) == 1.4e-5 #src +round(ForwardDiff.derivative(energy_at_final_time, 1.0), sigdigits = 2) +@test round(ForwardDiff.derivative(energy_at_final_time, 1.0), sigdigits = 2) == 1.4e-5 #src # This is rather small and we can treat it as zero in comparison to the value of this derivative at # other wave numbers `k`. dk_values = ForwardDiff.derivative.((energy_at_final_time,), k_values); -plot(k_values, dk_values, label="Derivative") +plot(k_values, dk_values, label = "Derivative") # If you remember basic calculus, a sufficient condition for a local maximum is that the first derivative # vanishes and the second derivative is negative. We can also check this discretely. -second_derivative = round(ForwardDiff.derivative( - k -> Trixi.ForwardDiff.derivative(energy_at_final_time, k), 1.0), - sigdigits=2) +second_derivative = round(ForwardDiff.derivative(k -> Trixi.ForwardDiff.derivative(energy_at_final_time, + k), 1.0), + sigdigits = 2) @test second_derivative ≈ -0.9 #src # Having seen this application, let's break down what happens step by step. function energy_at_final_time(k) # k is the wave number of the initial condition equations = LinearScalarAdvectionEquation2D(1.0, -0.3) - mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level=3, n_cells_max=10^4) + mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level = 3, + n_cells_max = 10^4) solver = DGSEM(3, flux_lax_friedrichs) initial_condition = (x, t, equation) -> begin x_trans = Trixi.x_trans_periodic_2d(x - equation.advection_velocity * t) return SVector(sinpi(k * sum(x_trans))) end semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - uEltype=typeof(k)) + uEltype = typeof(k)) ode = semidiscretize(semi, (0.0, 1.0)) - sol = solve(ode, BS3(), save_everystep=false) + sol = solve(ode, BS3(), save_everystep = false) Trixi.integrate(energy_total, sol.u[end], semi) end k = 1.0 -round(ForwardDiff.derivative(energy_at_final_time, k), sigdigits=2) -@test round(ForwardDiff.derivative(energy_at_final_time, 1.0), sigdigits=2) == 1.4e-5 #src +round(ForwardDiff.derivative(energy_at_final_time, k), sigdigits = 2) +@test round(ForwardDiff.derivative(energy_at_final_time, 1.0), sigdigits = 2) == 1.4e-5 #src # When calling `ForwardDiff.derivative(energy_at_final_time, k)` with `k=1.0`, ForwardDiff.jl # will basically use the chain rule and known derivatives of existing basic functions @@ -300,7 +300,7 @@ round(ForwardDiff.derivative(energy_at_final_time, k), sigdigits=2) # The first step in this example creates some basic ingredients of our simulation. equations = LinearScalarAdvectionEquation2D(1.0, -0.3) -mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level=3, n_cells_max=10^4) +mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level = 3, n_cells_max = 10^4) solver = DGSEM(3, flux_lax_friedrichs); # These do not have internal caches storing intermediate values of the numerical @@ -325,19 +325,18 @@ end; # need to tell Trixi.jl to allow `ForwardDiff.Dual` numbers in these caches. That's what # the keyword argument `uEltype=typeof(k)` in semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - uEltype=typeof(k)); + uEltype = typeof(k)); # does. This is basically the only part where you need to modify your standard Trixi.jl # code to enable automatic differentiation. From there on, the remaining steps ode = semidiscretize(semi, (0.0, 1.0)) -sol = solve(ode, BS3(), save_everystep=false) -round(Trixi.integrate(energy_total, sol.u[end], semi), sigdigits=5) -@test round(Trixi.integrate(energy_total, sol.u[end], semi), sigdigits=5) == 0.24986 #src +sol = solve(ode, BS3(), save_everystep = false) +round(Trixi.integrate(energy_total, sol.u[end], semi), sigdigits = 5) +@test round(Trixi.integrate(energy_total, sol.u[end], semi), sigdigits = 5) == 0.24986 #src # do not need any modifications since they are sufficiently generic (and enough effort # has been spend to allow general types inside these calls). - # ## Propagating errors using Measurements.jl # [![Error bars by Randall Munroe](https://imgs.xkcd.com/comics/error_bars.png)](https://xkcd.com/2110/) @@ -354,16 +353,16 @@ using Trixi, OrdinaryDiffEq, Measurements, Plots, LaTeXStrings equations = LinearScalarAdvectionEquation1D(1.0 ± 0.1) -mesh = TreeMesh((-1.0,), (1.0,), n_cells_max=10^5, initial_refinement_level=5) +mesh = TreeMesh((-1.0,), (1.0,), n_cells_max = 10^5, initial_refinement_level = 5) solver = DGSEM(3) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergence_test, - solver, uEltype=Measurement{Float64}) + solver, uEltype = Measurement{Float64}) ode = semidiscretize(semi, (0.0, 1.5)) -sol = solve(ode, BS3(), save_everystep=false); +sol = solve(ode, BS3(), save_everystep = false); plot(sol) @@ -378,7 +377,6 @@ plot(sol) # All this is possible due to allowing generic types and having good abstractions # in Julia that allow packages to work together seamlessly. - # ## Finite difference approximations # Trixi.jl provides the convenience function [`jacobian_fd`](@ref) to approximate the Jacobian @@ -390,7 +388,7 @@ equations = CompressibleEulerEquations2D(1.4) solver = DGSEM(3, flux_central) -mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level=2, n_cells_max=10^5) +mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level = 2, n_cells_max = 10^5) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_density_wave, solver) @@ -403,7 +401,6 @@ relative_difference = norm(J_fd - J_ad) / size(J_fd, 1) # This discrepancy is of the expected order of magnitude for central finite difference approximations. - # ## Linear systems # When a linear PDE is discretized using a linear scheme such as a standard DG method, @@ -426,9 +423,10 @@ equations = LinearScalarAdvectionEquation2D(1.0, -0.3) solver = DGSEM(3, flux_lax_friedrichs) -mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level=2, n_cells_max=10^5) +mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level = 2, n_cells_max = 10^5) -semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergence_test, solver) +semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergence_test, + solver) A, b = linear_structure(semi) @@ -447,7 +445,6 @@ scatter(real.(λ), imag.(λ)) relative_maximum = maximum(real, λ) / maximum(abs, λ) @test relative_maximum < 1.0e-15 #src - # ## Package versions # These results were obtained using the following versions. @@ -457,4 +454,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots", "ForwardDiff"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/first_steps/create_first_setup.jl b/docs/literate/src/files/first_steps/create_first_setup.jl index ae78a6a154..6b5b52a87d 100644 --- a/docs/literate/src/files/first_steps/create_first_setup.jl +++ b/docs/literate/src/files/first_steps/create_first_setup.jl @@ -60,7 +60,7 @@ equations = LinearScalarAdvectionEquation2D(advection_velocity) # All minimum and all maximum coordinates must be combined into `Tuples`. coordinates_min = (-1.0, -1.0) -coordinates_max = ( 1.0, 1.0) +coordinates_max = (1.0, 1.0) mesh = TreeMesh(coordinates_min, coordinates_max, initial_refinement_level = 4, n_cells_max = 30_000) @@ -72,7 +72,7 @@ mesh = TreeMesh(coordinates_min, coordinates_max, # in the weak formulation `DGSEM` initializes the surface flux as `flux_central` and uses the physical flux for # the volume integral. -solver = DGSEM(polydeg=3) +solver = DGSEM(polydeg = 3) # Now we need to define an initial condition for our problem. All the already implemented # initial conditions for [`LinearScalarAdvectionEquation2D`](@ref) can be found in @@ -108,7 +108,7 @@ initial_condition = initial_condition_sinpi # equation itself as arguments and returns the source term as a static vector `SVector`. function source_term_exp_sinpi(u, x, t, equations::LinearScalarAdvectionEquation2D) - u = - 2 * exp(-t) * sinpi(2*(x[1] - t)) * sinpi(2*(x[2] - t)) + u = -2 * exp(-t) * sinpi(2 * (x[1] - t)) * sinpi(2 * (x[2] - t)) return SVector(u) end @@ -182,7 +182,8 @@ save_restart = SaveRestartCallback(interval = 100, save_final_restart = true) # Create a `CallbackSet` to collect all callbacks so that they can be passed to the `solve` # function. -callbacks = CallbackSet(summary_callback, analysis_callback, alive_callback, stepsize_callback, +callbacks = CallbackSet(summary_callback, analysis_callback, alive_callback, + stepsize_callback, save_solution, save_restart); # The last step is to choose the time integration method. OrdinaryDiffEq.jl defines a wide range of @@ -203,14 +204,12 @@ summary_callback() # Now you can plot the solution as shown below, analyze it and improve the stability, accuracy or # efficiency of your setup. - # ## Visualize the solution # In the previous part of the tutorial, we calculated the final solution of the given problem, now we want # to visualize it. A more detailed explanation of visualization methods can be found in the section # [Visualization](@ref visualization). - # ### Using Plots.jl # The first option is to use the [Plots.jl](https://github.com/JuliaPlots/Plots.jl) package @@ -243,7 +242,6 @@ plot(pd["scalar"]) plot!(getmesh(pd)) - # ### Using Trixi2Vtk.jl # Another way to visualize a solution is to extract it from a saved HDF5 file. After we used the @@ -265,7 +263,7 @@ plot!(getmesh(pd)) # `out` folder. using Trixi2Vtk -trixi2vtk(joinpath("out", "solution_000032.h5"), output_directory="out") +trixi2vtk(joinpath("out", "solution_000032.h5"), output_directory = "out") # Now two files `solution_000032.vtu` and `solution_000032_celldata.vtu` have been generated in the # `out` folder. The first one contains all the information for visualizing the solution, the @@ -293,4 +291,4 @@ trixi2vtk(joinpath("out", "solution_000032.h5"), output_directory="out") # Trixi.jl. If you have an interest in contributing to Trixi.jl as a developer, refer to the third # part of the introduction titled [Changing Trixi.jl itself](@ref changing_trixi). -Sys.rm("out"; recursive=true, force=true) #hide #md \ No newline at end of file +Sys.rm("out"; recursive = true, force = true) #hide #md diff --git a/docs/literate/src/files/first_steps/getting_started.jl b/docs/literate/src/files/first_steps/getting_started.jl index 80ea78b51f..ae0983391f 100644 --- a/docs/literate/src/files/first_steps/getting_started.jl +++ b/docs/literate/src/files/first_steps/getting_started.jl @@ -14,7 +14,6 @@ # - [Getting an existing setup file](@ref Getting-an-existing-setup-file) # - [Modifying an existing setup](@ref Modifying-an-existing-setup) - # ## Julia installation # Trixi.jl is compatible with the latest stable release of Julia. Additional details regarding Julia @@ -24,7 +23,6 @@ # MacOS provided below. In the event of any issues during the installation process, please consult # the official [Julia installation instruction](https://julialang.org/downloads/). - # ### Windows # - Open a terminal by pressing `Win+r` and entering `cmd` in the opened window. @@ -39,7 +37,6 @@ # ``` # To exit Julia, execute `exit()` or press `Ctrl+d`. - # ### Linux and MacOS # - To install Julia, run the following command in a terminal: @@ -59,7 +56,6 @@ # ``` # To exit Julia, execute `exit()` or press `Ctrl+d`. - # ## Trixi.jl installation # Trixi.jl and its related tools are registered Julia packages, thus their installation @@ -84,10 +80,8 @@ # integration schemes used by Trixi.jl and [Plots.jl](https://github.com/JuliaPlots/Plots.jl) # can be used to directly visualize Trixi.jl results from the Julia REPL. - # ## Usage - # ### Running a simulation # To get you started, Trixi.jl has a large set @@ -147,7 +141,7 @@ # trixi_include(joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl")) # ``` using Trixi, OrdinaryDiffEq #hide #md -trixi_include(@__MODULE__,joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl")) #hide #md +trixi_include(@__MODULE__, joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl")) #hide #md # The output contains a recap of the setup and various information about the course of the simulation. # For instance, the solution was approximated over the [`TreeMesh`](@ref) with 1024 effective cells using @@ -166,7 +160,6 @@ trixi_include(@__MODULE__,joinpath(examples_dir(), "tree_2d_dgsem", "elixir_eule using Plots plot(sol) - # ### Getting an existing setup file # To obtain a list of all Trixi.jl elixirs execute @@ -188,7 +181,6 @@ get_examples() # (or `Save Link As...`). # - Choose a folder and save the file. - # ### Modifying an existing setup # As an example, we will change the initial condition for calculations that occur in @@ -214,8 +206,8 @@ function initial_condition_density_waves(x, t, equations::CompressibleEulerEquat v2 = 0.2 # velocity along y-axis rho = 1.0 + 0.98 * sinpi(sum(x) - t * (v1 + v2)) # density wave profile p = 20 # pressure - rho_e = p / (equations.gamma - 1) + 1/2 * rho * (v1^2 + v2^2) - return SVector(rho, rho*v1, rho*v2, rho_e) + rho_e = p / (equations.gamma - 1) + 1 / 2 * rho * (v1^2 + v2^2) + return SVector(rho, rho * v1, rho * v2, rho_e) end initial_condition = initial_condition_density_waves nothing; #hide #md @@ -231,13 +223,13 @@ nothing; #hide #md # Then you will obtain a new solution from running the simulation with a different initial # condition. -trixi_include(@__MODULE__,joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl"), #hide #md - initial_condition=initial_condition) #hide #md +trixi_include(@__MODULE__, joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl"), #hide #md + initial_condition = initial_condition) #hide #md pd = PlotData2D(sol) #hide #md p1 = plot(pd["rho"]) #hide #md -p2 = plot(pd["v1"], clim=(0.05, 0.15)) #hide #md -p3 = plot(pd["v2"], clim=(0.15, 0.25)) #hide #md -p4 = plot(pd["p"], clim=(10, 30)) #hide #md +p2 = plot(pd["v1"], clim = (0.05, 0.15)) #hide #md +p3 = plot(pd["v2"], clim = (0.15, 0.25)) #hide #md +p4 = plot(pd["p"], clim = (10, 30)) #hide #md plot(p1, p2, p3, p4) #hide #md # To get exactly the same picture execute the following. @@ -256,4 +248,4 @@ plot(p1, p2, p3, p4) #hide #md # further details on setting up a new simulation with Trixi.jl, refer to the second part of # the introduction titled [Create your first setup](@ref create_first_setup). -Sys.rm("out"; recursive=true, force=true) #hide #md \ No newline at end of file +Sys.rm("out"; recursive = true, force = true) #hide #md diff --git a/docs/literate/src/files/hohqmesh_tutorial.jl b/docs/literate/src/files/hohqmesh_tutorial.jl index dd81f47951..8b4b592516 100644 --- a/docs/literate/src/files/hohqmesh_tutorial.jl +++ b/docs/literate/src/files/hohqmesh_tutorial.jl @@ -36,8 +36,8 @@ using Trixi rm("out", force = true, recursive = true) #hide #md -redirect_stdio(stdout=devnull, stderr=devnull) do # code that prints annoying stuff we don't want to see here #hide #md -trixi_include(default_example_unstructured()) +redirect_stdio(stdout = devnull, stderr = devnull) do # code that prints annoying stuff we don't want to see here #hide #md + trixi_include(default_example_unstructured()) end #hide #md # This will compute a smooth, manufactured solution test case for the 2D compressible Euler equations @@ -53,8 +53,8 @@ end #hide #md # To convert the HDF5-formatted `.h5` output file(s) from Trixi.jl into VTK format execute the following using Trixi2Vtk -redirect_stdio(stdout=devnull, stderr=devnull) do # code that prints annoying stuff we don't want to see here #hide #md -trixi2vtk("out/solution_000180.h5", output_directory="out") +redirect_stdio(stdout = devnull, stderr = devnull) do # code that prints annoying stuff we don't want to see here #hide #md + trixi2vtk("out/solution_000180.h5", output_directory = "out") end #hide #md # Note this step takes about 15-30 seconds as the package `Trixi2Vtk` must be precompiled and executed for the first time @@ -63,8 +63,8 @@ end #hide #md # where the new files will be saved; it defaults to the current directory. (2) Specifying a higher number of # visualization nodes. For instance, if we want to use 12 uniformly spaced nodes for visualization we can execute -redirect_stdio(stdout=devnull, stderr=devnull) do # code that prints annoying stuff we don't want to see here #hide #md -trixi2vtk("out/solution_000180.h5", output_directory="out", nvisnodes=12) +redirect_stdio(stdout = devnull, stderr = devnull) do # code that prints annoying stuff we don't want to see here #hide #md + trixi2vtk("out/solution_000180.h5", output_directory = "out", nvisnodes = 12) end #hide #md # By default `trixi2vtk` sets `nvisnodes` to be the same as the number of nodes specified in @@ -72,8 +72,8 @@ end #hide #md # Finally, if you want to convert all the solution files to VTK execute -redirect_stdio(stdout=devnull, stderr=devnull) do # code that prints annoying stuff we don't want to see here #hide #md -trixi2vtk("out/solution_000*.h5", output_directory="out", nvisnodes=12) +redirect_stdio(stdout = devnull, stderr = devnull) do # code that prints annoying stuff we don't want to see here #hide #md + trixi2vtk("out/solution_000*.h5", output_directory = "out", nvisnodes = 12) end #hide #md # then it is possible to open the `.pvd` file with ParaView and create a video of the simulation. @@ -95,64 +95,64 @@ end #hide #md # The associated `ice_cream_straight_sides.control` file is created below. open("out/ice_cream_straight_sides.control", "w") do io - println(io, raw""" -\begin{CONTROL_INPUT} - \begin{RUN_PARAMETERS} - mesh file name = ice_cream_straight_sides.mesh - plot file name = ice_cream_straight_sides.tec - stats file name = none - mesh file format = ISM-v2 - polynomial order = 4 - plot file format = skeleton - \end{RUN_PARAMETERS} - - \begin{BACKGROUND_GRID} - x0 = [-8.0, -8.0, 0.0] - dx = [1.0, 1.0, 0.0] - N = [16,16,1] - \end{BACKGROUND_GRID} - - \begin{SPRING_SMOOTHER} - smoothing = ON - smoothing type = LinearAndCrossBarSpring - number of iterations = 25 - \end{SPRING_SMOOTHER} - -\end{CONTROL_INPUT} - -\begin{MODEL} - - \begin{INNER_BOUNDARIES} - - \begin{CHAIN} - name = IceCreamCone - \begin{END_POINTS_LINE} - name = LeftSlant - xStart = [-2.0, 1.0, 0.0] - xEnd = [ 0.0, -3.0, 0.0] - \end{END_POINTS_LINE} - - \begin{END_POINTS_LINE} - name = RightSlant - xStart = [ 0.0, -3.0, 0.0] - xEnd = [ 2.0, 1.0, 0.0] - \end{END_POINTS_LINE} - - \begin{CIRCULAR_ARC} - name = IceCream - units = degrees - center = [ 0.0, 1.0, 0.0] - radius = 2.0 - start angle = 0.0 - end angle = 180.0 - \end{CIRCULAR_ARC} - \end{CHAIN} - - \end{INNER_BOUNDARIES} - -\end{MODEL} -\end{FILE} -""") + println(io, raw""" + \begin{CONTROL_INPUT} + \begin{RUN_PARAMETERS} + mesh file name = ice_cream_straight_sides.mesh + plot file name = ice_cream_straight_sides.tec + stats file name = none + mesh file format = ISM-v2 + polynomial order = 4 + plot file format = skeleton + \end{RUN_PARAMETERS} + + \begin{BACKGROUND_GRID} + x0 = [-8.0, -8.0, 0.0] + dx = [1.0, 1.0, 0.0] + N = [16,16,1] + \end{BACKGROUND_GRID} + + \begin{SPRING_SMOOTHER} + smoothing = ON + smoothing type = LinearAndCrossBarSpring + number of iterations = 25 + \end{SPRING_SMOOTHER} + + \end{CONTROL_INPUT} + + \begin{MODEL} + + \begin{INNER_BOUNDARIES} + + \begin{CHAIN} + name = IceCreamCone + \begin{END_POINTS_LINE} + name = LeftSlant + xStart = [-2.0, 1.0, 0.0] + xEnd = [ 0.0, -3.0, 0.0] + \end{END_POINTS_LINE} + + \begin{END_POINTS_LINE} + name = RightSlant + xStart = [ 0.0, -3.0, 0.0] + xEnd = [ 2.0, 1.0, 0.0] + \end{END_POINTS_LINE} + + \begin{CIRCULAR_ARC} + name = IceCream + units = degrees + center = [ 0.0, 1.0, 0.0] + radius = 2.0 + start angle = 0.0 + end angle = 180.0 + \end{CIRCULAR_ARC} + \end{CHAIN} + + \end{INNER_BOUNDARIES} + + \end{MODEL} + \end{FILE} + """) end # The first three blocks of information are wrapped within a `CONTROL_INPUT` environment block as they define the @@ -305,18 +305,18 @@ equations = CompressibleEulerEquations2D(1.4) # set gas gamma = 1.4 ## freestream flow state with Ma_inf = 0.3 @inline function uniform_flow_state(x, t, equations::CompressibleEulerEquations2D) - ## set the freestream flow parameters - rho_freestream = 1.0 - u_freestream = 0.3 - p_freestream = inv(equations.gamma) + ## set the freestream flow parameters + rho_freestream = 1.0 + u_freestream = 0.3 + p_freestream = inv(equations.gamma) - theta = 0.0 # zero angle of attack - si, co = sincos(theta) - v1 = u_freestream * co - v2 = u_freestream * si + theta = 0.0 # zero angle of attack + si, co = sincos(theta) + v1 = u_freestream * co + v2 = u_freestream * si - prim = SVector(rho_freestream, v1, v2, p_freestream) - return prim2cons(prim, equations) + prim = SVector(rho_freestream, v1, v2, p_freestream) + return prim2cons(prim, equations) end ## initial condition @@ -326,13 +326,13 @@ initial_condition = uniform_flow_state boundary_condition_uniform_flow = BoundaryConditionDirichlet(uniform_flow_state) ## boundary condition dictionary -boundary_conditions = Dict( :Bottom => boundary_condition_uniform_flow, - :Top => boundary_condition_uniform_flow, - :Right => boundary_condition_uniform_flow, - :Left => boundary_condition_uniform_flow, - :LeftSlant => boundary_condition_slip_wall, - :RightSlant => boundary_condition_slip_wall, - :IceCream => boundary_condition_slip_wall ); +boundary_conditions = Dict(:Bottom => boundary_condition_uniform_flow, + :Top => boundary_condition_uniform_flow, + :Right => boundary_condition_uniform_flow, + :Left => boundary_condition_uniform_flow, + :LeftSlant => boundary_condition_slip_wall, + :RightSlant => boundary_condition_slip_wall, + :IceCream => boundary_condition_slip_wall); ## DGSEM solver. ## 1) polydeg must be >= the polynomial order set in the HOHQMesh control file to guarantee @@ -340,8 +340,8 @@ boundary_conditions = Dict( :Bottom => boundary_condition_uniform_flow, ## 2) VolumeIntegralFluxDifferencing with central volume flux is activated ## for dealiasing volume_flux = flux_ranocha -solver = DGSEM(polydeg=4, surface_flux=flux_hll, - volume_integral=VolumeIntegralFluxDifferencing(volume_flux)) +solver = DGSEM(polydeg = 4, surface_flux = flux_hll, + volume_integral = VolumeIntegralFluxDifferencing(volume_flux)) ## create the unstructured mesh from your mesh file mesh_file = joinpath("out", "ice_cream_straight_sides.mesh") @@ -349,29 +349,28 @@ mesh = UnstructuredMesh2D(mesh_file) ## Create semidiscretization with all spatial discretization-related components semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - boundary_conditions=boundary_conditions) + boundary_conditions = boundary_conditions) ## Create ODE problem from semidiscretization with time span from 0.0 to 2.0 tspan = (0.0, 2.0) ode = semidiscretize(semi, tspan) - ## Create the callbacks to output solution files and adapt the time step summary_callback = SummaryCallback() -save_solution = SaveSolutionCallback(interval=10, - save_initial_solution=true, - save_final_solution=true) -stepsize_callback = StepsizeCallback(cfl=1.0) +save_solution = SaveSolutionCallback(interval = 10, + save_initial_solution = true, + save_final_solution = true) +stepsize_callback = StepsizeCallback(cfl = 1.0) callbacks = CallbackSet(summary_callback, save_solution, stepsize_callback) -redirect_stdio(stdout=devnull, stderr=devnull) do # code that prints annoying stuff we don't want to see here #hide #md -## Evolve ODE problem in time using `solve` from OrdinaryDiffEq -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() +redirect_stdio(stdout = devnull, stderr = devnull) do # code that prints annoying stuff we don't want to see here #hide #md + ## Evolve ODE problem in time using `solve` from OrdinaryDiffEq + 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() end #hide #md # Visualization of the solution is carried out in a similar way as above. That is, one converts the `.h5` @@ -389,72 +388,72 @@ end #hide #md # We create the new control file `ice_cream_curved_sides.control` file below and will then highlight the # major differences compared to `ice_cream_straight_sides.control`. open("out/ice_cream_curved_sides.control", "w") do io - println(io, raw""" -\begin{CONTROL_INPUT} - \begin{RUN_PARAMETERS} - mesh file name = ice_cream_curved_sides.mesh - plot file name = ice_cream_curved_sides.tec - stats file name = none - mesh file format = ISM-v2 - polynomial order = 4 - plot file format = skeleton - \end{RUN_PARAMETERS} - - \begin{BACKGROUND_GRID} - background grid size = [1.0, 1.0, 0.0] - \end{BACKGROUND_GRID} - - \begin{SPRING_SMOOTHER} - smoothing = ON - smoothing type = LinearAndCrossBarSpring - number of iterations = 25 - \end{SPRING_SMOOTHER} - -\end{CONTROL_INPUT} - -\begin{MODEL} - - \begin{OUTER_BOUNDARY} - \begin{PARAMETRIC_EQUATION_CURVE} - name = OuterCircle - xEqn = x(t) = 8.0*sin(2.0*pi*t) - yEqn = y(t) = 8.0*cos(2.0*pi*t) - zEqn = z(t) = 0.0 - \end{PARAMETRIC_EQUATION_CURVE} - - \end{OUTER_BOUNDARY} - - \begin{INNER_BOUNDARIES} - - \begin{CHAIN} - name = IceCreamCone - \begin{END_POINTS_LINE} - name = LeftSlant - xStart = [-2.0, 1.0, 0.0] - xEnd = [ 0.0, -3.0, 0.0] - \end{END_POINTS_LINE} - - \begin{END_POINTS_LINE} - name = RightSlant - xStart = [ 0.0, -3.0, 0.0] - xEnd = [ 2.0, 1.0, 0.0] - \end{END_POINTS_LINE} - - \begin{CIRCULAR_ARC} - name = IceCream - units = degrees - center = [ 0.0, 1.0, 0.0] - radius = 2.0 - start angle = 0.0 - end angle = 180.0 - \end{CIRCULAR_ARC} - \end{CHAIN} - - \end{INNER_BOUNDARIES} - -\end{MODEL} -\end{FILE} -""") + println(io, raw""" + \begin{CONTROL_INPUT} + \begin{RUN_PARAMETERS} + mesh file name = ice_cream_curved_sides.mesh + plot file name = ice_cream_curved_sides.tec + stats file name = none + mesh file format = ISM-v2 + polynomial order = 4 + plot file format = skeleton + \end{RUN_PARAMETERS} + + \begin{BACKGROUND_GRID} + background grid size = [1.0, 1.0, 0.0] + \end{BACKGROUND_GRID} + + \begin{SPRING_SMOOTHER} + smoothing = ON + smoothing type = LinearAndCrossBarSpring + number of iterations = 25 + \end{SPRING_SMOOTHER} + + \end{CONTROL_INPUT} + + \begin{MODEL} + + \begin{OUTER_BOUNDARY} + \begin{PARAMETRIC_EQUATION_CURVE} + name = OuterCircle + xEqn = x(t) = 8.0*sin(2.0*pi*t) + yEqn = y(t) = 8.0*cos(2.0*pi*t) + zEqn = z(t) = 0.0 + \end{PARAMETRIC_EQUATION_CURVE} + + \end{OUTER_BOUNDARY} + + \begin{INNER_BOUNDARIES} + + \begin{CHAIN} + name = IceCreamCone + \begin{END_POINTS_LINE} + name = LeftSlant + xStart = [-2.0, 1.0, 0.0] + xEnd = [ 0.0, -3.0, 0.0] + \end{END_POINTS_LINE} + + \begin{END_POINTS_LINE} + name = RightSlant + xStart = [ 0.0, -3.0, 0.0] + xEnd = [ 2.0, 1.0, 0.0] + \end{END_POINTS_LINE} + + \begin{CIRCULAR_ARC} + name = IceCream + units = degrees + center = [ 0.0, 1.0, 0.0] + radius = 2.0 + start angle = 0.0 + end angle = 180.0 + \end{CIRCULAR_ARC} + \end{CHAIN} + + \end{INNER_BOUNDARIES} + + \end{MODEL} + \end{FILE} + """) end # The first alteration is that we have altered the second block of information @@ -501,10 +500,10 @@ output = generate_mesh(control_file); # dictionary because we now have a boundary named `OuterCircle` instead of four edges of a bounding box. ## boundary condition dictionary -boundary_conditions = Dict( :OuterCircle => boundary_condition_uniform_flow, - :LeftSlant => boundary_condition_slip_wall, - :RightSlant => boundary_condition_slip_wall, - :IceCream => boundary_condition_slip_wall ); +boundary_conditions = Dict(:OuterCircle => boundary_condition_uniform_flow, + :LeftSlant => boundary_condition_slip_wall, + :RightSlant => boundary_condition_slip_wall, + :IceCream => boundary_condition_slip_wall); # Also, we must update the construction of the mesh from our new mesh file `ice_cream_curved_sides.mesh` that # is located in the `out` folder. @@ -513,12 +512,10 @@ boundary_conditions = Dict( :OuterCircle => boundary_condition_uniform_flow, mesh_file = joinpath("out", "ice_cream_curved_sides.mesh") mesh = UnstructuredMesh2D(mesh_file); - # We can then post-process the solution file at the final time on the new mesh with `Trixi2Vtk` and visualize with ParaView. # ![simulation_curved_sides](https://user-images.githubusercontent.com/25242486/129733924-778795c1-9119-419a-8b89-bcbe13e33cd7.png) - # ## Setting up a simulation with AMR via `P4estMesh` # The above explained mesh file format of `ISM-V2` only works with `UnstructuredMesh2D` and so does # not support AMR. On the other hand, the mesh type [`P4estMesh`](@ref) allows AMR. The mesh @@ -568,7 +565,6 @@ mesh = UnstructuredMesh2D(mesh_file); # ![simulation_straight_sides_p4est_amr](https://user-images.githubusercontent.com/74359358/168049930-8abce6ac-cd47-4d04-b40b-0fa459bbd98d.png) - # ## Package versions # These results were obtained using the following versions. @@ -578,4 +574,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots", "Trixi2Vtk", "HOHQMesh"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/non_periodic_boundaries.jl b/docs/literate/src/files/non_periodic_boundaries.jl index 8f0e320dfd..8312f9e64a 100644 --- a/docs/literate/src/files/non_periodic_boundaries.jl +++ b/docs/literate/src/files/non_periodic_boundaries.jl @@ -27,7 +27,6 @@ # where `x` specifies the spatial coordinates, `t` is the current time, and `equations` is the # corresponding system of equations. - # We want to give a short example for a simulation with such a Dirichlet BC. # Consider the one-dimensional linear advection equation with domain $\Omega=[0, 2]$ and a constant @@ -41,7 +40,8 @@ initial_condition_zero(x, t, equation::LinearScalarAdvectionEquation1D) = SVecto initial_condition = initial_condition_zero using Plots -plot(x -> sum(initial_condition(x, 0.0, equations)), label="initial condition", ylim=(-1.5, 1.5)) +plot(x -> sum(initial_condition(x, 0.0, equations)), label = "initial condition", + ylim = (-1.5, 1.5)) # Using an advection velocity of `1.0` and the (local) Lax-Friedrichs/Rusanov flux # [`FluxLaxFriedrichs`](@ref) as a numerical surface flux, we are able to create an inflow boundary @@ -59,10 +59,10 @@ end boundary_condition = boundary_condition_sine_sector # We set the BC in negative and positive x-direction. -boundary_conditions = (x_neg=BoundaryConditionDirichlet(boundary_condition), - x_pos=BoundaryConditionDirichlet(boundary_condition)) +boundary_conditions = (x_neg = BoundaryConditionDirichlet(boundary_condition), + x_pos = BoundaryConditionDirichlet(boundary_condition)) #- -solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) +solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) coordinates_min = (0.0,) coordinates_max = (2.0,) @@ -70,41 +70,41 @@ coordinates_max = (2.0,) # For the mesh type `TreeMesh` the parameter `periodicity` must be set to `false` in the # corresponding direction. mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level=4, - n_cells_max=10_000, - periodicity=false) - + initial_refinement_level = 4, + n_cells_max = 10_000, + periodicity = false) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - boundary_conditions=boundary_conditions) + boundary_conditions = boundary_conditions) tspan = (0.0, 6.0) ode = semidiscretize(semi, tspan) -analysis_callback = AnalysisCallback(semi, interval=100,) +analysis_callback = AnalysisCallback(semi, interval = 100) -stepsize_callback = StepsizeCallback(cfl=0.9) +stepsize_callback = StepsizeCallback(cfl = 0.9) callbacks = CallbackSet(analysis_callback, stepsize_callback); # We define some equidistant nodes for the visualization -visnodes = range(tspan[1], tspan[2], length=300) +visnodes = range(tspan[1], tspan[2], length = 300) # and run the simulation. -sol = solve(ode, CarpenterKennedy2N54(williamson_condition=false), - dt=1, # solve needs some value here but it will be overwritten by the stepsize_callback - save_everystep=false, saveat=visnodes, callback=callbacks); +sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false), + dt = 1, # solve needs some value here but it will be overwritten by the stepsize_callback + save_everystep = false, saveat = visnodes, callback = callbacks); using Plots @gif for step in eachindex(sol.u) - plot(sol.u[step], semi, ylim=(-1.5, 1.5), legend=true, label="approximation", title="time t=$(round(sol.t[step], digits=5))") - scatter!([0.0], [sum(boundary_condition(SVector(0.0), sol.t[step], equations))], label="boundary condition") + plot(sol.u[step], semi, ylim = (-1.5, 1.5), legend = true, label = "approximation", + title = "time t=$(round(sol.t[step], digits=5))") + scatter!([0.0], [sum(boundary_condition(SVector(0.0), sol.t[step], equations))], + label = "boundary condition") end - # # Other available example elixirs with non-trivial BC # Moreover, there are other boundary conditions in Trixi.jl. For instance, you can use the slip wall # boundary condition [`boundary_condition_slip_wall`](@ref). @@ -158,7 +158,6 @@ end # ``` # Source: [`Video`](https://www.youtube.com/watch?v=w0A9X38cSe4) on Trixi.jl's YouTube channel [`Trixi Framework`](https://www.youtube.com/watch?v=WElqqdMhY4A) - # ## Package versions # These results were obtained using the following versions. @@ -168,4 +167,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/p4est_from_gmsh.jl b/docs/literate/src/files/p4est_from_gmsh.jl index abfe70eebc..caaea4faa9 100644 --- a/docs/literate/src/files/p4est_from_gmsh.jl +++ b/docs/literate/src/files/p4est_from_gmsh.jl @@ -16,8 +16,9 @@ # Mach 2 flow around the NACA6412 airfoil. using Trixi -redirect_stdio(stdout=devnull, stderr=devnull) do # code that prints annoying stuff we don't want to see here #hide #md -trixi_include(joinpath(examples_dir(), "p4est_2d_dgsem", "elixir_euler_NACA6412airfoil_mach2.jl"), tspan=(0.0, 0.5)) +redirect_stdio(stdout = devnull, stderr = devnull) do # code that prints annoying stuff we don't want to see here #hide #md + trixi_include(joinpath(examples_dir(), "p4est_2d_dgsem", + "elixir_euler_NACA6412airfoil_mach2.jl"), tspan = (0.0, 0.5)) end #hide #md # Conveniently, we use the Plots package to have a first look at the results: @@ -456,4 +457,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots", "Download"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/parabolic_terms.jl b/docs/literate/src/files/parabolic_terms.jl index d0a355bbc1..59db6eb05e 100644 --- a/docs/literate/src/files/parabolic_terms.jl +++ b/docs/literate/src/files/parabolic_terms.jl @@ -34,27 +34,33 @@ equations_parabolic = LaplaceDiffusion2D(diffusivity, equations_hyperbolic); boundary_condition_zero_dirichlet = BoundaryConditionDirichlet((x, t, equations) -> SVector(0.0)) -boundary_conditions_hyperbolic = (; x_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(1 + 0.5 * x[2])), - y_neg = boundary_condition_zero_dirichlet, - y_pos = boundary_condition_do_nothing, - x_pos = boundary_condition_do_nothing) - -boundary_conditions_parabolic = (; x_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(1 + 0.5 * x[2])), - y_neg = boundary_condition_zero_dirichlet, - y_pos = boundary_condition_zero_dirichlet, - x_pos = boundary_condition_zero_dirichlet); +boundary_conditions_hyperbolic = (; + x_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(1 + + 0.5 * + x[2])), + y_neg = boundary_condition_zero_dirichlet, + y_pos = boundary_condition_do_nothing, + x_pos = boundary_condition_do_nothing) + +boundary_conditions_parabolic = (; + x_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(1 + + 0.5 * + x[2])), + y_neg = boundary_condition_zero_dirichlet, + y_pos = boundary_condition_zero_dirichlet, + x_pos = boundary_condition_zero_dirichlet); # ## Defining the solver and mesh # The process of creating the DG solver and mesh is the same as for a purely # hyperbolic system of equations. -solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) +solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) coordinates_min = (-1.0, -1.0) # minimum coordinates (min(x), min(y)) -coordinates_max = ( 1.0, 1.0) # maximum coordinates (max(x), max(y)) +coordinates_max = (1.0, 1.0) # maximum coordinates (max(x), max(y)) mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level=4, - periodicity=false, n_cells_max=30_000) # set maximum capacity of tree data structure + initial_refinement_level = 4, + periodicity = false, n_cells_max = 30_000) # set maximum capacity of tree data structure initial_condition = (x, t, equations) -> SVector(0.0); @@ -68,8 +74,8 @@ initial_condition = (x, t, equations) -> SVector(0.0); semi = SemidiscretizationHyperbolicParabolic(mesh, (equations_hyperbolic, equations_parabolic), initial_condition, solver; - boundary_conditions=(boundary_conditions_hyperbolic, - boundary_conditions_parabolic)) + boundary_conditions = (boundary_conditions_hyperbolic, + boundary_conditions_parabolic)) # The rest of the code is identical to the hyperbolic case. We create a system of ODEs through # `semidiscretize`, defining callbacks, and then passing the system to OrdinaryDiffEq.jl. @@ -78,15 +84,14 @@ tspan = (0.0, 1.5) ode = semidiscretize(semi, tspan) callbacks = CallbackSet(SummaryCallback()) time_int_tol = 1.0e-6 -sol = solve(ode, RDPK3SpFSAL49(); abstol=time_int_tol, reltol=time_int_tol, - ode_default_options()..., callback=callbacks); +sol = solve(ode, RDPK3SpFSAL49(); abstol = time_int_tol, reltol = time_int_tol, + ode_default_options()..., callback = callbacks); # We can now visualize the solution, which develops a boundary layer at the outflow boundaries. using Plots plot(sol) - # ## Package versions # These results were obtained using the following versions. @@ -96,4 +101,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/scalar_linear_advection_1d.jl b/docs/literate/src/files/scalar_linear_advection_1d.jl index 3e2c7e6d0d..d74e064463 100644 --- a/docs/literate/src/files/scalar_linear_advection_1d.jl +++ b/docs/literate/src/files/scalar_linear_advection_1d.jl @@ -50,7 +50,6 @@ dx = (coordinates_max - coordinates_min) / n_elements # length of one element # ``` # Here, $u_t^{Q_l}$ and $u_\xi^{Q_l}$ denote the time and spatial derivatives of the solution on the element $Q_l$. - # ### ii. Polynomial approach # Now, we want to approximate the solution in each element $Q_l$ by a polynomial of degree $N$. Since we transformed # the equation, we can use the same polynomial approach for the reference coordinate $\xi\in[-1, 1]$ in every @@ -104,8 +103,7 @@ weights = basis.weights # \end{align*} # ``` # Let's use our nodes and weights for $N=3$ and plug in -integral = sum(nodes.^3 .* weights) - +integral = sum(nodes .^ 3 .* weights) # Using this polynomial approach leads to the equation # ```math @@ -119,10 +117,10 @@ integral = sum(nodes.^3 .* weights) # for every node. x = Matrix{Float64}(undef, length(nodes), n_elements) for element in 1:n_elements - x_l = coordinates_min + (element - 1) * dx + dx/2 + x_l = coordinates_min + (element - 1) * dx + dx / 2 for i in eachindex(nodes) ξ = nodes[i] # nodes in [-1, 1] - x[i, element] = x_l + dx/2 * ξ + x[i, element] = x_l + dx / 2 * ξ end end @@ -130,7 +128,7 @@ u0 = initial_condition_sine_wave.(x) # To have a look at the initial sinus curve, we plot it. using Plots -plot(vec(x), vec(u0), label="initial condition", legend=:topleft) +plot(vec(x), vec(u0), label = "initial condition", legend = :topleft) # ### iii. Variational formulation # After defining the equation and initial condition, we want to implement an algorithm to @@ -243,8 +241,9 @@ D = basis.derivative_matrix # ``` # for $k=0,...,N$ and therefore, $\underline{f}' = D \underline{f}$. basis_N8 = LobattoLegendreBasis(8) -plot(vec(x), x -> 3 * x^2, label="f'", lw=2) -scatter!(basis_N8.nodes, basis_N8.derivative_matrix * basis_N8.nodes.^3, label="Df", lw=3) +plot(vec(x), x -> 3 * x^2, label = "f'", lw = 2) +scatter!(basis_N8.nodes, basis_N8.derivative_matrix * basis_N8.nodes .^ 3, label = "Df", + lw = 3) # Combining the volume term for every $i=0,...,N$ results in # ```math @@ -302,13 +301,15 @@ function rhs!(du, u, x, t) ## Trixi.jl needs the equation we are dealing with and an additional `1`, that indicates the ## first coordinate direction. equations = LinearScalarAdvectionEquation1D(1.0) - for element in 2:n_elements-1 + for element in 2:(n_elements - 1) ## left interface - flux_numerical[1, element] = surface_flux(u[end, element-1], u[1, element], 1, equations) - flux_numerical[end, element-1] = flux_numerical[1, element] + flux_numerical[1, element] = surface_flux(u[end, element - 1], u[1, element], 1, + equations) + flux_numerical[end, element - 1] = flux_numerical[1, element] ## right interface - flux_numerical[end, element] = surface_flux(u[end, element], u[1, element+1], 1, equations) - flux_numerical[1, element+1] = flux_numerical[end, element] + flux_numerical[end, element] = surface_flux(u[end, element], u[1, element + 1], 1, + equations) + flux_numerical[1, element + 1] = flux_numerical[end, element] end ## boundary flux flux_numerical[1, 1] = surface_flux(u[end, end], u[1, 1], 1, equations) @@ -342,13 +343,12 @@ using OrdinaryDiffEq tspan = (0.0, 2.0) ode = ODEProblem(rhs!, u0, tspan, x) -sol = solve(ode, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, ode_default_options()...) +sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, + ode_default_options()...) @test maximum(abs.(u0 - sol.u[end])) < 5e-5 #src -plot(vec(x), vec(sol.u[end]), label="solution at t=$(tspan[2])", legend=:topleft, lw=3) - - - +plot(vec(x), vec(sol.u[end]), label = "solution at t=$(tspan[2])", legend = :topleft, + lw = 3) # ## Alternative Implementation based on Trixi.jl # Now, we implement the same example. But this time, we directly use the functionality that Trixi.jl @@ -362,7 +362,7 @@ equations = LinearScalarAdvectionEquation1D(advection_velocity) # Then, create a DG solver with polynomial degree = 3 and (local) Lax-Friedrichs/Rusanov flux as surface flux. # The implementation of the basis and the numerical flux is now already done. -solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) +solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) # We will now create a mesh with 16 elements for the physical domain `[-1, 1]` with periodic boundaries. # We use Trixi.jl's standard mesh [`TreeMesh`](@ref). Since it's limited to hypercube domains, we @@ -371,29 +371,30 @@ solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) coordinates_min = -1.0 # minimum coordinate coordinates_max = 1.0 # maximum coordinate mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level=4, # number of elements = 2^4 - n_cells_max=30_000) # set maximum capacity of tree data structure (only needed for AMR) + initial_refinement_level = 4, # number of elements = 2^4 + n_cells_max = 30_000) # set maximum capacity of tree data structure (only needed for AMR) # A semidiscretization collects data structures and functions for the spatial discretization. # In Trixi.jl, an initial condition has the following parameter structure and is of the type `SVector`. -initial_condition_sine_wave(x, t, equations) = SVector(1.0 + 0.5 * sin(pi * sum(x - equations.advection_velocity * t))) +function initial_condition_sine_wave(x, t, equations) + SVector(1.0 + 0.5 * sin(pi * sum(x - equations.advection_velocity * t))) +end semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_sine_wave, solver) # Again, combining all definitions and the function that calculates the right-hand side, we define the ODE and # solve it until `t=2` with OrdinaryDiffEq's `solve` function and the Runge-Kutta method `RDPK3SpFSAL49()`. tspan = (0.0, 2.0) -ode_trixi = semidiscretize(semi, tspan) +ode_trixi = semidiscretize(semi, tspan) -sol_trixi = solve(ode_trixi, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, ode_default_options()...); +sol_trixi = solve(ode_trixi, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, + ode_default_options()...); # We add a plot of the new approximated solution to the one calculated before. -plot!(sol_trixi, label="solution at t=$(tspan[2]) with Trixi.jl", legend=:topleft, linestyle=:dash, lw=2) +plot!(sol_trixi, label = "solution at t=$(tspan[2]) with Trixi.jl", legend = :topleft, + linestyle = :dash, lw = 2) @test maximum(abs.(vec(u0) - sol_trixi.u[end])) ≈ maximum(abs.(u0 - sol.u[end])) #src - - - # ## Summary of the code # To sum up, here is the complete code that we used. @@ -410,16 +411,16 @@ B = diagm([-1; zeros(polydeg - 1); 1]) ## mesh coordinates_min = -1.0 # minimum coordinate coordinates_max = 1.0 # maximum coordinate -n_elements = 16 # number of elements +n_elements = 16 # number of elements dx = (coordinates_max - coordinates_min) / n_elements # length of one element x = Matrix{Float64}(undef, length(nodes), n_elements) for element in 1:n_elements - x_l = -1 + (element - 1) * dx + dx/2 + x_l = -1 + (element - 1) * dx + dx / 2 for i in eachindex(nodes) # basis points in [-1, 1] ξ = nodes[i] - x[i, element] = x_l + dx/2 * ξ + x[i, element] = x_l + dx / 2 * ξ end end @@ -427,7 +428,7 @@ end initial_condition_sine_wave(x) = 1.0 + 0.5 * sin(pi * x) u0 = initial_condition_sine_wave.(x) -plot(vec(x), vec(u0), label="initial condition", legend=:topleft) +plot(vec(x), vec(u0), label = "initial condition", legend = :topleft) ## flux Lax-Friedrichs surface_flux = flux_lax_friedrichs @@ -440,13 +441,15 @@ function rhs!(du, u, x, t) ## calculate interface and boundary fluxes equations = LinearScalarAdvectionEquation1D(1.0) - for element in 2:n_elements-1 + for element in 2:(n_elements - 1) ## left interface - flux_numerical[1, element] = surface_flux(u[end, element-1], u[1, element], 1, equations) - flux_numerical[end, element-1] = flux_numerical[1, element] + flux_numerical[1, element] = surface_flux(u[end, element - 1], u[1, element], 1, + equations) + flux_numerical[end, element - 1] = flux_numerical[1, element] ## right interface - flux_numerical[end, element] = surface_flux(u[end, element], u[1, element+1], 1, equations) - flux_numerical[1, element+1] = flux_numerical[end, element] + flux_numerical[end, element] = surface_flux(u[end, element], u[1, element + 1], 1, + equations) + flux_numerical[1, element + 1] = flux_numerical[end, element] end ## boundary flux flux_numerical[1, 1] = surface_flux(u[end, end], u[1, 1], 1, equations) @@ -476,11 +479,12 @@ tspan = (0.0, 2.0) ode = ODEProblem(rhs!, u0, tspan, x) ## solve -sol = solve(ode, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, ode_default_options()...) +sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, + ode_default_options()...) @test maximum(abs.(vec(u0) - sol_trixi.u[end])) ≈ maximum(abs.(u0 - sol.u[end])) #src -plot(vec(x), vec(sol.u[end]), label="solution at t=$(tspan[2])", legend=:topleft, lw=3) - +plot(vec(x), vec(sol.u[end]), label = "solution at t=$(tspan[2])", legend = :topleft, + lw = 3) # ### Alternative Implementation based on Trixi.jl using Trixi, OrdinaryDiffEq, Plots @@ -490,29 +494,32 @@ advection_velocity = 1.0 equations = LinearScalarAdvectionEquation1D(advection_velocity) ## create DG solver with flux lax friedrichs and LGL basis -solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) +solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) ## distretize domain with `TreeMesh` coordinates_min = -1.0 # minimum coordinate coordinates_max = 1.0 # maximum coordinate mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level=4, # number of elements = 2^4 - n_cells_max=30_000) + initial_refinement_level = 4, # number of elements = 2^4 + n_cells_max = 30_000) ## create initial condition and semidiscretization -initial_condition_sine_wave(x, t, equations) = SVector(1.0 + 0.5 * sin(pi * sum(x - equations.advection_velocity * t))) +function initial_condition_sine_wave(x, t, equations) + SVector(1.0 + 0.5 * sin(pi * sum(x - equations.advection_velocity * t))) +end semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_sine_wave, solver) ## solve tspan = (0.0, 2.0) -ode_trixi = semidiscretize(semi, tspan) -sol_trixi = solve(ode_trixi, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, ode_default_options()...); +ode_trixi = semidiscretize(semi, tspan) +sol_trixi = solve(ode_trixi, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, + ode_default_options()...); -plot!(sol_trixi, label="solution at t=$(tspan[2]) with Trixi.jl", legend=:topleft, linestyle=:dash, lw=2) +plot!(sol_trixi, label = "solution at t=$(tspan[2]) with Trixi.jl", legend = :topleft, + linestyle = :dash, lw = 2) @test maximum(abs.(vec(u0) - sol_trixi.u[end])) ≈ maximum(abs.(u0 - sol.u[end])) #src - # ## Package versions # These results were obtained using the following versions. @@ -522,4 +529,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/shock_capturing.jl b/docs/literate/src/files/shock_capturing.jl index dd6698c2a8..f4b0ce4dde 100644 --- a/docs/literate/src/files/shock_capturing.jl +++ b/docs/literate/src/files/shock_capturing.jl @@ -4,7 +4,6 @@ # and its implementation in [Trixi.jl](https://github.com/trixi-framework/Trixi.jl). # In the second part, an implementation of a positivity preserving limiter is added to the simulation. - # # Shock capturing with flux differencing # The following rough explanation is on a very basic level. More information about an entropy stable @@ -36,7 +35,6 @@ # volume_flux_fv=volume_flux_fv) # ```` - # We now focus on a choice of the shock capturing indicator `indicator_sc`. # A possible indicator is $\alpha_{HG}$ presented by Hennemann et al. (p.10), which depends on the # current approximation with modal coefficients $\{m_j\}_{j=0}^N$ of a given `variable`. @@ -84,8 +82,6 @@ # variable=variable) # ```` - - # # Positivity preserving limiter # Some numerical solutions are physically meaningless, for instance negative values of pressure @@ -132,7 +128,6 @@ # SSPRK43(stage_limiter!). # ```` - # # Simulation with shock capturing and positivity preserving # Now, we can run a simulation using the described methods of shock capturing and positivity @@ -143,26 +138,26 @@ equations = CompressibleEulerEquations2D(1.4) # As our initial condition we use the Sedov blast wave setup. function initial_condition_sedov_blast_wave(x, t, equations::CompressibleEulerEquations2D) - ## Set up polar coordinates - inicenter = SVector(0.0, 0.0) - x_norm = x[1] - inicenter[1] - y_norm = x[2] - inicenter[2] - r = sqrt(x_norm^2 + y_norm^2) - - r0 = 0.21875 # = 3.5 * smallest dx (for domain length=4 and max-ref=6) - ## r0 = 0.5 # = more reasonable setup - E = 1.0 - p0_inner = 3 * (equations.gamma - 1) * E / (3 * pi * r0^2) - p0_outer = 1.0e-5 # = true Sedov setup - ## p0_outer = 1.0e-3 # = more reasonable setup - - ## Calculate primitive variables - rho = 1.0 - v1 = 0.0 - v2 = 0.0 - p = r > r0 ? p0_outer : p0_inner - - return prim2cons(SVector(rho, v1, v2, p), equations) + ## Set up polar coordinates + inicenter = SVector(0.0, 0.0) + x_norm = x[1] - inicenter[1] + y_norm = x[2] - inicenter[2] + r = sqrt(x_norm^2 + y_norm^2) + + r0 = 0.21875 # = 3.5 * smallest dx (for domain length=4 and max-ref=6) + ## r0 = 0.5 # = more reasonable setup + E = 1.0 + p0_inner = 3 * (equations.gamma - 1) * E / (3 * pi * r0^2) + p0_outer = 1.0e-5 # = true Sedov setup + ## p0_outer = 1.0e-3 # = more reasonable setup + + ## Calculate primitive variables + rho = 1.0 + v1 = 0.0 + v2 = 0.0 + p = r > r0 ? p0_outer : p0_inner + + return prim2cons(SVector(rho, v1, v2, p), equations) end initial_condition = initial_condition_sedov_blast_wave #- @@ -171,7 +166,7 @@ basis = LobattoLegendreBasis(3) # We set the numerical fluxes and divide between the surface flux and the two volume fluxes for the DG # and FV method. Here, we are using [`flux_lax_friedrichs`](@ref) and [`flux_ranocha`](@ref). surface_flux = flux_lax_friedrichs -volume_flux = flux_ranocha +volume_flux = flux_ranocha # Now, we specify the shock capturing indicator $\alpha$. @@ -180,26 +175,26 @@ volume_flux = flux_ranocha # Since density and pressure are the critical variables in this example, we use # `density_pressure = density * pressure = rho * p` as indicator variable. indicator_sc = IndicatorHennemannGassner(equations, basis, - alpha_max=0.5, - alpha_min=0.001, - alpha_smooth=true, - variable=density_pressure) + alpha_max = 0.5, + alpha_min = 0.001, + alpha_smooth = true, + variable = density_pressure) # Now, we can use the defined fluxes and the indicator to implement the volume integral using shock # capturing. volume_integral = VolumeIntegralShockCapturingHG(indicator_sc; - volume_flux_dg=volume_flux, - volume_flux_fv=surface_flux) + volume_flux_dg = volume_flux, + volume_flux_fv = surface_flux) # We finalize the discretization by implementing Trixi.jl's `solver`, `mesh`, `semi` and `ode`, # while `solver` now has the extra parameter `volume_integral`. solver = DGSEM(basis, surface_flux, volume_integral) coordinates_min = (-2.0, -2.0) -coordinates_max = ( 2.0, 2.0) +coordinates_max = (2.0, 2.0) mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level=6, - n_cells_max=10_000) + initial_refinement_level = 6, + n_cells_max = 10_000) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver) @@ -207,25 +202,24 @@ tspan = (0.0, 1.0) ode = semidiscretize(semi, tspan); # We add some callbacks to get an solution analysis and use a CFL-based time step size calculation. -analysis_callback = AnalysisCallback(semi, interval=100) +analysis_callback = AnalysisCallback(semi, interval = 100) -stepsize_callback = StepsizeCallback(cfl=0.8) +stepsize_callback = StepsizeCallback(cfl = 0.8) callbacks = CallbackSet(analysis_callback, stepsize_callback); # We now run the simulation using the positivity preserving limiter of Zhang and Shu for the variables # density and pressure. -stage_limiter! = PositivityPreservingLimiterZhangShu(thresholds=(5.0e-6, 5.0e-6), - variables=(Trixi.density, pressure)) +stage_limiter! = PositivityPreservingLimiterZhangShu(thresholds = (5.0e-6, 5.0e-6), + variables = (Trixi.density, pressure)) -sol = solve(ode, CarpenterKennedy2N54(stage_limiter!, 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); +sol = solve(ode, CarpenterKennedy2N54(stage_limiter!, 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); using Plots plot(sol) - # ## Package versions # These results were obtained using the following versions. @@ -235,4 +229,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/structured_mesh_mapping.jl b/docs/literate/src/files/structured_mesh_mapping.jl index c8da30bc2b..902301d445 100644 --- a/docs/literate/src/files/structured_mesh_mapping.jl +++ b/docs/literate/src/files/structured_mesh_mapping.jl @@ -18,15 +18,16 @@ using Trixi equations = CompressibleEulerEquations2D(1.4) # We start with a pressure perturbation at `(xs, 0.0)` as initial condition. -function initial_condition_pressure_perturbation(x, t, equations::CompressibleEulerEquations2D) - xs = 1.5 # location of the initial disturbance on the x axis - w = 1/8 # half width - p = exp(-log(2) * ((x[1]-xs)^2 + x[2]^2)/w^2) + 1.0 - v1 = 0.0 - v2 = 0.0 - rho = 1.0 - - return prim2cons(SVector(rho, v1, v2, p), equations) +function initial_condition_pressure_perturbation(x, t, + equations::CompressibleEulerEquations2D) + xs = 1.5 # location of the initial disturbance on the x axis + w = 1 / 8 # half width + p = exp(-log(2) * ((x[1] - xs)^2 + x[2]^2) / w^2) + 1.0 + v1 = 0.0 + v2 = 0.0 + rho = 1.0 + + return prim2cons(SVector(rho, v1, v2, p), equations) end initial_condition = initial_condition_pressure_perturbation @@ -35,8 +36,8 @@ boundary_conditions = boundary_condition_slip_wall # The approximation setup is an entropy-stable split-form DG method with `polydeg=4`. We are using # the two fluxes [`flux_ranocha`](@ref) and [`flux_lax_friedrichs`](@ref). -solver = DGSEM(polydeg=4, surface_flux=flux_lax_friedrichs, - volume_integral=VolumeIntegralFluxDifferencing(flux_ranocha)) +solver = DGSEM(polydeg = 4, surface_flux = flux_lax_friedrichs, + volume_integral = VolumeIntegralFluxDifferencing(flux_ranocha)) # We want to define a circular cylinder as physical domain. It contains an inner semicircle with # radius `r0` and an outer semicircle of radius `r1`. @@ -68,7 +69,6 @@ solver = DGSEM(polydeg=4, surface_flux=flux_lax_friedrichs, #src # \end{tikzpicture} #src # \end{document} - # The domain boundary curves with curve parameter in $[-1,1]$ are sorted as shown in the sketch. # They always are orientated from negative to positive coordinate, such that the corners have to # fit like this $f_1(+1) = f_4(-1)$, $f_3(+1) = f_2(-1)$, etc. @@ -76,37 +76,37 @@ solver = DGSEM(polydeg=4, surface_flux=flux_lax_friedrichs, # In our case we can define the domain boundary curves as follows: r0 = 0.5 # inner radius r1 = 5.0 # outer radius -f1(xi) = SVector( r0 + 0.5 * (r1 - r0) * (xi + 1), 0.0) # right line -f2(xi) = SVector(-r0 - 0.5 * (r1 - r0) * (xi + 1), 0.0) # left line +f1(xi) = SVector(r0 + 0.5 * (r1 - r0) * (xi + 1), 0.0) # right line +f2(xi) = SVector(-r0 - 0.5 * (r1 - r0) * (xi + 1), 0.0) # left line f3(eta) = SVector(r0 * cos(0.5 * pi * (eta + 1)), r0 * sin(0.5 * pi * (eta + 1))) # inner circle f4(eta) = SVector(r1 * cos(0.5 * pi * (eta + 1)), r1 * sin(0.5 * pi * (eta + 1))) # outer circle # We create a curved mesh with 16 x 16 elements. The defined domain boundary curves are passed as a tuple. cells_per_dimension = (16, 16) -mesh = StructuredMesh(cells_per_dimension, (f1, f2, f3, f4), periodicity=false) +mesh = StructuredMesh(cells_per_dimension, (f1, f2, f3, f4), periodicity = false) # Then, we define the simulation with endtime `T=3` with `semi`, `ode` and `callbacks`. semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - boundary_conditions=boundary_conditions) + boundary_conditions = boundary_conditions) tspan = (0.0, 3.0) ode = semidiscretize(semi, tspan) analysis_interval = 100 -analysis_callback = AnalysisCallback(semi, interval=analysis_interval) +analysis_callback = AnalysisCallback(semi, interval = analysis_interval) -alive_callback = AliveCallback(analysis_interval=analysis_interval) +alive_callback = AliveCallback(analysis_interval = analysis_interval) -stepsize_callback = StepsizeCallback(cfl=0.9) +stepsize_callback = StepsizeCallback(cfl = 0.9) callbacks = CallbackSet(analysis_callback, alive_callback, stepsize_callback); # Running the simulation -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); +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); using Plots plot(sol) @@ -115,7 +115,6 @@ pd = PlotData2D(sol) plot(pd["p"]) plot!(getmesh(pd)) - # ## Mesh directly defined by the transformation mapping # As mentioned before, you can also define the domain for a `StructuredMesh` by directly setting up # a transformation mapping. Here, we want to present a nice mapping, which is often used to test @@ -132,22 +131,22 @@ equations = CompressibleEulerEquations2D(1.4) # initial condition. initial_condition = initial_condition_constant -solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) +solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) # We define the transformation mapping with variables in $[-1, 1]$ as described in # Rueda-Ramírez et al. (2021), p.18 (reduced to 2D): function mapping(xi_, eta_) - ## Transform input variables between -1 and 1 onto [0,3] - xi = 1.5 * xi_ + 1.5 - eta = 1.5 * eta_ + 1.5 + ## Transform input variables between -1 and 1 onto [0,3] + xi = 1.5 * xi_ + 1.5 + eta = 1.5 * eta_ + 1.5 - y = eta + 3/8 * (cos(1.5 * pi * (2 * xi - 3)/3) * - cos(0.5 * pi * (2 * eta - 3)/3)) + y = eta + 3 / 8 * (cos(1.5 * pi * (2 * xi - 3) / 3) * + cos(0.5 * pi * (2 * eta - 3) / 3)) - x = xi + 3/8 * (cos(0.5 * pi * (2 * xi - 3)/3) * - cos(2 * pi * (2 * y - 3)/3)) + x = xi + 3 / 8 * (cos(0.5 * pi * (2 * xi - 3) / 3) * + cos(2 * pi * (2 * y - 3) / 3)) - return SVector(x, y) + return SVector(x, y) end # Instead of a tuple of boundary functions, the `mesh` now has the mapping as its parameter. @@ -159,28 +158,28 @@ semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver) tspan = (0.0, 1.0) ode = semidiscretize(semi, tspan) -analysis_callback = AnalysisCallback(semi, interval=250) +analysis_callback = AnalysisCallback(semi, interval = 250) -stepsize_callback = StepsizeCallback(cfl=0.8) +stepsize_callback = StepsizeCallback(cfl = 0.8) callbacks = CallbackSet(analysis_callback, stepsize_callback) -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); +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); # Now, we want to verify the free-stream preservation property and plot the mesh. For the verification, # we calculate the absolute difference of the first conservation variable density `u[1]` and `1.0`. # To plot this error and the mesh, we are using the visualization feature `ScalarPlotData2D`, # explained in [visualization](@ref visualization). error_density = let u = Trixi.wrap_array(sol.u[end], semi) - abs.(u[1, :, :, :] .- 1.0) # density, x, y, elements + abs.(u[1, :, :, :] .- 1.0) # density, x, y, elements end pd = ScalarPlotData2D(error_density, semi) using Plots -plot(pd, title="Error in density") +plot(pd, title = "Error in density") plot!(getmesh(pd)) # We observe that the errors in the variable `density` are at the level of machine accuracy. @@ -202,7 +201,6 @@ plot!(getmesh(pd)) # [High-Order Hex-Quad Mesh (HOHQMesh) generator](https://github.com/trixi-framework/HOHQMesh), # created and developed by David Kopriva. - # ## Package versions # These results were obtained using the following versions. @@ -212,4 +210,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/subcell_shock_capturing.jl b/docs/literate/src/files/subcell_shock_capturing.jl index 8b5399c23a..f189d54148 100644 --- a/docs/literate/src/files/subcell_shock_capturing.jl +++ b/docs/literate/src/files/subcell_shock_capturing.jl @@ -215,7 +215,6 @@ sol = Trixi.solve(ode, Trixi.SimpleSSPRK33(stage_callbacks = stage_callbacks); callback = callbacks); summary_callback() # print the timer summary - # ## Visualization # As for a standard simulation in Trixi.jl, it is possible to visualize the solution using the # `plot` routine from Plots.jl. @@ -243,7 +242,6 @@ plot(sol) # and get the following visualization. # ![blast_wave_paraview_reinterpolate=false](https://github.com/trixi-framework/Trixi.jl/assets/74359358/39274f18-0064-469c-b4da-bac4b843e116) - # ## Bounds checking # Subcell limiting is based on the fulfillment of target bounds - either global or local. # Although the implementation works and has been thoroughly tested, there are some cases where diff --git a/docs/literate/src/files/time_stepping.jl b/docs/literate/src/files/time_stepping.jl index de7a2a83a4..fdfbfe1818 100644 --- a/docs/literate/src/files/time_stepping.jl +++ b/docs/literate/src/files/time_stepping.jl @@ -33,7 +33,6 @@ # If you run Trixi in parallel with MPI you need to pass `internalnorm=ode_norm` and you should pass `unstable_check=ode_unstable_check` # to enable MPI aware error-based adaptive step size control. These keyword arguments are also included in [`ode_default_options`](@ref). - # # CFL-based step size control # The SciML ecosystem also provides time integration algorithms without adaptive time stepping on # their own, such as `CarpenterKennedy2N54`. Moreover, you also can deactivate the automatic adaptivity @@ -74,7 +73,6 @@ # [`elixir_advection_basic.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_2d_dgsem/elixir_advection_basic.jl) # or [`elixir_euler_source_terms.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_2d_dgsem/elixir_euler_source_terms.jl). - # ## Package versions # These results were obtained using the following versions. @@ -84,4 +82,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/upwind_fdsbp.jl b/docs/literate/src/files/upwind_fdsbp.jl index 6d3379fa30..e42cc19ca7 100644 --- a/docs/literate/src/files/upwind_fdsbp.jl +++ b/docs/literate/src/files/upwind_fdsbp.jl @@ -9,8 +9,8 @@ # operator can be created as follows. using Trixi D_SBP = derivative_operator(SummationByPartsOperators.MattssonNordström2004(), - derivative_order=1, accuracy_order=2, - xmin=0.0, xmax=1.0, N=11) + derivative_order = 1, accuracy_order = 2, + xmin = 0.0, xmax = 1.0, N = 11) # Instead of prefixing the source of coefficients `MattssonNordström2004()`, # you can also load the package SummationByPartsOperators.jl. Either way, # this yields an object representing the operator efficiently. If you want to @@ -21,8 +21,8 @@ Matrix(D_SBP) # Upwind SBP operators are a concept introduced in 2017 by Ken Mattsson. You can # create them as follows. D_upw = upwind_operators(SummationByPartsOperators.Mattsson2017, - derivative_order=1, accuracy_order=2, - xmin=0.0, xmax=1.0, N=11) + derivative_order = 1, accuracy_order = 2, + xmin = 0.0, xmax = 1.0, N = 11) # Upwind operators are derivative operators biased towards one direction. # The "minus" variants has a bias towards the left side, i.e., it uses values # from more nodes to the left than from the right to compute the discrete @@ -63,7 +63,6 @@ Matrix(D_upw.plus) # - [`elixir_euler_vortex.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_2d_fdsbp/elixir_euler_vortex.jl) # - [`elixir_euler_taylor_green_vortex.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_3d_fdsbp/elixir_euler_taylor_green_vortex.jl) - # ## Package versions # These results were obtained using the following versions. @@ -73,4 +72,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "SummationByPartsOperators"], - mode=PKGMODE_MANIFEST) + mode = PKGMODE_MANIFEST) diff --git a/docs/make.jl b/docs/make.jl index 73ee86abd8..822684829d 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -3,7 +3,8 @@ import Pkg using Changelog: Changelog # Fix for https://github.com/trixi-framework/Trixi.jl/issues/668 -if (get(ENV, "CI", nothing) != "true") && (get(ENV, "TRIXI_DOC_DEFAULT_ENVIRONMENT", nothing) != "true") +if (get(ENV, "CI", nothing) != "true") && + (get(ENV, "TRIXI_DOC_DEFAULT_ENVIRONMENT", nothing) != "true") push!(LOAD_PATH, dirname(@__DIR__)) end @@ -18,12 +19,13 @@ include(joinpath(trixi_root_dir, "docs", "literate", "make.jl")) # Copy list of authors to not need to synchronize it manually authors_text = read(joinpath(trixi_root_dir, "AUTHORS.md"), String) -authors_text = replace(authors_text, "in the [LICENSE.md](LICENSE.md) file" => "under [License](@ref)") +authors_text = replace(authors_text, + "in the [LICENSE.md](LICENSE.md) file" => "under [License](@ref)") write(joinpath(@__DIR__, "src", "authors.md"), authors_text) # Define module-wide setups such that the respective modules are available in doctests -DocMeta.setdocmeta!(Trixi, :DocTestSetup, :(using Trixi); recursive=true) -DocMeta.setdocmeta!(Trixi2Vtk, :DocTestSetup, :(using Trixi2Vtk); recursive=true) +DocMeta.setdocmeta!(Trixi, :DocTestSetup, :(using Trixi); recursive = true) +DocMeta.setdocmeta!(Trixi2Vtk, :DocTestSetup, :(using Trixi2Vtk); recursive = true) # Copy some files from the repository root directory to the docs and modify them # as necessary @@ -55,9 +57,9 @@ open(joinpath(@__DIR__, "src", "contributing.md"), "w") do io """) # Write the modified contents for line in eachline(joinpath(dirname(@__DIR__), "CONTRIBUTING.md")) - line = replace(line, "[LICENSE.md](LICENSE.md)" => "[License](@ref)") - line = replace(line, "[AUTHORS.md](AUTHORS.md)" => "[Authors](@ref)") - println(io, line) + line = replace(line, "[LICENSE.md](LICENSE.md)" => "[License](@ref)") + line = replace(line, "[AUTHORS.md](AUTHORS.md)" => "[Authors](@ref)") + println(io, line) end end @@ -97,79 +99,73 @@ files = [ "Explicit time stepping" => "time_stepping.jl", "Differentiable programming" => "differentiable_programming.jl", "Custom semidiscretizations" => "custom_semidiscretization.jl", - ] +] tutorials = create_tutorials(files) # Create changelog -Changelog.generate( - Changelog.Documenter(), # output type - joinpath(@__DIR__, "..", "NEWS.md"), # input file - joinpath(@__DIR__, "src", "changelog.md"); # output file - repo = "trixi-framework/Trixi.jl", # default repository for links -) +Changelog.generate(Changelog.Documenter(), # output type + joinpath(@__DIR__, "..", "NEWS.md"), # input file + joinpath(@__DIR__, "src", "changelog.md"); # output file + repo = "trixi-framework/Trixi.jl",) # Make documentation makedocs( - # Specify modules for which docstrings should be shown - modules = [Trixi, TrixiBase, Trixi2Vtk], - # Set sitename to Trixi.jl - sitename = "Trixi.jl", - # Provide additional formatting options - format = Documenter.HTML( - # Disable pretty URLs during manual testing - prettyurls = get(ENV, "CI", nothing) == "true", - # Explicitly add favicon as asset - assets = ["assets/favicon.ico"], - # Set canonical URL to GitHub pages URL - canonical = "https://trixi-framework.github.io/Trixi.jl/stable", - size_threshold_ignore = ["reference-trixi.md"] - ), - # Explicitly specify documentation structure - pages = [ - "Home" => "index.md", - "Getting started" => [ - "Overview" => "overview.md", - "Visualization" => "visualization.md", - "Restart simulation" => "restart.md", - ], - "Tutorials" => tutorials, - "Basic building blocks" => [ - "Meshes" => [ - "Tree mesh" => joinpath("meshes", "tree_mesh.md"), - "Structured mesh" => joinpath("meshes", "structured_mesh.md"), - "Unstructured mesh" => joinpath("meshes", "unstructured_quad_mesh.md"), - "P4est-based mesh" => joinpath("meshes", "p4est_mesh.md"), - "DGMulti mesh" => joinpath("meshes", "dgmulti_mesh.md"), - ], - "Time integration" => "time_integration.md", - "Callbacks" => "callbacks.md", - "Coupling" => "multi-physics_coupling.md" - ], - "Advanced topics & developers" => [ - "Conventions" =>"conventions.md", - "Development" => "development.md", - "GitHub & Git" => "github-git.md", - "Style guide" => "styleguide.md", - "Testing" => "testing.md", - "Performance" => "performance.md", - "Parallelization" => "parallelization.md", - ], - "Troubleshooting and FAQ" => "troubleshooting.md", - "Reference" => [ - "Trixi.jl" => "reference-trixi.md", - "TrixiBase.jl" => "reference-trixibase.md", - "Trixi2Vtk.jl" => "reference-trixi2vtk.md" - ], - "Changelog" => "changelog.md", - "Authors" => "authors.md", - "Contributing" => "contributing.md", - "Code of Conduct" => "code_of_conduct.md", - "License" => "license.md", - ] -) + # Specify modules for which docstrings should be shown + modules = [Trixi, TrixiBase, Trixi2Vtk], + # Set sitename to Trixi.jl + sitename = "Trixi.jl", + # Provide additional formatting options + format = Documenter.HTML( + # Disable pretty URLs during manual testing + prettyurls = get(ENV, "CI", nothing) == "true", + # Explicitly add favicon as asset + assets = ["assets/favicon.ico"], + # Set canonical URL to GitHub pages URL + canonical = "https://trixi-framework.github.io/Trixi.jl/stable", + size_threshold_ignore = ["reference-trixi.md"]), + # Explicitly specify documentation structure + pages = [ + "Home" => "index.md", + "Getting started" => [ + "Overview" => "overview.md", + "Visualization" => "visualization.md", + "Restart simulation" => "restart.md", + ], + "Tutorials" => tutorials, + "Basic building blocks" => [ + "Meshes" => [ + "Tree mesh" => joinpath("meshes", "tree_mesh.md"), + "Structured mesh" => joinpath("meshes", "structured_mesh.md"), + "Unstructured mesh" => joinpath("meshes", "unstructured_quad_mesh.md"), + "P4est-based mesh" => joinpath("meshes", "p4est_mesh.md"), + "DGMulti mesh" => joinpath("meshes", "dgmulti_mesh.md"), + ], + "Time integration" => "time_integration.md", + "Callbacks" => "callbacks.md", + "Coupling" => "multi-physics_coupling.md", + ], + "Advanced topics & developers" => [ + "Conventions" => "conventions.md", + "Development" => "development.md", + "GitHub & Git" => "github-git.md", + "Style guide" => "styleguide.md", + "Testing" => "testing.md", + "Performance" => "performance.md", + "Parallelization" => "parallelization.md", + ], + "Troubleshooting and FAQ" => "troubleshooting.md", + "Reference" => [ + "Trixi.jl" => "reference-trixi.md", + "TrixiBase.jl" => "reference-trixibase.md", + "Trixi2Vtk.jl" => "reference-trixi2vtk.md", + ], + "Changelog" => "changelog.md", + "Authors" => "authors.md", + "Contributing" => "contributing.md", + "Code of Conduct" => "code_of_conduct.md", + "License" => "license.md", + ]) -deploydocs( - repo = "github.com/trixi-framework/Trixi.jl", - devbranch = "main", - push_preview = true -) +deploydocs(repo = "github.com/trixi-framework/Trixi.jl", + devbranch = "main", + push_preview = true) diff --git a/src/time_integration/methods_2N.jl b/src/time_integration/methods_2N.jl index afcfe8c320..e5b970c6bd 100644 --- a/src/time_integration/methods_2N.jl +++ b/src/time_integration/methods_2N.jl @@ -132,7 +132,7 @@ function init(ode::ODEProblem, alg::SimpleAlgorithm2N; end # Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1 -function solve(ode::ODEProblem, alg:: SimpleAlgorithm2N; +function solve(ode::ODEProblem, alg::SimpleAlgorithm2N; dt, callback = nothing, kwargs...) integrator = init(ode, alg, dt = dt, callback = callback; kwargs...) diff --git a/src/time_integration/methods_3Sstar.jl b/src/time_integration/methods_3Sstar.jl index 9a6ad09f7f..6128d1551d 100644 --- a/src/time_integration/methods_3Sstar.jl +++ b/src/time_integration/methods_3Sstar.jl @@ -171,7 +171,7 @@ function Base.getproperty(integrator::SimpleIntegrator3Sstar, field::Symbol) return getfield(integrator, field) end -function init(ode::ODEProblem, alg:: SimpleAlgorithm3Sstar; +function init(ode::ODEProblem, alg::SimpleAlgorithm3Sstar; dt, callback = nothing, kwargs...) u = copy(ode.u0) du = similar(u) @@ -202,7 +202,7 @@ function init(ode::ODEProblem, alg:: SimpleAlgorithm3Sstar; end # Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1 -function solve(ode::ODEProblem, alg:: SimpleAlgorithm3Sstar; +function solve(ode::ODEProblem, alg::SimpleAlgorithm3Sstar; dt, callback = nothing, kwargs...) integrator = init(ode, alg, dt = dt, callback = callback; kwargs...) From 01f9e1c764144fee3695fb6104cf574ba4acefc7 Mon Sep 17 00:00:00 2001 From: Warisa Date: Tue, 18 Jun 2024 17:22:30 +0200 Subject: [PATCH 6/8] Revert "fmt" This reverts commit edb92b0c6f380b5f18fb5800f9a69d5750df21de. --- docs/literate/make.jl | 42 +-- docs/literate/src/files/DGMulti_1.jl | 70 ++-- docs/literate/src/files/DGMulti_2.jl | 15 +- docs/literate/src/files/DGSEM_FluxDiff.jl | 49 +-- .../src/files/adaptive_mesh_refinement.jl | 38 +- .../src/files/adding_new_parabolic_terms.jl | 85 ++--- .../src/files/adding_new_scalar_equations.jl | 71 ++-- .../files/adding_nonconservative_equation.jl | 81 +++-- .../behind_the_scenes_simulation_setup.jl | 7 + ...scretizationHyperbolic_structure_figure.jl | 106 ++---- .../src/generate_boundary_figure.jl | 296 ++++++--------- .../src/generate_elements_figure.jl | 179 ++++----- .../src/generate_interfaces_figure.jl | 229 +++++------- .../src/generate_mortars_figure.jl | 257 +++++-------- .../src/generate_nodes_figure.jl | 8 +- .../src/generate_treemesh_figure.jl | 53 +-- .../src/rhs_structure_figure.jl | 61 ++-- .../src/semidiscretize_structure_figure.jl | 79 ++-- .../src/files/custom_semidiscretization.jl | 15 +- .../src/files/differentiable_programming.jl | 143 ++++---- .../files/first_steps/create_first_setup.jl | 16 +- .../src/files/first_steps/getting_started.jl | 26 +- docs/literate/src/files/hohqmesh_tutorial.jl | 340 +++++++++--------- .../src/files/non_periodic_boundaries.jl | 41 +-- docs/literate/src/files/p4est_from_gmsh.jl | 7 +- docs/literate/src/files/parabolic_terms.jl | 43 +-- .../src/files/scalar_linear_advection_1d.jl | 105 +++--- docs/literate/src/files/shock_capturing.jl | 82 +++-- .../src/files/structured_mesh_mapping.jl | 80 +++-- .../src/files/subcell_shock_capturing.jl | 2 + docs/literate/src/files/time_stepping.jl | 4 +- docs/literate/src/files/upwind_fdsbp.jl | 11 +- docs/make.jl | 148 ++++---- src/time_integration/methods_2N.jl | 2 +- src/time_integration/methods_3Sstar.jl | 4 +- 35 files changed, 1258 insertions(+), 1537 deletions(-) diff --git a/docs/literate/make.jl b/docs/literate/make.jl index deda425ff3..262a236971 100644 --- a/docs/literate/make.jl +++ b/docs/literate/make.jl @@ -3,22 +3,22 @@ using Test: @testset import Pkg # Create markdown and notebook files for `file` -function create_files(title, file, repo_src, pages_dir, notebooks_dir; folder = "") +function create_files(title, file, repo_src, pages_dir, notebooks_dir; folder="") notebook_filename = first(splitext(file)) * ".ipynb" if !isempty(folder) notebook_filename = joinpath(folder, notebook_filename) end - binder_logo = "https://mybinder.org/badge_logo.svg" + binder_logo = "https://mybinder.org/badge_logo.svg" nbviewer_logo = "https://img.shields.io/badge/render-nbviewer-f37726" raw_notebook_logo = "https://img.shields.io/badge/raw-notebook-4cc61e" notebook_path = "tutorials/notebooks/$notebook_filename" - binder_url = "https://mybinder.org/v2/gh/trixi-framework/Trixi.jl/tutorial_notebooks?filepath=$notebook_path" + binder_url = "https://mybinder.org/v2/gh/trixi-framework/Trixi.jl/tutorial_notebooks?filepath=$notebook_path" nbviewer_url = "https://nbviewer.jupyter.org/github/trixi-framework/Trixi.jl/blob/tutorial_notebooks/$notebook_path" raw_notebook_url = "https://raw.githubusercontent.com/trixi-framework/Trixi.jl/tutorial_notebooks/$notebook_path" - binder_badge = "# [![]($binder_logo)]($binder_url)" + binder_badge = "# [![]($binder_logo)]($binder_url)" nbviewer_badge = "# [![]($nbviewer_logo)]($nbviewer_url)" raw_notebook_badge = "# [![]($raw_notebook_logo)]($raw_notebook_url)" @@ -28,28 +28,25 @@ function create_files(title, file, repo_src, pages_dir, notebooks_dir; folder = # available for the latest stable release of Trixi.jl at the time of caching.\n\n" return string("# # $title\n\n", warning, content) end - Literate.notebook(joinpath(repo_src, folder, file), joinpath(notebooks_dir, folder); - execute = false, preprocess = preprocess_notebook, credit = false) + Literate.notebook(joinpath(repo_src, folder, file), joinpath(notebooks_dir, folder); execute=false, preprocess=preprocess_notebook, credit=false) # Generate markdown file function preprocess_docs(content) - return string("# # [$title](@id $(splitext(file)[1]))\n $binder_badge\n $nbviewer_badge\n $raw_notebook_badge\n\n", - content) + return string("# # [$title](@id $(splitext(file)[1]))\n $binder_badge\n $nbviewer_badge\n $raw_notebook_badge\n\n", content) end - Literate.markdown(joinpath(repo_src, folder, file), joinpath(pages_dir, folder); - preprocess = preprocess_docs,) + Literate.markdown(joinpath(repo_src, folder, file), joinpath(pages_dir, folder); preprocess=preprocess_docs,) end # Create tutorials with Literate.jl function create_tutorials(files) - repo_src = joinpath(@__DIR__, "src", "files") + repo_src = joinpath(@__DIR__, "src", "files") - pages_dir = joinpath(@__DIR__, "..", "src", "tutorials") - notebooks_dir = joinpath(pages_dir, "notebooks") + pages_dir = joinpath(@__DIR__, "..", "src", "tutorials") + notebooks_dir = joinpath(pages_dir, "notebooks") - Sys.rm(pages_dir; recursive = true, force = true) + Sys.rm(pages_dir; recursive=true, force=true) - Sys.rm("out"; recursive = true, force = true) + Sys.rm("out"; recursive=true, force=true) # Run tests on all tutorial files @testset "TrixiTutorials" begin @@ -62,8 +59,7 @@ function create_tutorials(files) mod = gensym(filename[j][2][2]) @testset "$(filename[j][2][2])" begin @eval module $mod - include(joinpath($repo_src, $(filename[j][2][1]), - $(filename[j][2][2]))) + include(joinpath($repo_src, $(filename[j][2][1]), $(filename[j][2][2]))) end end end @@ -71,7 +67,7 @@ function create_tutorials(files) mod = gensym(title) @testset "$title" begin @eval module $mod - include(joinpath($repo_src, $filename)) + include(joinpath($repo_src, $filename)) end end end @@ -89,10 +85,9 @@ function create_tutorials(files) end return content end - Literate.markdown(joinpath(repo_src, "index.jl"), pages_dir; name = "introduction", - preprocess = preprocess_introduction) + Literate.markdown(joinpath(repo_src, "index.jl"), pages_dir; name="introduction", preprocess=preprocess_introduction) # Navigation system for makedocs - pages = Any["Introduction" => "tutorials/introduction.md"] + pages = Any["Introduction" => "tutorials/introduction.md",] # Create markdown and notebook files for tutorials for (i, (title, filename)) in enumerate(files) @@ -100,9 +95,8 @@ function create_tutorials(files) if filename isa Vector vector = [] for j in eachindex(filename) - create_files("$i.$j: $title: $(filename[j][1])", filename[j][2][2], - repo_src, - pages_dir, notebooks_dir; folder = filename[j][2][1]) + create_files("$i.$j: $title: $(filename[j][1])", filename[j][2][2], repo_src, + pages_dir, notebooks_dir; folder=filename[j][2][1]) path = "$(filename[j][2][1])/$(splitext(filename[j][2][2])[1]).md" push!(vector, "$i.$j $(filename[j][1])" => "tutorials/$path") diff --git a/docs/literate/src/files/DGMulti_1.jl b/docs/literate/src/files/DGMulti_1.jl index c3095d8938..6c9a5aea93 100644 --- a/docs/literate/src/files/DGMulti_1.jl +++ b/docs/literate/src/files/DGMulti_1.jl @@ -30,22 +30,22 @@ dg = DGMulti(polydeg = 3, cells_per_dimension = (32, 32) mesh = DGMultiMesh(dg, cells_per_dimension, # initial_refinement_level = 5 - coordinates_min = (-2.0, -2.0), - coordinates_max = (2.0, 2.0), - periodicity = true) + coordinates_min=(-2.0, -2.0), + coordinates_max=( 2.0, 2.0), + periodicity=true) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg, - boundary_conditions = boundary_condition_periodic) + boundary_conditions=boundary_condition_periodic) tspan = (0.0, 0.4) ode = semidiscretize(semi, tspan) -alive_callback = AliveCallback(alive_interval = 10) -analysis_callback = AnalysisCallback(semi, interval = 100, uEltype = real(dg)) +alive_callback = AliveCallback(alive_interval=10) +analysis_callback = AnalysisCallback(semi, interval=100, uEltype=real(dg)) callbacks = CallbackSet(analysis_callback, alive_callback); # Run the simulation with the same time integration algorithm as before. -sol = solve(ode, RDPK3SpFSAL49(), abstol = 1.0e-6, reltol = 1.0e-6, - callback = callbacks, save_everystep = false); +sol = solve(ode, RDPK3SpFSAL49(), abstol=1.0e-6, reltol=1.0e-6, + callback=callbacks, save_everystep=false); #- using Plots pd = PlotData2D(sol) @@ -60,6 +60,7 @@ plot!(getmesh(pd)) # (2021) provides a nice runtime comparison between the different mesh types. On the other hand, # the functions are more general and thus we have more option we can choose from. + # ## Simulation with Gauss nodes # For instance, we can change the approximation type of our simulation. using Trixi, OrdinaryDiffEq @@ -77,27 +78,28 @@ dg = DGMulti(polydeg = 3, cells_per_dimension = (32, 32) mesh = DGMultiMesh(dg, - cells_per_dimension, # initial_refinement_level = 5 - coordinates_min = (-2.0, -2.0), - coordinates_max = (2.0, 2.0), - periodicity = true) + cells_per_dimension, # initial_refinement_level = 5 + coordinates_min=(-2.0, -2.0), + coordinates_max=( 2.0, 2.0), + periodicity=true) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg, - boundary_conditions = boundary_condition_periodic) + boundary_conditions=boundary_condition_periodic) tspan = (0.0, 0.4) ode = semidiscretize(semi, tspan) -alive_callback = AliveCallback(alive_interval = 10) -analysis_callback = AnalysisCallback(semi, interval = 100, uEltype = real(dg)) +alive_callback = AliveCallback(alive_interval=10) +analysis_callback = AnalysisCallback(semi, interval=100, uEltype=real(dg)) callbacks = CallbackSet(analysis_callback, alive_callback); -sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, - ode_default_options()..., callback = callbacks); +sol = solve(ode, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, + ode_default_options()..., callback=callbacks); #- using Plots pd = PlotData2D(sol) plot(pd) + # ## Simulation with triangular elements # Also, we can set another element type. We want to use triangles now. using Trixi, OrdinaryDiffEq @@ -117,21 +119,21 @@ dg = DGMulti(polydeg = 3, cells_per_dimension = (32, 32) mesh = DGMultiMesh(dg, cells_per_dimension, # initial_refinement_level = 5 - coordinates_min = (-2.0, -2.0), - coordinates_max = (2.0, 2.0), - periodicity = true) + coordinates_min=(-2.0, -2.0), + coordinates_max=( 2.0, 2.0), + periodicity=true) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg, - boundary_conditions = boundary_condition_periodic) + boundary_conditions=boundary_condition_periodic) tspan = (0.0, 0.4) ode = semidiscretize(semi, tspan) -alive_callback = AliveCallback(alive_interval = 10) -analysis_callback = AnalysisCallback(semi, interval = 100, uEltype = real(dg)) +alive_callback = AliveCallback(alive_interval=10) +analysis_callback = AnalysisCallback(semi, interval=100, uEltype=real(dg)) callbacks = CallbackSet(analysis_callback, alive_callback); -sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, - ode_default_options()..., callback = callbacks); +sol = solve(ode, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, + ode_default_options()..., callback=callbacks); #- using Plots pd = PlotData2D(sol) @@ -140,6 +142,7 @@ plot(pd) plot(pd["rho"]) plot!(getmesh(pd)) + # ## Triangular meshes on non-Cartesian domains # To use triangular meshes on a non-Cartesian domain, Trixi.jl uses the package [StartUpDG.jl](https://github.com/jlchan/StartUpDG.jl). # The following example is based on [`elixir_euler_triangulate_pkg_mesh.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/dgmulti_2d/elixir_euler_triangulate_pkg_mesh.jl) @@ -154,7 +157,7 @@ source_terms = source_terms_convergence_test # We create the solver `DGMulti` with triangular elements (`Tri()`) as before. dg = DGMulti(polydeg = 3, element_type = Tri(), - approximation_type = Polynomial(), + approximation_type=Polynomial(), surface_flux = flux_lax_friedrichs, volume_integral = VolumeIntegralFluxDifferencing(flux_ranocha)) @@ -165,11 +168,11 @@ meshIO = StartUpDG.triangulate_domain(StartUpDG.RectangularDomainWithHole()); # The pre-defined Triangulate geometry in StartUpDG has integer boundary tags. With [`DGMultiMesh`](@ref) # we assign boundary faces based on these integer boundary tags and create a mesh compatible with Trixi.jl. -mesh = DGMultiMesh(dg, meshIO, Dict(:outer_boundary => 1, :inner_boundary => 2)) +mesh = DGMultiMesh(dg, meshIO, Dict(:outer_boundary=>1, :inner_boundary=>2)) #- boundary_condition_convergence_test = BoundaryConditionDirichlet(initial_condition) boundary_conditions = (; :outer_boundary => boundary_condition_convergence_test, - :inner_boundary => boundary_condition_convergence_test) + :inner_boundary => boundary_condition_convergence_test) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg, source_terms = source_terms, @@ -178,12 +181,12 @@ semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg, tspan = (0.0, 0.2) ode = semidiscretize(semi, tspan) -alive_callback = AliveCallback(alive_interval = 20) -analysis_callback = AnalysisCallback(semi, interval = 200, uEltype = real(dg)) +alive_callback = AliveCallback(alive_interval=20) +analysis_callback = AnalysisCallback(semi, interval=200, uEltype=real(dg)) callbacks = CallbackSet(alive_callback, analysis_callback); -sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false), - dt = 0.5 * estimate_dt(mesh, dg), save_everystep = false, callback = callbacks); +sol = solve(ode, CarpenterKennedy2N54(williamson_condition=false), + dt = 0.5 * estimate_dt(mesh, dg), save_everystep=false, callback=callbacks); #- using Plots pd = PlotData2D(sol) @@ -192,6 +195,7 @@ plot!(getmesh(pd)) # For more information, please have a look in the [StartUpDG.jl documentation](https://jlchan.github.io/StartUpDG.jl/stable/). + # ## Package versions # These results were obtained using the following versions. @@ -201,4 +205,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "StartUpDG", "OrdinaryDiffEq", "Plots"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/DGMulti_2.jl b/docs/literate/src/files/DGMulti_2.jl index c90063c3a0..0624856234 100644 --- a/docs/literate/src/files/DGMulti_2.jl +++ b/docs/literate/src/files/DGMulti_2.jl @@ -8,8 +8,8 @@ # to the `DGMulti` constructor. For example, the classical second-order FD SBP operator # can be created as using Trixi.SummationByPartsOperators # or add SummationByPartsOperators to your project and use it directly -D = derivative_operator(MattssonNordström2004(), derivative_order = 1, accuracy_order = 2, - xmin = 0.0, xmax = 1.0, N = 11) +D = derivative_operator(MattssonNordström2004(), derivative_order=1, accuracy_order=2, + xmin=0.0, xmax=1.0, N=11) # Here, the arguments `xmin` and `xmax` do not matter beyond setting the real type # used for the operator - they just set a reference element and are rescaled on the # physical elements. The parameter `N` determines the number of finite difference nodes. @@ -20,8 +20,8 @@ D = derivative_operator(MattssonNordström2004(), derivative_order = 1, accuracy # # You can also use fully periodic single-block FD methods by creating a periodic SBP # operator. For example, a fully periodic FD operator can be constructed as -D = periodic_derivative_operator(derivative_order = 1, accuracy_order = 2, - xmin = 0.0, xmax = 1.0, N = 11) +D = periodic_derivative_operator(derivative_order=1, accuracy_order=2, + xmin=0.0, xmax=1.0, N=11) # An example using such an FD method is implemented in # [`elixir_euler_fdsbp_periodic.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/dgmulti_2d/elixir_euler_fdsbp_periodic.jl). # For all parameters and other calling options, please have a look in the @@ -31,14 +31,15 @@ D = periodic_derivative_operator(derivative_order = 1, accuracy_order = 2, # method with polynomial degree of `3` (`N=4` Legendre Lobatto nodes on `[0, 1]`) coupled continuously # on a uniform mesh with `Nx=10` elements by setting `approximation_type` to using Trixi.SummationByPartsOperators # or add SummationByPartsOperators to your project and use it directly -D = couple_continuously(legendre_derivative_operator(xmin = 0.0, xmax = 1.0, N = 4), - UniformPeriodicMesh1D(xmin = -1.0, xmax = 1.0, Nx = 10)) +D = couple_continuously(legendre_derivative_operator(xmin=0.0, xmax=1.0, N=4), + UniformPeriodicMesh1D(xmin=-1.0, xmax=1.0, Nx=10)) # To choose a discontinuous coupling (DGSEM), use `couple_discontinuously()` instead of `couple_continuously()`. # For more information and other SBP operators, see the documentations of [StartUpDG.jl](https://jlchan.github.io/StartUpDG.jl/dev/) # and [SummationByPartsOperators.jl](https://ranocha.de/SummationByPartsOperators.jl/stable/). + # ## Package versions # These results were obtained using the following versions. @@ -48,4 +49,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "StartUpDG", "SummationByPartsOperators"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/DGSEM_FluxDiff.jl b/docs/literate/src/files/DGSEM_FluxDiff.jl index faafe45812..a576990026 100644 --- a/docs/literate/src/files/DGSEM_FluxDiff.jl +++ b/docs/literate/src/files/DGSEM_FluxDiff.jl @@ -20,6 +20,7 @@ # J u_t + f(u)_{\xi} = 0, \qquad t\in \mathbb{R}^+, \xi\in [-1,1] # ``` + # ## The weak form of the DGSEM # We consider the so-called discontinuous Galerkin spectral element method (DGSEM) with collocation. # It results from choosing a nodal DG ansatz using $N+1$ Gauss-Lobatto nodes $\xi_i$ in $[-1,1]$ @@ -76,6 +77,7 @@ # ``` # More information about the equivalence you can find in [Kopriva, Gassner (2010)](https://doi.org/10.1007/s10915-010-9372-3). + # ## DGSEM with flux differencing # When using the diagonal SBP property it is possible to rewrite the application of the derivative # operator $D$ in the calculation of the volume integral into a subcell based finite volume type @@ -103,6 +105,7 @@ # flux $f=f_{surface}$ used for the numerical flux $f_{surface}^*$ and the already mentioned volume # flux $f_{vol}$ especially for this formulation. + # This formulation creates a more stable version of DGSEM, because it fulfils entropy stability. # Moreover it allows the construction of entropy conserving discretizations without relying on # exact integration. This is achieved when using a two-point entropy conserving flux function as @@ -110,6 +113,8 @@ # Then, the numerical surface flux can be used to control the dissipation of the discretization and to # guarantee decreasing entropy, i.e. entropy stability. + + # ## [Implementation in Trixi.jl](@id fluxDiffExample) # Now, we have a look at the implementation of DGSEM with flux differencing with [Trixi.jl](https://github.com/trixi-framework/Trixi.jl). using OrdinaryDiffEq, Trixi @@ -153,21 +158,21 @@ initial_condition = initial_condition_weak_blast_wave # We will confirm the entropy conservation property numerically. volume_flux = flux_ranocha # = f_vol -solver = DGSEM(polydeg = 3, surface_flux = volume_flux, - volume_integral = VolumeIntegralFluxDifferencing(volume_flux)) +solver = DGSEM(polydeg=3, surface_flux=volume_flux, + volume_integral=VolumeIntegralFluxDifferencing(volume_flux)) # Now, we implement Trixi.jl's `mesh`, `semi` and `ode` in a simple framework. For more information please # have a look at the documentation, the basic tutorial [introduction to DG methods](@ref scalar_linear_advection_1d) # or some basic elixirs. coordinates_min = (-2.0, -2.0) -coordinates_max = (2.0, 2.0) +coordinates_max = ( 2.0, 2.0) mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level = 5, - n_cells_max = 10_000, - periodicity = true) + initial_refinement_level=5, + n_cells_max=10_000, + periodicity=true) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - boundary_conditions = boundary_condition_periodic) + boundary_conditions=boundary_condition_periodic) ## ODE solvers tspan = (0.0, 0.4) @@ -175,11 +180,11 @@ ode = semidiscretize(semi, tspan); # To analyse the entropy conservation of the approximation, we will use the analysis calllback # implemented in Trixi. It provides some information about the approximation including the entropy change. -analysis_callback = AnalysisCallback(semi, interval = 100); +analysis_callback = AnalysisCallback(semi, interval=100); # We now run the simulation using `flux_ranocha` for both surface and volume flux. -sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, - ode_default_options()..., callback = analysis_callback); +sol = solve(ode, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, + ode_default_options()..., callback=analysis_callback); # A look at the change in entropy $\sum \partial S/\partial U \cdot U_t$ in the analysis callback # confirms that the flux is entropy conserving since the change is about machine precision. @@ -197,33 +202,34 @@ equations = CompressibleEulerEquations2D(gamma) initial_condition = initial_condition_weak_blast_wave volume_flux = flux_ranocha # = f_vol -solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs, - volume_integral = VolumeIntegralFluxDifferencing(volume_flux)) +solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs, + volume_integral=VolumeIntegralFluxDifferencing(volume_flux)) coordinates_min = (-2.0, -2.0) -coordinates_max = (2.0, 2.0) +coordinates_max = ( 2.0, 2.0) mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level = 5, - n_cells_max = 10_000, - periodicity = true) + initial_refinement_level=5, + n_cells_max=10_000, + periodicity=true) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - boundary_conditions = boundary_condition_periodic) + boundary_conditions=boundary_condition_periodic) ## ODE solvers tspan = (0.0, 0.4) ode = semidiscretize(semi, tspan); -analysis_callback = AnalysisCallback(semi, interval = 100); +analysis_callback = AnalysisCallback(semi, interval=100); # We now run the simulation using the volume flux `flux_ranocha` and surface flux `flux_lax_friedrichs`. -sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, - ode_default_options()..., callback = analysis_callback); +sol = solve(ode, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, + ode_default_options()..., callback=analysis_callback); # The change in entropy confirms the expected entropy stability. using Plots plot(sol) + # Of course, you can use more than these two fluxes in Trixi. Here, we will give a short list # of possible fluxes for the compressible Euler equations. # For the volume flux Trixi.jl provides for example [`flux_ranocha`](@ref), [`flux_shima_etal`](@ref), @@ -231,6 +237,7 @@ plot(sol) # As surface flux you can use all volume fluxes and additionally for instance [`flux_lax_friedrichs`](@ref), # [`flux_hll`](@ref), [`flux_hllc`](@ref). + # ## Package versions # These results were obtained using the following versions. @@ -240,4 +247,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/adaptive_mesh_refinement.jl b/docs/literate/src/files/adaptive_mesh_refinement.jl index 608c415efd..46af8f7952 100644 --- a/docs/literate/src/files/adaptive_mesh_refinement.jl +++ b/docs/literate/src/files/adaptive_mesh_refinement.jl @@ -50,6 +50,7 @@ # amr_indicator = IndicatorMax(semi, variable=variable) # ```` + # ### Controllers # The spatial discretization into elements is tree-based for both AMR supporting mesh types `TreeMesh` # and `P4estMesh`. Thus, the higher the level in the tree the higher the level of refinement. @@ -86,6 +87,7 @@ # This controller is for instance used in # [`elixir_euler_astro_jet_amr.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_2d_dgsem/elixir_euler_astro_jet_amr.jl). + # ### Callback # The AMR indicator and controller are added to the simulation through the callback [`AMRCallback`](@ref). # It contains a semidiscretization `semi`, the controller `amr_controller` and the parameters `interval`, @@ -101,6 +103,7 @@ # adapt_initial_condition_only_refine=true) # ```` + # # Exemplary simulation # Here, we want to implement a simple AMR simulation of the 2D linear advection equation for a Gaussian pulse. @@ -111,16 +114,17 @@ advection_velocity = (0.2, -0.7) equations = LinearScalarAdvectionEquation2D(advection_velocity) initial_condition = initial_condition_gauss -solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) +solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) coordinates_min = (-5.0, -5.0) -coordinates_max = (5.0, 5.0) +coordinates_max = ( 5.0, 5.0) mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level = 4, - n_cells_max = 30_000) + initial_refinement_level=4, + n_cells_max=30_000) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver) + tspan = (0.0, 10.0) ode = semidiscretize(semi, tspan); @@ -128,29 +132,29 @@ ode = semidiscretize(semi, tspan); # `IndicatorMax`. As described before, it returns the maximal value of the specified variable # (here the only conserved variable). Therefore, regions with a high maximum are refined. # This is not really useful numerical application, but a nice demonstration example. -amr_indicator = IndicatorMax(semi, variable = first) +amr_indicator = IndicatorMax(semi, variable=first) # These values are transferred to a refinement level with the `ControllerThreeLevel`, such that # every element with maximal value greater than `0.1` is refined once and elements with maximum # above `0.6` are refined twice. amr_controller = ControllerThreeLevel(semi, amr_indicator, - base_level = 4, - med_level = 5, med_threshold = 0.1, - max_level = 6, max_threshold = 0.6) + base_level=4, + med_level=5, med_threshold=0.1, + max_level=6, max_threshold=0.6) amr_callback = AMRCallback(semi, amr_controller, - interval = 5, - adapt_initial_condition = true, - adapt_initial_condition_only_refine = true) + interval=5, + adapt_initial_condition=true, + adapt_initial_condition_only_refine=true) -stepsize_callback = StepsizeCallback(cfl = 0.9) +stepsize_callback = StepsizeCallback(cfl=0.9) callbacks = CallbackSet(amr_callback, stepsize_callback); # Running the simulation. -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); +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); # We plot the solution and add the refined mesh at the end of the simulation. using Plots @@ -158,6 +162,7 @@ pd = PlotData2D(sol) plot(pd) plot!(getmesh(pd)) + # # More examples # Trixi.jl provides many elixirs using AMR. We want to give some examples for different mesh types: # - `elixir_euler_blast_wave_amr.jl` for [`TreeMesh`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_2d_dgsem/elixir_euler_blast_wave_amr.jl) @@ -198,6 +203,7 @@ plot!(getmesh(pd)) # For more information, please have a look at the respective links. + # ## Package versions # These results were obtained using the following versions. @@ -207,4 +213,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/adding_new_parabolic_terms.jl b/docs/literate/src/files/adding_new_parabolic_terms.jl index 5240a67447..209ef62c98 100644 --- a/docs/literate/src/files/adding_new_parabolic_terms.jl +++ b/docs/literate/src/files/adding_new_parabolic_terms.jl @@ -7,6 +7,7 @@ using OrdinaryDiffEq using Trixi + advection_velocity = (1.0, 1.0) equations_hyperbolic = LinearScalarAdvectionEquation2D(advection_velocity); @@ -25,15 +26,13 @@ equations_hyperbolic = LinearScalarAdvectionEquation2D(advection_velocity); # the gradient with respect to a different set of variables; see, for example, the implementation of # [`CompressibleNavierStokesDiffusion2D`](@ref), which can utilize either "primitive" or "entropy" variables. -struct ConstantAnisotropicDiffusion2D{E, T} <: - Trixi.AbstractEquationsParabolic{2, 1, GradientVariablesConservative} - diffusivity::T - equations_hyperbolic::E +struct ConstantAnisotropicDiffusion2D{E, T} <: Trixi.AbstractEquationsParabolic{2, 1, GradientVariablesConservative} + diffusivity::T + equations_hyperbolic::E end -function varnames(variable_mapping, equations_parabolic::ConstantAnisotropicDiffusion2D) - varnames(variable_mapping, equations_parabolic.equations_hyperbolic) -end +varnames(variable_mapping, equations_parabolic::ConstantAnisotropicDiffusion2D) = + varnames(variable_mapping, equations_parabolic.equations_hyperbolic) # Next, we define the viscous flux function. We assume that the mixed hyperbolic-parabolic system # is of the form @@ -47,15 +46,14 @@ end # # Here, we specialize the flux to our new parabolic equation type `ConstantAnisotropicDiffusion2D`. -function Trixi.flux(u, gradients, orientation::Integer, - equations_parabolic::ConstantAnisotropicDiffusion2D) - @unpack diffusivity = equations_parabolic - dudx, dudy = gradients - if orientation == 1 - return SVector(diffusivity[1, 1] * dudx + diffusivity[1, 2] * dudy) - else # if orientation == 2 - return SVector(diffusivity[2, 1] * dudx + diffusivity[2, 2] * dudy) - end +function Trixi.flux(u, gradients, orientation::Integer, equations_parabolic::ConstantAnisotropicDiffusion2D) + @unpack diffusivity = equations_parabolic + dudx, dudy = gradients + if orientation == 1 + return SVector(diffusivity[1, 1] * dudx + diffusivity[1, 2] * dudy) + else # if orientation == 2 + return SVector(diffusivity[2, 1] * dudx + diffusivity[2, 2] * dudy) + end end # ## Defining boundary conditions @@ -78,7 +76,7 @@ end # As an example, let us introduce a Dirichlet boundary condition with constant boundary data. struct BoundaryConditionConstantDirichlet{T <: Real} - boundary_value::T + boundary_value::T end # This boundary condition contains only the field `boundary_value`, which we assume to be some @@ -89,13 +87,10 @@ end # the `Gradient` and `Divergence`. Since the gradient is operating on the solution `u`, the boundary # data should be the value of `u`, and we can directly impose Dirichlet data. -@inline function (boundary_condition::BoundaryConditionConstantDirichlet)(flux_inner, - u_inner, - normal::AbstractVector, - x, t, - operator_type::Trixi.Gradient, +@inline function (boundary_condition::BoundaryConditionConstantDirichlet)(flux_inner, u_inner, normal::AbstractVector, + x, t, operator_type::Trixi.Gradient, equations_parabolic::ConstantAnisotropicDiffusion2D) - return boundary_condition.boundary_value + return boundary_condition.boundary_value end # While the gradient acts on the solution `u`, the divergence acts on the viscous flux ``\bm{\sigma}``. @@ -107,13 +102,10 @@ end # `flux_inner`, which is boundary data for ``\bm{\sigma}`` computed using the "inner" or interior solution. # This way, we supply boundary data for the divergence operation without imposing any additional conditions. -@inline function (boundary_condition::BoundaryConditionConstantDirichlet)(flux_inner, - u_inner, - normal::AbstractVector, - x, t, - operator_type::Trixi.Divergence, +@inline function (boundary_condition::BoundaryConditionConstantDirichlet)(flux_inner, u_inner, normal::AbstractVector, + x, t, operator_type::Trixi.Divergence, equations_parabolic::ConstantAnisotropicDiffusion2D) - return flux_inner + return flux_inner end # ### A note on the choice of gradient variables @@ -138,42 +130,42 @@ using Trixi: SMatrix diffusivity = 5.0e-2 * SMatrix{2, 2}([2 -1; -1 2]) equations_parabolic = ConstantAnisotropicDiffusion2D(diffusivity, equations_hyperbolic); -boundary_conditions_hyperbolic = (; - x_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(1.0)), - y_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(2.0)), - y_pos = boundary_condition_do_nothing, - x_pos = boundary_condition_do_nothing) +boundary_conditions_hyperbolic = (; x_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(1.0)), + y_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(2.0)), + y_pos = boundary_condition_do_nothing, + x_pos = boundary_condition_do_nothing) boundary_conditions_parabolic = (; x_neg = BoundaryConditionConstantDirichlet(1.0), - y_neg = BoundaryConditionConstantDirichlet(2.0), - y_pos = BoundaryConditionConstantDirichlet(0.0), - x_pos = BoundaryConditionConstantDirichlet(0.0)); + y_neg = BoundaryConditionConstantDirichlet(2.0), + y_pos = BoundaryConditionConstantDirichlet(0.0), + x_pos = BoundaryConditionConstantDirichlet(0.0)); -solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) +solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) coordinates_min = (-1.0, -1.0) # minimum coordinates (min(x), min(y)) -coordinates_max = (1.0, 1.0) # maximum coordinates (max(x), max(y)) +coordinates_max = ( 1.0, 1.0) # maximum coordinates (max(x), max(y)) mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level = 4, - periodicity = false, n_cells_max = 30_000) # set maximum capacity of tree data structure + initial_refinement_level=4, + periodicity=false, n_cells_max=30_000) # set maximum capacity of tree data structure initial_condition = (x, t, equations) -> SVector(0.0) semi = SemidiscretizationHyperbolicParabolic(mesh, (equations_hyperbolic, equations_parabolic), initial_condition, solver; - boundary_conditions = (boundary_conditions_hyperbolic, - boundary_conditions_parabolic)) + boundary_conditions=(boundary_conditions_hyperbolic, + boundary_conditions_parabolic)) tspan = (0.0, 2.0) ode = semidiscretize(semi, tspan) callbacks = CallbackSet(SummaryCallback()) time_int_tol = 1.0e-6 -sol = solve(ode, RDPK3SpFSAL49(); abstol = time_int_tol, reltol = time_int_tol, - ode_default_options()..., callback = callbacks); +sol = solve(ode, RDPK3SpFSAL49(); abstol=time_int_tol, reltol=time_int_tol, + ode_default_options()..., callback=callbacks); using Plots plot(sol) + # ## Package versions # These results were obtained using the following versions. @@ -183,4 +175,5 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) + diff --git a/docs/literate/src/files/adding_new_scalar_equations.jl b/docs/literate/src/files/adding_new_scalar_equations.jl index 243d379351..a65b4de7f1 100644 --- a/docs/literate/src/files/adding_new_scalar_equations.jl +++ b/docs/literate/src/files/adding_new_scalar_equations.jl @@ -12,8 +12,8 @@ # ## Basic setup using Trixi -struct CubicEquation <: Trixi.AbstractEquations{1, #= number of spatial dimensions =# - 1} #= number of primary variables, i.e. scalar =# +struct CubicEquation <: Trixi.AbstractEquations{1 #= number of spatial dimensions =#, + 1 #= number of primary variables, i.e. scalar =#}; end # We create `CubicEquation` as an empty `struct` since we do not use any parameters @@ -23,7 +23,7 @@ end # Next, we define the physical flux `f(u) = u^3` using the calling structure # used in Trixi.jl. -Trixi.flux(u, orientation, equation::CubicEquation) = u .^ 3 +Trixi.flux(u, orientation, equation::CubicEquation) = u.^3 Trixi.varnames(_, ::CubicEquation) = ("scalar",) # In Trixi.jl, the conserved variables `u` are usually passed as `SVector`s of variables @@ -41,10 +41,10 @@ equation = CubicEquation() initial_condition_sine(x, t, equation::CubicEquation) = SVector(sinpi(x[1])) mesh = TreeMesh(-1.0, 1.0, # min/max coordinates - initial_refinement_level = 4, - n_cells_max = 10^4) + initial_refinement_level=4, + n_cells_max=10^4) -solver = DGSEM(3, flux_central) #= polynomial degree =# +solver = DGSEM(3 #= polynomial degree =#, flux_central) semi = SemidiscretizationHyperbolic(mesh, equation, initial_condition_sine, solver) @@ -67,7 +67,7 @@ callbacks = CallbackSet(summary_callback) ## OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks sol = solve(ode, SSPRK43(); - ode_default_options()..., callback = callbacks); + ode_default_options()..., callback=callbacks); # That's it, you ran your first simulation using your new equation with Trixi.jl! Now, we can plot # the solution at the final time using Plots.jl. @@ -79,21 +79,20 @@ plot(sol) # To avoid these issues, we need to use dissipative numerical fluxes (approximate # Riemann solvers) at interfaces. + # ## Advanced setup # Thus, we add a Godunov's flux for our cubic equation. That is easy for this equation # since the wave speed `f'(u) = 3u^2` is always non-negative. -@inline Trixi.flux_godunov(u_ll, u_rr, orientation, equation::CubicEquation) = flux(u_ll, - orientation, - equation) +@inline Trixi.flux_godunov(u_ll, u_rr, orientation, equation::CubicEquation) = flux(u_ll, orientation, equation) # Let's run the example again but with a dissipative numerical flux at interfaces. # `remake` will recreate the semidiscretization we used before and only change # selected parameters, in this case the `solver`. ## A new setup with dissipation -semi = remake(semi, solver = DGSEM(3, flux_godunov)) +semi = remake(semi, solver=DGSEM(3, flux_godunov)) ode = semidiscretize(semi, tspan) sol = solve(ode, SSPRK43(); ode_default_options()...) plot!(sol) @@ -102,9 +101,8 @@ plot!(sol) # Now let's increase the final time (and also the spatial resolution). ## A larger final time: Nonclassical shocks develop (you can even increase the refinement to 12) -semi = remake(semi, - mesh = TreeMesh(-1.0, 1.0, initial_refinement_level = 8, n_cells_max = 10^5)) -ode = semidiscretize(semi, (0.0, 0.5)) #= tspan =# +semi = remake(semi, mesh=TreeMesh(-1.0, 1.0, initial_refinement_level=8, n_cells_max=10^5)) +ode = semidiscretize(semi, (0.0, 0.5) #= tspan =#) sol = solve(ode, SSPRK43(); ode_default_options()...) plot(sol) @@ -114,16 +112,14 @@ plot(sol) # to define an entropy-conservative numerical flux @inline function Trixi.flux_ec(u_ll, u_rr, orientation, equation::CubicEquation) - return SVector(0.25 * - (u_ll[1]^3 + u_ll[1]^2 * u_rr[1] + u_ll[1] * u_rr[1]^2 + u_rr[1]^3)) + return SVector(0.25 * (u_ll[1]^3 + u_ll[1]^2 * u_rr[1] + u_ll[1] * u_rr[1]^2 + u_rr[1]^3)) end # and use a [`VolumeIntegralFluxDifferencing`](@ref) instead of the standard # [`VolumeIntegralWeakForm`](@ref) in the DGSEM. ## Let's use a provably entropy-dissipative semidiscretization -semi = remake(semi, - solver = DGSEM(3, flux_godunov, VolumeIntegralFluxDifferencing(flux_ec))) +semi = remake(semi, solver=DGSEM(3, flux_godunov, VolumeIntegralFluxDifferencing(flux_ec))) ode = semidiscretize(semi, (0.0, 0.5)) sol = solve(ode, SSPRK43(); ode_default_options()...); plot(sol) @@ -141,6 +137,7 @@ plot(sol) # the 2D scalar "KPP equation" from [Kurganov, Petrova, Popov (2007)](https://doi.org/10.1137/040614189) is # implemented. + # ## Summary of the code # To sum up, here is the complete code that we used (without the callbacks since these create a @@ -153,23 +150,21 @@ module CubicConservationLaw using Trixi -struct CubicEquation <: Trixi.AbstractEquations{1, #= number of spatial dimensions =# - 1} #= number of primary variables, i.e. scalar =# +struct CubicEquation <: Trixi.AbstractEquations{1 #= number of spatial dimensions =#, + 1 #= number of primary variables, i.e. scalar =#} end -@inline Trixi.flux(u, orientation, equation::CubicEquation) = u .^ 3 +@inline Trixi.flux(u, orientation, equation::CubicEquation) = u.^3 Trixi.varnames(_, ::CubicEquation) = ("scalar",) -@inline Trixi.flux_godunov(u_ll, u_rr, orientation, equation::CubicEquation) = flux(u_ll, - orientation, - equation) +@inline Trixi.flux_godunov(u_ll, u_rr, orientation, equation::CubicEquation) = flux(u_ll, orientation, equation) @inline function Trixi.flux_ec(u_ll, u_rr, orientation, equation::CubicEquation) - return SVector(0.25 * - (u_ll[1]^3 + u_ll[1]^2 * u_rr[1] + u_ll[1] * u_rr[1]^2 + u_rr[1]^3)) + return SVector(0.25 * (u_ll[1]^3 + u_ll[1]^2 * u_rr[1] + u_ll[1] * u_rr[1]^2 + u_rr[1]^3)) end end # module + ## Create a simulation setup import .CubicConservationLaw using Trixi @@ -178,15 +173,13 @@ using Plots equation = CubicConservationLaw.CubicEquation() -function initial_condition_sine(x, t, equation::CubicConservationLaw.CubicEquation) - SVector(sinpi(x[1])) -end +initial_condition_sine(x, t, equation::CubicConservationLaw.CubicEquation) = SVector(sinpi(x[1])) mesh = TreeMesh(-1.0, 1.0, # min/max coordinates - initial_refinement_level = 4, - n_cells_max = 10^4) + initial_refinement_level=4, + n_cells_max=10^4) -solver = DGSEM(3, flux_central) #= polynomial degree =# +solver = DGSEM(3 #= polynomial degree =#, flux_central) semi = SemidiscretizationHyperbolic(mesh, equation, initial_condition_sine, solver) @@ -198,26 +191,28 @@ ode = semidiscretize(semi, tspan) sol = solve(ode, SSPRK43(); ode_default_options()...) plot(sol) + ## A new setup with dissipation -semi = remake(semi, solver = DGSEM(3, flux_godunov)) +semi = remake(semi, solver=DGSEM(3, flux_godunov)) ode = semidiscretize(semi, tspan) sol = solve(ode, SSPRK43(); ode_default_options()...) plot!(sol) + ## A larger final time: Nonclassical shocks develop (you can even increase the refinement to 12) -semi = remake(semi, - mesh = TreeMesh(-1.0, 1.0, initial_refinement_level = 8, n_cells_max = 10^5)) +semi = remake(semi, mesh=TreeMesh(-1.0, 1.0, initial_refinement_level=8, n_cells_max=10^5)) ode = semidiscretize(semi, (0.0, 0.5)) sol = solve(ode, SSPRK43(); ode_default_options()...) plot(sol) + ## Let's use a provably entropy-dissipative semidiscretization -semi = remake(semi, - solver = DGSEM(3, flux_godunov, VolumeIntegralFluxDifferencing(flux_ec))) +semi = remake(semi, solver=DGSEM(3, flux_godunov, VolumeIntegralFluxDifferencing(flux_ec))) ode = semidiscretize(semi, (0.0, 0.5)) sol = solve(ode, SSPRK43(); ode_default_options()...) plot(sol) + # ## Package versions # These results were obtained using the following versions. @@ -227,4 +222,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/adding_nonconservative_equation.jl b/docs/literate/src/files/adding_nonconservative_equation.jl index 798253210e..b40e21fb11 100644 --- a/docs/literate/src/files/adding_nonconservative_equation.jl +++ b/docs/literate/src/files/adding_nonconservative_equation.jl @@ -40,28 +40,27 @@ import Trixi: varnames, default_analysis_integrals, flux, max_abs_speed_naive, ## Since there is no native support for variable coefficients, we use two ## variables: one for the basic unknown `u` and another one for the coefficient `a` -struct NonconservativeLinearAdvectionEquation <: AbstractEquations{1, #= spatial dimension =# - 2} #= two variables (u,a) =# +struct NonconservativeLinearAdvectionEquation <: AbstractEquations{1 #= spatial dimension =#, + 2 #= two variables (u,a) =#} end -function varnames(::typeof(cons2cons), ::NonconservativeLinearAdvectionEquation) - ("scalar", "advection_velocity") -end +varnames(::typeof(cons2cons), ::NonconservativeLinearAdvectionEquation) = ("scalar", "advection_velocity") default_analysis_integrals(::NonconservativeLinearAdvectionEquation) = () + ## The conservative part of the flux is zero flux(u, orientation, equation::NonconservativeLinearAdvectionEquation) = zero(u) ## Calculate maximum wave speed for local Lax-Friedrichs-type dissipation -function max_abs_speed_naive(u_ll, u_rr, orientation::Integer, - ::NonconservativeLinearAdvectionEquation) +function max_abs_speed_naive(u_ll, u_rr, orientation::Integer, ::NonconservativeLinearAdvectionEquation) _, advection_velocity_ll = u_ll _, advection_velocity_rr = u_rr return max(abs(advection_velocity_ll), abs(advection_velocity_rr)) end + ## We use nonconservative terms have_nonconservative_terms(::NonconservativeLinearAdvectionEquation) = Trixi.True() @@ -74,7 +73,7 @@ have_nonconservative_terms(::NonconservativeLinearAdvectionEquation) = Trixi.Tru function flux_nonconservative(u_mine, u_other, orientation, equations::NonconservativeLinearAdvectionEquation) _, advection_velocity = u_mine - scalar, _ = u_other + scalar, _ = u_other return SVector(advection_velocity * scalar, zero(scalar)) end @@ -106,15 +105,15 @@ end ## Create a uniform mesh in 1D in the interval [-π, π] with periodic boundaries mesh = TreeMesh(-Float64(π), Float64(π), # min/max coordinates - initial_refinement_level = 4, n_cells_max = 10^4) + initial_refinement_level=4, n_cells_max=10^4) ## Create a DGSEM solver with polynomials of degree `polydeg` ## Remember to pass a tuple of the form `(conservative_flux, nonconservative_flux)` ## as `surface_flux` and `volume_flux` when working with nonconservative terms -volume_flux = (flux_central, flux_nonconservative) +volume_flux = (flux_central, flux_nonconservative) surface_flux = (flux_lax_friedrichs, flux_nonconservative) -solver = DGSEM(polydeg = 3, surface_flux = surface_flux, - volume_integral = VolumeIntegralFluxDifferencing(volume_flux)) +solver = DGSEM(polydeg=3, surface_flux=surface_flux, + volume_integral=VolumeIntegralFluxDifferencing(volume_flux)) ## Setup the spatial semidiscretization containing all ingredients semi = SemidiscretizationHyperbolic(mesh, equation, initial_condition_sine, solver) @@ -126,13 +125,13 @@ ode = semidiscretize(semi, tspan) ## Set up some standard callbacks summarizing the simulation setup and computing ## errors of the numerical solution summary_callback = SummaryCallback() -analysis_callback = AnalysisCallback(semi, interval = 50) +analysis_callback = AnalysisCallback(semi, interval=50) callbacks = CallbackSet(summary_callback, analysis_callback) ## OrdinaryDiffEq's `solve` method evolves the solution in time and executes ## the passed callbacks -sol = solve(ode, Tsit5(), abstol = 1.0e-6, reltol = 1.0e-6, - save_everystep = false, callback = callbacks) +sol = solve(ode, Tsit5(), abstol=1.0e-6, reltol=1.0e-6, + save_everystep=false, callback=callbacks) ## Print the timer summary summary_callback() @@ -153,7 +152,7 @@ error_1 = analysis_callback(sol).l2 |> first # simulation again. mesh = TreeMesh(-Float64(π), Float64(π), # min/max coordinates - initial_refinement_level = 5, n_cells_max = 10^4) + initial_refinement_level=5, n_cells_max=10^4) semi = SemidiscretizationHyperbolic(mesh, equation, initial_condition_sine, solver) @@ -161,22 +160,24 @@ tspan = (0.0, 1.0) ode = semidiscretize(semi, tspan); summary_callback = SummaryCallback() -analysis_callback = AnalysisCallback(semi, interval = 50) +analysis_callback = AnalysisCallback(semi, interval=50) callbacks = CallbackSet(summary_callback, analysis_callback); -sol = solve(ode, Tsit5(), abstol = 1.0e-6, reltol = 1.0e-6, - save_everystep = false, callback = callbacks); +sol = solve(ode, Tsit5(), abstol=1.0e-6, reltol=1.0e-6, + save_everystep=false, callback=callbacks); summary_callback() #nb #- error_2 = analysis_callback(sol).l2 |> first -@test isapprox(error_2, 1.860295931682964e-5, rtol = 0.05) #src +@test isapprox(error_2, 1.860295931682964e-5, rtol=0.05) #src #- error_1 / error_2 -@test isapprox(error_1 / error_2, 15.916970234784808, rtol = 0.05) #src +@test isapprox(error_1 / error_2, 15.916970234784808, rtol=0.05) #src # As expected, the new error is roughly reduced by a factor of 16, corresponding # to an experimental order of convergence of 4 (for polynomials of degree 3). + + # ## Summary of the code # Here is the complete code that we used (without the callbacks since these @@ -185,6 +186,7 @@ error_1 / error_2 # That ensures that we can re-create `struct`s defined therein without having to # restart Julia. + # Define new physics module NonconservativeLinearAdvection @@ -195,28 +197,27 @@ import Trixi: varnames, default_analysis_integrals, flux, max_abs_speed_naive, ## Since there is not yet native support for variable coefficients, we use two ## variables: one for the basic unknown `u` and another one for the coefficient `a` -struct NonconservativeLinearAdvectionEquation <: AbstractEquations{1, #= spatial dimension =# - 2} #= two variables (u,a) =# +struct NonconservativeLinearAdvectionEquation <: AbstractEquations{1 #= spatial dimension =#, + 2 #= two variables (u,a) =#} end -function varnames(::typeof(cons2cons), ::NonconservativeLinearAdvectionEquation) - ("scalar", "advection_velocity") -end +varnames(::typeof(cons2cons), ::NonconservativeLinearAdvectionEquation) = ("scalar", "advection_velocity") default_analysis_integrals(::NonconservativeLinearAdvectionEquation) = () + ## The conservative part of the flux is zero flux(u, orientation, equation::NonconservativeLinearAdvectionEquation) = zero(u) ## Calculate maximum wave speed for local Lax-Friedrichs-type dissipation -function max_abs_speed_naive(u_ll, u_rr, orientation::Integer, - ::NonconservativeLinearAdvectionEquation) +function max_abs_speed_naive(u_ll, u_rr, orientation::Integer, ::NonconservativeLinearAdvectionEquation) _, advection_velocity_ll = u_ll _, advection_velocity_rr = u_rr return max(abs(advection_velocity_ll), abs(advection_velocity_rr)) end + ## We use nonconservative terms have_nonconservative_terms(::NonconservativeLinearAdvectionEquation) = Trixi.True() @@ -229,13 +230,15 @@ have_nonconservative_terms(::NonconservativeLinearAdvectionEquation) = Trixi.Tru function flux_nonconservative(u_mine, u_other, orientation, equations::NonconservativeLinearAdvectionEquation) _, advection_velocity = u_mine - scalar, _ = u_other + scalar, _ = u_other return SVector(advection_velocity * scalar, zero(scalar)) end end # module + + ## Create a simulation setup import .NonconservativeLinearAdvection using Trixi @@ -245,8 +248,7 @@ equation = NonconservativeLinearAdvection.NonconservativeLinearAdvectionEquation ## You can derive the exact solution for this setup using the method of ## characteristics -function initial_condition_sine(x, t, - equation::NonconservativeLinearAdvection.NonconservativeLinearAdvectionEquation) +function initial_condition_sine(x, t, equation::NonconservativeLinearAdvection.NonconservativeLinearAdvectionEquation) x0 = -2 * atan(sqrt(3) * tan(sqrt(3) / 2 * t - atan(tan(x[1] / 2) / sqrt(3)))) scalar = sin(x0) advection_velocity = 2 + cos(x[1]) @@ -255,15 +257,15 @@ end ## Create a uniform mesh in 1D in the interval [-π, π] with periodic boundaries mesh = TreeMesh(-Float64(π), Float64(π), # min/max coordinates - initial_refinement_level = 4, n_cells_max = 10^4) + initial_refinement_level=4, n_cells_max=10^4) ## Create a DGSEM solver with polynomials of degree `polydeg` ## Remember to pass a tuple of the form `(conservative_flux, nonconservative_flux)` ## as `surface_flux` and `volume_flux` when working with nonconservative terms -volume_flux = (flux_central, NonconservativeLinearAdvection.flux_nonconservative) +volume_flux = (flux_central, NonconservativeLinearAdvection.flux_nonconservative) surface_flux = (flux_lax_friedrichs, NonconservativeLinearAdvection.flux_nonconservative) -solver = DGSEM(polydeg = 3, surface_flux = surface_flux, - volume_integral = VolumeIntegralFluxDifferencing(volume_flux)) +solver = DGSEM(polydeg=3, surface_flux=surface_flux, + volume_integral=VolumeIntegralFluxDifferencing(volume_flux)) ## Setup the spatial semidiscretization containing all ingredients semi = SemidiscretizationHyperbolic(mesh, equation, initial_condition_sine, solver) @@ -275,18 +277,19 @@ ode = semidiscretize(semi, tspan); ## Set up some standard callbacks summarizing the simulation setup and computing ## errors of the numerical solution summary_callback = SummaryCallback() -analysis_callback = AnalysisCallback(semi, interval = 50) +analysis_callback = AnalysisCallback(semi, interval=50) callbacks = CallbackSet(summary_callback, analysis_callback); ## OrdinaryDiffEq's `solve` method evolves the solution in time and executes ## the passed callbacks -sol = solve(ode, Tsit5(), abstol = 1.0e-6, reltol = 1.0e-6, - save_everystep = false); +sol = solve(ode, Tsit5(), abstol=1.0e-6, reltol=1.0e-6, + save_everystep=false); ## Plot the numerical solution at the final time using Plots: plot plot(sol); + # ## Package versions # These results were obtained using the following versions. @@ -296,4 +299,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/behind_the_scenes_simulation_setup.jl b/docs/literate/src/files/behind_the_scenes_simulation_setup.jl index ecb3c94c8d..c93660e9bc 100644 --- a/docs/literate/src/files/behind_the_scenes_simulation_setup.jl +++ b/docs/literate/src/files/behind_the_scenes_simulation_setup.jl @@ -62,6 +62,7 @@ semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergen # perform the necessary initialization steps. A brief description of the key sub-functions is # provided below. + # - `init_elements(leaf_cell_ids, mesh, equations, dg.basis, RealT, uEltype)` # The fundamental elements for approximating the solution are the leaf @@ -72,12 +73,14 @@ semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergen # coordinates, and maps the Gauss-Lobatto nodes from the 1D interval ``[-1, 1]`` onto each coordinate axis # of every element. + # ![elements_example](https://github.com/trixi-framework/Trixi.jl/assets/119304909/9f486670-b579-4e42-8697-439540c8bbb4) # The visualization of elements with nodes shown here includes spaces between elements, which do # not exist in reality. This spacing is included only for illustrative purposes to underscore the # separation of elements and the independent projection of nodes onto each element. + # - `init_interfaces(leaf_cell_ids, mesh, elements)` # At this point, the elements with nodes have been defined; however, they lack the necessary @@ -99,6 +102,7 @@ semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergen # ![interfaces_example](https://github.com/trixi-framework/Trixi.jl/assets/119304909/bc3b6b02-afbc-4371-aaf7-c7bdc5a6c540) + # - `init_mortars(leaf_cell_ids, mesh, elements, dg.mortar)` # Returning to the consideration of different sizes among adjacent elements, within the @@ -119,6 +123,7 @@ semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergen # ![mortars_example](https://github.com/trixi-framework/Trixi.jl/assets/119304909/43a95a60-3a31-4b1f-8724-14049e7a0481) + # - `init_boundaries(leaf_cell_ids, mesh, elements)` # In order to apply boundary conditions, it is necessary to identify the locations of the @@ -164,6 +169,7 @@ ode = semidiscretize(semi, (0.0, 1.0)); # The `semidiscretize` function involves a deep tree of subsequent calls, with the primary ones # explained below. + # - `allocate_coefficients(mesh, equations, solver, cache)` # To apply initial conditions, a data structure ("container") needs to be generated to store the @@ -192,6 +198,7 @@ ode = semidiscretize(semi, (0.0, 1.0)); # This is possible because, from a storage perspective, they share the same stored data, while # access to this data is provided in different ways. + # - `compute_coefficients!(u, initial_conditions, t, mesh::DG, equations, solver, cache)` # Now the variable `u`, intended to store solutions, has been allocated and wrapped, it is time diff --git a/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/SemidiscretizationHyperbolic_structure_figure.jl b/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/SemidiscretizationHyperbolic_structure_figure.jl index 3066a0a515..cae7b19d47 100644 --- a/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/SemidiscretizationHyperbolic_structure_figure.jl +++ b/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/SemidiscretizationHyperbolic_structure_figure.jl @@ -1,94 +1,64 @@ using Plots -plot(Shape([(-2.3, 4.5), (2.35, 4.5), (2.35, 2.5), (-2.3, 2.5)]), linecolor = "black", - fillcolor = "white", label = false, linewidth = 2, size = (800, 600), showaxis = false, - grid = false, xlim = (-2.4, 2.8), ylim = (-25, 5.5)) -annotate!(2.3, 3.5, - ("SemidiscretizationHyperbolic(mesh, equations, initial_conditions, solver; source_terms, +plot(Shape([(-2.3,4.5), (2.35,4.5), (2.35,2.5), (-2.3,2.5)]), linecolor="black", fillcolor="white", label=false,linewidth=2, size=(800,600), showaxis=false, grid=false, xlim=(-2.4,2.8), ylim=(-25,5.5)) +annotate!(2.3, 3.5, ("SemidiscretizationHyperbolic(mesh, equations, initial_conditions, solver; source_terms, boundary_conditions, RealT, uEltype, initial_cache) ", 10, :black, :right)) -annotate!(-2.3, 1.5, - ("creates and returns SemidiscretizationHyperbolic object, initialized using a mesh, equations, +annotate!(-2.3, 1.5, ("creates and returns SemidiscretizationHyperbolic object, initialized using a mesh, equations, initial_conditions, boundary_conditions, source_terms, solver and cache", 9, :black, :left)) -plot!([-1.2, -1.2], [0.6, -2], arrow = true, color = :black, linewidth = 2, label = "") -plot!([-1.2, -1.4], [0.6, -2], arrow = true, color = :black, linewidth = 2, label = "") -plot!([-1.2, -1.0], [0.6, -2], arrow = true, color = :black, linewidth = 2, label = "") +plot!([-1.2,-1.2],[0.6,-2],arrow=true,color=:black,linewidth=2,label="") +plot!([-1.2,-1.4],[0.6,-2],arrow=true,color=:black,linewidth=2,label="") +plot!([-1.2,-1.],[0.6,-2],arrow=true,color=:black,linewidth=2,label="") annotate!(-1, -0.7, ("specialized for mesh and solver types", 9, :black, :left)) -plot!([1.25, 1.25], [0.6, -2], arrow = true, color = :black, linewidth = 2, label = "") -plot!([1.25, 1.05], [0.6, -2], arrow = true, color = :black, linewidth = 2, label = "") -plot!([1.25, 1.45], [0.6, -2], arrow = true, color = :black, linewidth = 2, label = "") +plot!([1.25,1.25],[0.6,-2],arrow=true,color=:black,linewidth=2,label="") +plot!([1.25,1.05],[0.6,-2],arrow=true,color=:black,linewidth=2,label="") +plot!([1.25,1.45],[0.6,-2],arrow=true,color=:black,linewidth=2,label="") annotate!(1.48, -0.7, ("specialized for mesh and boundary_conditions types", 9, :black, :left)) -plot!(Shape([(-2.3, -2), (-0.1, -2), (-0.1, -4), (-2.3, -4)]), linecolor = "black", - fillcolor = "white", label = false, linewidth = 2) +plot!(Shape([(-2.3,-2), (-0.1,-2), (-0.1,-4), (-2.3,-4)]), linecolor="black", fillcolor="white", label=false,linewidth=2) annotate!(-1.2, -3, ("create_cache(mesh::TreeMesh, equations, solver::Dg, RealT, uEltype)", 10, :black, :center)) -plot!([-2.22, -2.22], [-4, -22], arrow = false, color = :black, linewidth = 2, label = "") +plot!([-2.22,-2.22],[-4,-22],arrow=false,color=:black,linewidth=2,label="") -plot!(Shape([(-0.05, -2), (2.6, -2), (2.6, -4), (-0.05, -4)]), linecolor = "black", - fillcolor = "white", label = false, linewidth = 2) -annotate!(1.27, -3, - ("digest_boundary_conditions(boundary_conditions, - mesh, solver, cache)", 10, :black, :center)) +plot!(Shape([(-0.05,-2), (2.6,-2), (2.6,-4), (-0.05,-4)]), linecolor="black", fillcolor="white", label=false,linewidth=2) +annotate!(1.27, -3, ("digest_boundary_conditions(boundary_conditions, + mesh, solver, cache)", 10, :black, :center)) annotate!(2.6, -5, ("if necessary, converts passed boundary_conditions into a suitable form for processing by Trixi.jl", 9, :black, :right)) -plot!(Shape([(-2, -6), (-0.55, -6), (-0.55, -7.1), (-2, -7.1)]), linecolor = "black", - fillcolor = "white", label = false, linewidth = 2) +plot!(Shape([(-2,-6), (-0.55,-6), (-0.55,-7.1), (-2,-7.1)]), linecolor="black", fillcolor="white", label=false,linewidth=2) annotate!(-1.95, -6.5, ("local_leaf_cells(mesh.tree)", 10, :black, :left)) -annotate!(-2, -7.5, - ("returns cells for which an element needs to be created (i.e. all leaf cells)", - 9, :black, :left)) -plot!([-2.22, -2], [-6.5, -6.5], arrow = true, color = :black, linewidth = 2, label = "") +annotate!(-2, -7.5, ("returns cells for which an element needs to be created (i.e. all leaf cells)", 9, :black, :left)) +plot!([-2.22,-2],[-6.5,-6.5],arrow=true,color=:black,linewidth=2,label="") -plot!(Shape([(-2, -9), (1.73, -9), (1.73, -10.1), (-2, -10.1)]), linecolor = "black", - fillcolor = "white", label = false, linewidth = 2) -annotate!(-1.95, -9.5, - ("init_elements(leaf_cell_ids, mesh, equations, dg.basis, RealT, uEltype)", 10, - :black, :left)) -annotate!(-2, -10.5, - ("creates and initializes elements, projects Gauss-Lobatto basis onto each of them", - 9, :black, :left)) -plot!([-2.22, -2], [-9.5, -9.5], arrow = true, color = :black, linewidth = 2, label = "") +plot!(Shape([(-2,-9), (1.73,-9), (1.73,-10.1), (-2,-10.1)]), linecolor="black", fillcolor="white", label=false,linewidth=2) +annotate!(-1.95, -9.5, ("init_elements(leaf_cell_ids, mesh, equations, dg.basis, RealT, uEltype)", 10, :black, :left)) +annotate!(-2, -10.5, ("creates and initializes elements, projects Gauss-Lobatto basis onto each of them", 9, :black, :left)) +plot!([-2.22,-2],[-9.5,-9.5],arrow=true,color=:black,linewidth=2,label="") -plot!(Shape([(-2, -12), (0.4, -12), (0.4, -13.1), (-2, -13.1)]), linecolor = "black", - fillcolor = "white", label = false, linewidth = 2) -annotate!(-1.95, -12.5, - ("init_interfaces(leaf_cell_ids, mesh, elements)", 10, :black, :left)) -annotate!(-2, -13.5, - ("creates and initializes interfaces between each pair of adjacent elements of the same size", - 9, :black, :left)) -plot!([-2.22, -2], [-12.5, -12.5], arrow = true, color = :black, linewidth = 2, label = "") +plot!(Shape([(-2,-12), (0.4,-12), (0.4,-13.1), (-2,-13.1)]), linecolor="black", fillcolor="white", label=false,linewidth=2) +annotate!(-1.95, -12.5, ("init_interfaces(leaf_cell_ids, mesh, elements)", 10, :black, :left)) +annotate!(-2, -13.5, ("creates and initializes interfaces between each pair of adjacent elements of the same size", 9, :black, :left)) +plot!([-2.22,-2],[-12.5,-12.5],arrow=true,color=:black,linewidth=2,label="") -plot!(Shape([(-2, -15), (0.5, -15), (0.5, -16.1), (-2, -16.1)]), linecolor = "black", - fillcolor = "white", label = false, linewidth = 2) -annotate!(-1.95, -15.5, - ("init_boundaries(leaf_cell_ids, mesh, elements)", 10, :black, :left)) -annotate!(-2, -17, - ("creates and initializes boundaries, remembers each boundary element, as well as the coordinates of +plot!(Shape([(-2,-15), (0.5,-15), (0.5,-16.1), (-2,-16.1)]), linecolor="black", fillcolor="white", label=false,linewidth=2) +annotate!(-1.95, -15.5, ("init_boundaries(leaf_cell_ids, mesh, elements)", 10, :black, :left)) +annotate!(-2, -17, ("creates and initializes boundaries, remembers each boundary element, as well as the coordinates of each boundary node", 9, :black, :left)) -plot!([-2.22, -2], [-15.5, -15.5], arrow = true, color = :black, linewidth = 2, label = "") +plot!([-2.22,-2],[-15.5,-15.5],arrow=true,color=:black,linewidth=2,label="") -plot!(Shape([(-1.6, -18), (1.3, -18), (1.3, -19.1), (-1.6, -19.1)]), linecolor = "black", - fillcolor = "white", label = false, linewidth = 2) -annotate!(-1.55, -18.5, - ("init_mortars(leaf_cell_ids, mesh, elements, dg.mortar)", 10, :black, :left)) -annotate!(-1.6, -20, - ("creates and initializes mortars (type of interfaces) between each triple of adjacent coarsened +plot!(Shape([(-1.6,-18), (1.3,-18), (1.3,-19.1), (-1.6,-19.1)]), linecolor="black", fillcolor="white", label=false,linewidth=2) +annotate!(-1.55, -18.5, ("init_mortars(leaf_cell_ids, mesh, elements, dg.mortar)", 10, :black, :left)) +annotate!(-1.6, -20, ("creates and initializes mortars (type of interfaces) between each triple of adjacent coarsened and corresponding small elements", 9, :black, :left)) -plot!([-2.22, -1.6], [-18.5, -18.5], arrow = true, color = :black, linewidth = 2, - label = "") +plot!([-2.22,-1.6],[-18.5,-18.5],arrow=true,color=:black,linewidth=2,label="") annotate!(-2.15, -19, ("2D and 3D", 8, :black, :left)) -plot!(Shape([(-2, -21), (1.5, -21), (1.5, -23.1), (-2, -23.1)]), linecolor = "black", - fillcolor = "white", label = false, linewidth = 2) -annotate!(-1.95, -22, - ("create_cache(mesh, equations, dg.volume_integral, dg, uEltype) +plot!(Shape([(-2,-21), (1.5,-21), (1.5,-23.1), (-2,-23.1)]), linecolor="black", fillcolor="white", label=false,linewidth=2) +annotate!(-1.95, -22, ("create_cache(mesh, equations, dg.volume_integral, dg, uEltype) for 2D and 3D create_cache(mesh, equations, dg.mortar, uEltype)", 10, :black, :left)) -annotate!(-2, -23.5, - ("add specialized parts of the cache required to compute the volume integral, etc.", - 9, :black, :left)) -plot!([-2.22, -2], [-22, -22], arrow = true, color = :black, linewidth = 2, label = "") +annotate!(-2, -23.5, ("add specialized parts of the cache required to compute the volume integral, etc.", 9, :black, :left)) +plot!([-2.22,-2],[-22,-22],arrow=true,color=:black,linewidth=2,label="") -savefig("./SemidiscretizationHyperbolic") +savefig("./SemidiscretizationHyperbolic") \ No newline at end of file diff --git a/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/generate_boundary_figure.jl b/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/generate_boundary_figure.jl index 9083610cfc..14475d2133 100644 --- a/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/generate_boundary_figure.jl +++ b/docs/literate/src/files/behind_the_scenes_simulation_setup_plots/src/generate_boundary_figure.jl @@ -1,268 +1,190 @@ using Plots function min(coordinates::Vector{Tuple{Float64, Float64}}, i) - min = coordinates[1][i] - for j in coordinates - if min > j[i] - min = j[i] - end + min=coordinates[1][i] + for j in coordinates + if min>j[i] + min=j[i] end - return min + end + return min end function max(coordinates::Vector{Tuple{Float64, Float64}}, i) - max = coordinates[1][i] - for j in coordinates - if max < j[i] - max = j[i] - end + max=coordinates[1][i] + for j in coordinates + if max j[i] - min = j[i] - end + min=coordinates[1][i] + for j in coordinates + if min>j[i] + min=j[i] end - return min + end + return min end function max(coordinates::Vector{Tuple{Float64, Float64}}, i) - max = coordinates[1][i] - for j in coordinates - if max < j[i] - max = j[i] - end + max=coordinates[1][i] + for j in coordinates + if max j[i] - min = j[i] - end + min=coordinates[1][i] + for j in coordinates + if min>j[i] + min=j[i] end - return min + end + return min end function max(coordinates::Vector{Tuple{Float64, Float64}}, i) - max = coordinates[1][i] - for j in coordinates - if max < j[i] - max = j[i] - end + max=coordinates[1][i] + for j in coordinates + if max j[i] - min = j[i] - end + min=coordinates[1][i] + for j in coordinates + if min>j[i] + min=j[i] end - return min + end + return min end function max(coordinates::Vector{Tuple{Float64, Float64}}, i) - max = coordinates[1][i] - for j in coordinates - if max < j[i] - max = j[i] - end + max=coordinates[1][i] + for j in coordinates + if max begin - equations_inner = CompressibleEulerEquations2D(first(γ)) - semi_inner = Trixi.remake(semi, equations = equations_inner, - uEltype = eltype(γ)) - Trixi.rhs!(du_ode, u0_ode, semi_inner, 0.0) - end, similar(u0_ode), [1.4]); # γ needs to be an `AbstractArray` + equations_inner = CompressibleEulerEquations2D(first(γ)) + semi_inner = Trixi.remake(semi, equations=equations_inner, uEltype=eltype(γ)) + Trixi.rhs!(du_ode, u0_ode, semi_inner, 0.0) +end, similar(u0_ode), [1.4]); # γ needs to be an `AbstractArray` -round.(extrema(J), sigdigits = 2) -@test round.(extrema(J), sigdigits = 2) == (-220.0, 220.0) #src +round.(extrema(J), sigdigits=2) +@test round.(extrema(J), sigdigits=2) == (-220.0, 220.0) #src # Note that we create a semidiscretization `semi` at first to determine the state `u0_ode` around # which we want to perform the linearization. Next, we wrap the RHS evaluation inside a closure @@ -210,6 +211,7 @@ norm(J[1:4:end]) # Here, we used some knowledge about the internal memory layout of Trixi.jl, an array of structs # with the conserved variables as fastest-varying index in memory. + # ## Differentiating through a complete simulation # It is also possible to differentiate through a complete simulation. As an example, let's differentiate @@ -220,23 +222,22 @@ using Trixi, OrdinaryDiffEq, ForwardDiff, Plots function energy_at_final_time(k) # k is the wave number of the initial condition equations = LinearScalarAdvectionEquation2D(1.0, -0.3) - mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level = 3, - n_cells_max = 10^4) + mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level=3, n_cells_max=10^4) solver = DGSEM(3, flux_lax_friedrichs) initial_condition = (x, t, equation) -> begin - x_trans = Trixi.x_trans_periodic_2d(x - equation.advection_velocity * t) - return SVector(sinpi(k * sum(x_trans))) + x_trans = Trixi.x_trans_periodic_2d(x - equation.advection_velocity * t) + return SVector(sinpi(k * sum(x_trans))) end semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - uEltype = typeof(k)) + uEltype=typeof(k)) ode = semidiscretize(semi, (0.0, 1.0)) - sol = solve(ode, BS3(), save_everystep = false) + sol = solve(ode, BS3(), save_everystep=false) Trixi.integrate(energy_total, sol.u[end], semi) end -k_values = range(0.9, 1.1, length = 101) +k_values = range(0.9, 1.1, length=101) -plot(k_values, energy_at_final_time.(k_values), label = "Energy") +plot(k_values, energy_at_final_time.(k_values), label="Energy") # You see a plot of a curve that resembles a parabola with local maximum around `k = 1.0`. # Why's that? Well, the domain is fixed but the wave number changes. Thus, if the wave number is @@ -248,45 +249,44 @@ plot(k_values, energy_at_final_time.(k_values), label = "Energy") # We can compute the discrete derivative of the energy at the final time with respect to the wave # number `k` as follows. -round(ForwardDiff.derivative(energy_at_final_time, 1.0), sigdigits = 2) -@test round(ForwardDiff.derivative(energy_at_final_time, 1.0), sigdigits = 2) == 1.4e-5 #src +round(ForwardDiff.derivative(energy_at_final_time, 1.0), sigdigits=2) +@test round(ForwardDiff.derivative(energy_at_final_time, 1.0), sigdigits=2) == 1.4e-5 #src # This is rather small and we can treat it as zero in comparison to the value of this derivative at # other wave numbers `k`. dk_values = ForwardDiff.derivative.((energy_at_final_time,), k_values); -plot(k_values, dk_values, label = "Derivative") +plot(k_values, dk_values, label="Derivative") # If you remember basic calculus, a sufficient condition for a local maximum is that the first derivative # vanishes and the second derivative is negative. We can also check this discretely. -second_derivative = round(ForwardDiff.derivative(k -> Trixi.ForwardDiff.derivative(energy_at_final_time, - k), 1.0), - sigdigits = 2) +second_derivative = round(ForwardDiff.derivative( + k -> Trixi.ForwardDiff.derivative(energy_at_final_time, k), 1.0), + sigdigits=2) @test second_derivative ≈ -0.9 #src # Having seen this application, let's break down what happens step by step. function energy_at_final_time(k) # k is the wave number of the initial condition equations = LinearScalarAdvectionEquation2D(1.0, -0.3) - mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level = 3, - n_cells_max = 10^4) + mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level=3, n_cells_max=10^4) solver = DGSEM(3, flux_lax_friedrichs) initial_condition = (x, t, equation) -> begin x_trans = Trixi.x_trans_periodic_2d(x - equation.advection_velocity * t) return SVector(sinpi(k * sum(x_trans))) end semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - uEltype = typeof(k)) + uEltype=typeof(k)) ode = semidiscretize(semi, (0.0, 1.0)) - sol = solve(ode, BS3(), save_everystep = false) + sol = solve(ode, BS3(), save_everystep=false) Trixi.integrate(energy_total, sol.u[end], semi) end k = 1.0 -round(ForwardDiff.derivative(energy_at_final_time, k), sigdigits = 2) -@test round(ForwardDiff.derivative(energy_at_final_time, 1.0), sigdigits = 2) == 1.4e-5 #src +round(ForwardDiff.derivative(energy_at_final_time, k), sigdigits=2) +@test round(ForwardDiff.derivative(energy_at_final_time, 1.0), sigdigits=2) == 1.4e-5 #src # When calling `ForwardDiff.derivative(energy_at_final_time, k)` with `k=1.0`, ForwardDiff.jl # will basically use the chain rule and known derivatives of existing basic functions @@ -300,7 +300,7 @@ round(ForwardDiff.derivative(energy_at_final_time, k), sigdigits = 2) # The first step in this example creates some basic ingredients of our simulation. equations = LinearScalarAdvectionEquation2D(1.0, -0.3) -mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level = 3, n_cells_max = 10^4) +mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level=3, n_cells_max=10^4) solver = DGSEM(3, flux_lax_friedrichs); # These do not have internal caches storing intermediate values of the numerical @@ -325,18 +325,19 @@ end; # need to tell Trixi.jl to allow `ForwardDiff.Dual` numbers in these caches. That's what # the keyword argument `uEltype=typeof(k)` in semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - uEltype = typeof(k)); + uEltype=typeof(k)); # does. This is basically the only part where you need to modify your standard Trixi.jl # code to enable automatic differentiation. From there on, the remaining steps ode = semidiscretize(semi, (0.0, 1.0)) -sol = solve(ode, BS3(), save_everystep = false) -round(Trixi.integrate(energy_total, sol.u[end], semi), sigdigits = 5) -@test round(Trixi.integrate(energy_total, sol.u[end], semi), sigdigits = 5) == 0.24986 #src +sol = solve(ode, BS3(), save_everystep=false) +round(Trixi.integrate(energy_total, sol.u[end], semi), sigdigits=5) +@test round(Trixi.integrate(energy_total, sol.u[end], semi), sigdigits=5) == 0.24986 #src # do not need any modifications since they are sufficiently generic (and enough effort # has been spend to allow general types inside these calls). + # ## Propagating errors using Measurements.jl # [![Error bars by Randall Munroe](https://imgs.xkcd.com/comics/error_bars.png)](https://xkcd.com/2110/) @@ -353,16 +354,16 @@ using Trixi, OrdinaryDiffEq, Measurements, Plots, LaTeXStrings equations = LinearScalarAdvectionEquation1D(1.0 ± 0.1) -mesh = TreeMesh((-1.0,), (1.0,), n_cells_max = 10^5, initial_refinement_level = 5) +mesh = TreeMesh((-1.0,), (1.0,), n_cells_max=10^5, initial_refinement_level=5) solver = DGSEM(3) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergence_test, - solver, uEltype = Measurement{Float64}) + solver, uEltype=Measurement{Float64}) ode = semidiscretize(semi, (0.0, 1.5)) -sol = solve(ode, BS3(), save_everystep = false); +sol = solve(ode, BS3(), save_everystep=false); plot(sol) @@ -377,6 +378,7 @@ plot(sol) # All this is possible due to allowing generic types and having good abstractions # in Julia that allow packages to work together seamlessly. + # ## Finite difference approximations # Trixi.jl provides the convenience function [`jacobian_fd`](@ref) to approximate the Jacobian @@ -388,7 +390,7 @@ equations = CompressibleEulerEquations2D(1.4) solver = DGSEM(3, flux_central) -mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level = 2, n_cells_max = 10^5) +mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level=2, n_cells_max=10^5) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_density_wave, solver) @@ -401,6 +403,7 @@ relative_difference = norm(J_fd - J_ad) / size(J_fd, 1) # This discrepancy is of the expected order of magnitude for central finite difference approximations. + # ## Linear systems # When a linear PDE is discretized using a linear scheme such as a standard DG method, @@ -423,10 +426,9 @@ equations = LinearScalarAdvectionEquation2D(1.0, -0.3) solver = DGSEM(3, flux_lax_friedrichs) -mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level = 2, n_cells_max = 10^5) +mesh = TreeMesh((-1.0, -1.0), (1.0, 1.0), initial_refinement_level=2, n_cells_max=10^5) -semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergence_test, - solver) +semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergence_test, solver) A, b = linear_structure(semi) @@ -445,6 +447,7 @@ scatter(real.(λ), imag.(λ)) relative_maximum = maximum(real, λ) / maximum(abs, λ) @test relative_maximum < 1.0e-15 #src + # ## Package versions # These results were obtained using the following versions. @@ -454,4 +457,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots", "ForwardDiff"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/first_steps/create_first_setup.jl b/docs/literate/src/files/first_steps/create_first_setup.jl index 6b5b52a87d..ae78a6a154 100644 --- a/docs/literate/src/files/first_steps/create_first_setup.jl +++ b/docs/literate/src/files/first_steps/create_first_setup.jl @@ -60,7 +60,7 @@ equations = LinearScalarAdvectionEquation2D(advection_velocity) # All minimum and all maximum coordinates must be combined into `Tuples`. coordinates_min = (-1.0, -1.0) -coordinates_max = (1.0, 1.0) +coordinates_max = ( 1.0, 1.0) mesh = TreeMesh(coordinates_min, coordinates_max, initial_refinement_level = 4, n_cells_max = 30_000) @@ -72,7 +72,7 @@ mesh = TreeMesh(coordinates_min, coordinates_max, # in the weak formulation `DGSEM` initializes the surface flux as `flux_central` and uses the physical flux for # the volume integral. -solver = DGSEM(polydeg = 3) +solver = DGSEM(polydeg=3) # Now we need to define an initial condition for our problem. All the already implemented # initial conditions for [`LinearScalarAdvectionEquation2D`](@ref) can be found in @@ -108,7 +108,7 @@ initial_condition = initial_condition_sinpi # equation itself as arguments and returns the source term as a static vector `SVector`. function source_term_exp_sinpi(u, x, t, equations::LinearScalarAdvectionEquation2D) - u = -2 * exp(-t) * sinpi(2 * (x[1] - t)) * sinpi(2 * (x[2] - t)) + u = - 2 * exp(-t) * sinpi(2*(x[1] - t)) * sinpi(2*(x[2] - t)) return SVector(u) end @@ -182,8 +182,7 @@ save_restart = SaveRestartCallback(interval = 100, save_final_restart = true) # Create a `CallbackSet` to collect all callbacks so that they can be passed to the `solve` # function. -callbacks = CallbackSet(summary_callback, analysis_callback, alive_callback, - stepsize_callback, +callbacks = CallbackSet(summary_callback, analysis_callback, alive_callback, stepsize_callback, save_solution, save_restart); # The last step is to choose the time integration method. OrdinaryDiffEq.jl defines a wide range of @@ -204,12 +203,14 @@ summary_callback() # Now you can plot the solution as shown below, analyze it and improve the stability, accuracy or # efficiency of your setup. + # ## Visualize the solution # In the previous part of the tutorial, we calculated the final solution of the given problem, now we want # to visualize it. A more detailed explanation of visualization methods can be found in the section # [Visualization](@ref visualization). + # ### Using Plots.jl # The first option is to use the [Plots.jl](https://github.com/JuliaPlots/Plots.jl) package @@ -242,6 +243,7 @@ plot(pd["scalar"]) plot!(getmesh(pd)) + # ### Using Trixi2Vtk.jl # Another way to visualize a solution is to extract it from a saved HDF5 file. After we used the @@ -263,7 +265,7 @@ plot!(getmesh(pd)) # `out` folder. using Trixi2Vtk -trixi2vtk(joinpath("out", "solution_000032.h5"), output_directory = "out") +trixi2vtk(joinpath("out", "solution_000032.h5"), output_directory="out") # Now two files `solution_000032.vtu` and `solution_000032_celldata.vtu` have been generated in the # `out` folder. The first one contains all the information for visualizing the solution, the @@ -291,4 +293,4 @@ trixi2vtk(joinpath("out", "solution_000032.h5"), output_directory = "out") # Trixi.jl. If you have an interest in contributing to Trixi.jl as a developer, refer to the third # part of the introduction titled [Changing Trixi.jl itself](@ref changing_trixi). -Sys.rm("out"; recursive = true, force = true) #hide #md +Sys.rm("out"; recursive=true, force=true) #hide #md \ No newline at end of file diff --git a/docs/literate/src/files/first_steps/getting_started.jl b/docs/literate/src/files/first_steps/getting_started.jl index ae0983391f..80ea78b51f 100644 --- a/docs/literate/src/files/first_steps/getting_started.jl +++ b/docs/literate/src/files/first_steps/getting_started.jl @@ -14,6 +14,7 @@ # - [Getting an existing setup file](@ref Getting-an-existing-setup-file) # - [Modifying an existing setup](@ref Modifying-an-existing-setup) + # ## Julia installation # Trixi.jl is compatible with the latest stable release of Julia. Additional details regarding Julia @@ -23,6 +24,7 @@ # MacOS provided below. In the event of any issues during the installation process, please consult # the official [Julia installation instruction](https://julialang.org/downloads/). + # ### Windows # - Open a terminal by pressing `Win+r` and entering `cmd` in the opened window. @@ -37,6 +39,7 @@ # ``` # To exit Julia, execute `exit()` or press `Ctrl+d`. + # ### Linux and MacOS # - To install Julia, run the following command in a terminal: @@ -56,6 +59,7 @@ # ``` # To exit Julia, execute `exit()` or press `Ctrl+d`. + # ## Trixi.jl installation # Trixi.jl and its related tools are registered Julia packages, thus their installation @@ -80,8 +84,10 @@ # integration schemes used by Trixi.jl and [Plots.jl](https://github.com/JuliaPlots/Plots.jl) # can be used to directly visualize Trixi.jl results from the Julia REPL. + # ## Usage + # ### Running a simulation # To get you started, Trixi.jl has a large set @@ -141,7 +147,7 @@ # trixi_include(joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl")) # ``` using Trixi, OrdinaryDiffEq #hide #md -trixi_include(@__MODULE__, joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl")) #hide #md +trixi_include(@__MODULE__,joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl")) #hide #md # The output contains a recap of the setup and various information about the course of the simulation. # For instance, the solution was approximated over the [`TreeMesh`](@ref) with 1024 effective cells using @@ -160,6 +166,7 @@ trixi_include(@__MODULE__, joinpath(examples_dir(), "tree_2d_dgsem", "elixir_eul using Plots plot(sol) + # ### Getting an existing setup file # To obtain a list of all Trixi.jl elixirs execute @@ -181,6 +188,7 @@ get_examples() # (or `Save Link As...`). # - Choose a folder and save the file. + # ### Modifying an existing setup # As an example, we will change the initial condition for calculations that occur in @@ -206,8 +214,8 @@ function initial_condition_density_waves(x, t, equations::CompressibleEulerEquat v2 = 0.2 # velocity along y-axis rho = 1.0 + 0.98 * sinpi(sum(x) - t * (v1 + v2)) # density wave profile p = 20 # pressure - rho_e = p / (equations.gamma - 1) + 1 / 2 * rho * (v1^2 + v2^2) - return SVector(rho, rho * v1, rho * v2, rho_e) + rho_e = p / (equations.gamma - 1) + 1/2 * rho * (v1^2 + v2^2) + return SVector(rho, rho*v1, rho*v2, rho_e) end initial_condition = initial_condition_density_waves nothing; #hide #md @@ -223,13 +231,13 @@ nothing; #hide #md # Then you will obtain a new solution from running the simulation with a different initial # condition. -trixi_include(@__MODULE__, joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl"), #hide #md - initial_condition = initial_condition) #hide #md +trixi_include(@__MODULE__,joinpath(examples_dir(), "tree_2d_dgsem", "elixir_euler_ec.jl"), #hide #md + initial_condition=initial_condition) #hide #md pd = PlotData2D(sol) #hide #md p1 = plot(pd["rho"]) #hide #md -p2 = plot(pd["v1"], clim = (0.05, 0.15)) #hide #md -p3 = plot(pd["v2"], clim = (0.15, 0.25)) #hide #md -p4 = plot(pd["p"], clim = (10, 30)) #hide #md +p2 = plot(pd["v1"], clim=(0.05, 0.15)) #hide #md +p3 = plot(pd["v2"], clim=(0.15, 0.25)) #hide #md +p4 = plot(pd["p"], clim=(10, 30)) #hide #md plot(p1, p2, p3, p4) #hide #md # To get exactly the same picture execute the following. @@ -248,4 +256,4 @@ plot(p1, p2, p3, p4) #hide #md # further details on setting up a new simulation with Trixi.jl, refer to the second part of # the introduction titled [Create your first setup](@ref create_first_setup). -Sys.rm("out"; recursive = true, force = true) #hide #md +Sys.rm("out"; recursive=true, force=true) #hide #md \ No newline at end of file diff --git a/docs/literate/src/files/hohqmesh_tutorial.jl b/docs/literate/src/files/hohqmesh_tutorial.jl index 8b4b592516..dd81f47951 100644 --- a/docs/literate/src/files/hohqmesh_tutorial.jl +++ b/docs/literate/src/files/hohqmesh_tutorial.jl @@ -36,8 +36,8 @@ using Trixi rm("out", force = true, recursive = true) #hide #md -redirect_stdio(stdout = devnull, stderr = devnull) do # code that prints annoying stuff we don't want to see here #hide #md - trixi_include(default_example_unstructured()) +redirect_stdio(stdout=devnull, stderr=devnull) do # code that prints annoying stuff we don't want to see here #hide #md +trixi_include(default_example_unstructured()) end #hide #md # This will compute a smooth, manufactured solution test case for the 2D compressible Euler equations @@ -53,8 +53,8 @@ end #hide #md # To convert the HDF5-formatted `.h5` output file(s) from Trixi.jl into VTK format execute the following using Trixi2Vtk -redirect_stdio(stdout = devnull, stderr = devnull) do # code that prints annoying stuff we don't want to see here #hide #md - trixi2vtk("out/solution_000180.h5", output_directory = "out") +redirect_stdio(stdout=devnull, stderr=devnull) do # code that prints annoying stuff we don't want to see here #hide #md +trixi2vtk("out/solution_000180.h5", output_directory="out") end #hide #md # Note this step takes about 15-30 seconds as the package `Trixi2Vtk` must be precompiled and executed for the first time @@ -63,8 +63,8 @@ end #hide #md # where the new files will be saved; it defaults to the current directory. (2) Specifying a higher number of # visualization nodes. For instance, if we want to use 12 uniformly spaced nodes for visualization we can execute -redirect_stdio(stdout = devnull, stderr = devnull) do # code that prints annoying stuff we don't want to see here #hide #md - trixi2vtk("out/solution_000180.h5", output_directory = "out", nvisnodes = 12) +redirect_stdio(stdout=devnull, stderr=devnull) do # code that prints annoying stuff we don't want to see here #hide #md +trixi2vtk("out/solution_000180.h5", output_directory="out", nvisnodes=12) end #hide #md # By default `trixi2vtk` sets `nvisnodes` to be the same as the number of nodes specified in @@ -72,8 +72,8 @@ end #hide #md # Finally, if you want to convert all the solution files to VTK execute -redirect_stdio(stdout = devnull, stderr = devnull) do # code that prints annoying stuff we don't want to see here #hide #md - trixi2vtk("out/solution_000*.h5", output_directory = "out", nvisnodes = 12) +redirect_stdio(stdout=devnull, stderr=devnull) do # code that prints annoying stuff we don't want to see here #hide #md +trixi2vtk("out/solution_000*.h5", output_directory="out", nvisnodes=12) end #hide #md # then it is possible to open the `.pvd` file with ParaView and create a video of the simulation. @@ -95,64 +95,64 @@ end #hide #md # The associated `ice_cream_straight_sides.control` file is created below. open("out/ice_cream_straight_sides.control", "w") do io - println(io, raw""" - \begin{CONTROL_INPUT} - \begin{RUN_PARAMETERS} - mesh file name = ice_cream_straight_sides.mesh - plot file name = ice_cream_straight_sides.tec - stats file name = none - mesh file format = ISM-v2 - polynomial order = 4 - plot file format = skeleton - \end{RUN_PARAMETERS} - - \begin{BACKGROUND_GRID} - x0 = [-8.0, -8.0, 0.0] - dx = [1.0, 1.0, 0.0] - N = [16,16,1] - \end{BACKGROUND_GRID} - - \begin{SPRING_SMOOTHER} - smoothing = ON - smoothing type = LinearAndCrossBarSpring - number of iterations = 25 - \end{SPRING_SMOOTHER} - - \end{CONTROL_INPUT} - - \begin{MODEL} - - \begin{INNER_BOUNDARIES} - - \begin{CHAIN} - name = IceCreamCone - \begin{END_POINTS_LINE} - name = LeftSlant - xStart = [-2.0, 1.0, 0.0] - xEnd = [ 0.0, -3.0, 0.0] - \end{END_POINTS_LINE} - - \begin{END_POINTS_LINE} - name = RightSlant - xStart = [ 0.0, -3.0, 0.0] - xEnd = [ 2.0, 1.0, 0.0] - \end{END_POINTS_LINE} - - \begin{CIRCULAR_ARC} - name = IceCream - units = degrees - center = [ 0.0, 1.0, 0.0] - radius = 2.0 - start angle = 0.0 - end angle = 180.0 - \end{CIRCULAR_ARC} - \end{CHAIN} - - \end{INNER_BOUNDARIES} - - \end{MODEL} - \end{FILE} - """) + println(io, raw""" +\begin{CONTROL_INPUT} + \begin{RUN_PARAMETERS} + mesh file name = ice_cream_straight_sides.mesh + plot file name = ice_cream_straight_sides.tec + stats file name = none + mesh file format = ISM-v2 + polynomial order = 4 + plot file format = skeleton + \end{RUN_PARAMETERS} + + \begin{BACKGROUND_GRID} + x0 = [-8.0, -8.0, 0.0] + dx = [1.0, 1.0, 0.0] + N = [16,16,1] + \end{BACKGROUND_GRID} + + \begin{SPRING_SMOOTHER} + smoothing = ON + smoothing type = LinearAndCrossBarSpring + number of iterations = 25 + \end{SPRING_SMOOTHER} + +\end{CONTROL_INPUT} + +\begin{MODEL} + + \begin{INNER_BOUNDARIES} + + \begin{CHAIN} + name = IceCreamCone + \begin{END_POINTS_LINE} + name = LeftSlant + xStart = [-2.0, 1.0, 0.0] + xEnd = [ 0.0, -3.0, 0.0] + \end{END_POINTS_LINE} + + \begin{END_POINTS_LINE} + name = RightSlant + xStart = [ 0.0, -3.0, 0.0] + xEnd = [ 2.0, 1.0, 0.0] + \end{END_POINTS_LINE} + + \begin{CIRCULAR_ARC} + name = IceCream + units = degrees + center = [ 0.0, 1.0, 0.0] + radius = 2.0 + start angle = 0.0 + end angle = 180.0 + \end{CIRCULAR_ARC} + \end{CHAIN} + + \end{INNER_BOUNDARIES} + +\end{MODEL} +\end{FILE} +""") end # The first three blocks of information are wrapped within a `CONTROL_INPUT` environment block as they define the @@ -305,18 +305,18 @@ equations = CompressibleEulerEquations2D(1.4) # set gas gamma = 1.4 ## freestream flow state with Ma_inf = 0.3 @inline function uniform_flow_state(x, t, equations::CompressibleEulerEquations2D) - ## set the freestream flow parameters - rho_freestream = 1.0 - u_freestream = 0.3 - p_freestream = inv(equations.gamma) + ## set the freestream flow parameters + rho_freestream = 1.0 + u_freestream = 0.3 + p_freestream = inv(equations.gamma) - theta = 0.0 # zero angle of attack - si, co = sincos(theta) - v1 = u_freestream * co - v2 = u_freestream * si + theta = 0.0 # zero angle of attack + si, co = sincos(theta) + v1 = u_freestream * co + v2 = u_freestream * si - prim = SVector(rho_freestream, v1, v2, p_freestream) - return prim2cons(prim, equations) + prim = SVector(rho_freestream, v1, v2, p_freestream) + return prim2cons(prim, equations) end ## initial condition @@ -326,13 +326,13 @@ initial_condition = uniform_flow_state boundary_condition_uniform_flow = BoundaryConditionDirichlet(uniform_flow_state) ## boundary condition dictionary -boundary_conditions = Dict(:Bottom => boundary_condition_uniform_flow, - :Top => boundary_condition_uniform_flow, - :Right => boundary_condition_uniform_flow, - :Left => boundary_condition_uniform_flow, - :LeftSlant => boundary_condition_slip_wall, - :RightSlant => boundary_condition_slip_wall, - :IceCream => boundary_condition_slip_wall); +boundary_conditions = Dict( :Bottom => boundary_condition_uniform_flow, + :Top => boundary_condition_uniform_flow, + :Right => boundary_condition_uniform_flow, + :Left => boundary_condition_uniform_flow, + :LeftSlant => boundary_condition_slip_wall, + :RightSlant => boundary_condition_slip_wall, + :IceCream => boundary_condition_slip_wall ); ## DGSEM solver. ## 1) polydeg must be >= the polynomial order set in the HOHQMesh control file to guarantee @@ -340,8 +340,8 @@ boundary_conditions = Dict(:Bottom => boundary_condition_uniform_flow, ## 2) VolumeIntegralFluxDifferencing with central volume flux is activated ## for dealiasing volume_flux = flux_ranocha -solver = DGSEM(polydeg = 4, surface_flux = flux_hll, - volume_integral = VolumeIntegralFluxDifferencing(volume_flux)) +solver = DGSEM(polydeg=4, surface_flux=flux_hll, + volume_integral=VolumeIntegralFluxDifferencing(volume_flux)) ## create the unstructured mesh from your mesh file mesh_file = joinpath("out", "ice_cream_straight_sides.mesh") @@ -349,28 +349,29 @@ mesh = UnstructuredMesh2D(mesh_file) ## Create semidiscretization with all spatial discretization-related components semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - boundary_conditions = boundary_conditions) + boundary_conditions=boundary_conditions) ## Create ODE problem from semidiscretization with time span from 0.0 to 2.0 tspan = (0.0, 2.0) ode = semidiscretize(semi, tspan) + ## Create the callbacks to output solution files and adapt the time step summary_callback = SummaryCallback() -save_solution = SaveSolutionCallback(interval = 10, - save_initial_solution = true, - save_final_solution = true) -stepsize_callback = StepsizeCallback(cfl = 1.0) +save_solution = SaveSolutionCallback(interval=10, + save_initial_solution=true, + save_final_solution=true) +stepsize_callback = StepsizeCallback(cfl=1.0) callbacks = CallbackSet(summary_callback, save_solution, stepsize_callback) -redirect_stdio(stdout = devnull, stderr = devnull) do # code that prints annoying stuff we don't want to see here #hide #md - ## Evolve ODE problem in time using `solve` from OrdinaryDiffEq - 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() +redirect_stdio(stdout=devnull, stderr=devnull) do # code that prints annoying stuff we don't want to see here #hide #md +## Evolve ODE problem in time using `solve` from OrdinaryDiffEq +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() end #hide #md # Visualization of the solution is carried out in a similar way as above. That is, one converts the `.h5` @@ -388,72 +389,72 @@ end #hide #md # We create the new control file `ice_cream_curved_sides.control` file below and will then highlight the # major differences compared to `ice_cream_straight_sides.control`. open("out/ice_cream_curved_sides.control", "w") do io - println(io, raw""" - \begin{CONTROL_INPUT} - \begin{RUN_PARAMETERS} - mesh file name = ice_cream_curved_sides.mesh - plot file name = ice_cream_curved_sides.tec - stats file name = none - mesh file format = ISM-v2 - polynomial order = 4 - plot file format = skeleton - \end{RUN_PARAMETERS} - - \begin{BACKGROUND_GRID} - background grid size = [1.0, 1.0, 0.0] - \end{BACKGROUND_GRID} - - \begin{SPRING_SMOOTHER} - smoothing = ON - smoothing type = LinearAndCrossBarSpring - number of iterations = 25 - \end{SPRING_SMOOTHER} - - \end{CONTROL_INPUT} - - \begin{MODEL} - - \begin{OUTER_BOUNDARY} - \begin{PARAMETRIC_EQUATION_CURVE} - name = OuterCircle - xEqn = x(t) = 8.0*sin(2.0*pi*t) - yEqn = y(t) = 8.0*cos(2.0*pi*t) - zEqn = z(t) = 0.0 - \end{PARAMETRIC_EQUATION_CURVE} - - \end{OUTER_BOUNDARY} - - \begin{INNER_BOUNDARIES} - - \begin{CHAIN} - name = IceCreamCone - \begin{END_POINTS_LINE} - name = LeftSlant - xStart = [-2.0, 1.0, 0.0] - xEnd = [ 0.0, -3.0, 0.0] - \end{END_POINTS_LINE} - - \begin{END_POINTS_LINE} - name = RightSlant - xStart = [ 0.0, -3.0, 0.0] - xEnd = [ 2.0, 1.0, 0.0] - \end{END_POINTS_LINE} - - \begin{CIRCULAR_ARC} - name = IceCream - units = degrees - center = [ 0.0, 1.0, 0.0] - radius = 2.0 - start angle = 0.0 - end angle = 180.0 - \end{CIRCULAR_ARC} - \end{CHAIN} - - \end{INNER_BOUNDARIES} - - \end{MODEL} - \end{FILE} - """) + println(io, raw""" +\begin{CONTROL_INPUT} + \begin{RUN_PARAMETERS} + mesh file name = ice_cream_curved_sides.mesh + plot file name = ice_cream_curved_sides.tec + stats file name = none + mesh file format = ISM-v2 + polynomial order = 4 + plot file format = skeleton + \end{RUN_PARAMETERS} + + \begin{BACKGROUND_GRID} + background grid size = [1.0, 1.0, 0.0] + \end{BACKGROUND_GRID} + + \begin{SPRING_SMOOTHER} + smoothing = ON + smoothing type = LinearAndCrossBarSpring + number of iterations = 25 + \end{SPRING_SMOOTHER} + +\end{CONTROL_INPUT} + +\begin{MODEL} + + \begin{OUTER_BOUNDARY} + \begin{PARAMETRIC_EQUATION_CURVE} + name = OuterCircle + xEqn = x(t) = 8.0*sin(2.0*pi*t) + yEqn = y(t) = 8.0*cos(2.0*pi*t) + zEqn = z(t) = 0.0 + \end{PARAMETRIC_EQUATION_CURVE} + + \end{OUTER_BOUNDARY} + + \begin{INNER_BOUNDARIES} + + \begin{CHAIN} + name = IceCreamCone + \begin{END_POINTS_LINE} + name = LeftSlant + xStart = [-2.0, 1.0, 0.0] + xEnd = [ 0.0, -3.0, 0.0] + \end{END_POINTS_LINE} + + \begin{END_POINTS_LINE} + name = RightSlant + xStart = [ 0.0, -3.0, 0.0] + xEnd = [ 2.0, 1.0, 0.0] + \end{END_POINTS_LINE} + + \begin{CIRCULAR_ARC} + name = IceCream + units = degrees + center = [ 0.0, 1.0, 0.0] + radius = 2.0 + start angle = 0.0 + end angle = 180.0 + \end{CIRCULAR_ARC} + \end{CHAIN} + + \end{INNER_BOUNDARIES} + +\end{MODEL} +\end{FILE} +""") end # The first alteration is that we have altered the second block of information @@ -500,10 +501,10 @@ output = generate_mesh(control_file); # dictionary because we now have a boundary named `OuterCircle` instead of four edges of a bounding box. ## boundary condition dictionary -boundary_conditions = Dict(:OuterCircle => boundary_condition_uniform_flow, - :LeftSlant => boundary_condition_slip_wall, - :RightSlant => boundary_condition_slip_wall, - :IceCream => boundary_condition_slip_wall); +boundary_conditions = Dict( :OuterCircle => boundary_condition_uniform_flow, + :LeftSlant => boundary_condition_slip_wall, + :RightSlant => boundary_condition_slip_wall, + :IceCream => boundary_condition_slip_wall ); # Also, we must update the construction of the mesh from our new mesh file `ice_cream_curved_sides.mesh` that # is located in the `out` folder. @@ -512,10 +513,12 @@ boundary_conditions = Dict(:OuterCircle => boundary_condition_uniform_flow, mesh_file = joinpath("out", "ice_cream_curved_sides.mesh") mesh = UnstructuredMesh2D(mesh_file); + # We can then post-process the solution file at the final time on the new mesh with `Trixi2Vtk` and visualize with ParaView. # ![simulation_curved_sides](https://user-images.githubusercontent.com/25242486/129733924-778795c1-9119-419a-8b89-bcbe13e33cd7.png) + # ## Setting up a simulation with AMR via `P4estMesh` # The above explained mesh file format of `ISM-V2` only works with `UnstructuredMesh2D` and so does # not support AMR. On the other hand, the mesh type [`P4estMesh`](@ref) allows AMR. The mesh @@ -565,6 +568,7 @@ mesh = UnstructuredMesh2D(mesh_file); # ![simulation_straight_sides_p4est_amr](https://user-images.githubusercontent.com/74359358/168049930-8abce6ac-cd47-4d04-b40b-0fa459bbd98d.png) + # ## Package versions # These results were obtained using the following versions. @@ -574,4 +578,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots", "Trixi2Vtk", "HOHQMesh"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/non_periodic_boundaries.jl b/docs/literate/src/files/non_periodic_boundaries.jl index 8312f9e64a..8f0e320dfd 100644 --- a/docs/literate/src/files/non_periodic_boundaries.jl +++ b/docs/literate/src/files/non_periodic_boundaries.jl @@ -27,6 +27,7 @@ # where `x` specifies the spatial coordinates, `t` is the current time, and `equations` is the # corresponding system of equations. + # We want to give a short example for a simulation with such a Dirichlet BC. # Consider the one-dimensional linear advection equation with domain $\Omega=[0, 2]$ and a constant @@ -40,8 +41,7 @@ initial_condition_zero(x, t, equation::LinearScalarAdvectionEquation1D) = SVecto initial_condition = initial_condition_zero using Plots -plot(x -> sum(initial_condition(x, 0.0, equations)), label = "initial condition", - ylim = (-1.5, 1.5)) +plot(x -> sum(initial_condition(x, 0.0, equations)), label="initial condition", ylim=(-1.5, 1.5)) # Using an advection velocity of `1.0` and the (local) Lax-Friedrichs/Rusanov flux # [`FluxLaxFriedrichs`](@ref) as a numerical surface flux, we are able to create an inflow boundary @@ -59,10 +59,10 @@ end boundary_condition = boundary_condition_sine_sector # We set the BC in negative and positive x-direction. -boundary_conditions = (x_neg = BoundaryConditionDirichlet(boundary_condition), - x_pos = BoundaryConditionDirichlet(boundary_condition)) +boundary_conditions = (x_neg=BoundaryConditionDirichlet(boundary_condition), + x_pos=BoundaryConditionDirichlet(boundary_condition)) #- -solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) +solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) coordinates_min = (0.0,) coordinates_max = (2.0,) @@ -70,41 +70,41 @@ coordinates_max = (2.0,) # For the mesh type `TreeMesh` the parameter `periodicity` must be set to `false` in the # corresponding direction. mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level = 4, - n_cells_max = 10_000, - periodicity = false) + initial_refinement_level=4, + n_cells_max=10_000, + periodicity=false) + semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - boundary_conditions = boundary_conditions) + boundary_conditions=boundary_conditions) tspan = (0.0, 6.0) ode = semidiscretize(semi, tspan) -analysis_callback = AnalysisCallback(semi, interval = 100) +analysis_callback = AnalysisCallback(semi, interval=100,) -stepsize_callback = StepsizeCallback(cfl = 0.9) +stepsize_callback = StepsizeCallback(cfl=0.9) callbacks = CallbackSet(analysis_callback, stepsize_callback); # We define some equidistant nodes for the visualization -visnodes = range(tspan[1], tspan[2], length = 300) +visnodes = range(tspan[1], tspan[2], length=300) # and run the simulation. -sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false), - dt = 1, # solve needs some value here but it will be overwritten by the stepsize_callback - save_everystep = false, saveat = visnodes, callback = callbacks); +sol = solve(ode, CarpenterKennedy2N54(williamson_condition=false), + dt=1, # solve needs some value here but it will be overwritten by the stepsize_callback + save_everystep=false, saveat=visnodes, callback=callbacks); using Plots @gif for step in eachindex(sol.u) - plot(sol.u[step], semi, ylim = (-1.5, 1.5), legend = true, label = "approximation", - title = "time t=$(round(sol.t[step], digits=5))") - scatter!([0.0], [sum(boundary_condition(SVector(0.0), sol.t[step], equations))], - label = "boundary condition") + plot(sol.u[step], semi, ylim=(-1.5, 1.5), legend=true, label="approximation", title="time t=$(round(sol.t[step], digits=5))") + scatter!([0.0], [sum(boundary_condition(SVector(0.0), sol.t[step], equations))], label="boundary condition") end + # # Other available example elixirs with non-trivial BC # Moreover, there are other boundary conditions in Trixi.jl. For instance, you can use the slip wall # boundary condition [`boundary_condition_slip_wall`](@ref). @@ -158,6 +158,7 @@ end # ``` # Source: [`Video`](https://www.youtube.com/watch?v=w0A9X38cSe4) on Trixi.jl's YouTube channel [`Trixi Framework`](https://www.youtube.com/watch?v=WElqqdMhY4A) + # ## Package versions # These results were obtained using the following versions. @@ -167,4 +168,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/p4est_from_gmsh.jl b/docs/literate/src/files/p4est_from_gmsh.jl index caaea4faa9..abfe70eebc 100644 --- a/docs/literate/src/files/p4est_from_gmsh.jl +++ b/docs/literate/src/files/p4est_from_gmsh.jl @@ -16,9 +16,8 @@ # Mach 2 flow around the NACA6412 airfoil. using Trixi -redirect_stdio(stdout = devnull, stderr = devnull) do # code that prints annoying stuff we don't want to see here #hide #md - trixi_include(joinpath(examples_dir(), "p4est_2d_dgsem", - "elixir_euler_NACA6412airfoil_mach2.jl"), tspan = (0.0, 0.5)) +redirect_stdio(stdout=devnull, stderr=devnull) do # code that prints annoying stuff we don't want to see here #hide #md +trixi_include(joinpath(examples_dir(), "p4est_2d_dgsem", "elixir_euler_NACA6412airfoil_mach2.jl"), tspan=(0.0, 0.5)) end #hide #md # Conveniently, we use the Plots package to have a first look at the results: @@ -457,4 +456,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots", "Download"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/parabolic_terms.jl b/docs/literate/src/files/parabolic_terms.jl index 59db6eb05e..d0a355bbc1 100644 --- a/docs/literate/src/files/parabolic_terms.jl +++ b/docs/literate/src/files/parabolic_terms.jl @@ -34,33 +34,27 @@ equations_parabolic = LaplaceDiffusion2D(diffusivity, equations_hyperbolic); boundary_condition_zero_dirichlet = BoundaryConditionDirichlet((x, t, equations) -> SVector(0.0)) -boundary_conditions_hyperbolic = (; - x_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(1 + - 0.5 * - x[2])), - y_neg = boundary_condition_zero_dirichlet, - y_pos = boundary_condition_do_nothing, - x_pos = boundary_condition_do_nothing) - -boundary_conditions_parabolic = (; - x_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(1 + - 0.5 * - x[2])), - y_neg = boundary_condition_zero_dirichlet, - y_pos = boundary_condition_zero_dirichlet, - x_pos = boundary_condition_zero_dirichlet); +boundary_conditions_hyperbolic = (; x_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(1 + 0.5 * x[2])), + y_neg = boundary_condition_zero_dirichlet, + y_pos = boundary_condition_do_nothing, + x_pos = boundary_condition_do_nothing) + +boundary_conditions_parabolic = (; x_neg = BoundaryConditionDirichlet((x, t, equations) -> SVector(1 + 0.5 * x[2])), + y_neg = boundary_condition_zero_dirichlet, + y_pos = boundary_condition_zero_dirichlet, + x_pos = boundary_condition_zero_dirichlet); # ## Defining the solver and mesh # The process of creating the DG solver and mesh is the same as for a purely # hyperbolic system of equations. -solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) +solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) coordinates_min = (-1.0, -1.0) # minimum coordinates (min(x), min(y)) -coordinates_max = (1.0, 1.0) # maximum coordinates (max(x), max(y)) +coordinates_max = ( 1.0, 1.0) # maximum coordinates (max(x), max(y)) mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level = 4, - periodicity = false, n_cells_max = 30_000) # set maximum capacity of tree data structure + initial_refinement_level=4, + periodicity=false, n_cells_max=30_000) # set maximum capacity of tree data structure initial_condition = (x, t, equations) -> SVector(0.0); @@ -74,8 +68,8 @@ initial_condition = (x, t, equations) -> SVector(0.0); semi = SemidiscretizationHyperbolicParabolic(mesh, (equations_hyperbolic, equations_parabolic), initial_condition, solver; - boundary_conditions = (boundary_conditions_hyperbolic, - boundary_conditions_parabolic)) + boundary_conditions=(boundary_conditions_hyperbolic, + boundary_conditions_parabolic)) # The rest of the code is identical to the hyperbolic case. We create a system of ODEs through # `semidiscretize`, defining callbacks, and then passing the system to OrdinaryDiffEq.jl. @@ -84,14 +78,15 @@ tspan = (0.0, 1.5) ode = semidiscretize(semi, tspan) callbacks = CallbackSet(SummaryCallback()) time_int_tol = 1.0e-6 -sol = solve(ode, RDPK3SpFSAL49(); abstol = time_int_tol, reltol = time_int_tol, - ode_default_options()..., callback = callbacks); +sol = solve(ode, RDPK3SpFSAL49(); abstol=time_int_tol, reltol=time_int_tol, + ode_default_options()..., callback=callbacks); # We can now visualize the solution, which develops a boundary layer at the outflow boundaries. using Plots plot(sol) + # ## Package versions # These results were obtained using the following versions. @@ -101,4 +96,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/scalar_linear_advection_1d.jl b/docs/literate/src/files/scalar_linear_advection_1d.jl index d74e064463..3e2c7e6d0d 100644 --- a/docs/literate/src/files/scalar_linear_advection_1d.jl +++ b/docs/literate/src/files/scalar_linear_advection_1d.jl @@ -50,6 +50,7 @@ dx = (coordinates_max - coordinates_min) / n_elements # length of one element # ``` # Here, $u_t^{Q_l}$ and $u_\xi^{Q_l}$ denote the time and spatial derivatives of the solution on the element $Q_l$. + # ### ii. Polynomial approach # Now, we want to approximate the solution in each element $Q_l$ by a polynomial of degree $N$. Since we transformed # the equation, we can use the same polynomial approach for the reference coordinate $\xi\in[-1, 1]$ in every @@ -103,7 +104,8 @@ weights = basis.weights # \end{align*} # ``` # Let's use our nodes and weights for $N=3$ and plug in -integral = sum(nodes .^ 3 .* weights) +integral = sum(nodes.^3 .* weights) + # Using this polynomial approach leads to the equation # ```math @@ -117,10 +119,10 @@ integral = sum(nodes .^ 3 .* weights) # for every node. x = Matrix{Float64}(undef, length(nodes), n_elements) for element in 1:n_elements - x_l = coordinates_min + (element - 1) * dx + dx / 2 + x_l = coordinates_min + (element - 1) * dx + dx/2 for i in eachindex(nodes) ξ = nodes[i] # nodes in [-1, 1] - x[i, element] = x_l + dx / 2 * ξ + x[i, element] = x_l + dx/2 * ξ end end @@ -128,7 +130,7 @@ u0 = initial_condition_sine_wave.(x) # To have a look at the initial sinus curve, we plot it. using Plots -plot(vec(x), vec(u0), label = "initial condition", legend = :topleft) +plot(vec(x), vec(u0), label="initial condition", legend=:topleft) # ### iii. Variational formulation # After defining the equation and initial condition, we want to implement an algorithm to @@ -241,9 +243,8 @@ D = basis.derivative_matrix # ``` # for $k=0,...,N$ and therefore, $\underline{f}' = D \underline{f}$. basis_N8 = LobattoLegendreBasis(8) -plot(vec(x), x -> 3 * x^2, label = "f'", lw = 2) -scatter!(basis_N8.nodes, basis_N8.derivative_matrix * basis_N8.nodes .^ 3, label = "Df", - lw = 3) +plot(vec(x), x -> 3 * x^2, label="f'", lw=2) +scatter!(basis_N8.nodes, basis_N8.derivative_matrix * basis_N8.nodes.^3, label="Df", lw=3) # Combining the volume term for every $i=0,...,N$ results in # ```math @@ -301,15 +302,13 @@ function rhs!(du, u, x, t) ## Trixi.jl needs the equation we are dealing with and an additional `1`, that indicates the ## first coordinate direction. equations = LinearScalarAdvectionEquation1D(1.0) - for element in 2:(n_elements - 1) + for element in 2:n_elements-1 ## left interface - flux_numerical[1, element] = surface_flux(u[end, element - 1], u[1, element], 1, - equations) - flux_numerical[end, element - 1] = flux_numerical[1, element] + flux_numerical[1, element] = surface_flux(u[end, element-1], u[1, element], 1, equations) + flux_numerical[end, element-1] = flux_numerical[1, element] ## right interface - flux_numerical[end, element] = surface_flux(u[end, element], u[1, element + 1], 1, - equations) - flux_numerical[1, element + 1] = flux_numerical[end, element] + flux_numerical[end, element] = surface_flux(u[end, element], u[1, element+1], 1, equations) + flux_numerical[1, element+1] = flux_numerical[end, element] end ## boundary flux flux_numerical[1, 1] = surface_flux(u[end, end], u[1, 1], 1, equations) @@ -343,12 +342,13 @@ using OrdinaryDiffEq tspan = (0.0, 2.0) ode = ODEProblem(rhs!, u0, tspan, x) -sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, - ode_default_options()...) +sol = solve(ode, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, ode_default_options()...) @test maximum(abs.(u0 - sol.u[end])) < 5e-5 #src -plot(vec(x), vec(sol.u[end]), label = "solution at t=$(tspan[2])", legend = :topleft, - lw = 3) +plot(vec(x), vec(sol.u[end]), label="solution at t=$(tspan[2])", legend=:topleft, lw=3) + + + # ## Alternative Implementation based on Trixi.jl # Now, we implement the same example. But this time, we directly use the functionality that Trixi.jl @@ -362,7 +362,7 @@ equations = LinearScalarAdvectionEquation1D(advection_velocity) # Then, create a DG solver with polynomial degree = 3 and (local) Lax-Friedrichs/Rusanov flux as surface flux. # The implementation of the basis and the numerical flux is now already done. -solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) +solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) # We will now create a mesh with 16 elements for the physical domain `[-1, 1]` with periodic boundaries. # We use Trixi.jl's standard mesh [`TreeMesh`](@ref). Since it's limited to hypercube domains, we @@ -371,30 +371,29 @@ solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) coordinates_min = -1.0 # minimum coordinate coordinates_max = 1.0 # maximum coordinate mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level = 4, # number of elements = 2^4 - n_cells_max = 30_000) # set maximum capacity of tree data structure (only needed for AMR) + initial_refinement_level=4, # number of elements = 2^4 + n_cells_max=30_000) # set maximum capacity of tree data structure (only needed for AMR) # A semidiscretization collects data structures and functions for the spatial discretization. # In Trixi.jl, an initial condition has the following parameter structure and is of the type `SVector`. -function initial_condition_sine_wave(x, t, equations) - SVector(1.0 + 0.5 * sin(pi * sum(x - equations.advection_velocity * t))) -end +initial_condition_sine_wave(x, t, equations) = SVector(1.0 + 0.5 * sin(pi * sum(x - equations.advection_velocity * t))) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_sine_wave, solver) # Again, combining all definitions and the function that calculates the right-hand side, we define the ODE and # solve it until `t=2` with OrdinaryDiffEq's `solve` function and the Runge-Kutta method `RDPK3SpFSAL49()`. tspan = (0.0, 2.0) -ode_trixi = semidiscretize(semi, tspan) +ode_trixi = semidiscretize(semi, tspan) -sol_trixi = solve(ode_trixi, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, - ode_default_options()...); +sol_trixi = solve(ode_trixi, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, ode_default_options()...); # We add a plot of the new approximated solution to the one calculated before. -plot!(sol_trixi, label = "solution at t=$(tspan[2]) with Trixi.jl", legend = :topleft, - linestyle = :dash, lw = 2) +plot!(sol_trixi, label="solution at t=$(tspan[2]) with Trixi.jl", legend=:topleft, linestyle=:dash, lw=2) @test maximum(abs.(vec(u0) - sol_trixi.u[end])) ≈ maximum(abs.(u0 - sol.u[end])) #src + + + # ## Summary of the code # To sum up, here is the complete code that we used. @@ -411,16 +410,16 @@ B = diagm([-1; zeros(polydeg - 1); 1]) ## mesh coordinates_min = -1.0 # minimum coordinate coordinates_max = 1.0 # maximum coordinate -n_elements = 16 # number of elements +n_elements = 16 # number of elements dx = (coordinates_max - coordinates_min) / n_elements # length of one element x = Matrix{Float64}(undef, length(nodes), n_elements) for element in 1:n_elements - x_l = -1 + (element - 1) * dx + dx / 2 + x_l = -1 + (element - 1) * dx + dx/2 for i in eachindex(nodes) # basis points in [-1, 1] ξ = nodes[i] - x[i, element] = x_l + dx / 2 * ξ + x[i, element] = x_l + dx/2 * ξ end end @@ -428,7 +427,7 @@ end initial_condition_sine_wave(x) = 1.0 + 0.5 * sin(pi * x) u0 = initial_condition_sine_wave.(x) -plot(vec(x), vec(u0), label = "initial condition", legend = :topleft) +plot(vec(x), vec(u0), label="initial condition", legend=:topleft) ## flux Lax-Friedrichs surface_flux = flux_lax_friedrichs @@ -441,15 +440,13 @@ function rhs!(du, u, x, t) ## calculate interface and boundary fluxes equations = LinearScalarAdvectionEquation1D(1.0) - for element in 2:(n_elements - 1) + for element in 2:n_elements-1 ## left interface - flux_numerical[1, element] = surface_flux(u[end, element - 1], u[1, element], 1, - equations) - flux_numerical[end, element - 1] = flux_numerical[1, element] + flux_numerical[1, element] = surface_flux(u[end, element-1], u[1, element], 1, equations) + flux_numerical[end, element-1] = flux_numerical[1, element] ## right interface - flux_numerical[end, element] = surface_flux(u[end, element], u[1, element + 1], 1, - equations) - flux_numerical[1, element + 1] = flux_numerical[end, element] + flux_numerical[end, element] = surface_flux(u[end, element], u[1, element+1], 1, equations) + flux_numerical[1, element+1] = flux_numerical[end, element] end ## boundary flux flux_numerical[1, 1] = surface_flux(u[end, end], u[1, 1], 1, equations) @@ -479,12 +476,11 @@ tspan = (0.0, 2.0) ode = ODEProblem(rhs!, u0, tspan, x) ## solve -sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, - ode_default_options()...) +sol = solve(ode, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, ode_default_options()...) @test maximum(abs.(vec(u0) - sol_trixi.u[end])) ≈ maximum(abs.(u0 - sol.u[end])) #src -plot(vec(x), vec(sol.u[end]), label = "solution at t=$(tspan[2])", legend = :topleft, - lw = 3) +plot(vec(x), vec(sol.u[end]), label="solution at t=$(tspan[2])", legend=:topleft, lw=3) + # ### Alternative Implementation based on Trixi.jl using Trixi, OrdinaryDiffEq, Plots @@ -494,32 +490,29 @@ advection_velocity = 1.0 equations = LinearScalarAdvectionEquation1D(advection_velocity) ## create DG solver with flux lax friedrichs and LGL basis -solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) +solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) ## distretize domain with `TreeMesh` coordinates_min = -1.0 # minimum coordinate coordinates_max = 1.0 # maximum coordinate mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level = 4, # number of elements = 2^4 - n_cells_max = 30_000) + initial_refinement_level=4, # number of elements = 2^4 + n_cells_max=30_000) ## create initial condition and semidiscretization -function initial_condition_sine_wave(x, t, equations) - SVector(1.0 + 0.5 * sin(pi * sum(x - equations.advection_velocity * t))) -end +initial_condition_sine_wave(x, t, equations) = SVector(1.0 + 0.5 * sin(pi * sum(x - equations.advection_velocity * t))) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_sine_wave, solver) ## solve tspan = (0.0, 2.0) -ode_trixi = semidiscretize(semi, tspan) -sol_trixi = solve(ode_trixi, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6, - ode_default_options()...); +ode_trixi = semidiscretize(semi, tspan) +sol_trixi = solve(ode_trixi, RDPK3SpFSAL49(); abstol=1.0e-6, reltol=1.0e-6, ode_default_options()...); -plot!(sol_trixi, label = "solution at t=$(tspan[2]) with Trixi.jl", legend = :topleft, - linestyle = :dash, lw = 2) +plot!(sol_trixi, label="solution at t=$(tspan[2]) with Trixi.jl", legend=:topleft, linestyle=:dash, lw=2) @test maximum(abs.(vec(u0) - sol_trixi.u[end])) ≈ maximum(abs.(u0 - sol.u[end])) #src + # ## Package versions # These results were obtained using the following versions. @@ -529,4 +522,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/shock_capturing.jl b/docs/literate/src/files/shock_capturing.jl index f4b0ce4dde..dd6698c2a8 100644 --- a/docs/literate/src/files/shock_capturing.jl +++ b/docs/literate/src/files/shock_capturing.jl @@ -4,6 +4,7 @@ # and its implementation in [Trixi.jl](https://github.com/trixi-framework/Trixi.jl). # In the second part, an implementation of a positivity preserving limiter is added to the simulation. + # # Shock capturing with flux differencing # The following rough explanation is on a very basic level. More information about an entropy stable @@ -35,6 +36,7 @@ # volume_flux_fv=volume_flux_fv) # ```` + # We now focus on a choice of the shock capturing indicator `indicator_sc`. # A possible indicator is $\alpha_{HG}$ presented by Hennemann et al. (p.10), which depends on the # current approximation with modal coefficients $\{m_j\}_{j=0}^N$ of a given `variable`. @@ -82,6 +84,8 @@ # variable=variable) # ```` + + # # Positivity preserving limiter # Some numerical solutions are physically meaningless, for instance negative values of pressure @@ -128,6 +132,7 @@ # SSPRK43(stage_limiter!). # ```` + # # Simulation with shock capturing and positivity preserving # Now, we can run a simulation using the described methods of shock capturing and positivity @@ -138,26 +143,26 @@ equations = CompressibleEulerEquations2D(1.4) # As our initial condition we use the Sedov blast wave setup. function initial_condition_sedov_blast_wave(x, t, equations::CompressibleEulerEquations2D) - ## Set up polar coordinates - inicenter = SVector(0.0, 0.0) - x_norm = x[1] - inicenter[1] - y_norm = x[2] - inicenter[2] - r = sqrt(x_norm^2 + y_norm^2) - - r0 = 0.21875 # = 3.5 * smallest dx (for domain length=4 and max-ref=6) - ## r0 = 0.5 # = more reasonable setup - E = 1.0 - p0_inner = 3 * (equations.gamma - 1) * E / (3 * pi * r0^2) - p0_outer = 1.0e-5 # = true Sedov setup - ## p0_outer = 1.0e-3 # = more reasonable setup - - ## Calculate primitive variables - rho = 1.0 - v1 = 0.0 - v2 = 0.0 - p = r > r0 ? p0_outer : p0_inner - - return prim2cons(SVector(rho, v1, v2, p), equations) + ## Set up polar coordinates + inicenter = SVector(0.0, 0.0) + x_norm = x[1] - inicenter[1] + y_norm = x[2] - inicenter[2] + r = sqrt(x_norm^2 + y_norm^2) + + r0 = 0.21875 # = 3.5 * smallest dx (for domain length=4 and max-ref=6) + ## r0 = 0.5 # = more reasonable setup + E = 1.0 + p0_inner = 3 * (equations.gamma - 1) * E / (3 * pi * r0^2) + p0_outer = 1.0e-5 # = true Sedov setup + ## p0_outer = 1.0e-3 # = more reasonable setup + + ## Calculate primitive variables + rho = 1.0 + v1 = 0.0 + v2 = 0.0 + p = r > r0 ? p0_outer : p0_inner + + return prim2cons(SVector(rho, v1, v2, p), equations) end initial_condition = initial_condition_sedov_blast_wave #- @@ -166,7 +171,7 @@ basis = LobattoLegendreBasis(3) # We set the numerical fluxes and divide between the surface flux and the two volume fluxes for the DG # and FV method. Here, we are using [`flux_lax_friedrichs`](@ref) and [`flux_ranocha`](@ref). surface_flux = flux_lax_friedrichs -volume_flux = flux_ranocha +volume_flux = flux_ranocha # Now, we specify the shock capturing indicator $\alpha$. @@ -175,26 +180,26 @@ volume_flux = flux_ranocha # Since density and pressure are the critical variables in this example, we use # `density_pressure = density * pressure = rho * p` as indicator variable. indicator_sc = IndicatorHennemannGassner(equations, basis, - alpha_max = 0.5, - alpha_min = 0.001, - alpha_smooth = true, - variable = density_pressure) + alpha_max=0.5, + alpha_min=0.001, + alpha_smooth=true, + variable=density_pressure) # Now, we can use the defined fluxes and the indicator to implement the volume integral using shock # capturing. volume_integral = VolumeIntegralShockCapturingHG(indicator_sc; - volume_flux_dg = volume_flux, - volume_flux_fv = surface_flux) + volume_flux_dg=volume_flux, + volume_flux_fv=surface_flux) # We finalize the discretization by implementing Trixi.jl's `solver`, `mesh`, `semi` and `ode`, # while `solver` now has the extra parameter `volume_integral`. solver = DGSEM(basis, surface_flux, volume_integral) coordinates_min = (-2.0, -2.0) -coordinates_max = (2.0, 2.0) +coordinates_max = ( 2.0, 2.0) mesh = TreeMesh(coordinates_min, coordinates_max, - initial_refinement_level = 6, - n_cells_max = 10_000) + initial_refinement_level=6, + n_cells_max=10_000) semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver) @@ -202,24 +207,25 @@ tspan = (0.0, 1.0) ode = semidiscretize(semi, tspan); # We add some callbacks to get an solution analysis and use a CFL-based time step size calculation. -analysis_callback = AnalysisCallback(semi, interval = 100) +analysis_callback = AnalysisCallback(semi, interval=100) -stepsize_callback = StepsizeCallback(cfl = 0.8) +stepsize_callback = StepsizeCallback(cfl=0.8) callbacks = CallbackSet(analysis_callback, stepsize_callback); # We now run the simulation using the positivity preserving limiter of Zhang and Shu for the variables # density and pressure. -stage_limiter! = PositivityPreservingLimiterZhangShu(thresholds = (5.0e-6, 5.0e-6), - variables = (Trixi.density, pressure)) +stage_limiter! = PositivityPreservingLimiterZhangShu(thresholds=(5.0e-6, 5.0e-6), + variables=(Trixi.density, pressure)) -sol = solve(ode, CarpenterKennedy2N54(stage_limiter!, 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); +sol = solve(ode, CarpenterKennedy2N54(stage_limiter!, 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); using Plots plot(sol) + # ## Package versions # These results were obtained using the following versions. @@ -229,4 +235,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/structured_mesh_mapping.jl b/docs/literate/src/files/structured_mesh_mapping.jl index 902301d445..c8da30bc2b 100644 --- a/docs/literate/src/files/structured_mesh_mapping.jl +++ b/docs/literate/src/files/structured_mesh_mapping.jl @@ -18,16 +18,15 @@ using Trixi equations = CompressibleEulerEquations2D(1.4) # We start with a pressure perturbation at `(xs, 0.0)` as initial condition. -function initial_condition_pressure_perturbation(x, t, - equations::CompressibleEulerEquations2D) - xs = 1.5 # location of the initial disturbance on the x axis - w = 1 / 8 # half width - p = exp(-log(2) * ((x[1] - xs)^2 + x[2]^2) / w^2) + 1.0 - v1 = 0.0 - v2 = 0.0 - rho = 1.0 - - return prim2cons(SVector(rho, v1, v2, p), equations) +function initial_condition_pressure_perturbation(x, t, equations::CompressibleEulerEquations2D) + xs = 1.5 # location of the initial disturbance on the x axis + w = 1/8 # half width + p = exp(-log(2) * ((x[1]-xs)^2 + x[2]^2)/w^2) + 1.0 + v1 = 0.0 + v2 = 0.0 + rho = 1.0 + + return prim2cons(SVector(rho, v1, v2, p), equations) end initial_condition = initial_condition_pressure_perturbation @@ -36,8 +35,8 @@ boundary_conditions = boundary_condition_slip_wall # The approximation setup is an entropy-stable split-form DG method with `polydeg=4`. We are using # the two fluxes [`flux_ranocha`](@ref) and [`flux_lax_friedrichs`](@ref). -solver = DGSEM(polydeg = 4, surface_flux = flux_lax_friedrichs, - volume_integral = VolumeIntegralFluxDifferencing(flux_ranocha)) +solver = DGSEM(polydeg=4, surface_flux=flux_lax_friedrichs, + volume_integral=VolumeIntegralFluxDifferencing(flux_ranocha)) # We want to define a circular cylinder as physical domain. It contains an inner semicircle with # radius `r0` and an outer semicircle of radius `r1`. @@ -69,6 +68,7 @@ solver = DGSEM(polydeg = 4, surface_flux = flux_lax_friedrichs, #src # \end{tikzpicture} #src # \end{document} + # The domain boundary curves with curve parameter in $[-1,1]$ are sorted as shown in the sketch. # They always are orientated from negative to positive coordinate, such that the corners have to # fit like this $f_1(+1) = f_4(-1)$, $f_3(+1) = f_2(-1)$, etc. @@ -76,37 +76,37 @@ solver = DGSEM(polydeg = 4, surface_flux = flux_lax_friedrichs, # In our case we can define the domain boundary curves as follows: r0 = 0.5 # inner radius r1 = 5.0 # outer radius -f1(xi) = SVector(r0 + 0.5 * (r1 - r0) * (xi + 1), 0.0) # right line -f2(xi) = SVector(-r0 - 0.5 * (r1 - r0) * (xi + 1), 0.0) # left line +f1(xi) = SVector( r0 + 0.5 * (r1 - r0) * (xi + 1), 0.0) # right line +f2(xi) = SVector(-r0 - 0.5 * (r1 - r0) * (xi + 1), 0.0) # left line f3(eta) = SVector(r0 * cos(0.5 * pi * (eta + 1)), r0 * sin(0.5 * pi * (eta + 1))) # inner circle f4(eta) = SVector(r1 * cos(0.5 * pi * (eta + 1)), r1 * sin(0.5 * pi * (eta + 1))) # outer circle # We create a curved mesh with 16 x 16 elements. The defined domain boundary curves are passed as a tuple. cells_per_dimension = (16, 16) -mesh = StructuredMesh(cells_per_dimension, (f1, f2, f3, f4), periodicity = false) +mesh = StructuredMesh(cells_per_dimension, (f1, f2, f3, f4), periodicity=false) # Then, we define the simulation with endtime `T=3` with `semi`, `ode` and `callbacks`. semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, - boundary_conditions = boundary_conditions) + boundary_conditions=boundary_conditions) tspan = (0.0, 3.0) ode = semidiscretize(semi, tspan) analysis_interval = 100 -analysis_callback = AnalysisCallback(semi, interval = analysis_interval) +analysis_callback = AnalysisCallback(semi, interval=analysis_interval) -alive_callback = AliveCallback(analysis_interval = analysis_interval) +alive_callback = AliveCallback(analysis_interval=analysis_interval) -stepsize_callback = StepsizeCallback(cfl = 0.9) +stepsize_callback = StepsizeCallback(cfl=0.9) callbacks = CallbackSet(analysis_callback, alive_callback, stepsize_callback); # Running the simulation -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); +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); using Plots plot(sol) @@ -115,6 +115,7 @@ pd = PlotData2D(sol) plot(pd["p"]) plot!(getmesh(pd)) + # ## Mesh directly defined by the transformation mapping # As mentioned before, you can also define the domain for a `StructuredMesh` by directly setting up # a transformation mapping. Here, we want to present a nice mapping, which is often used to test @@ -131,22 +132,22 @@ equations = CompressibleEulerEquations2D(1.4) # initial condition. initial_condition = initial_condition_constant -solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) +solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs) # We define the transformation mapping with variables in $[-1, 1]$ as described in # Rueda-Ramírez et al. (2021), p.18 (reduced to 2D): function mapping(xi_, eta_) - ## Transform input variables between -1 and 1 onto [0,3] - xi = 1.5 * xi_ + 1.5 - eta = 1.5 * eta_ + 1.5 + ## Transform input variables between -1 and 1 onto [0,3] + xi = 1.5 * xi_ + 1.5 + eta = 1.5 * eta_ + 1.5 - y = eta + 3 / 8 * (cos(1.5 * pi * (2 * xi - 3) / 3) * - cos(0.5 * pi * (2 * eta - 3) / 3)) + y = eta + 3/8 * (cos(1.5 * pi * (2 * xi - 3)/3) * + cos(0.5 * pi * (2 * eta - 3)/3)) - x = xi + 3 / 8 * (cos(0.5 * pi * (2 * xi - 3) / 3) * - cos(2 * pi * (2 * y - 3) / 3)) + x = xi + 3/8 * (cos(0.5 * pi * (2 * xi - 3)/3) * + cos(2 * pi * (2 * y - 3)/3)) - return SVector(x, y) + return SVector(x, y) end # Instead of a tuple of boundary functions, the `mesh` now has the mapping as its parameter. @@ -158,28 +159,28 @@ semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver) tspan = (0.0, 1.0) ode = semidiscretize(semi, tspan) -analysis_callback = AnalysisCallback(semi, interval = 250) +analysis_callback = AnalysisCallback(semi, interval=250) -stepsize_callback = StepsizeCallback(cfl = 0.8) +stepsize_callback = StepsizeCallback(cfl=0.8) callbacks = CallbackSet(analysis_callback, stepsize_callback) -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); +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); # Now, we want to verify the free-stream preservation property and plot the mesh. For the verification, # we calculate the absolute difference of the first conservation variable density `u[1]` and `1.0`. # To plot this error and the mesh, we are using the visualization feature `ScalarPlotData2D`, # explained in [visualization](@ref visualization). error_density = let u = Trixi.wrap_array(sol.u[end], semi) - abs.(u[1, :, :, :] .- 1.0) # density, x, y, elements + abs.(u[1, :, :, :] .- 1.0) # density, x, y, elements end pd = ScalarPlotData2D(error_density, semi) using Plots -plot(pd, title = "Error in density") +plot(pd, title="Error in density") plot!(getmesh(pd)) # We observe that the errors in the variable `density` are at the level of machine accuracy. @@ -201,6 +202,7 @@ plot!(getmesh(pd)) # [High-Order Hex-Quad Mesh (HOHQMesh) generator](https://github.com/trixi-framework/HOHQMesh), # created and developed by David Kopriva. + # ## Package versions # These results were obtained using the following versions. @@ -210,4 +212,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq", "Plots"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/subcell_shock_capturing.jl b/docs/literate/src/files/subcell_shock_capturing.jl index f189d54148..8b5399c23a 100644 --- a/docs/literate/src/files/subcell_shock_capturing.jl +++ b/docs/literate/src/files/subcell_shock_capturing.jl @@ -215,6 +215,7 @@ sol = Trixi.solve(ode, Trixi.SimpleSSPRK33(stage_callbacks = stage_callbacks); callback = callbacks); summary_callback() # print the timer summary + # ## Visualization # As for a standard simulation in Trixi.jl, it is possible to visualize the solution using the # `plot` routine from Plots.jl. @@ -242,6 +243,7 @@ plot(sol) # and get the following visualization. # ![blast_wave_paraview_reinterpolate=false](https://github.com/trixi-framework/Trixi.jl/assets/74359358/39274f18-0064-469c-b4da-bac4b843e116) + # ## Bounds checking # Subcell limiting is based on the fulfillment of target bounds - either global or local. # Although the implementation works and has been thoroughly tested, there are some cases where diff --git a/docs/literate/src/files/time_stepping.jl b/docs/literate/src/files/time_stepping.jl index fdfbfe1818..de7a2a83a4 100644 --- a/docs/literate/src/files/time_stepping.jl +++ b/docs/literate/src/files/time_stepping.jl @@ -33,6 +33,7 @@ # If you run Trixi in parallel with MPI you need to pass `internalnorm=ode_norm` and you should pass `unstable_check=ode_unstable_check` # to enable MPI aware error-based adaptive step size control. These keyword arguments are also included in [`ode_default_options`](@ref). + # # CFL-based step size control # The SciML ecosystem also provides time integration algorithms without adaptive time stepping on # their own, such as `CarpenterKennedy2N54`. Moreover, you also can deactivate the automatic adaptivity @@ -73,6 +74,7 @@ # [`elixir_advection_basic.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_2d_dgsem/elixir_advection_basic.jl) # or [`elixir_euler_source_terms.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_2d_dgsem/elixir_euler_source_terms.jl). + # ## Package versions # These results were obtained using the following versions. @@ -82,4 +84,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "OrdinaryDiffEq"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/literate/src/files/upwind_fdsbp.jl b/docs/literate/src/files/upwind_fdsbp.jl index e42cc19ca7..6d3379fa30 100644 --- a/docs/literate/src/files/upwind_fdsbp.jl +++ b/docs/literate/src/files/upwind_fdsbp.jl @@ -9,8 +9,8 @@ # operator can be created as follows. using Trixi D_SBP = derivative_operator(SummationByPartsOperators.MattssonNordström2004(), - derivative_order = 1, accuracy_order = 2, - xmin = 0.0, xmax = 1.0, N = 11) + derivative_order=1, accuracy_order=2, + xmin=0.0, xmax=1.0, N=11) # Instead of prefixing the source of coefficients `MattssonNordström2004()`, # you can also load the package SummationByPartsOperators.jl. Either way, # this yields an object representing the operator efficiently. If you want to @@ -21,8 +21,8 @@ Matrix(D_SBP) # Upwind SBP operators are a concept introduced in 2017 by Ken Mattsson. You can # create them as follows. D_upw = upwind_operators(SummationByPartsOperators.Mattsson2017, - derivative_order = 1, accuracy_order = 2, - xmin = 0.0, xmax = 1.0, N = 11) + derivative_order=1, accuracy_order=2, + xmin=0.0, xmax=1.0, N=11) # Upwind operators are derivative operators biased towards one direction. # The "minus" variants has a bias towards the left side, i.e., it uses values # from more nodes to the left than from the right to compute the discrete @@ -63,6 +63,7 @@ Matrix(D_upw.plus) # - [`elixir_euler_vortex.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_2d_fdsbp/elixir_euler_vortex.jl) # - [`elixir_euler_taylor_green_vortex.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_3d_fdsbp/elixir_euler_taylor_green_vortex.jl) + # ## Package versions # These results were obtained using the following versions. @@ -72,4 +73,4 @@ versioninfo() using Pkg Pkg.status(["Trixi", "SummationByPartsOperators"], - mode = PKGMODE_MANIFEST) + mode=PKGMODE_MANIFEST) diff --git a/docs/make.jl b/docs/make.jl index 822684829d..73ee86abd8 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -3,8 +3,7 @@ import Pkg using Changelog: Changelog # Fix for https://github.com/trixi-framework/Trixi.jl/issues/668 -if (get(ENV, "CI", nothing) != "true") && - (get(ENV, "TRIXI_DOC_DEFAULT_ENVIRONMENT", nothing) != "true") +if (get(ENV, "CI", nothing) != "true") && (get(ENV, "TRIXI_DOC_DEFAULT_ENVIRONMENT", nothing) != "true") push!(LOAD_PATH, dirname(@__DIR__)) end @@ -19,13 +18,12 @@ include(joinpath(trixi_root_dir, "docs", "literate", "make.jl")) # Copy list of authors to not need to synchronize it manually authors_text = read(joinpath(trixi_root_dir, "AUTHORS.md"), String) -authors_text = replace(authors_text, - "in the [LICENSE.md](LICENSE.md) file" => "under [License](@ref)") +authors_text = replace(authors_text, "in the [LICENSE.md](LICENSE.md) file" => "under [License](@ref)") write(joinpath(@__DIR__, "src", "authors.md"), authors_text) # Define module-wide setups such that the respective modules are available in doctests -DocMeta.setdocmeta!(Trixi, :DocTestSetup, :(using Trixi); recursive = true) -DocMeta.setdocmeta!(Trixi2Vtk, :DocTestSetup, :(using Trixi2Vtk); recursive = true) +DocMeta.setdocmeta!(Trixi, :DocTestSetup, :(using Trixi); recursive=true) +DocMeta.setdocmeta!(Trixi2Vtk, :DocTestSetup, :(using Trixi2Vtk); recursive=true) # Copy some files from the repository root directory to the docs and modify them # as necessary @@ -57,9 +55,9 @@ open(joinpath(@__DIR__, "src", "contributing.md"), "w") do io """) # Write the modified contents for line in eachline(joinpath(dirname(@__DIR__), "CONTRIBUTING.md")) - line = replace(line, "[LICENSE.md](LICENSE.md)" => "[License](@ref)") - line = replace(line, "[AUTHORS.md](AUTHORS.md)" => "[Authors](@ref)") - println(io, line) + line = replace(line, "[LICENSE.md](LICENSE.md)" => "[License](@ref)") + line = replace(line, "[AUTHORS.md](AUTHORS.md)" => "[Authors](@ref)") + println(io, line) end end @@ -99,73 +97,79 @@ files = [ "Explicit time stepping" => "time_stepping.jl", "Differentiable programming" => "differentiable_programming.jl", "Custom semidiscretizations" => "custom_semidiscretization.jl", -] + ] tutorials = create_tutorials(files) # Create changelog -Changelog.generate(Changelog.Documenter(), # output type - joinpath(@__DIR__, "..", "NEWS.md"), # input file - joinpath(@__DIR__, "src", "changelog.md"); # output file - repo = "trixi-framework/Trixi.jl",) +Changelog.generate( + Changelog.Documenter(), # output type + joinpath(@__DIR__, "..", "NEWS.md"), # input file + joinpath(@__DIR__, "src", "changelog.md"); # output file + repo = "trixi-framework/Trixi.jl", # default repository for links +) # Make documentation makedocs( - # Specify modules for which docstrings should be shown - modules = [Trixi, TrixiBase, Trixi2Vtk], - # Set sitename to Trixi.jl - sitename = "Trixi.jl", - # Provide additional formatting options - format = Documenter.HTML( - # Disable pretty URLs during manual testing - prettyurls = get(ENV, "CI", nothing) == "true", - # Explicitly add favicon as asset - assets = ["assets/favicon.ico"], - # Set canonical URL to GitHub pages URL - canonical = "https://trixi-framework.github.io/Trixi.jl/stable", - size_threshold_ignore = ["reference-trixi.md"]), - # Explicitly specify documentation structure - pages = [ - "Home" => "index.md", - "Getting started" => [ - "Overview" => "overview.md", - "Visualization" => "visualization.md", - "Restart simulation" => "restart.md", - ], - "Tutorials" => tutorials, - "Basic building blocks" => [ - "Meshes" => [ - "Tree mesh" => joinpath("meshes", "tree_mesh.md"), - "Structured mesh" => joinpath("meshes", "structured_mesh.md"), - "Unstructured mesh" => joinpath("meshes", "unstructured_quad_mesh.md"), - "P4est-based mesh" => joinpath("meshes", "p4est_mesh.md"), - "DGMulti mesh" => joinpath("meshes", "dgmulti_mesh.md"), - ], - "Time integration" => "time_integration.md", - "Callbacks" => "callbacks.md", - "Coupling" => "multi-physics_coupling.md", - ], - "Advanced topics & developers" => [ - "Conventions" => "conventions.md", - "Development" => "development.md", - "GitHub & Git" => "github-git.md", - "Style guide" => "styleguide.md", - "Testing" => "testing.md", - "Performance" => "performance.md", - "Parallelization" => "parallelization.md", - ], - "Troubleshooting and FAQ" => "troubleshooting.md", - "Reference" => [ - "Trixi.jl" => "reference-trixi.md", - "TrixiBase.jl" => "reference-trixibase.md", - "Trixi2Vtk.jl" => "reference-trixi2vtk.md", - ], - "Changelog" => "changelog.md", - "Authors" => "authors.md", - "Contributing" => "contributing.md", - "Code of Conduct" => "code_of_conduct.md", - "License" => "license.md", - ]) + # Specify modules for which docstrings should be shown + modules = [Trixi, TrixiBase, Trixi2Vtk], + # Set sitename to Trixi.jl + sitename = "Trixi.jl", + # Provide additional formatting options + format = Documenter.HTML( + # Disable pretty URLs during manual testing + prettyurls = get(ENV, "CI", nothing) == "true", + # Explicitly add favicon as asset + assets = ["assets/favicon.ico"], + # Set canonical URL to GitHub pages URL + canonical = "https://trixi-framework.github.io/Trixi.jl/stable", + size_threshold_ignore = ["reference-trixi.md"] + ), + # Explicitly specify documentation structure + pages = [ + "Home" => "index.md", + "Getting started" => [ + "Overview" => "overview.md", + "Visualization" => "visualization.md", + "Restart simulation" => "restart.md", + ], + "Tutorials" => tutorials, + "Basic building blocks" => [ + "Meshes" => [ + "Tree mesh" => joinpath("meshes", "tree_mesh.md"), + "Structured mesh" => joinpath("meshes", "structured_mesh.md"), + "Unstructured mesh" => joinpath("meshes", "unstructured_quad_mesh.md"), + "P4est-based mesh" => joinpath("meshes", "p4est_mesh.md"), + "DGMulti mesh" => joinpath("meshes", "dgmulti_mesh.md"), + ], + "Time integration" => "time_integration.md", + "Callbacks" => "callbacks.md", + "Coupling" => "multi-physics_coupling.md" + ], + "Advanced topics & developers" => [ + "Conventions" =>"conventions.md", + "Development" => "development.md", + "GitHub & Git" => "github-git.md", + "Style guide" => "styleguide.md", + "Testing" => "testing.md", + "Performance" => "performance.md", + "Parallelization" => "parallelization.md", + ], + "Troubleshooting and FAQ" => "troubleshooting.md", + "Reference" => [ + "Trixi.jl" => "reference-trixi.md", + "TrixiBase.jl" => "reference-trixibase.md", + "Trixi2Vtk.jl" => "reference-trixi2vtk.md" + ], + "Changelog" => "changelog.md", + "Authors" => "authors.md", + "Contributing" => "contributing.md", + "Code of Conduct" => "code_of_conduct.md", + "License" => "license.md", + ] +) -deploydocs(repo = "github.com/trixi-framework/Trixi.jl", - devbranch = "main", - push_preview = true) +deploydocs( + repo = "github.com/trixi-framework/Trixi.jl", + devbranch = "main", + push_preview = true +) diff --git a/src/time_integration/methods_2N.jl b/src/time_integration/methods_2N.jl index e5b970c6bd..afcfe8c320 100644 --- a/src/time_integration/methods_2N.jl +++ b/src/time_integration/methods_2N.jl @@ -132,7 +132,7 @@ function init(ode::ODEProblem, alg::SimpleAlgorithm2N; end # Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1 -function solve(ode::ODEProblem, alg::SimpleAlgorithm2N; +function solve(ode::ODEProblem, alg:: SimpleAlgorithm2N; dt, callback = nothing, kwargs...) integrator = init(ode, alg, dt = dt, callback = callback; kwargs...) diff --git a/src/time_integration/methods_3Sstar.jl b/src/time_integration/methods_3Sstar.jl index 6128d1551d..9a6ad09f7f 100644 --- a/src/time_integration/methods_3Sstar.jl +++ b/src/time_integration/methods_3Sstar.jl @@ -171,7 +171,7 @@ function Base.getproperty(integrator::SimpleIntegrator3Sstar, field::Symbol) return getfield(integrator, field) end -function init(ode::ODEProblem, alg::SimpleAlgorithm3Sstar; +function init(ode::ODEProblem, alg:: SimpleAlgorithm3Sstar; dt, callback = nothing, kwargs...) u = copy(ode.u0) du = similar(u) @@ -202,7 +202,7 @@ function init(ode::ODEProblem, alg::SimpleAlgorithm3Sstar; end # Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1 -function solve(ode::ODEProblem, alg::SimpleAlgorithm3Sstar; +function solve(ode::ODEProblem, alg:: SimpleAlgorithm3Sstar; dt, callback = nothing, kwargs...) integrator = init(ode, alg, dt = dt, callback = callback; kwargs...) From 56ccd629ee40f0d210e192fbfe3478576a18aa30 Mon Sep 17 00:00:00 2001 From: Warisa Date: Tue, 18 Jun 2024 17:24:15 +0200 Subject: [PATCH 7/8] fmt --- src/time_integration/methods_2N.jl | 2 +- src/time_integration/methods_3Sstar.jl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/time_integration/methods_2N.jl b/src/time_integration/methods_2N.jl index afcfe8c320..e5b970c6bd 100644 --- a/src/time_integration/methods_2N.jl +++ b/src/time_integration/methods_2N.jl @@ -132,7 +132,7 @@ function init(ode::ODEProblem, alg::SimpleAlgorithm2N; end # Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1 -function solve(ode::ODEProblem, alg:: SimpleAlgorithm2N; +function solve(ode::ODEProblem, alg::SimpleAlgorithm2N; dt, callback = nothing, kwargs...) integrator = init(ode, alg, dt = dt, callback = callback; kwargs...) diff --git a/src/time_integration/methods_3Sstar.jl b/src/time_integration/methods_3Sstar.jl index 9a6ad09f7f..6128d1551d 100644 --- a/src/time_integration/methods_3Sstar.jl +++ b/src/time_integration/methods_3Sstar.jl @@ -171,7 +171,7 @@ function Base.getproperty(integrator::SimpleIntegrator3Sstar, field::Symbol) return getfield(integrator, field) end -function init(ode::ODEProblem, alg:: SimpleAlgorithm3Sstar; +function init(ode::ODEProblem, alg::SimpleAlgorithm3Sstar; dt, callback = nothing, kwargs...) u = copy(ode.u0) du = similar(u) @@ -202,7 +202,7 @@ function init(ode::ODEProblem, alg:: SimpleAlgorithm3Sstar; end # Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1 -function solve(ode::ODEProblem, alg:: SimpleAlgorithm3Sstar; +function solve(ode::ODEProblem, alg::SimpleAlgorithm3Sstar; dt, callback = nothing, kwargs...) integrator = init(ode, alg, dt = dt, callback = callback; kwargs...) From a169e579d5e78ef05b963ad99bc891cba33ce3e6 Mon Sep 17 00:00:00 2001 From: Warisa Date: Tue, 18 Jun 2024 17:29:31 +0200 Subject: [PATCH 8/8] add name to AUTHORS.md --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 54d6321633..5ab164c0ed 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -38,6 +38,7 @@ are listed in alphabetical order: * Julia Odenthal * Sigrun Ortleb * Hendrik Ranocha +* Warisa Roongaraya * Andrés M. Rueda-Ramírez * Felipe Santillan * Michael Schlottke-Lakemper