1 #include "../src/cpp_macros.h"
7 integer,
parameter :: n_vars = 2+ndim
8 integer,
parameter :: ncells = 8
9 integer,
parameter :: coord_type = af_xyz
10 real(dp),
parameter :: euler_gamma = 1.4_dp
11 integer,
parameter :: time_integrator = af_heuns_method
14 integer,
parameter :: i_rho = 1
15 integer,
parameter :: i_mom(NDIM) = [2, 3]
16 integer,
parameter :: i_e = 4
18 integer :: variables(n_vars)
19 integer :: cc_rho, cc_mom(2), cc_e
20 integer :: fluxes(n_vars)
21 real(dp) :: l_max(NDIM), l_min(NDIM)
23 logical :: periodicBC(NDIM)
24 real(dp) :: u0(4, n_vars)
26 real(dp) :: dt, dt_lim, time, end_time, dt_output
27 real(dp) :: dt_amr, time_prev_refine
28 character(len=100) :: fname
29 character(len=20) :: carg
30 integer :: n, output_cnt
36 type(ref_info_t) :: refine_info
37 integer :: refine_steps
39 character(len=10) :: var_names(n_vars)
41 var_names(i_rho) =
"rho"
42 var_names(i_mom) = [
"mom_x",
"mom_y"]
45 print *,
"Running Euler 2D with KT scheme"
46 print *,
"Number of threads", af_get_max_threads()
49 call af_add_cc_variable(tree, var_names(n), ix=variables(n), n_copies=2)
50 call af_add_fc_variable(tree,
"flux", ix=fluxes(n))
51 call af_set_cc_methods(tree, variables(n), af_bc_neumann_zero)
54 cc_rho = variables(i_rho)
55 cc_mom = variables(i_mom)
59 if (command_argument_count() > 0)
then
60 call get_command_argument(1, carg)
62 print *,
"Initial condition type: ", trim(carg)
66 u0(:, i_e) = [1.0_dp, 0.4_dp, 0.0439_dp, 0.15_dp]
67 u0(:, i_rho) = [1.0_dp, 0.5197_dp, 0.1072_dp, 0.2579_dp]
68 u0(:, i_mom(1)) = [0.0_dp, -0.7259_dp, -0.7259_dp, 0.0_dp]
69 u0(:, i_mom(2)) = [0.0_dp, 0.0_dp, -1.4045_dp, -1.4045_dp]
71 u0(:, i_e) = [1.0_dp, 1.0_dp, 1.0_dp, 1.0_dp]
72 u0(:, i_rho) = [1.0_dp, 2.0_dp, 1.0_dp, 3.0_dp]
73 u0(:, i_mom(1)) = [0.75_dp, 0.75_dp, -0.75_dp, -0.75_dp]
74 u0(:, i_mom(2)) = [-0.5_dp, 0.5_dp, 0.5_dp, -0.5_dp]
77 u0(:, i_rho) = [0.125_dp, 1.0_dp, 1.0_dp, 0.125_dp]
78 u0(:, i_e) = [0.1_dp, 1.0_dp, 1.0_dp, 0.1_dp]
79 u0(:, i_mom(1)) = [0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp]
80 u0(:, i_mom(2)) = [0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp]
82 error stop
"Unknown initial condition"
85 call to_conservative(4, n_vars, u0)
88 if (command_argument_count() > 1)
then
89 call get_command_argument(2, carg)
92 print *,
"Use AMR: ", use_amr
95 if (command_argument_count() > 2)
then
96 call get_command_argument(3, carg)
97 read(carg, *) benchmark
99 print *,
"Benchmark: ", benchmark
104 periodicbc(:) = .false.
106 call af_init(tree, ncells, l_max-l_min, grid, &
107 periodic=periodicbc, r_min=l_min, &
112 refine_steps = refine_steps + 1
115 call af_loop_box(tree, set_init_conds)
116 call af_gc_tree(tree, variables)
117 call af_adjust_refinement(tree, ref_rout, refine_info, 1)
118 if (refine_info%n_add == 0)
exit
120 call af_restrict_tree(tree, variables)
121 call af_gc_tree(tree, variables)
123 call af_loop_box(tree, set_init_conds)
124 call af_gc_tree(tree, variables)
128 time_prev_refine = time
132 dt_output = end_time / 20
133 dt_amr = end_time / 100
136 if (.not. benchmark .and. output_cnt * dt_output <= time)
then
137 write(fname,
"(A,I0)")
"output/euler_" // dimname //
"_", output_cnt
138 call af_write_silo(tree, trim(fname), output_cnt, time, &
139 add_vars = write_primitives, add_names=[
"xVel",
"yVel",
"pres"])
140 output_cnt = output_cnt + 1
143 call af_advance(tree, dt, dt_lim, time, variables, &
144 time_integrator, forward_euler)
148 if (use_amr .and. time > time_prev_refine + dt_amr)
then
149 call af_gc_tree(tree, variables)
150 call af_adjust_refinement(tree, ref_rout, refine_info, 1)
151 time_prev_refine = time
154 call af_tree_maxabs_cc(tree, variables(i_rho), rho_max)
155 if (rho_max > 10.0_dp) &
156 error stop
"solution diverging!"
158 if (time > end_time)
exit
161 call af_destroy(tree)
166 subroutine forward_euler(tree, dt, dt_stiff, dt_lim, time, s_deriv, n_prev, &
167 s_prev, w_prev, s_out, i_step, n_steps)
168 type(af_t),
intent(inout) :: tree
169 real(dp),
intent(in) :: dt
170 real(dp),
intent(in) :: dt_stiff
171 real(dp),
intent(inout) :: dt_lim
172 real(dp),
intent(in) :: time
173 integer,
intent(in) :: s_deriv
174 integer,
intent(in) :: n_prev
175 integer,
intent(in) :: s_prev(n_prev)
176 real(dp),
intent(in) :: w_prev(n_prev)
177 integer,
intent(in) :: s_out
178 integer,
intent(in) :: i_step, n_steps
179 real(dp) :: dummy_dt(0)
181 call flux_generic_tree(tree, n_vars, variables, s_deriv, fluxes, dt_lim, &
182 max_wavespeed, get_fluxes, flux_dummy_modify, flux_dummy_line_modify, &
183 to_primitive, to_conservative, af_limiter_vanleer_t)
184 call flux_update_densities(tree, dt, n_vars, variables, n_vars, variables, fluxes, &
185 s_deriv, n_prev, s_prev, w_prev, s_out, flux_dummy_source, 0, dummy_dt)
186 end subroutine forward_euler
189 subroutine set_init_conds(box)
190 type(box_t),
intent(inout) :: box
197 rr = af_r_cc(box, [ijk])
198 if (rr(1) > 0.5_dp .and. rr(2) > 0.5_dp)
then
199 box%cc(ijk, variables) = u0(1, :)
200 elseif (rr(1) <= 0.5_dp .and. rr(2) >= 0.5_dp)
then
201 box%cc(ijk, variables) = u0(2, :)
202 elseif (rr(1) <= 0.5_dp .and. rr(2) <= 0.5_dp)
then
203 box%cc(ijk, variables) = u0(3, :)
205 box%cc(ijk, variables) = u0(4, :)
208 end subroutine set_init_conds
210 subroutine to_primitive(n_values, n_vars, u)
211 integer,
intent(in) :: n_values, n_vars
212 real(dp),
intent(inout) :: u(n_values, n_vars)
214 u(:, i_mom(1)) = u(:, i_mom(1))/u(:, i_rho)
215 u(:, i_mom(2)) = u(:, i_mom(2))/u(:, i_rho)
216 u(:, i_e) = (euler_gamma-1.0_dp) * (u(:, i_e) - &
217 0.5_dp*u(:, i_rho)* sum(u(:, i_mom(:))**2, dim=2))
218 end subroutine to_primitive
220 subroutine to_conservative(n_values, n_vars, u)
221 integer,
intent(in) :: n_values, n_vars
222 real(dp),
intent(inout) :: u(n_values, n_vars)
223 real(dp) :: kin_en(n_values)
228 kin_en = 0.5_dp * u(:, i_rho) * sum(u(:, i_mom(:))**2, dim=2)
231 inv_fac = 1/(euler_gamma - 1.0_dp)
232 u(:, i_e) = u(:, i_e) * inv_fac + kin_en
236 u(:, i_mom(i)) = u(:, i_rho) * u(:, i_mom(i))
238 end subroutine to_conservative
240 subroutine max_wavespeed(n_values, n_var, flux_dim, u, w)
241 integer,
intent(in) :: n_values
242 integer,
intent(in) :: n_var
243 integer,
intent(in) :: flux_dim
244 real(dp),
intent(in) :: u(n_values, n_var)
245 real(dp),
intent(out) :: w(n_values)
246 real(dp) :: sound_speeds(n_values)
248 sound_speeds = sqrt(euler_gamma * u(:, i_e) / u(:, i_rho))
249 w = sound_speeds + abs(u(:, i_mom(flux_dim)))
250 end subroutine max_wavespeed
252 subroutine get_fluxes(n_values, n_var, flux_dim, u, flux, box, line_ix, s_deriv)
253 integer,
intent(in) :: n_values
254 integer,
intent(in) :: n_var
255 integer,
intent(in) :: flux_dim
256 real(dp),
intent(in) :: u(n_values, n_var)
257 real(dp),
intent(out) :: flux(n_values, n_var)
258 type(box_t),
intent(in) :: box
259 integer,
intent(in) :: line_ix(NDIM-1)
260 integer,
intent(in) :: s_deriv
261 real(dp) :: E(n_values), inv_fac
268 flux(:, i_rho) = u(:, i_rho) * u(:, i_mom(flux_dim))
272 flux(:, i_mom(i)) = u(:, i_rho) * &
273 u(:, i_mom(i)) * u(:, i_mom(flux_dim))
277 flux(:, i_mom(flux_dim)) = flux(:, i_mom(flux_dim)) + u(:, i_e)
280 inv_fac = 1/(euler_gamma-1.0_dp)
281 e = u(:, i_e) * inv_fac + 0.5_dp * u(:, i_rho) * &
282 sum(u(:, i_mom(:))**2, dim=2)
285 flux(:, i_e) = u(:, i_mom(flux_dim)) * (e + u(:, i_e))
287 end subroutine get_fluxes
289 subroutine ref_rout( box, cell_flags )
290 type(box_t),
intent(in) :: box
291 integer,
intent(out) :: cell_flags(DTIMES(box%n_cell))
292 real(dp) :: diff, tol
298 diff = box%dr(1)**2*abs(box%cc(i+1,j,i_rho)+box%cc(i-1,j,i_rho) &
299 -2*box%cc(i,j,i_rho)) + &
300 box%dr(2)**2*abs(box%cc(i,j+1,i_rho)+box%cc(i,j-1,i_rho) &
301 -2*box%cc(i,j,i_rho))
302 if (diff > tol .and. box%lvl < 3)
then
303 cell_flags(ijk) = af_do_ref
304 else if (diff < 0.1_dp*tol)
then
305 cell_flags(ijk) = af_rm_ref
307 cell_flags(ijk) = af_keep_ref
310 end subroutine ref_rout
312 subroutine write_primitives(box, new_vars, n_var)
313 type(box_t),
intent(in) :: box
314 integer,
intent(in) :: n_var
315 real(dp) :: new_vars(DTIMES(0:box%n_cell+1),n_var)
318 new_vars(dtimes(:), 1) = box%cc(dtimes(:), cc_mom(1))/box%cc(dtimes(:), cc_rho)
320 new_vars(dtimes(:), 2) = box%cc(dtimes(:), cc_mom(2))/box%cc(dtimes(:), cc_rho)
322 new_vars(dtimes(:), 3) = (euler_gamma-1.0_dp)*(box%cc(dtimes(:), cc_e) - &
323 sum(box%cc(dtimes(:), cc_mom(:))**2, dim=ndim+1) &
324 /(2.0_dp*box%cc(dtimes(:), cc_rho)))
325 end subroutine write_primitives
Module which contains all Afivo modules, so that a user does not have to include them separately.