-
Notifications
You must be signed in to change notification settings - Fork 152
New Paired Explicit Runge-Kutta Integrator: Third Order #2008
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
Merged
Merged
Changes from all commits
Commits
Show all changes
180 commits
Select commit
Hold shift + click to select a range
da330cc
make NLsolve a weapdep
warisa-r a6789b3
fmt
warisa-r bcd4091
add NEWS.md but TBD on the ref pull request
warisa-r fd3d4ca
add comments and adjustment on solve_a_unknown
warisa-r c280292
modular implementation with init, step!, and solve_step!
warisa-r 3ddf5c4
fmt
warisa-r b9b4243
add test
warisa-r a727a87
adda body of p3 constructor test
warisa-r cb98a3f
changes according to test and correct variable names
warisa-r d84daed
only check the values of a_matrix from second row to end
warisa-r 1332c28
adjust the the constructor of path coefficient and its test
warisa-r 777f28c
Merge branch 'DanielDoehring:main' into PERK_p3_single_ext
warisa-r 7bf717a
adjust the test and add a seed to the randomized initial guess for re…
warisa-r 05853cf
Merge branch 'PERK_p3_single_ext' of https://github.com/warisa-r/Trix…
warisa-r 43cf02d
add NLsolve as a dependency for testing
warisa-r 9ed5e2b
Update ext/TrixiNLsolveExt.jl
warisa-r a739350
Update ext/TrixiNLsolveExt.jl
warisa-r cf71784
Update ext/TrixiNLsolveExt.jl
warisa-r 01a4343
Update ext/TrixiNLsolveExt.jl
warisa-r 0deb7bc
Update ext/TrixiNLsolveExt.jl
warisa-r 0708bc4
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r 0a5ad48
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r 0a3ab55
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r 8c978e2
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r 45324a2
optimize the loop for step! by moving the condition outside
warisa-r ca5951a
fmt
warisa-r 76a7a6b
more type generic
warisa-r 03fad1b
change some names
warisa-r 78ae8da
update test
warisa-r c5c455f
Correcting steps!
warisa-r 1bfb576
Apply suggestions from code review
warisa-r 86a4daa
Update examples/structured_1d_dgsem/elixir_burgers_perk3.jl
warisa-r 786de99
Update examples/structured_1d_dgsem/elixir_burgers_perk3.jl
warisa-r a3d6df5
add docstring about dt_opt
warisa-r f84d171
Merge branch 'main' into PERK_p3_single_ext
DanielDoehring 4e35589
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r a4b3df6
merge k_higher in the last stage to a bigger loop
warisa-r 6a03a3a
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r b5f227a
change solve_step! to solve!
warisa-r d029c21
Correct the logic of step!
warisa-r ff5c590
deprecation
DanielDoehring df7ec64
Optimize K_S1 away
DanielDoehring b9977c0
fmt
DanielDoehring 34d0eb5
remove dt_opt as an attribute of PERK3
warisa-r 13ac6dc
change the objective function to match the number of equations
warisa-r 516e95f
fmt
warisa-r fdba17d
minor comment fix
warisa-r b78f39a
delete some stuff left from random
warisa-r 000f117
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r 3289faf
minor adjustments
warisa-r d73c377
minor change to the comment
warisa-r b22476e
add proper comment and bring seed back
warisa-r 2ec41fa
update test values
warisa-r 03fb32f
fmt
warisa-r cda3c84
change the keyword according to the error in the test pipeline and ed…
warisa-r 84f6a6d
remove unused import
warisa-r 144bfa1
fix test values in misc
warisa-r 6e53ad2
add max iteration
warisa-r a34d412
Update ext/TrixiNLsolveExt.jl
warisa-r a65cdb8
Apply suggestions from code review
DanielDoehring 6d2fc6d
remove the allocating part of is_sol_valid
warisa-r cd22981
Merge branch 'PERK_p3_single_ext' of https://github.com/warisa-r/Trix…
warisa-r e95fe97
removing dt_opt and update test values
warisa-r c61187c
Update NEWS.md
warisa-r 2fc3085
update cfl number for the simulation
warisa-r ac055ab
Merge branch 'PERK_p3_single_ext' of https://github.com/warisa-r/Trix…
warisa-r bd55f1d
Update examples/structured_1d_dgsem/elixir_burgers_perk3.jl
warisa-r 8d08b87
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r c5c00bc
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r 6fa8647
change from a_stages_stages.txt to a_stages.txt
warisa-r 532f483
Merge branch 'PERK_p3_single_ext' of https://github.com/warisa-r/Trix…
warisa-r 88c92e2
fixed step size should work with save solution now
warisa-r 71f2841
Update examples/structured_1d_dgsem/elixir_burgers_perk3.jl
warisa-r 739b54b
add save solution to the example
warisa-r 995107b
update test to be compatible with save_solution
warisa-r 640c7f6
move comment regarding seed upwards
warisa-r e923305
Revert "Correct the logic of step!" only the part that meddles with m…
warisa-r f3f4e25
correct methods_PERK3
warisa-r a6addd7
move is_sol_valid closer to the for loop
warisa-r 87c6cae
fmt
warisa-r 0d642fb
Revert some random changes in other test unit
warisa-r d602a95
add tolerance to the test
warisa-r 2669e76
Merge branch 'main' into PERK_p3_single_ext
warisa-r bc358e4
modify functions so that they are also compatible with PERK3
warisa-r 10d7126
change function's name to be more descriptive
warisa-r 75de088
change function's name to be more descriptive in all files
warisa-r 58fabb7
Revert irrelevent change in TrixiConvexECOSExt.jl
warisa-r 40dd610
add PR number to NEWS.md
warisa-r c104ff2
fmt
warisa-r 76487b5
change from using Random to StableRNGs
warisa-r ecbb0ff
fix the value in unit test
warisa-r bcadd5a
remove prints
warisa-r 47e52d0
minor comment correction
warisa-r 9826457
attempt to fix the error at fixed time step
warisa-r d66b241
add the missing clause to test set
warisa-r d405551
adjust allocation values in test of perk3
warisa-r f070668
update test value
warisa-r 5746b5f
move objective function to the extension
warisa-r b87592e
minor fix with compute_c_coeffs
warisa-r 24cbde6
remove explicit import of solve_a_unknown from line 18
warisa-r a083ac0
Apply suggestions from code review
DanielDoehring fe26ef1
document why additional packages are loaded
warisa-r d7c1ce6
Merge branch 'PERK_p3_single_ext' of https://github.com/warisa-r/Trix…
warisa-r e42ecaf
Merge branch 'main' into PERK_p3_single_ext
warisa-r 339eae2
correct docstring
warisa-r 5e4676d
Merge branch 'PERK_p3_single_ext' of https://github.com/warisa-r/Trix…
warisa-r 1a0bf58
use Float32
warisa-r 6d95ec6
Update ext/TrixiNLsolveExt.jl
warisa-r 485a2a7
Update ext/TrixiNLsolveExt.jl
warisa-r f8731c1
Update ext/TrixiNLsolveExt.jl
warisa-r 3faf2cc
change some Flot32 back to the way they originally were
warisa-r 339f43e
add line that get the type that a_unknown should be
warisa-r 6ebf7c8
Merge branch 'main' into PERK_p3_single_ext
warisa-r ad47a2f
due to some the change of type, print out some values of a_matrix tha…
warisa-r 2974301
update test values
warisa-r 3023dc2
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r 3071c48
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r 5bff1d6
Merge branch 'main' into PERK_p3_single_ext
warisa-r 6454c46
Apply suggestions from code review
warisa-r f325f99
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r 8334c75
allocate c_eq once per solve_a_unknown is called
warisa-r b309ca5
Update ext/TrixiNLsolveExt.jl
warisa-r 08733ba
Update ext/TrixiNLsolveExt.jl
warisa-r 01bc757
Update ext/TrixiNLsolveExt.jl
warisa-r 33bdcb8
minor fix regarding recent changes witjh c_eq
warisa-r ff7ec1a
adjust a constructor to get num stages from reading the files directly
warisa-r fd05aff
Revert "adjust a constructor to get num stages from reading the files…
warisa-r 582dd87
Update TrixiNLsolveExt.jl to use forward autodiff in solve_a_butcher_…
warisa-r 022eb9a
Merge branch 'main' into PERK_p3_single_ext
warisa-r 859bf37
Apply suggestions from code review
DanielDoehring 5541844
Slight modifications a values
DanielDoehring fd46502
Merge branch 'main' into PERK_p3_single_ext
warisa-r 0d626b7
Merge branch 'main' into PERK_p3_single_ext
DanielDoehring 0b01fd5
Merge branch 'main' into PERK_p3_single_ext
DanielDoehring 877c562
Merge branch 'main' into PERK_p3_single_ext
warisa-r a50a4e0
add cfl number calculation for PERK3
warisa-r 0d9e664
update CI values
warisa-r b18688a
Merge branch 'main' into PERK_p3_single_ext
warisa-r 71cf293
remove the example without cfl calculation
warisa-r 2a0f18e
Merge branch 'PERK_p3_single_ext' of https://github.com/warisa-r/Trix…
warisa-r 995e228
Apply suggestions from code review
warisa-r 109bad9
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r 5b6edb0
add DOI to a reference in TrixiNLsolveExt
warisa-r 34303c6
update the test of perk3
warisa-r 3bce082
Merge branch 'main' into PERK_p3_single_ext
sloede e9065e7
Update examples/structured_1d_dgsem/elixir_burgers_perk3.jl
DanielDoehring acef080
Merge branch 'main' into PERK_p3_single_ext
DanielDoehring 571846c
Update examples/structured_1d_dgsem/elixir_burgers_perk3.jl
warisa-r aec9e34
Update examples/structured_1d_dgsem/elixir_burgers_perk3.jl
warisa-r f64fa34
add to docstring packages needed in order to use PERK3
warisa-r 52a5a0f
update NEWS.md
warisa-r 9ac05a6
changes according to #2026
warisa-r b73d76e
add comments to the test without stepsize callback
warisa-r f78bc28
Update ext/TrixiNLsolveExt.jl
warisa-r 3f2380b
fmt
warisa-r 54451f3
slight modification according to #2123
warisa-r fc47101
Update test/test_unit.jl
warisa-r 50e5493
Update src/time_integration/paired_explicit_runge_kutta/methods_PERK3.jl
warisa-r 8671df6
fmt + minor correction
warisa-r c1cb200
update NEWS.md
warisa-r 2079d8c
Merge branch 'main' into PERK_p3_single_ext
warisa-r 58d6bc8
make functions more general for PERK
warisa-r 823ec71
remove base.resize for perk3
warisa-r 33a7dd8
Merge branch 'main' into PERK_p3_single_ext
warisa-r 08366d3
put all the general functions of PERK into paired_explicit_runge_kutt…
warisa-r b5915f2
Update src/time_integration/paired_explicit_runge_kutta/paired_explic…
warisa-r 6587629
modify some functions to be useable for both multi and single scheme
warisa-r 00e7269
Merge branch 'PERK_p3_single_ext' of https://github.com/warisa-r/Trix…
warisa-r dee1cd4
fmt
warisa-r 3c8df33
Merge branch 'main' into PERK_p3_single_ext
warisa-r 2d77255
Merge branch 'main' into PERK_p3_single_ext
warisa-r fd469d2
ensure type consistency in compute_c_coeffs
warisa-r 127d32f
print out the full a_matrix
warisa-r 26b8e35
print out the new a_matrix from the latest change
warisa-r 96ca252
remove the false line of PERK construction
warisa-r 3098d89
fix the test values
warisa-r 11371a4
Merge branch 'main' into PERK_p3_single_ext
warisa-r 2fd7f67
move using statements to src/Trixi.jl
warisa-r a872076
Merge branch 'PERK_p3_single_ext' of https://github.com/warisa-r/Trix…
warisa-r e138bc8
Merge branch 'main' into PERK_p3_single_ext
warisa-r File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| # Convex and ECOS are imported because they are used for finding the optimal time step and optimal | ||
| # monomial coefficients in the stability polynomial of P-ERK time integrators. | ||
| using Convex, ECOS | ||
|
|
||
| # NLsolve is imported to solve the system of nonlinear equations to find the coefficients | ||
| # in the Butcher tableau in the third order P-ERK time integrator. | ||
| using NLsolve | ||
|
|
||
| using OrdinaryDiffEq | ||
| using Trixi | ||
|
|
||
| ############################################################################### | ||
| # semidiscretization of the (inviscid) Burgers equation | ||
|
|
||
| equations = InviscidBurgersEquation1D() | ||
|
|
||
| initial_condition = initial_condition_convergence_test | ||
|
|
||
| # Create DG solver with polynomial degree = 4 and (local) Lax-Friedrichs/Rusanov flux as surface flux | ||
| solver = DGSEM(polydeg = 4, surface_flux = flux_lax_friedrichs) | ||
|
|
||
| coordinates_min = (0.0,) # minimum coordinate | ||
| coordinates_max = (1.0,) # maximum coordinate | ||
| cells_per_dimension = (64,) | ||
|
|
||
| mesh = StructuredMesh(cells_per_dimension, coordinates_min, coordinates_max) | ||
|
|
||
| semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, | ||
| source_terms = source_terms_convergence_test) | ||
|
|
||
| ############################################################################### | ||
| # ODE solvers, callbacks etc. | ||
|
|
||
| tspan = (0.0, 2.0) | ||
| ode = semidiscretize(semi, tspan) | ||
|
|
||
| summary_callback = SummaryCallback() | ||
|
|
||
| analysis_interval = 200 | ||
| analysis_callback = AnalysisCallback(semi, interval = analysis_interval) | ||
|
|
||
| alive_callback = AliveCallback(analysis_interval = analysis_interval) | ||
|
|
||
| save_solution = SaveSolutionCallback(dt = 0.1, | ||
| save_initial_solution = true, | ||
| save_final_solution = true, | ||
| solution_variables = cons2prim) | ||
|
|
||
| # Construct third order paired explicit Runge-Kutta method with 8 stages for given simulation setup. | ||
| # Pass `tspan` to calculate maximum time step allowed for the bisection algorithm used | ||
| # in calculating the polynomial coefficients in the ODE algorithm. | ||
| ode_algorithm = Trixi.PairedExplicitRK3(8, tspan, semi) | ||
|
|
||
| cfl_number = Trixi.calculate_cfl(ode_algorithm, ode) | ||
| # For non-linear problems, the CFL number should be reduced by a safety factor | ||
| # as the spectrum changes (in general) over the course of a simulation | ||
| stepsize_callback = StepsizeCallback(cfl = 0.85 * cfl_number) | ||
|
|
||
| callbacks = CallbackSet(summary_callback, | ||
| analysis_callback, alive_callback, save_solution, | ||
| stepsize_callback) | ||
|
|
||
| ############################################################################### | ||
| # run the simulation | ||
| sol = Trixi.solve(ode, ode_algorithm, | ||
| 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() | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| # Package extension for adding NLsolve-based features to Trixi.jl | ||
| module TrixiNLsolveExt | ||
|
|
||
| # Required for finding coefficients in Butcher tableau in the third order of | ||
| # P-ERK scheme integrators | ||
| if isdefined(Base, :get_extension) | ||
| using NLsolve: nlsolve | ||
| else | ||
| # Until Julia v1.9 is the minimum required version for Trixi.jl, we still support Requires.jl | ||
| using ..NLsolve: nlsolve | ||
| end | ||
|
|
||
| # We use a random initialization of the nonlinear solver. | ||
| # To make the tests reproducible, we need to seed the RNG | ||
| using StableRNGs: StableRNG, rand | ||
|
|
||
| # Use functions that are to be extended and additional symbols that are not exported | ||
| using Trixi: Trixi, compute_c_coeffs, @muladd | ||
|
|
||
| # By default, Julia/LLVM does not use fused multiply-add operations (FMAs). | ||
| # Since these FMAs can increase the performance of many numerical algorithms, | ||
| # we need to opt-in explicitly. | ||
| # See https://ranocha.de/blog/Optimizing_EC_Trixi for further details. | ||
| @muladd begin | ||
| #! format: noindent | ||
|
|
||
| # Compute residuals for nonlinear equations to match a stability polynomial with given coefficients, | ||
| # in order to find A-matrix in the Butcher-Tableau | ||
| function PairedExplicitRK3_butcher_tableau_objective_function!(c_eq, a_unknown, | ||
| num_stages, | ||
| num_stage_evals, | ||
| monomial_coeffs, | ||
| cS2) | ||
| c_ts = compute_c_coeffs(num_stages, cS2) # ts = timestep | ||
| # For explicit methods, a_{1,1} = 0 and a_{2,1} = c_2 (Butcher's condition) | ||
| a_coeff = [0, c_ts[2], a_unknown...] | ||
| # Equality constraint array that ensures that the stability polynomial computed from | ||
| # the to-be-constructed Butcher-Tableau matches the monomial coefficients of the | ||
| # optimized stability polynomial. | ||
| # For details, see Chapter 4.3, Proposition 3.2, Equation (3.3) from | ||
| # Hairer, Wanner: Solving Ordinary Differential Equations 2 | ||
|
warisa-r marked this conversation as resolved.
|
||
| # DOI: 10.1007/978-3-662-09947-6 | ||
|
|
||
| # Lower-order terms: Two summands present | ||
| for i in 1:(num_stage_evals - 4) | ||
| term1 = a_coeff[num_stage_evals - 1] | ||
| term2 = a_coeff[num_stage_evals] | ||
| for j in 1:i | ||
| term1 *= a_coeff[num_stage_evals - 1 - j] | ||
| term2 *= a_coeff[num_stage_evals - j] | ||
| end | ||
| term1 *= c_ts[num_stages - 2 - i] * 1 / 6 # 1 / 6 = b_{S-1} | ||
| term2 *= c_ts[num_stages - 1 - i] * 2 / 3 # 2 / 3 = b_S | ||
|
|
||
| c_eq[i] = monomial_coeffs[i] - (term1 + term2) | ||
| end | ||
|
|
||
| # Highest coefficient: Only one term present | ||
| i = num_stage_evals - 3 | ||
| term2 = a_coeff[num_stage_evals] | ||
| for j in 1:i | ||
| term2 *= a_coeff[num_stage_evals - j] | ||
| end | ||
| term2 *= c_ts[num_stages - 1 - i] * 2 / 3 # 2 / 3 = b_S | ||
|
|
||
| c_eq[i] = monomial_coeffs[i] - term2 | ||
| # Third-order consistency condition (Cf. eq. (27) from https://doi.org/10.1016/j.jcp.2022.111470 | ||
| c_eq[num_stage_evals - 2] = 1 - 4 * a_coeff[num_stage_evals] - | ||
| a_coeff[num_stage_evals - 1] | ||
| end | ||
|
|
||
| # Find the values of the a_{i, i-1} in the Butcher tableau matrix A by solving a system of | ||
| # non-linear equations that arise from the relation of the stability polynomial to the Butcher tableau. | ||
| # For details, see Proposition 3.2, Equation (3.3) from | ||
| # Hairer, Wanner: Solving Ordinary Differential Equations 2 | ||
| function Trixi.solve_a_butcher_coeffs_unknown!(a_unknown, num_stages, monomial_coeffs, | ||
|
DanielDoehring marked this conversation as resolved.
|
||
| c_s2, c; | ||
| verbose, max_iter = 100000) | ||
|
|
||
| # Define the objective_function | ||
| function objective_function!(c_eq, x) | ||
| return PairedExplicitRK3_butcher_tableau_objective_function!(c_eq, x, | ||
| num_stages, | ||
| num_stages, | ||
| monomial_coeffs, | ||
| c_s2) | ||
| end | ||
|
warisa-r marked this conversation as resolved.
|
||
|
|
||
| # RealT is determined as the type of the first element in monomial_coeffs to ensure type consistency | ||
| RealT = typeof(monomial_coeffs[1]) | ||
|
|
||
| # To ensure consistency and reproducibility of results across runs, we use | ||
| # a seeded random initial guess. | ||
| rng = StableRNG(555) | ||
|
|
||
| for _ in 1:max_iter | ||
| # Due to the nature of the nonlinear solver, different initial guesses can lead to | ||
| # small numerical differences in the solution. | ||
|
|
||
| x0 = convert(RealT, 0.1) .* rand(rng, RealT, num_stages - 2) | ||
|
|
||
| sol = nlsolve(objective_function!, x0, method = :trust_region, | ||
| ftol = 4.0e-16, # Enforce objective up to machine precision | ||
| iterations = 10^4, xtol = 1.0e-13, autodiff = :forward) | ||
|
|
||
| a_unknown = sol.zero # Retrieve solution (root = zero) | ||
|
|
||
| # Check if the values a[i, i-1] >= 0.0 (which stem from the nonlinear solver) | ||
| # and also c[i] - a[i, i-1] >= 0.0 since all coefficients should be non-negative | ||
|
warisa-r marked this conversation as resolved.
|
||
| # to avoid downwinding of numerical fluxes. | ||
| is_sol_valid = all(x -> !isnan(x) && x >= 0, a_unknown) && | ||
| all(!isnan(c[i] - a_unknown[i - 2]) && | ||
| c[i] - a_unknown[i - 2] >= 0 for i in eachindex(c) if i > 2) | ||
|
|
||
| if is_sol_valid | ||
| return a_unknown | ||
| else | ||
| if verbose | ||
| println("Solution invalid. Restart the process of solving non-linear system of equations again.") | ||
| end | ||
| end | ||
| end | ||
|
|
||
| error("Maximum number of iterations ($max_iter) reached. Cannot find valid sets of coefficients.") | ||
| end | ||
| end # @muladd | ||
|
|
||
| end # module TrixiNLsolveExt | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.