Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ jobs:
include:
- version: '1.11'
os: ubuntu-latest
- version: '1.12'
os: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: julia-actions/setup-julia@v2
Expand Down
86 changes: 86 additions & 0 deletions .github/workflows/JET.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: JET
on:
push:
branches:
- main
tags: ['*']
paths-ignore:
- 'CITATION.bib'
- 'LICENSE.md'
- 'README.md'
- '.zenodo.json'
- '.github/workflows/benchmark.yml'
- '.github/workflows/CompatHelper.yml'
- '.github/workflows/Documenter.yml'
- '.github/workflows/Format-check.yml'
- '.github/workflows/TagBot.yml'
- '.github/workflows/SpellCheck.yml'
- 'benchmark/**'
- 'docs/**'
pull_request:
paths-ignore:
- 'CITATION.bib'
- 'LICENSE.md'
- 'README.md'
- '.zenodo.json'
- '.github/workflows/benchmark.yml'
- '.github/workflows/CompatHelper.yml'
- '.github/workflows/Documenter.yml'
- '.github/workflows/Format-check.yml'
- '.github/workflows/TagBot.yml'
- '.github/workflows/SpellCheck.yml'
- 'benchmark/**'
- 'docs/**'
workflow_dispatch:

concurrency:
# Skip intermediate builds: always.
# Cancel intermediate builds: only if it is a pull request build.
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}

jobs:
test:
if: "!contains(github.event.head_commit.message, 'skip ci')"
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ github.event_name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
version:
- '1.12'
os:
- ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.version }}
- run: julia -e 'using InteractiveUtils; versioninfo(verbose=true)'
- uses: julia-actions/cache@v2
- name: Install and run JET.jl
shell: julia --project="." --color=yes {0}
run: |
using Pkg
Pkg.add("JET")
Pkg.instantiate()
using JET
using DispersiveShallowWater

# JET.jl
# With the default settings as of 2025-05-08, JET.jl
# reports issues originating from RecipesBase.jl.
# The only way to ignore them seems to be something like the
# following hack inspired by the discussion in
# https://github.com/aviatesk/JET.jl/issues/570
struct IgnoreRecipesBase end
function JET.match_module(::IgnoreRecipesBase,
@nospecialize(report::JET.InferenceErrorReport))
s = "MethodInstance for RecipesBase.apply_recipe"
any(report.vst) do vst
occursin(s, string(vst))
end
end
test_package(DispersiveShallowWater;
target_defined_modules = true,
ignored_modules = (IgnoreRecipesBase(),))
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*.jl.*.cov
*.jl.cov
*.jl.mem
**/Manifest.toml
**/Manifest*.toml
out*/
/docs/build/
docs/src/changelog.md
Expand Down
18 changes: 9 additions & 9 deletions src/semidiscretization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,12 @@ function PolynomialBases.integrate(q, semi::Semidiscretization)
integrate(identity, q, semi)
end

function integrate_quantity(func, q, semi::Semidiscretization)
function integrate_quantity(func, q, semi)
quantity = zeros(eltype(q), nnodes(semi))
integrate_quantity!(quantity, func, q, semi)
end

function integrate_quantity!(quantity, func, q, semi::Semidiscretization)
function integrate_quantity!(quantity, func, q, semi)
for i in eachnode(semi)
quantity[i] = func(get_node_vars(q, semi.equations, i), semi.equations)
end
Expand All @@ -186,26 +186,26 @@ function integrate_quantity!(quantity,
func::Union{typeof(energy_total_modified),
typeof(entropy_modified),
typeof(hamiltonian)}, q,
semi::Semidiscretization)
semi)
inplace_version(func)(quantity, q, semi.equations, semi.cache)
integrate(quantity, semi)
end

@inline function mesh_equations_solver(semi::Semidiscretization)
@inline function mesh_equations_solver(semi)
@unpack mesh, equations, solver = semi
return mesh, equations, solver
end

@inline function mesh_equations_solver_cache(semi::Semidiscretization)
@inline function mesh_equations_solver_cache(semi)
@unpack mesh, equations, solver, cache = semi
return mesh, equations, solver, cache
end

function calc_error_norms(q, t, semi::Semidiscretization)
function calc_error_norms(q, t, semi)
calc_error_norms(q, t, semi.initial_condition, mesh_equations_solver(semi)...)
end

function rhs!(dq, q, semi::Semidiscretization, t)
function rhs!(dq, q, semi, t)
@unpack mesh, equations, initial_condition, boundary_conditions, solver, source_terms, cache = semi

