Skip to content

Commit b26e0ea

Browse files
authored
Merge pull request #172 from ranocha/calc_error
extend calc_error_norms(func, dg, t)
2 parents 80a350c + beb5359 commit b26e0ea

File tree

7 files changed

+114
-10
lines changed

7 files changed

+114
-10
lines changed

src/equations/equations.jl

+3
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ DG method (except floating point errors).
8080
end
8181

8282

83+
@inline cons2cons(u, equation::AbstractEquation) = u
84+
85+
8386
####################################################################################################
8487
# Include files with actual implementations for different systems of equations.
8588

src/solvers/dg/2d/dg.jl

+45-4
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ integrate(u, dg::Dg2D; normalize=true) = integrate(identity, u, dg; normalize=no
706706

707707

708708
# Calculate L2/Linf error norms based on "exact solution"
709-
function calc_error_norms(dg::Dg2D, t)
709+
function calc_error_norms(func, dg::Dg2D, t)
710710
# Gather necessary information
711711
equation = equations(dg)
712712
n_nodes_analysis = size(dg.analysis_vandermonde, 1)
@@ -722,8 +722,8 @@ function calc_error_norms(dg::Dg2D, t)
722722
2, size(dg.analysis_vandermonde, 1), size(dg.analysis_vandermonde, 2))
723723

724724
# Set up data structures
725-
l2_error = @SVector zeros(nvariables(equation))
726-
linf_error = @SVector zeros(nvariables(equation))
725+
l2_error = zero(func(get_node_vars(dg.elements.u, dg, 1, 1, 1), equation))
726+
linf_error = zero(func(get_node_vars(dg.elements.u, dg, 1, 1, 1), equation))
727727

