10 integer,
parameter :: dp = kind(0.0d0)
12 public :: flux_diff_1d, flux_diff_2d, flux_diff_3d
13 public :: flux_koren_1d, flux_koren_2d, flux_koren_3d
18 subroutine flux_diff_1d(cc, dc, inv_dr, nc, ngc)
19 integer,
intent(in) :: nc
20 integer,
intent(in) :: ngc
21 real(dp),
intent(in) :: cc(1-ngc:nc+ngc)
23 real(dp),
intent(inout) :: dc(1:nc+1)
24 real(dp),
intent(in) :: inv_dr
28 dc(i) = -dc(i) * (cc(i) - cc(i-1)) * inv_dr
30 end subroutine flux_diff_1d
33 subroutine flux_diff_2d(cc, dc, inv_dr, nc, ngc)
34 integer,
intent(in) :: nc
35 integer,
intent(in) :: ngc
37 real(dp),
intent(in) :: cc(1-ngc:nc+ngc, 1-ngc:nc+ngc)
39 real(dp),
intent(inout) :: dc(1:nc+1, 1:nc+1, 2)
40 real(dp),
intent(in) :: inv_dr
41 real(dp) :: cc_1d(1-ngc:nc+ngc), dc_1d(1:nc+1)
46 call flux_diff_1d(cc(:, n), dc(:, n, 1), inv_dr, nc, ngc)
51 call flux_diff_1d(cc_1d, dc_1d, inv_dr, nc, ngc)
54 end subroutine flux_diff_2d
57 subroutine flux_diff_3d(cc, dc, inv_dr, nc, ngc)
59 integer,
intent(in) :: nc
61 integer,
intent(in) :: ngc
63 real(dp),
intent(in) :: cc(1-ngc:nc+ngc, 1-ngc:nc+ngc, 1-ngc:nc+ngc)
65 real(dp),
intent(inout) :: dc(1:nc+1, 1:nc+1, 1:nc+1, 3)
67 real(dp),
intent(in) :: inv_dr
68 real(dp) :: cc_1d(1-ngc:nc+ngc), dc_1d(1:nc+1)
74 call flux_diff_1d(cc(:, n, m), dc(:, n, m, 1), &
79 dc_1d = dc(n, :, m, 2)
80 call flux_diff_1d(cc_1d, dc_1d, inv_dr, nc, ngc)
81 dc(n, :, m, 2) = dc_1d
85 dc_1d = dc(n, m, :, 3)
86 call flux_diff_1d(cc_1d, dc_1d, inv_dr, nc, ngc)
87 dc(n, m, :, 3) = dc_1d
90 end subroutine flux_diff_3d
93 subroutine flux_koren_1d(cc, v, nc, ngc)
94 integer,
intent(in) :: nc
95 integer,
intent(in) :: ngc
96 real(dp),
intent(in) :: cc(1-ngc:nc+ngc)
98 real(dp),
intent(inout) :: v(1:nc+1)
99 real(dp) :: gradp, gradc, gradn
103 gradc = cc(n) - cc(n-1)
104 if (v(n) < 0.0_dp)
then 105 gradn = cc(n+1) - cc(n)
106 v(n) = v(n) * (cc(n) - koren_mlim(gradc, gradn))
108 gradp = cc(n-1) - cc(n-2)
109 v(n) = v(n) * (cc(n-1) + koren_mlim(gradc, gradp))
113 end subroutine flux_koren_1d
116 subroutine flux_koren_2d(cc, v, nc, ngc)
117 integer,
intent(in) :: nc
118 integer,
intent(in) :: ngc
120 real(dp),
intent(in) :: cc(1-ngc:nc+ngc, 1-ngc:nc+ngc)
122 real(dp),
intent(inout) :: v(1:nc+1, 1:nc+1, 2)
123 real(dp) :: cc_1d(1-ngc:nc+ngc), v_1d(1:nc+1)
128 call flux_koren_1d(cc(:, n), v(:, n, 1), nc, ngc)
133 call flux_koren_1d(cc_1d, v_1d, nc, ngc)
136 end subroutine flux_koren_2d
139 subroutine flux_koren_3d(cc, v, nc, ngc)
141 integer,
intent(in) :: nc
143 integer,
intent(in) :: ngc
145 real(dp),
intent(in) :: cc(1-ngc:nc+ngc, 1-ngc:nc+ngc, 1-ngc:nc+ngc)
147 real(dp),
intent(inout) :: v(1:nc+1, 1:nc+1, 1:nc+1, 3)
148 real(dp) :: cc_1d(1-ngc:nc+ngc), v_1d(1:nc+1)
154 call flux_koren_1d(cc(:, n, m), v(:, n, m, 1), &
160 call flux_koren_1d(cc_1d, v_1d, nc, ngc)
166 call flux_koren_1d(cc_1d, v_1d, nc, ngc)
170 end subroutine flux_koren_3d
176 elemental function koren_mlim(a, b)
result(bphi)
177 real(dp),
intent(in) :: a
178 real(dp),
intent(in) :: b
179 real(dp),
parameter :: sixth = 1/6.0_dp
180 real(dp) :: bphi, aa, ab
189 else if (aa <= 0.25_dp * ab)
then 192 else if (aa <= 2.5_dp * ab)
then 194 bphi = sixth * (b + 2*a)
199 end function koren_mlim
Module containing a couple simple flux schemes for scalar advection/diffusion problems.