@trixi_timeit timer() "rhs!" rhs!(dq, q, t, mesh, equations, initial_condition,
Expand All @@ -214,14 +214,14 @@ function rhs!(dq, q, semi::Semidiscretization, t)
return nothing
end

function compute_coefficients(func, t, semi::Semidiscretization)
function compute_coefficients(func, t, semi)
@unpack mesh, equations, solver = semi
q = allocate_coefficients(mesh_equations_solver(semi)...)
compute_coefficients!(q, func, t, semi)
return q
end

function compute_coefficients!(q, func, t, semi::Semidiscretization)
function compute_coefficients!(q, func, t, semi)
# Call `compute_coefficients` defined by the solver
mesh, equations, solver = mesh_equations_solver(semi)
compute_coefficients!(q, func, t, mesh,
Expand Down
32 changes: 18 additions & 14 deletions src/solver.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ Create a solver, where the three summation-by-parts (SBP) first-, second-, and t
are of accuracy order `accuracy_order` and associated to the `mesh`.

!!! warning "Periodic operators only"
This constructor creates periodic derivative operators that are only compatible with periodic
boundary conditions. For non-periodic boundary conditions, use the `Solver(D1, D2, D3)`
This constructor creates periodic derivative operators that are only compatible with periodic
boundary conditions. For non-periodic boundary conditions, use the `Solver(D1, D2, D3)`
constructor with appropriate non-periodic operators (or `nothing`).
"""
function Solver(mesh, accuracy_order)
Expand All @@ -78,7 +78,7 @@ end

Create a solver, where `D1` is an `AbstractDerivativeOperator`
from [SummationByPartsOperators.jl](https://github.com/ranocha/SummationByPartsOperators.jl)
of first `derivative_order`, `D2` is an `AbstractDerivativeOperator`
of first `derivative_order`, `D2` is an `AbstractDerivativeOperator`
of second `derivative_order` or an `AbstractMatrix`, and `D3` is an `AbstractDerivativeOperator`
of third `derivative_order` or an `AbstractMatrix`. `D2` and `D3` can also be `nothing`
if that derivative is not used by the discretization.
Expand Down Expand Up @@ -135,28 +135,34 @@ end
return nothing
end

function allocate_coefficients(mesh::Mesh1D, equations, solver::AbstractSolver)
function allocate_coefficients(mesh, equations, solver)
return ArrayPartition(ntuple(_ -> zeros(real(solver), nnodes(mesh)),
Val(nvariables(equations))))
end

function compute_coefficients!(q, func, t, mesh::Mesh1D,
function compute_coefficients!(q, func, t, mesh,
is_hyperbolic_appproximation::Val{false},
equations, solver::AbstractSolver)
equations, solver)
x = grid(solver)
for i in eachnode(solver)
q_node = func(x[i], t, equations, mesh)
set_node_vars!(q, q_node, equations, i)
end
end

# `set_approximation_variables!` is defined for equations, which are hyperbolic
# approximations, but below it is called for `equations` for which the compiler
# doesn't know from type annotations that these are hyperbolic approximations.
# Therefore, JET.jl fails. We provide a fallback definition here that does nothing.
set_approximation_variables!(q, mesh, equations, solver) = nothing

# For a hyperbolic approximation, we allow returning either the full set
# of variables or a reduced number determining only the limit system.
# In the second case, we compute the remaining variables using the default
# initialization specific to the equations.
function compute_coefficients!(q, func, t, mesh::Mesh1D,
function compute_coefficients!(q, func, t, mesh,
is_hyperbolic_appproximation::Val{true},
equations, solver::AbstractSolver)
equations, solver)
x = grid(solver)
q_node = func(x[begin], t, equations, mesh)
if length(q_node) == nvariables(equations)
Expand All @@ -176,8 +182,8 @@ function compute_coefficients!(q, func, t, mesh::Mesh1D,
end
end

function calc_error_norms(q, t, initial_condition, mesh::Mesh1D, equations,
solver::AbstractSolver)
function calc_error_norms(q, t, initial_condition, mesh, equations,
solver)
q_exact = similar(q)
compute_coefficients!(q_exact, initial_condition, t, mesh,
is_hyperbolic_appproximation(equations), equations,
Expand All @@ -192,13 +198,11 @@ function calc_error_norms(q, t, initial_condition, mesh::Mesh1D, equations,
return l2_error, linf_error
end

function calc_sources!(dq, q, t, source_terms::Nothing,
equations::AbstractEquations{1}, solver::Solver)
function calc_sources!(dq, q, t, source_terms::Nothing, equations, solver)
return nothing
end

function calc_sources!(dq, q, t, source_terms,
equations::AbstractEquations{1}, solver::Solver)
function calc_sources!(dq, q, t, source_terms, equations, solver)
x = grid(solver)
for i in eachnode(solver)
local_source = source_terms(get_node_vars(q, equations, i), x[i], t, equations)
Expand Down
4 changes: 2 additions & 2 deletions src/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function convergence_test(mod::Module, example::AbstractString, Ns::AbstractVect

trixi_include(mod, example; kwargs..., N = Ns[iter])

l2_error, linf_error = mod.analysis_callback(mod.sol)
l2_error, linf_error = @invokelatest mod.analysis_callback(@invokelatest mod.sol)

# collect errors as one vector to reshape later
append!(errors[:l2], l2_error)
Expand All @@ -112,7 +112,7 @@ function convergence_test(mod::Module, example::AbstractString, Ns::AbstractVect
end

# Use raw error values to compute EOC
analyze_convergence(io, errors, iterations, mod.semi, Ns)
analyze_convergence(io, errors, iterations, (@invokelatest mod.semi), Ns)
end

# Analyze convergence for any semidiscretization
Expand Down
2 changes: 0 additions & 2 deletions test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
OrdinaryDiffEqLowStorageRK = "b0944070-b475-4768-8dec-fb6eb410534d"
OrdinaryDiffEqRosenbrock = "43230ef6-c299-4910-a778-202eb28ce4ce"
OrdinaryDiffEqTsit5 = "b1df2697-797e-41e3-8120-5422d3b24e4a"
Expand All @@ -18,7 +17,6 @@ TrixiTest = "0a316866-cbd0-4425-8bcb-08103b2c1f26"
Aqua = "0.7, 0.8"
ExplicitImports = "1.0.1"
ForwardDiff = "0.10.36, 1"
JET = "0.9.9"
OrdinaryDiffEqLowStorageRK = "1.1"
OrdinaryDiffEqRosenbrock = "1.9"
OrdinaryDiffEqTsit5 = "1.1"
Expand Down
19 changes: 0 additions & 19 deletions test/test_aqua.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
@testitem "Aqua.jl" setup=[Setup] begin
using Aqua
using ExplicitImports: check_no_implicit_imports, check_no_stale_explicit_imports
using JET

# Aqua.jl
Aqua.test_all(DispersiveShallowWater,
Expand All @@ -10,22 +9,4 @@
# ExplicitImports.jl
@test isnothing(check_no_implicit_imports(DispersiveShallowWater))
@test isnothing(check_no_stale_explicit_imports(DispersiveShallowWater))

# JET.jl
# With the default settings as of 2025-05-08, JET.jl
# reports issues originating from RecipesBase.jl.
# The only way to ignore them seems to be something like the
# following hack inspired by the discussion in
# https://github.com/aviatesk/JET.jl/issues/570
struct IgnoreRecipesBase end
function JET.match_module(::IgnoreRecipesBase,
@nospecialize(report::JET.InferenceErrorReport))
s = "MethodInstance for RecipesBase.apply_recipe"
any(report.vst) do vst
occursin(s, string(vst))
end
end
test_package(DispersiveShallowWater;
target_defined_modules = true,
ignored_modules = (IgnoreRecipesBase(),))
end
2 changes: 1 addition & 1 deletion test/test_hyperbolic_serre_green_naghdi_1d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ end
0.0,
1.141036530464996,
4.819814592771365e-6
])
], atol=1e-8) # to make CI pass

@test_allocations(DispersiveShallowWater.rhs!, semi, sol, allocs=1_000)
end
Expand Down
3 changes: 2 additions & 1 deletion test/test_kdv_1d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ end
linf=[8.131770758672274e-5],
cons_error=[2.842170943040401e-14],
change_waterheight=2.842170943040401e-14,
change_entropy=5.861043206323302e-9)
change_entropy=5.861043206323302e-9,
atol=1e-9) # to make CI pass

@test_allocations(DispersiveShallowWater.rhs!, semi, sol, allocs=5_000)
end
2 changes: 1 addition & 1 deletion test/test_serre_green_naghdi_1d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ end
cons_error=[1.7763568394002505e-15 5.265416110067367e-5 0.0],
change_waterheight=-1.7763568394002505e-15,
change_entropy_modified=130.79560136094597,
atol=1e-11) # to make CI pass
atol=1e-10) # to make CI pass

@test_allocations(DispersiveShallowWater.rhs!, semi, sol, allocs=410_000)
end
Expand Down
4 changes: 2 additions & 2 deletions test/test_unit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -540,15 +540,15 @@ end

accuracy_orders = [2, 4, 6]
for accuracy_order in accuracy_orders
eoc_mean_values, _ = convergence_test(default_example(), 2, N = 512,
eoc_mean_values, _ = convergence_test(@__MODULE__, default_example(), 2, N = 512,
tspan = (0.0, 1.0),
accuracy_order = accuracy_order)
@test isapprox(eoc_mean_values[:l2][1], accuracy_order, atol = 0.5)
@test isapprox(eoc_mean_values[:linf][2], accuracy_order, atol = 0.5)
@test isapprox(eoc_mean_values[:l2][1], accuracy_order, atol = 0.5)
@test isapprox(eoc_mean_values[:linf][2], accuracy_order, atol = 0.5)

eoc_mean_values2, _ = convergence_test(default_example(), [512, 1024],
eoc_mean_values2, _ = convergence_test(@__MODULE__, default_example(), [512, 1024],
tspan = (0.0, 1.0),
accuracy_order = accuracy_order)
for kind in (:l2, :linf), variable in (1, 2)
Expand Down