728728
# Iterate over all elements for error calculations
729729
for element_id in 1:dg.n_elements
@@ -736,7 +736,7 @@ function calc_error_norms(dg::Dg2D, t)
736736
jacobian_volume = inv(dg.elements.inverse_jacobian[element_id])^ndims(dg)
737737
for j in 1:n_nodes_analysis, i in 1:n_nodes_analysis
738738
u_exact = dg.initial_conditions(get_node_coords(x, dg, i, j), t, equation)
739-
diff = u_exact - get_node_vars(u, dg, i, j)
739+
diff = func(u_exact, equation) - func(get_node_vars(u, dg, i, j), equation)
740740
l2_error += diff.^2 * (weights[i] * weights[j] * jacobian_volume)
741741
linf_error = @. max(linf_error, abs(diff))
742742
end
@@ -920,6 +920,37 @@ function analyze_solution(dg::Dg2D, mesh::TreeMesh, time::Real, dt::Real, step::
920920
println()
921921
end
922922

923+
# L2/L∞ errors of the primitive variables
924+
if :l2_error_primitive in dg.analysis_quantities || :linf_error_primitive in dg.analysis_quantities
925+
l2_error_prim, linf_error_prim = calc_error_norms(cons2prim, dg, time)
926+
927+
print(" Variable: ")
928+
for v in 1:nvariables(equation)
929+
@printf(" %-14s", varnames_prim(equation)[v])
930+
end
931+
println()
932+
933+
# L2 error
934+
if :l2_error_primitive in dg.analysis_quantities
935+
print(" L2 error prim.: ")
936+
for v in 1:nvariables(equation)
937+
@printf("%10.8e ", l2_error_prim[v])
938+
dg.save_analysis && @printf(f, " % 10.8e", l2_error_prim[v])
939+
end
940+
println()
941+
end
942+
943+
# L∞ error
944+
if :linf_error_primitive in dg.analysis_quantities
945+
print(" Linf error pri.:")
946+
for v in 1:nvariables(equation)
947+
@printf("%10.8e ", linf_error_prim[v])
948+
dg.save_analysis && @printf(f, " % 10.8e", linf_error_prim[v])
949+
end
950+
println()
951+
end
952+
end
953+
923954
# Entropy time derivative
924955
if :dsdu_ut in dg.analysis_quantities
925956
duds_ut = calc_entropy_timederivative(dg, time)
@@ -1088,6 +1119,16 @@ function save_analysis_header(filename, quantities, equation::AbstractEquation{2
10881119
@printf(f, " %-14s", "res_" * v)
10891120
end
10901121
end
1122+
if :l2_error_primitive in quantities
1123+
for v in varnames_prim(equation)
1124+
@printf(f, " %-14s", "l2_" * v)
1125+
end
1126+
end
1127+
if :linf_error_primitive in quantities
1128+
for v in varnames_prim(equation)
1129+
@printf(f, " %-14s", "linf_" * v)
1130+
end
1131+
end
10911132
if :dsdu_ut in quantities
10921133
@printf(f, " %-14s", "dsdu_ut")
10931134
end

src/solvers/dg/3d/dg.jl

+46-5
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ integrate(u, dg::Dg3D; normalize=true) = integrate(identity, u, dg; normalize=no
750750

751751

752752
# Calculate L2/Linf error norms based on "exact solution"
753-
function calc_error_norms(dg::Dg3D, t)
753+
function calc_error_norms(func, dg::Dg3D, t)
754754
# Gather necessary information
755755
equation = equations(dg)
756756
n_nodes_analysis = size(dg.analysis_vandermonde, 1)
@@ -770,8 +770,8 @@ function calc_error_norms(dg::Dg3D, t)
770770
3, size(dg.analysis_vandermonde, 1), size(dg.analysis_vandermonde, 1), size(dg.analysis_vandermonde, 2))
771771

772772
# Set up data structures
773-
l2_error = @SVector zeros(nvariables(equation))
774-
linf_error = @SVector zeros(nvariables(equation))
773+
l2_error = zero(func(get_node_vars(dg.elements.u, dg, 1, 1, 1, 1), equation))
774+
linf_error = zero(func(get_node_vars(dg.elements.u, dg, 1, 1, 1, 1), equation))
775775

776776
# Iterate over all elements for error calculations
777777
for element_id in 1:dg.n_elements
@@ -784,7 +784,7 @@ function calc_error_norms(dg::Dg3D, t)
784784
jacobian_volume = inv(dg.elements.inverse_jacobian[element_id])^ndims(dg)
785785
for k in 1:n_nodes_analysis, j in 1:n_nodes_analysis, i in 1:n_nodes_analysis
786786
u_exact = dg.initial_conditions(get_node_coords(x, dg, i, j, k), t, equation)
787-
diff = u_exact - get_node_vars(u, dg, i, j, k)
787+
diff = func(u_exact, equation) - func(get_node_vars(u, dg, i, j, k), equation)
788788
l2_error += diff.^2 * (weights[i] * weights[j] * weights[k] * jacobian_volume)
789789
linf_error = @. max(linf_error, abs(diff))
790790
end
@@ -968,7 +968,7 @@ function analyze_solution(dg::Dg3D, mesh::TreeMesh, time::Real, dt::Real, step::
968968
end
969969

970970
# Calculate L2/Linf errors, which are also returned by analyze_solution
971-
l2_error, linf_error = calc_error_norms(dg, time)
971+
l2_error, linf_error = calc_error_norms(dg, time)
972972

973973
# L2 error
974974
if :l2_error in dg.analysis_quantities
@@ -1022,6 +1022,37 @@ function analyze_solution(dg::Dg3D, mesh::TreeMesh, time::Real, dt::Real, step::
10221022
println()
10231023
end
10241024

1025+
# L2/L∞ errors of the primitive variables
1026+
if :l2_error_primitive in dg.analysis_quantities || :linf_error_primitive in dg.analysis_quantities
1027+
l2_error_prim, linf_error_prim = calc_error_norms(cons2prim, dg, time)
1028+
1029+
print(" Variable: ")
1030+
for v in 1:nvariables(equation)
1031+
@printf(" %-14s", varnames_prim(equation)[v])
1032+
end
1033+
println()
1034+
1035+
# L2 error
1036+
if :l2_error_primitive in dg.analysis_quantities
1037+
print(" L2 error prim.: ")
1038+
for v in 1:nvariables(equation)
1039+
@printf("%10.8e ", l2_error_prim[v])
1040+
dg.save_analysis && @printf(f, " % 10.8e", l2_error_prim[v])
1041+
end
1042+
println()
1043+
end
1044+
1045+
# L∞ error
1046+
if :linf_error_primitive in dg.analysis_quantities
1047+
print(" Linf error pri.:")
1048+
for v in 1:nvariables(equation)
1049+
@printf("%10.8e ", linf_error_prim[v])
1050+
dg.save_analysis && @printf(f, " % 10.8e", linf_error_prim[v])
1051+
end
1052+
println()
1053+
end
1054+
end
1055+
10251056
# Entropy time derivative
10261057
if :dsdu_ut in dg.analysis_quantities
10271058
duds_ut = calc_entropy_timederivative(dg, time)
@@ -1181,6 +1212,16 @@ function save_analysis_header(filename, quantities, equation::AbstractEquation{3
11811212
@printf(f, " %-14s", "res_" * v)
11821213
end
11831214
end
1215+
if :l2_error_primitive in quantities
1216+
for v in varnames_prim(equation)
1217+
@printf(f, " %-14s", "l2_" * v)
1218+
end
1219+
end
1220+
if :linf_error_primitive in quantities
1221+
for v in varnames_prim(equation)
1222+
@printf(f, " %-14s", "linf_" * v)
1223+
end
1224+
end
11841225
if :dsdu_ut in quantities
11851226
@printf(f, " %-14s", "dsdu_ut")
11861227
end

src/solvers/dg/dg.jl

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ end
5353
return nothing
5454
end
5555

56+
5657
# Include utilities
5758
include("interpolation.jl")
5859
include("l2projection.jl")

src/solvers/solvers.jl

+11
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ function make_solver(name::String, equations::AbstractEquation, mesh::TreeMesh;
3838
end
3939

4040

41+
"""
42+
calc_error_norms([func=(u,equation)->u,] solver, t)
43+
44+
Calculate the discrete L2 and L∞ errors of `func` applied to the conservative variables of
45+
the problem encapsulated by `solver` at time `t`, where `func` is called as `func(u, equation)`.
46+
"""
47+
function calc_error_norms end
48+
49+
@inline calc_error_norms(solver::AbstractSolver, t) = calc_error_norms(cons2cons, solver, t)
50+
51+
4152
####################################################################################################
4253
# Include files with actual implementations for different systems of equations.
4354

test/test_examples_2d.jl

+6
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ const EXAMPLES_DIR = joinpath(pathof(Trixi) |> dirname |> dirname, "examples", "
7575
l2 = [0.06159341742582756, 0.05012484425381723, 0.05013298724507752, 0.22537740506116724],
7676
linf = [0.29912627861573327, 0.30886767304359375, 0.3088108573487326, 1.0657556075017878])
7777
end
78+
@testset "parameters_density_wave.toml" begin
79+
test_trixi_run(joinpath(EXAMPLES_DIR, "parameters_density_wave.toml"),
80+
l2 = [0.001060077845747576, 0.00010600778457107525, 0.00021201556914875742, 2.6501946139091318e-5],
81+
linf = [0.0065356386867677085, 0.0006535638688170142, 0.0013071277374487877, 0.0001633909674296774],
82+
extra_analysis_quantities=["l2_error_primitive", "linf_error_primitive"], t_end=0.5)
83+
end
7884
@testset "parameters_ec_mhd.toml" begin
7985
test_trixi_run(joinpath(EXAMPLES_DIR, "parameters_ec_mhd.toml"),
8086
l2 = [0.03607862694368351, 0.04281395008247395, 0.04280207686965749, 0.025746770192645763, 0.1611518499414067, 0.017455917249117023, 0.017456981264942977, 0.02688321120361229, 0.00015024027267648003],

test/test_examples_3d.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ const EXAMPLES_DIR = joinpath(pathof(Trixi) |> dirname |> dirname, "examples", "
120120
test_trixi_run(joinpath(EXAMPLES_DIR, "parameters_density_pulse.toml"),
121121
l2 = [0.05719652660597408, 0.0571965266059741, 0.05719652660597407, 0.05719652660597409, 0.08579478990896279],
122122
linf = [0.27375961853433606, 0.27375961853433517, 0.27375961853433384, 0.2737596185343343, 0.4106394278015033],
123-
source_terms=Trixi.source_terms_harmonic)
123+
source_terms=Trixi.source_terms_harmonic,
124+
extra_analysis_quantities=["l2_error_primitive", "linf_error_primitive"])
124125
end
125126
@testset "parameters_taylor_green_vortex.toml" begin
126127
test_trixi_run(joinpath(EXAMPLES_DIR, "parameters_taylor_green_vortex.toml"),

0 commit comments

Comments
 (0)