1 #include "cpp_macros.h"
14 integer,
intent(in) :: n_values, n_vars
15 real(dp),
intent(inout) :: u(n_values, n_vars)
20 integer,
intent(in) :: nf
21 integer,
intent(in) :: n_var
22 integer,
intent(in) :: flux_dim
23 real(dp),
intent(in) :: u(nf, n_var)
24 real(dp),
intent(out) :: w(nf)
27 subroutine subr_flux(nf, n_var, flux_dim, u, flux, box, line_ix, s_deriv)
29 integer,
intent(in) :: nf
30 integer,
intent(in) :: n_var
31 integer,
intent(in) :: flux_dim
32 real(dp),
intent(in) :: u(nf, n_var)
33 real(dp),
intent(out) :: flux(nf, n_var)
34 type(
box_t),
intent(in) :: box
35 integer,
intent(in) :: line_ix(NDIM-1)
36 integer,
intent(in) :: s_deriv
40 n_other_dt, other_dt, box, line_ix, s_deriv)
42 integer,
intent(in) :: nf
43 integer,
intent(in) :: n_var
44 integer,
intent(in) :: flux_dim
45 real(dp),
intent(in) :: u(nf, n_var)
46 real(dp),
intent(out) :: flux(nf, n_var)
48 real(dp),
intent(out) :: cfl_sum(nf-1)
49 integer,
intent(in) :: n_other_dt
50 real(dp),
intent(inout) :: other_dt(n_other_dt)
51 type(
box_t),
intent(in) :: box
52 integer,
intent(in) :: line_ix(NDIM-1)
53 integer,
intent(in) :: s_deriv
58 integer,
intent(in) :: nf
59 integer,
intent(in) :: n_var
60 integer,
intent(in) :: flux_dim
61 real(dp),
intent(inout) :: flux(nf, n_var)
62 type(
box_t),
intent(in) :: box
63 integer,
intent(in) :: line_ix(NDIM-1)
64 integer,
intent(in) :: s_deriv
67 subroutine subr_flux_dir(box, line_ix, s_deriv, n_var, flux_dim, direction_positive)
69 type(
box_t),
intent(in) :: box
70 integer,
intent(in) :: line_ix(NDIM-1)
71 integer,
intent(in) :: s_deriv
72 integer,
intent(in) :: n_var
73 integer,
intent(in) :: flux_dim
75 logical,
intent(out) :: direction_positive(box%n_cell+1, n_var)
80 integer,
intent(in) :: n_cc
81 integer,
intent(in) :: n_var
82 real(dp),
intent(inout) :: cc_line(n_cc, n_var)
83 integer,
intent(in) :: flux_dim
84 type(
box_t),
intent(in) :: box
85 integer,
intent(in) :: line_ix(NDIM-1)
86 integer,
intent(in) :: s_deriv
89 subroutine subr_source(box, dt, n_vars, i_cc, s_deriv, s_out, n_dt, dt_lim, mask)
91 type(
box_t),
intent(inout) :: box
92 real(dp),
intent(in) :: dt
93 integer,
intent(in) :: n_vars
94 integer,
intent(in) :: i_cc(n_vars)
95 integer,
intent(in) :: s_deriv
96 integer,
intent(in) :: s_out
98 integer,
intent(in) :: n_dt
100 real(dp),
intent(inout) :: dt_lim(n_dt)
102 logical,
intent(in) :: mask(DTIMES(box%n_cell))
107 type(
box_t),
intent(in) :: box
108 logical,
intent(out) :: mask(DTIMES(box%n_cell))
112 public :: flux_diff_1d, flux_diff_2d, flux_diff_3d
113 public :: flux_koren_1d, flux_koren_2d, flux_koren_3d
114 public :: flux_upwind_1d, flux_upwind_2d, flux_upwind_3d
115 public :: flux_kurganovtadmor_1d, reconstruct_lr_1d
116 public :: flux_generic_box, flux_generic_tree
117 public :: flux_upwind_box, flux_upwind_tree
118 public :: flux_update_densities
119 public :: flux_dummy_conversion
120 public :: flux_dummy_source
121 public :: flux_dummy_modify
122 public :: flux_dummy_line_modify
123 public :: flux_get_line_cc, flux_get_line_1cc
124 public :: flux_get_line_fc, flux_get_line_1fc
129 subroutine flux_diff_1d(cc, dc, inv_dr, nc, ngc)
130 integer,
intent(in) :: nc
131 integer,
intent(in) :: ngc
132 real(dp),
intent(in) :: cc(1-ngc:nc+ngc)
134 real(dp),
intent(inout) :: dc(1:nc+1)
135 real(dp),
intent(in) :: inv_dr
139 dc(i) = -dc(i) * (cc(i) - cc(i-1)) * inv_dr
141 end subroutine flux_diff_1d
144 subroutine flux_diff_2d(cc, dc, inv_dr, nc, ngc)
145 integer,
intent(in) :: nc
146 integer,
intent(in) :: ngc
148 real(dp),
intent(in) :: cc(1-ngc:nc+ngc, 1-ngc:nc+ngc)
150 real(dp),
intent(inout) :: dc(1:nc+1, 1:nc+1, 2)
151 real(dp),
intent(in) :: inv_dr(2)
152 real(dp) :: cc_1d(1-ngc:nc+ngc), dc_1d(1:nc+1)
157 call flux_diff_1d(cc(:, n), dc(:, n, 1), inv_dr(1), nc, ngc)
162 call flux_diff_1d(cc_1d, dc_1d, inv_dr(2), nc, ngc)
165 end subroutine flux_diff_2d
168 subroutine flux_diff_3d(cc, dc, inv_dr, nc, ngc)
170 integer,
intent(in) :: nc
172 integer,
intent(in) :: ngc
174 real(dp),
intent(in) :: cc(1-ngc:nc+ngc, 1-ngc:nc+ngc, 1-ngc:nc+ngc)
176 real(dp),
intent(inout) :: dc(1:nc+1, 1:nc+1, 1:nc+1, 3)
178 real(dp),
intent(in) :: inv_dr(3)
179 real(dp) :: cc_1d(1-ngc:nc+ngc), dc_1d(1:nc+1)
185 call flux_diff_1d(cc(:, n, m), dc(:, n, m, 1), &
190 dc_1d = dc(n, :, m, 2)
191 call flux_diff_1d(cc_1d, dc_1d, inv_dr(2), nc, ngc)
192 dc(n, :, m, 2) = dc_1d
196 dc_1d = dc(n, m, :, 3)
197 call flux_diff_1d(cc_1d, dc_1d, inv_dr(3), nc, ngc)
198 dc(n, m, :, 3) = dc_1d
201 end subroutine flux_diff_3d
204 subroutine flux_koren_1d(cc, v, nc, ngc)
205 integer,
intent(in) :: nc
206 integer,
intent(in) :: ngc
207 real(dp),
intent(in) :: cc(1-ngc:nc+ngc)
209 real(dp),
intent(inout) :: v(1:nc+1)
210 real(dp) :: gradp, gradc, gradn
214 gradc = cc(n) - cc(n-1)
215 if (v(n) < 0.0_dp)
then
216 gradn = cc(n+1) - cc(n)
217 v(n) = v(n) * (cc(n) - 0.5_dp * af_limiter_koren(gradc, gradn))
219 gradp = cc(n-1) - cc(n-2)
220 v(n) = v(n) * (cc(n-1) + 0.5_dp * af_limiter_koren(gradc, gradp))
224 end subroutine flux_koren_1d
227 subroutine flux_koren_2d(cc, v, nc, ngc)
228 integer,
intent(in) :: nc
229 integer,
intent(in) :: ngc
231 real(dp),
intent(in) :: cc(1-ngc:nc+ngc, 1-ngc:nc+ngc)
233 real(dp),
intent(inout) :: v(1:nc+1, 1:nc+1, 2)
234 real(dp) :: cc_1d(1-ngc:nc+ngc), v_1d(1:nc+1)
239 call flux_koren_1d(cc(:, n), v(:, n, 1), nc, ngc)
244 call flux_koren_1d(cc_1d, v_1d, nc, ngc)
247 end subroutine flux_koren_2d
252 subroutine reconstruct_lr_1d(nc, ngc, n_vars, cc, u_l, u_r, limiter)
253 integer,
intent(in) :: nc
254 integer,
intent(in) :: ngc
255 integer,
intent(in) :: n_vars
256 real(dp),
intent(in) :: cc(1-ngc:nc+ngc, n_vars)
258 real(dp),
intent(inout) :: u_l(1:nc+1, n_vars)
260 real(dp),
intent(inout) :: u_r(1:nc+1, n_vars)
261 integer,
intent(in) :: limiter
262 real(dp) :: slopes(0:nc+1, n_vars)
264 associate(a=>cc(1:nc+2, :) - cc(0:nc+1, :), &
265 b=>cc(0:nc+1, :) - cc(-1:nc, :))
267 slopes = af_limiter_apply(a, b, limiter)
270 u_l(1:nc+1, :) = cc(0:nc, :) + 0.5_dp * slopes(0:nc, :)
272 if (af_limiter_symmetric(limiter))
then
273 u_r(1:nc+1, :) = cc(1:nc+1, :) - 0.5_dp * slopes(1:nc+1, :)
275 slopes = af_limiter_apply(b, a, limiter)
276 u_r(1:nc+1, :) = cc(1:nc+1, :) - 0.5_dp * slopes(1:nc+1, :)
279 end subroutine reconstruct_lr_1d
282 subroutine reconstruct_upwind_1d(nc, ngc, n_vars, cc, u_f, limiter, direction_positive)
283 integer,
intent(in) :: nc
284 integer,
intent(in) :: ngc
285 integer,
intent(in) :: n_vars
286 real(dp),
intent(in) :: cc(1-ngc:nc+ngc, n_vars)
288 real(dp),
intent(inout) :: u_f(1:nc+1, n_vars)
289 integer,
intent(in) :: limiter
291 logical,
intent(in) :: direction_positive(nc+1, n_vars)
293 associate(a=>cc(1:nc+2, :) - cc(0:nc+1, :), &
294 b=>cc(0:nc+1, :) - cc(-1:nc, :))
295 where (direction_positive)
296 u_f = cc(0:nc, :) + 0.5_dp * &
297 af_limiter_apply(a(1:nc+1, :), b(1:nc+1, :), limiter)
299 u_f = cc(1:nc+1, :) - 0.5_dp * &
300 af_limiter_apply(b(2:nc+2, :), a(2:nc+2, :), limiter)
303 end subroutine reconstruct_upwind_1d
306 subroutine flux_kurganovtadmor_1d(n_values, n_vars, flux_l, flux_r, &
307 u_l, u_r, wmax, flux)
308 integer,
intent(in) :: n_values
309 integer,
intent(in) :: n_vars
310 real(dp),
intent(in) :: flux_l(n_values, n_vars)
311 real(dp),
intent(in) :: flux_r(n_values, n_vars)
312 real(dp),
intent(in) :: u_l(n_values, n_vars)
313 real(dp),
intent(in) :: u_r(n_values, n_vars)
314 real(dp),
intent(in) :: wmax(n_values)
315 real(dp),
intent(inout) :: flux(n_values, n_vars)
317 flux = 0.5_dp * (flux_l + flux_r - spread(wmax, 2, n_vars) * (u_r - u_l))
318 end subroutine flux_kurganovtadmor_1d
320 subroutine flux_update_densities(tree, dt, n_vars, i_cc, n_vars_flux, i_cc_flux, i_flux, &
321 s_deriv, n_prev, s_prev, w_prev, s_out, add_source_box, n_dt, dt_lim, get_mask)
322 type(af_t),
intent(inout) :: tree
323 real(dp),
intent(in) :: dt
324 integer,
intent(in) :: n_vars
325 integer,
intent(in) :: i_cc(n_vars)
326 integer,
intent(in) :: n_vars_flux
327 integer,
intent(in) :: i_cc_flux(n_vars_flux)
328 integer,
intent(in) :: i_flux(n_vars_flux)
329 integer,
intent(in) :: s_deriv
330 integer,
intent(in) :: n_prev
331 integer,
intent(in) :: s_prev(n_prev)
332 real(dp),
intent(in) :: w_prev(n_prev)
333 integer,
intent(in) :: s_out
337 integer,
intent(in) :: n_dt
339 real(dp),
intent(out) :: dt_lim(n_dt)
342 integer :: lvl, n, id, ijk, nc, i_var, iv
343 logical :: mask(dtimes(tree%n_cell))
344 real(dp) :: dt_dr(ndim), my_dt(n_dt)
345 real(dp) :: rfac(2, tree%n_cell)
356 do lvl = 1, tree%highest_lvl
358 do n = 1,
size(tree%lvls(lvl)%leaves)
359 id = tree%lvls(lvl)%leaves(n)
360 dt_dr = dt/tree%boxes(id)%dr
362 associate(cc => tree%boxes(id)%cc, fc => tree%boxes(id)%fc)
363 if (
present(get_mask))
then
364 call get_mask(tree%boxes(id), mask)
372 tree%boxes(id)%cc(ijk, iv+s_out) = sum(w_prev * &
373 tree%boxes(id)%cc(ijk, iv+s_prev))
377 call add_source_box(tree%boxes(id), dt, n_vars, i_cc, s_deriv, &
378 s_out, n_dt, my_dt, mask)
379 dt_lim = min(dt_lim, my_dt)
384 cc(i, i_cc_flux+s_out) = cc(i, i_cc_flux+s_out) + &
386 (fc(i, 1, i_flux) - fc(i+1, 1, i_flux))
390 if (tree%coord_t == af_cyl)
then
391 call af_cyl_flux_factors(tree%boxes(id), rfac)
394 cc(i, j, i_cc_flux+s_out) = cc(i, j, i_cc_flux+s_out) + &
396 rfac(1, i) * fc(i, j, 1, i_flux) - &
397 rfac(2, i) * fc(i+1, j, 1, i_flux)) &
399 (fc(i, j, 2, i_flux) - fc(i, j+1, 2, i_flux))
405 cc(i, j, i_cc_flux+s_out) = cc(i, j, i_cc_flux+s_out) + &
407 (fc(i, j, 1, i_flux) - fc(i+1, j, 1, i_flux)) &
409 (fc(i, j, 2, i_flux) - fc(i, j+1, 2, i_flux))
416 cc(i, j, k, i_cc_flux+s_out) = cc(i, j, k, i_cc_flux+s_out) + &
418 (fc(i, j, k, 1, i_flux) - fc(i+1, j, k, 1, i_flux)) + &
420 (fc(i, j, k, 2, i_flux) - fc(i, j+1, k, 2, i_flux)) + &
422 (fc(i, j, k, 3, i_flux) - fc(i, j, k+1, 3, i_flux))
431 end subroutine flux_update_densities
434 subroutine flux_generic_tree(tree, n_vars, i_cc, s_deriv, i_flux, dt_lim, &
435 max_wavespeed, flux_from_primitives, flux_modify, line_modify, &
436 to_primitive, to_conservative, limiter)
439 type(af_t),
intent(inout) :: tree
440 integer,
intent(in) :: n_vars
441 integer,
intent(in) :: i_cc(n_vars)
442 integer,
intent(in) :: s_deriv
443 integer,
intent(in) :: i_flux(n_vars)
445 real(dp),
intent(out) :: dt_lim
449 procedure(
subr_flux) :: flux_from_primitives
459 integer,
intent(in) :: limiter
465 call af_restrict_ref_boundary(tree, i_cc+s_deriv)
471 do lvl = 1, tree%highest_lvl
473 do i = 1,
size(tree%lvls(lvl)%leaves)
474 call flux_generic_box(tree, tree%lvls(lvl)%leaves(i), tree%n_cell, &
475 n_vars, i_cc, s_deriv, i_flux, my_dt, max_wavespeed, &
476 flux_from_primitives, flux_modify, line_modify, &
477 to_primitive, to_conservative, limiter)
478 dt_lim = min(dt_lim, my_dt)
485 call af_consistent_fluxes(tree, i_flux)
487 end subroutine flux_generic_tree
490 subroutine flux_generic_box(tree, id, nc, n_vars, i_cc, s_deriv, i_flux, dt_lim, &
491 max_wavespeed, flux_from_primitives, flux_modify, line_modify, &
492 to_primitive, to_conservative, limiter)
495 type(
af_t),
intent(inout) :: tree
496 integer,
intent(in) :: id
497 integer,
intent(in) :: nc
498 integer,
intent(in) :: n_vars
499 integer,
intent(in) :: i_cc(n_vars)
500 integer,
intent(in) :: s_deriv
501 integer,
intent(in) :: i_flux(n_vars)
503 real(dp),
intent(out) :: dt_lim
507 procedure(
subr_flux) :: flux_from_primitives
517 integer,
intent(in) :: limiter
520 real(dp) :: cc(dtimes(-1:nc+2), n_vars)
521 real(dp) :: cc_line(-1:nc+2, n_vars)
522 real(dp) :: flux(nc+1, n_vars)
523 real(dp) :: u_l(nc+1, n_vars), u_r(nc+1, n_vars)
524 real(dp) :: w_l(nc+1), w_r(nc+1)
525 real(dp) :: flux_l(nc+1, n_vars), flux_r(nc+1, n_vars)
526 real(dp) :: cfl_sum(dtimes(nc)), cfl_sum_line(nc), inv_dr(ndim)
527 integer :: flux_dim, line_ix(ndim-1)
535 inv_dr = 1/tree%boxes(id)%dr
538 call af_gc2_box(tree, id, i_cc+s_deriv, cc)
549 do flux_dim = 1, ndim
557 select case (flux_dim)
563 cc_line = cc(:, i, :)
565 cc_line = cc(i, :, :)
568 cc_line = cc(:, i, j, :)
570 cc_line = cc(i, :, j, :)
572 cc_line = cc(i, j, :, :)
583 call line_modify(nc+4, n_vars, cc_line, flux_dim, &
584 tree%boxes(id), line_ix, s_deriv)
588 call to_primitive(nc+4, n_vars, cc_line)
592 call reconstruct_lr_1d(nc, 2, n_vars, cc_line, u_l, u_r, limiter)
595 call max_wavespeed(nc+1, n_vars, flux_dim, u_l, w_l)
596 call max_wavespeed(nc+1, n_vars, flux_dim, u_r, w_r)
599 call flux_from_primitives(nc+1, n_vars, flux_dim, u_l, flux_l, &
600 tree%boxes(id), line_ix, s_deriv)
601 call flux_from_primitives(nc+1, n_vars, flux_dim, u_r, flux_r, &
602 tree%boxes(id), line_ix, s_deriv)
605 call to_conservative(nc+1, n_vars, u_l)
606 call to_conservative(nc+1, n_vars, u_r)
612 cfl_sum_line = max(w_l(1:nc), w_l(2:nc+1)) * inv_dr(ndim)
615 call flux_kurganovtadmor_1d(nc+1, n_vars, flux_l, flux_r, &
619 call flux_modify(nc+1, n_vars, flux_dim, flux, &
620 tree%boxes(id), line_ix, s_deriv)
623 select case (flux_dim)
626 tree%boxes(id)%fc(:, flux_dim, i_flux) = flux
627 cfl_sum = cfl_sum + cfl_sum_line
630 tree%boxes(id)%fc(:, i, flux_dim, i_flux) = flux
631 cfl_sum(:, i) = cfl_sum(:, i) + cfl_sum_line
633 tree%boxes(id)%fc(i, :, flux_dim, i_flux) = flux
634 cfl_sum(i, :) = cfl_sum(i, :) + cfl_sum_line
637 tree%boxes(id)%fc(:, i, j, flux_dim, i_flux) = flux
638 cfl_sum(:, i, j) = cfl_sum(:, i, j) + cfl_sum_line
640 tree%boxes(id)%fc(i, :, j, flux_dim, i_flux) = flux
641 cfl_sum(i, :, j) = cfl_sum(i, :, j) + cfl_sum_line
643 tree%boxes(id)%fc(i, j, :, flux_dim, i_flux) = flux
644 cfl_sum(i, j, :) = cfl_sum(i, j, :) + cfl_sum_line
656 dt_lim = 1/max(maxval(cfl_sum), 1e-100_dp)
658 end subroutine flux_generic_box
661 subroutine flux_upwind_tree(tree, n_vars, i_cc, s_deriv, i_flux, n_dt, dt_lim, &
662 flux_upwind, flux_direction, line_modify, limiter)
665 type(af_t),
intent(inout) :: tree
666 integer,
intent(in) :: n_vars
667 integer,
intent(in) :: i_cc(n_vars)
668 integer,
intent(in) :: s_deriv
669 integer,
intent(in) :: i_flux(n_vars)
671 integer,
intent(in) :: n_dt
673 real(dp),
intent(out) :: dt_lim(n_dt)
681 integer,
intent(in) :: limiter
683 real(dp) :: my_dt(n_dt)
686 call af_restrict_ref_boundary(tree, i_cc+s_deriv)
692 do lvl = 1, tree%highest_lvl
694 do i = 1,
size(tree%lvls(lvl)%leaves)
695 call flux_upwind_box(tree, tree%lvls(lvl)%leaves(i), tree%n_cell, &
696 n_vars, i_cc, s_deriv, i_flux, n_dt, my_dt, flux_upwind, &
697 flux_direction, line_modify, limiter)
698 dt_lim = min(dt_lim, my_dt)
705 call af_consistent_fluxes(tree, i_flux)
707 end subroutine flux_upwind_tree
710 subroutine flux_upwind_box(tree, id, nc, n_vars, i_cc, s_deriv, i_flux, &
711 n_dt, dt_lim, flux_upwind, flux_direction, line_modify, limiter)
714 type(
af_t),
intent(inout) :: tree
715 integer,
intent(in) :: id
716 integer,
intent(in) :: nc
717 integer,
intent(in) :: n_vars
718 integer,
intent(in) :: i_cc(n_vars)
719 integer,
intent(in) :: s_deriv
720 integer,
intent(in) :: i_flux(n_vars)
722 integer,
intent(in) :: n_dt
723 real(dp),
intent(inout) :: dt_lim(n_dt)
731 integer,
intent(in) :: limiter
733 real(dp) :: cc(dtimes(-1:nc+2), n_vars)
734 real(dp) :: cc_line(-1:nc+2, n_vars)
735 real(dp) :: flux(nc+1, n_vars)
736 real(dp) :: u_l(nc+1, n_vars)
737 real(dp) :: cfl_sum(dtimes(nc)), cfl_sum_line(nc)
738 real(dp) :: other_dt(n_dt-1)
739 logical :: direction_positive(nc+1, n_vars)
740 integer :: flux_dim, line_ix(ndim-1)
749 call af_gc2_box(tree, id, i_cc+s_deriv, cc)
755 dt_lim(2:) = 1e100_dp
758 associate(fc => tree%boxes(id)%fc)
759 do flux_dim = 1, ndim
767 select case (flux_dim)
773 cc_line = cc(:, i, :)
775 cc_line = cc(i, :, :)
778 cc_line = cc(:, i, j, :)
780 cc_line = cc(i, :, j, :)
782 cc_line = cc(i, j, :, :)
791 call flux_direction(tree%boxes(id), line_ix, s_deriv, &
792 n_vars, flux_dim, direction_positive)
795 call line_modify(nc+4, n_vars, cc_line, flux_dim, &
796 tree%boxes(id), line_ix, s_deriv)
799 call reconstruct_upwind_1d(nc, 2, n_vars, cc_line, u_l, &
800 limiter, direction_positive)
802 call flux_upwind(nc+1, n_vars, flux_dim, u_l, flux, cfl_sum_line, &
803 n_dt-1, other_dt, tree%boxes(id), line_ix, s_deriv)
804 dt_lim(2:) = min(dt_lim(2:), other_dt)
807 select case (flux_dim)
810 fc(:, flux_dim, i_flux) = flux
811 cfl_sum = cfl_sum + cfl_sum_line
814 fc(:, i, flux_dim, i_flux) = flux
815 cfl_sum(:, i) = cfl_sum(:, i) + cfl_sum_line
817 fc(i, :, flux_dim, i_flux) = flux
818 cfl_sum(i, :) = cfl_sum(i, :) + cfl_sum_line
821 fc(:, i, j, flux_dim, i_flux) = flux
822 cfl_sum(:, i, j) = cfl_sum(:, i, j) + cfl_sum_line
824 fc(i, :, j, flux_dim, i_flux) = flux
825 cfl_sum(i, :, j) = cfl_sum(i, :, j) + cfl_sum_line
827 fc(i, j, :, flux_dim, i_flux) = flux
828 cfl_sum(i, j, :) = cfl_sum(i, j, :) + cfl_sum_line
841 dt_lim(1) = 1/maxval(cfl_sum)
843 end subroutine flux_upwind_box
848 subroutine flux_get_line_cc(box, ivs, flux_dim, line_ix, cc_line)
849 type(box_t),
intent(in) :: box
850 integer,
intent(in) :: ivs(:)
851 integer,
intent(in) :: flux_dim
852 integer,
intent(in) :: line_ix(ndim-1)
853 real(dp),
intent(inout) :: cc_line(box%n_cell+2, size(ivs))
855 select case (flux_dim)
858 cc_line = box%cc(:, ivs)
861 cc_line = box%cc(:, line_ix(1), ivs)
863 cc_line = box%cc(line_ix(1), :, ivs)
866 cc_line = box%cc(:, line_ix(1), line_ix(2), ivs)
868 cc_line = box%cc(line_ix(1), :, line_ix(2), ivs)
870 cc_line = box%cc(line_ix(1), line_ix(2), :, ivs)
873 end subroutine flux_get_line_cc
878 subroutine flux_get_line_1cc(box, iv, flux_dim, line_ix, cc_line)
879 type(box_t),
intent(in) :: box
880 integer,
intent(in) :: iv
881 integer,
intent(in) :: flux_dim
882 integer,
intent(in) :: line_ix(ndim-1)
883 real(dp),
intent(inout) :: cc_line(box%n_cell+2)
885 select case (flux_dim)
888 cc_line = box%cc(:, iv)
891 cc_line = box%cc(:, line_ix(1), iv)
893 cc_line = box%cc(line_ix(1), :, iv)
896 cc_line = box%cc(:, line_ix(1), line_ix(2), iv)
898 cc_line = box%cc(line_ix(1), :, line_ix(2), iv)
900 cc_line = box%cc(line_ix(1), line_ix(2), :, iv)
903 end subroutine flux_get_line_1cc
907 subroutine flux_get_line_fc(box, ivs, flux_dim, line_ix, fc_line)
908 type(box_t),
intent(in) :: box
909 integer,
intent(in) :: ivs(:)
910 integer,
intent(in) :: flux_dim
911 integer,
intent(in) :: line_ix(ndim-1)
912 real(dp),
intent(inout) :: fc_line(box%n_cell+1, size(ivs))
914 select case (flux_dim)
917 fc_line = box%fc(:, flux_dim, ivs)
920 fc_line = box%fc(:, line_ix(1), flux_dim, ivs)
922 fc_line = box%fc(line_ix(1), :, flux_dim, ivs)
925 fc_line = box%fc(:, line_ix(1), line_ix(2), flux_dim, ivs)
927 fc_line = box%fc(line_ix(1), :, line_ix(2), flux_dim, ivs)
929 fc_line = box%fc(line_ix(1), line_ix(2), :, flux_dim, ivs)
932 end subroutine flux_get_line_fc
936 subroutine flux_get_line_1fc(box, iv, flux_dim, line_ix, fc_line)
937 type(box_t),
intent(in) :: box
938 integer,
intent(in) :: iv
939 integer,
intent(in) :: flux_dim
940 integer,
intent(in) :: line_ix(ndim-1)
941 real(dp),
intent(inout) :: fc_line(box%n_cell+1)
943 select case (flux_dim)
946 fc_line = box%fc(:, flux_dim, iv)
949 fc_line = box%fc(:, line_ix(1), flux_dim, iv)
951 fc_line = box%fc(line_ix(1), :, flux_dim, iv)
954 fc_line = box%fc(:, line_ix(1), line_ix(2), flux_dim, iv)
956 fc_line = box%fc(line_ix(1), :, line_ix(2), flux_dim, iv)
958 fc_line = box%fc(line_ix(1), line_ix(2), :, flux_dim, iv)
961 end subroutine flux_get_line_1fc
964 subroutine flux_koren_3d(cc, v, nc, ngc)
966 integer,
intent(in) :: nc
968 integer,
intent(in) :: ngc
970 real(dp),
intent(in) :: cc(1-ngc:nc+ngc, 1-ngc:nc+ngc, 1-ngc:nc+ngc)
972 real(dp),
intent(inout) :: v(1:nc+1, 1:nc+1, 1:nc+1, 3)
973 real(dp) :: cc_1d(1-ngc:nc+ngc), v_1d(1:nc+1)
979 call flux_koren_1d(cc(:, n, m), v(:, n, m, 1), &
985 call flux_koren_1d(cc_1d, v_1d, nc, ngc)
991 call flux_koren_1d(cc_1d, v_1d, nc, ngc)
995 end subroutine flux_koren_3d
998 subroutine flux_upwind_1d(cc, v, nc, ngc)
999 integer,
intent(in) :: nc
1000 integer,
intent(in) :: ngc
1001 real(dp),
intent(in) :: cc(1-ngc:nc+ngc)
1003 real(dp),
intent(inout) :: v(1:nc+1)
1007 if (v(n) < 0.0_dp)
then
1010 v(n) = v(n) * cc(n-1)
1014 end subroutine flux_upwind_1d
1017 subroutine flux_upwind_2d(cc, v, nc, ngc)
1018 integer,
intent(in) :: nc
1019 integer,
intent(in) :: ngc
1021 real(dp),
intent(in) :: cc(1-ngc:nc+ngc, 1-ngc:nc+ngc)
1023 real(dp),
intent(inout) :: v(1:nc+1, 1:nc+1, 2)
1024 real(dp) :: cc_1d(1-ngc:nc+ngc), v_1d(1:nc+1)
1029 call flux_upwind_1d(cc(:, n), v(:, n, 1), nc, ngc)
1034 call flux_upwind_1d(cc_1d, v_1d, nc, ngc)
1037 end subroutine flux_upwind_2d
1040 subroutine flux_upwind_3d(cc, v, nc, ngc)
1042 integer,
intent(in) :: nc
1044 integer,
intent(in) :: ngc
1046 real(dp),
intent(in) :: cc(1-ngc:nc+ngc, 1-ngc:nc+ngc, 1-ngc:nc+ngc)
1048 real(dp),
intent(inout) :: v(1:nc+1, 1:nc+1, 1:nc+1, 3)
1049 real(dp) :: cc_1d(1-ngc:nc+ngc), v_1d(1:nc+1)
1055 call flux_upwind_1d(cc(:, n, m), v(:, n, m, 1), &
1060 v_1d = v(n, :, m, 2)
1061 call flux_upwind_1d(cc_1d, v_1d, nc, ngc)
1062 v(n, :, m, 2) = v_1d
1066 v_1d = v(n, m, :, 3)
1067 call flux_upwind_1d(cc_1d, v_1d, nc, ngc)
1068 v(n, m, :, 3) = v_1d
1071 end subroutine flux_upwind_3d
1074 subroutine flux_dummy_conversion(n_values, n_vars, u)
1075 integer,
intent(in) :: n_values, n_vars
1076 real(dp),
intent(inout) :: u(n_values, n_vars)
1077 end subroutine flux_dummy_conversion
1079 subroutine flux_dummy_source(box, dt, n_vars, i_cc, s_deriv, s_out, n_dt, dt_lim, mask)
1080 type(box_t),
intent(inout) :: box
1081 real(dp),
intent(in) :: dt
1082 integer,
intent(in) :: n_vars
1083 integer,
intent(in) :: i_cc(n_vars)
1084 integer,
intent(in) :: s_deriv
1085 integer,
intent(in) :: s_out
1086 integer,
intent(in) :: n_dt
1087 real(dp),
intent(inout) :: dt_lim(n_dt)
1088 logical,
intent(in) :: mask(dtimes(box%n_cell))
1089 end subroutine flux_dummy_source
1091 subroutine flux_dummy_modify(nf, n_var, flux_dim, flux, box, line_ix, s_deriv)
1092 integer,
intent(in) :: nf
1093 integer,
intent(in) :: n_var
1094 integer,
intent(in) :: flux_dim
1095 real(dp),
intent(inout) :: flux(nf, n_var)
1096 type(box_t),
intent(in) :: box
1097 integer,
intent(in) :: line_ix(ndim-1)
1098 integer,
intent(in) :: s_deriv
1099 end subroutine flux_dummy_modify
1101 subroutine flux_dummy_line_modify(n_cc, n_var, cc_line, flux_dim, box, &
1103 integer,
intent(in) :: n_cc
1104 integer,
intent(in) :: n_var
1105 real(dp),
intent(inout) :: cc_line(n_cc, n_var)
1106 integer,
intent(in) :: flux_dim
1107 type(box_t),
intent(in) :: box
1108 integer,
intent(in) :: line_ix(ndim-1)
1109 integer,
intent(in) :: s_deriv
1110 end subroutine flux_dummy_line_modify
This module contains the core routines of Afivo, namely those that deal with initializing and changin...
Module containing a couple flux schemes for solving hyperbolic problems explicitly,...
This module contains routines related to the filling of ghost cells. Note that corner ghost cells are...
Module containing slope limiters.
This module contains routines for restriction: going from fine to coarse variables.
This module contains the basic types and constants that are used in the NDIM-dimensional version of A...
Type which stores all the boxes and levels, as well as some information about the number of boxes,...
The basic building block of afivo: a box with cell-centered and face centered data,...