-
Notifications
You must be signed in to change notification settings - Fork 5
Added IMEX for KdV eq. #207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 3 commits
65979bd
62f42fe
d9806af
a3c1c50
8ec469f
a33f088
bc57c2b
062f4d9
f1c24e9
b61e48d
15a3707
b95b2d2
aa2edf7
3a7d72d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| using OrdinaryDiffEqTsit5 | ||
| using DispersiveShallowWater | ||
| using SummationByPartsOperators: upwind_operators, periodic_derivative_operator | ||
|
|
||
| ############################################################################### | ||
| # Semidiscretization of the KdV equation | ||
|
|
||
| equations = KdVEquation1D(gravity = 9.81, D = 1.0) | ||
| initial_condition = initial_condition_convergence_test | ||
| boundary_conditions = boundary_condition_periodic | ||
|
|
||
| # create homogeneous mesh | ||
| coordinates_min = -50.0 | ||
| coordinates_max = 50.0 | ||
| N = 512 | ||
| mesh = Mesh1D(coordinates_min, coordinates_max, N) | ||
|
|
||
| # Create solver with periodic SBP operators of accuracy order 3, | ||
| # which results in a 4th order accurate semi discretizations. | ||
| # We can set the accuracy order of the upwind operators to 3 since | ||
| # we only use central versions/combinations of the upwind operators. | ||
| D1_upwind = upwind_operators(periodic_derivative_operator; | ||
| derivative_order = 1, accuracy_order = 3, | ||
| xmin = xmin(mesh), xmax = xmax(mesh), | ||
| N = nnodes(mesh)) | ||
| solver = Solver(D1_upwind) | ||
|
|
||
| semi = Semidiscretization(mesh, equations, initial_condition, solver, | ||
| boundary_conditions = boundary_conditions) | ||
|
|
||
| tspan = (0.0, 5.0) | ||
| ode = semidiscretize(semi, tspan, no_splitform = false) | ||
|
|
||
| summary_callback = SummaryCallback() | ||
| analysis_callback = AnalysisCallback(semi; interval = 100, | ||
| extra_analysis_errors = (:conservation_error,), | ||
| extra_analysis_integrals = (waterheight_total, | ||
| waterheight)) | ||
| callbacks = CallbackSet(analysis_callback, summary_callback) | ||
| saveat = range(tspan..., length = 100) | ||
|
|
||
| # alg = Rodas5() # not working because of https://github.com/SciML/OrdinaryDiffEq.jl/issues/2719 | ||
| # alg = KenCarp4() # would need to add OrdinaryDiffEqSDIRK - can to that, but I dont want to bloat DSW.jl with package s | ||
| alg = Tsit5() | ||
| sol = solve(ode, alg, abstol = 1e-7, reltol = 1e-7, | ||
| save_everystep = false, callback = callbacks, saveat = saveat) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -186,6 +186,28 @@ function rhs!(dq, q, semi::Semidiscretization, t) | |
| return nothing | ||
| end | ||
|
|
||
| function rhs_split_1!(dq, q, semi::Semidiscretization, t) | ||
| @unpack mesh, equations, initial_condition, boundary_conditions, solver, source_terms, cache = semi | ||
|
|
||
| @trixi_timeit timer() "rhs_split_1!" rhs_split_1!(dq, q, t, mesh, equations, | ||
| initial_condition, | ||
| boundary_conditions, source_terms, | ||
| solver, | ||
| cache) | ||
| return nothing | ||
| end | ||
|
|
||
| function rhs_split_2!(dq, q, semi::Semidiscretization, t) | ||
| @unpack mesh, equations, initial_condition, boundary_conditions, solver, source_terms, cache = semi | ||
|
|
||
| @trixi_timeit timer() "rhs_split_2!" rhs_split_2!(dq, q, t, mesh, equations, | ||
| initial_condition, | ||
| boundary_conditions, source_terms, | ||
| solver, | ||
| cache) | ||
| return nothing | ||
| end | ||
|
|
||
| function compute_coefficients(func, t, semi::Semidiscretization) | ||
| @unpack mesh, equations, solver = semi | ||
| q = allocate_coefficients(mesh_equations_solver(semi)...) | ||
|
|
@@ -214,16 +236,21 @@ function check_bathymetry(equations::AbstractShallowWaterEquations, q0) | |
| end | ||
|
|
||
| """ | ||
| semidiscretize(semi::Semidiscretization, tspan) | ||
| semidiscretize(semi::Semidiscretization, tspan; no_splitform = true) | ||
|
|
||
| Wrap the semidiscretization `semi` as an ODE problem in the time interval `tspan` | ||
| that can be passed to `solve` from the [SciML ecosystem](https://diffeq.sciml.ai/latest/). | ||
| """ | ||
| function semidiscretize(semi::Semidiscretization, tspan) | ||
| function semidiscretize(semi::Semidiscretization, tspan; no_splitform = true) | ||
|
||
| q0 = compute_coefficients(semi.initial_condition, first(tspan), semi) | ||
| check_bathymetry(semi.equations, q0) | ||
| iip = true # is-inplace, i.e., we modify a vector when calling rhs! | ||
| return ODEProblem{iip}(rhs!, q0, tspan, semi) | ||
| if no_splitform | ||
| ode = ODEProblem{iip}(rhs!, q0, tspan, semi) | ||
| else | ||
| ode = ODEProblem{iip}(SplitFunction(rhs_split_1!, rhs_split_2!), q0, tspan, semi) | ||
| end | ||
| return ode | ||
| end | ||
|
|
||
| """ | ||
|
|
@@ -241,7 +268,8 @@ of the semidiscretization `semi` at the state `q0`. | |
| function jacobian(semi::Semidiscretization; | ||
| t = 0.0, | ||
| q0 = compute_coefficients(semi.initial_condition, t, semi)) | ||
| J = ForwardDiff.jacobian(similar(q0), q0) do dq, q | ||
| @unpack tmp_partitioned = semi.cache | ||
| J = ForwardDiff.jacobian(tmp_partitioned, q0) do dq, q | ||
| DispersiveShallowWater.rhs!(dq, q, semi, t) | ||
| end | ||
| return J | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to use a true IMEX scheme like
KenCarp4here. Something likeTsit5will use explicit time stepping also for the stiff part, right? I think it's fine to just add OrdinaryDiffEqSDIRK.jl to the test suite. It doesn't need to be a dependency of DSW.jl.