@@ -48,31 +48,46 @@ function default_example()
48
48
" bbm_bbm_variable_bathymetry_1d_basic.jl" )
49
49
end
50
50
51
+ function convergence_test (example:: AbstractString , iterations_or_Ns; kwargs... )
52
+ convergence_test (Main, example:: AbstractString , iterations_or_Ns; kwargs... )
53
+ end
54
+
51
55
"""
52
- convergence_test([mod::Module=Main,] example::AbstractString, iterations; kwargs...)
56
+ convergence_test([mod::Module=Main,] example::AbstractString, iterations; io::IO = stdout, kwargs...)
57
+ convergence_test([mod::Module=Main,] example::AbstractString, Ns::AbstractVector; io::IO = stdout, kwargs...)
53
58
54
- Run `iterations` simulations using the setup given in `example` and compute
59
+ Run multiple simulations using the setup given in `example` and compute
55
60
the experimental order of convergence (EOC) in the ``L^2`` and ``L^\\ infty`` norm.
56
- In each iteration, the resolution of the respective mesh will be doubled.
61
+ If `iterations` is passed as integer, in each iteration, the resolution of the respective mesh
62
+ will be doubled. If `Ns` is passed as vector, the simulations will be run for each value of `Ns`.
57
63
Additional keyword arguments `kwargs...` and the optional module `mod` are passed directly
58
64
to [`trixi_include`](@ref).
59
65
60
66
Adjusted from [Trixi.jl](https://github.com/trixi-framework/Trixi.jl).
61
67
"""
62
- function convergence_test (mod:: Module , example:: AbstractString , iterations; kwargs... )
68
+ function convergence_test (mod:: Module , example:: AbstractString , iterations; io:: IO = stdout ,
69
+ kwargs... )
63
70
@assert (iterations> 1 ,
64
71
" Number of iterations must be bigger than 1 for a convergence analysis" )
65
72
73
+ initial_N = extract_initial_N (example, kwargs)
74
+ Ns = initial_N * 2 .^ (0 : (iterations - 1 ))
75
+ convergence_test (mod, example, Ns; io = io, kwargs... )
76
+ end
77
+
78
+ function convergence_test (mod:: Module , example:: AbstractString , Ns:: AbstractVector ;
79
+ io:: IO = stdout , kwargs... )
66
80
# Types of errors to be calculated
67
81
errors = Dict (:l2 => Float64[], :linf => Float64[])
68
82
69
- initial_N = extract_initial_N (example, kwargs)
70
-
83
+ Base. require_one_based_indexing (Ns)
84
+ sort! (Ns)
85
+ iterations = length (Ns)
71
86
# run simulations and extract errors
72
87
for iter in 1 : iterations
73
88
println (" Running convtest iteration " , iter, " /" , iterations)
74
89
75
- trixi_include (mod, example; kwargs... , N = initial_N * 2 ^ ( iter - 1 ) )
90
+ trixi_include (mod, example; kwargs... , N = Ns[ iter] )
76
91
77
92
l2_error, linf_error = mod. analysis_callback (mod. sol)
78
93
@@ -85,20 +100,20 @@ function convergence_test(mod::Module, example::AbstractString, iterations; kwar
85
100
end
86
101
87
102
# Use raw error values to compute EOC
88
- analyze_convergence (errors, iterations, mod. semi, initial_N )
103
+ analyze_convergence (io, errors, iterations, mod. semi, Ns )
89
104
end
90
105
91
106
# Analyze convergence for any semidiscretization
92
107
# Note: this intermediate method is to allow dispatching on the semidiscretization
93
- function analyze_convergence (errors, iterations, semi:: Semidiscretization , initial_N )
108
+ function analyze_convergence (io, errors, iterations, semi:: Semidiscretization , Ns )
94
109
_, equations, _, _ = mesh_equations_solver_cache (semi)
95
110
variablenames = varnames (prim2prim, equations)
96
- analyze_convergence (errors, iterations, variablenames, initial_N )
111
+ analyze_convergence (io, errors, iterations, variablenames, Ns )
97
112
end
98
113
99
114
# This method is called with the collected error values to actually compute and print the EOC
100
- function analyze_convergence (errors, iterations,
101
- variablenames:: Union{Tuple, AbstractArray} , initial_N )
115
+ function analyze_convergence (io, errors, iterations,
116
+ variablenames:: Union{Tuple, AbstractArray} , Ns )
102
117
nvariables = length (variablenames)
103
118
104
119
# Reshape errors to get a matrix where the i-th row represents the i-th iteration
@@ -107,66 +122,62 @@ function analyze_convergence(errors, iterations,
107
122
for (kind, error) in errors)
108
123
109
124
# Calculate EOCs where the columns represent the variables
110
- # As dx halves in every iteration the denominator needs to be log(1/2)
111
- eocs = Dict (kind => log .(error[ 2 : end , :] ./ error[ 1 : (end - 1 ), :]) ./ log ( 1 / 2 )
125
+ eocs = Dict (kind => log .(error[ 2 : end , :] ./ error[ 1 : ( end - 1 ), :]) ./
126
+ log .(Ns[ 1 : (end - 1 )] ./ Ns[ 2 : end ] )
112
127
for (kind, error) in errorsmatrix)
113
128
114
129
eoc_mean_values = Dict {Symbol, Any} ()
115
130
eoc_mean_values[:variables ] = variablenames
116
131
117
132
for (kind, error) in errorsmatrix
118
- println (kind)
133
+ println (io, kind)
119
134
120
135
for v in variablenames
121
- @printf (" %-25s" , v)
136
+ @printf (io, " %-25s" , v)
122
137
end
123
- println (" " )
138
+ println (io, " " )
124
139
125
140
for k in 1 : nvariables
126
- @printf (" %-5s" , " N" )
127
- @printf (" %-10s" , " error" )
128
- @printf (" %-10s" , " EOC" )
141
+ @printf (io, " %-5s" , " N" )
142
+ @printf (io, " %-10s" , " error" )
143
+ @printf (io, " %-10s" , " EOC" )
129
144
end
130
- println (" " )
145
+ println (io, " " )
131
146
132
147
# Print errors for the first iteration
133
148
for k in 1 : nvariables
134
- @printf (" %-5d" , initial_N )
135
- @printf (" %-10.2e" , error[1 , k])
136
- @printf (" %-10s" , " -" )
149
+ @printf (io, " %-5d" , Ns[ 1 ] )
150
+ @printf (io, " %-10.2e" , error[1 , k])
151
+ @printf (io, " %-10s" , " -" )
137
152
end
138
- println (" " )
153
+ println (io, " " )
139
154
140
155
# For the following iterations print errors and EOCs
141
156
for j in 2 : iterations
142
157
for k in 1 : nvariables
143
- @printf (" %-5d" , initial_N * 2 ^ (j - 1 ) )
144
- @printf (" %-10.2e" , error[j, k])
145
- @printf (" %-10.2f" , eocs[kind][j - 1 , k])
158
+ @printf (io, " %-5d" , Ns[j] )
159
+ @printf (io, " %-10.2e" , error[j, k])
160
+ @printf (io, " %-10.2f" , eocs[kind][j - 1 , k])
146
161
end
147
- println (" " )
162
+ println (io, " " )
148
163
end
149
- println (" " )
164
+ println (io, " " )
150
165
151
166
# Print mean EOCs
152
167
mean_values = zeros (nvariables)
153
168
for v in 1 : nvariables
154
169
mean_values[v] = sum (eocs[kind][:, v]) ./ length (eocs[kind][:, v])
155
- @printf (" %-15s" , " mean" )
156
- @printf (" %-10.2f" , mean_values[v])
170
+ @printf (io, " %-15s" , " mean" )
171
+ @printf (io, " %-10.2f" , mean_values[v])
157
172
end
158
173
eoc_mean_values[kind] = mean_values
159
- println (" " )
160
- println (" -" ^ 100 )
174
+ println (io, " " )
175
+ println (io, " -" ^ 100 )
161
176
end
162
177
163
178
return eoc_mean_values, errorsmatrix
164
179
end
165
180
166
- function convergence_test (example:: AbstractString , iterations; kwargs... )
167
- convergence_test (Main, example:: AbstractString , iterations; kwargs... )
168
- end
169
-
170
181
function extract_initial_N (example, kwargs)
171
182
code = read (example, String)
172
183
expr = Meta. parse (" begin \n $code \n end" )
0 commit comments