10 public :: a2_prolong_copy_from
11 public :: a2_prolong_copy
12 public :: a2_prolong_linear_from
13 public :: a2_prolong_sparse
14 public :: a2_prolong_linear
18 public :: a2_prolong_limit
19 public :: a2_prolong_linear_cons
24 subroutine a2_prolong_copy_from(boxes, id, iv, iv_to, add)
25 type(
box2_t),
intent(inout) :: boxes(:)
26 integer,
intent(in) :: id
27 integer,
intent(in) :: iv
28 integer,
intent(in),
optional :: iv_to
29 logical,
intent(in),
optional :: add
32 do i_c = 1, a2_num_children
33 c_id = boxes(id)%children(i_c)
34 if (c_id == af_no_box) cycle
35 call a2_prolong_copy(boxes(id), boxes(c_id), iv, iv_to=iv_to, add=add)
37 end subroutine a2_prolong_copy_from
40 subroutine a2_prolong_copy(box_p, box_c, iv, iv_to, low, high, add)
42 type(
box2_t),
intent(inout) :: box_c
43 integer,
intent(in) :: iv
44 integer,
intent(in),
optional :: iv_to
45 integer,
intent(in),
optional :: low(2)
46 integer,
intent(in),
optional :: high(2)
47 logical,
intent(in),
optional :: add
49 integer :: nc, ix_offset(2), ivc
50 integer :: i, j, i_c1, j_c1, lo(2), hi(2)
53 add_to = .false.;
if (
present(add)) add_to = add
54 ivc = iv;
if (
present(iv_to)) ivc = iv_to
55 lo = 1;
if (
present(low)) lo = low
56 hi = nc;
if (
present(high)) hi = high
59 ix_offset = a2_get_child_offset(box_c)
63 j_c1 = ix_offset(2) + ishft(j+1, -1)
65 i_c1 = ix_offset(1) + ishft(i+1, -1)
66 box_c%cc(i, j, ivc) = box_c%cc(i, j, ivc) + &
67 box_p%cc(i_c1, j_c1, iv)
72 j_c1 = ix_offset(2) + ishft(j+1, -1)
74 i_c1 = ix_offset(1) + ishft(i+1, -1)
75 box_c%cc(i, j, ivc) = box_p%cc(i_c1, j_c1, iv)
79 end subroutine a2_prolong_copy
83 subroutine a2_prolong_linear_from(boxes, id, iv, iv_to, add)
84 type(
box2_t),
intent(inout) :: boxes(:)
85 integer,
intent(in) :: id
86 integer,
intent(in) :: iv
87 integer,
intent(in),
optional :: iv_to
88 logical,
intent(in),
optional :: add
91 do i_c = 1, a2_num_children
92 c_id = boxes(id)%children(i_c)
93 if (c_id == af_no_box) cycle
94 call a2_prolong_linear(boxes(id), boxes(c_id), iv, iv_to, add)
96 end subroutine a2_prolong_linear_from
101 subroutine a2_prolong_sparse(box_p, box_c, iv, iv_to, add)
103 type(
box2_t),
intent(inout) :: box_c
104 integer,
intent(in) :: iv
105 integer,
intent(in),
optional :: iv_to
106 logical,
intent(in),
optional :: add
107 integer :: hnc, nc, ix_offset(2), ivc
108 integer :: i, j, i_c, i_f, j_c, j_f
109 real(dp) :: f0, flx, fhx, fly, fhy
113 hnc = ishft(box_c%n_cell, -1)
114 ix_offset = a2_get_child_offset(box_c)
115 add_to = .false.;
if (
present(add)) add_to = add
116 ivc = iv;
if (
present(iv_to)) ivc = iv_to
118 if (.not. add_to)
then 119 box_c%cc(1:nc, 1:nc, ivc) = 0
123 j_c = j + ix_offset(2)
126 i_c = i + ix_offset(1)
129 f0 = 0.5_dp * box_p%cc(i_c, j_c, iv)
130 flx = 0.25_dp * box_p%cc(i_c-1, j_c, iv)
131 fhx = 0.25_dp * box_p%cc(i_c+1, j_c, iv)
132 fly = 0.25_dp * box_p%cc(i_c, j_c-1, iv)
133 fhy = 0.25_dp * box_p%cc(i_c, j_c+1, iv)
135 box_c%cc(i_f, j_f, ivc) = f0 + flx + fly &
136 + box_c%cc(i_f, j_f, ivc)
137 box_c%cc(i_f+1, j_f, ivc) = f0 + fhx + fly &
138 + box_c%cc(i_f+1, j_f, ivc)
139 box_c%cc(i_f, j_f+1, ivc) = f0 + flx + fhy &
140 + box_c%cc(i_f, j_f+1, ivc)
141 box_c%cc(i_f+1, j_f+1, ivc) = f0 + fhx + fhy &
142 + box_c%cc(i_f+1, j_f+1, ivc)
145 end subroutine a2_prolong_sparse
150 subroutine a2_prolong_limit(box_p, box_c, iv, iv_to, add)
152 type(
box2_t),
intent(inout) :: box_c
153 integer,
intent(in) :: iv
154 integer,
intent(in),
optional :: iv_to
155 logical,
intent(in),
optional :: add
156 integer :: hnc, nc, ix_offset(2), ivc
157 integer :: i, j, i_c, i_f, j_c, j_f
158 real(dp) :: f0, fxL, fxR, fyL, fyR, fx, fy
162 hnc = ishft(box_c%n_cell, -1)
163 ix_offset = a2_get_child_offset(box_c)
164 add_to = .false.;
if (
present(add)) add_to = add
165 ivc = iv;
if (
present(iv_to)) ivc = iv_to
167 if (.not. add_to)
then 168 box_c%cc(1:nc, 1:nc, ivc) = 0
172 j_c = j + ix_offset(2)
175 i_c = i + ix_offset(1)
178 f0 = box_p%cc(i_c, j_c, iv)
179 fxl = f0 - box_p%cc(i_c-1, j_c, iv)
180 fxr = box_p%cc(i_c+1, j_c, iv) - f0
181 fyl = f0 - box_p%cc(i_c, j_c-1, iv)
182 fyr = box_p%cc(i_c, j_c+1, iv) - f0
184 fx = 0.25_dp * limit_slope(fxl, fxr)
185 fy = 0.25_dp * limit_slope(fyl, fyr)
187 box_c%cc(i_f, j_f, ivc) = f0 - fx - fy &
188 + box_c%cc(i_f, j_f, ivc)
189 box_c%cc(i_f+1, j_f, ivc) = f0 + fx - fy &
190 + box_c%cc(i_f+1, j_f, ivc)
191 box_c%cc(i_f, j_f+1, ivc) = f0 - fx + fy &
192 + box_c%cc(i_f, j_f+1, ivc)
193 box_c%cc(i_f+1, j_f+1, ivc) = f0 + fx + fy &
194 + box_c%cc(i_f+1, j_f+1, ivc)
200 elemental function limit_slope(ll, rr)
result(slope)
201 real(dp),
intent(in) :: ll, rr
204 if (ll * rr < 0)
then 206 else if (ll * ll < rr * rr)
then 211 end function limit_slope
213 end subroutine a2_prolong_limit
217 subroutine a2_prolong_linear_cons(box_p, box_c, iv, iv_to, add)
219 type(
box2_t),
intent(inout) :: box_c
220 integer,
intent(in) :: iv
221 integer,
intent(in),
optional :: iv_to
222 logical,
intent(in),
optional :: add
223 integer :: hnc, nc, ix_offset(2), ivc
224 integer :: i, j, i_c, i_f, j_c, j_f
225 real(dp) :: f0, fx, fy
229 hnc = ishft(box_c%n_cell, -1)
230 ix_offset = a2_get_child_offset(box_c)
231 add_to = .false.;
if (
present(add)) add_to = add
232 ivc = iv;
if (
present(iv_to)) ivc = iv_to
234 if (.not. add_to)
then 235 box_c%cc(1:nc, 1:nc, ivc) = 0
239 j_c = j + ix_offset(2)
242 i_c = i + ix_offset(1)
245 f0 = box_p%cc(i_c, j_c, iv)
246 fx = 0.125_dp * (box_p%cc(i_c+1, j_c, iv) - &
247 box_p%cc(i_c-1, j_c, iv))
248 fy = 0.125_dp * (box_p%cc(i_c, j_c+1, iv) - &
249 box_p%cc(i_c, j_c-1, iv))
251 box_c%cc(i_f, j_f, ivc) = f0 - fx - fy &
252 + box_c%cc(i_f, j_f, ivc)
253 box_c%cc(i_f+1, j_f, ivc) = f0 + fx - fy &
254 + box_c%cc(i_f+1, j_f, ivc)
255 box_c%cc(i_f, j_f+1, ivc) = f0 - fx + fy &
256 + box_c%cc(i_f, j_f+1, ivc)
257 box_c%cc(i_f+1, j_f+1, ivc) = f0 + fx + fy &
258 + box_c%cc(i_f+1, j_f+1, ivc)
262 end subroutine a2_prolong_linear_cons
265 subroutine a2_prolong_linear(box_p, box_c, iv, iv_to, add)
267 type(
box2_t),
intent(inout) :: box_c
268 integer,
intent(in) :: iv
269 integer,
intent(in),
optional :: iv_to
270 logical,
intent(in),
optional :: add
271 integer :: hnc, nc, ix_offset(2), ivc
272 integer :: i, j, i_c, i_f, j_c, j_f
274 real(dp) :: f0, flx, fhx, fly, fhy
275 real(dp) :: fll, fhl, flh, fhh
276 real(dp),
parameter :: f1 = 1/16.0_dp, f3=3/16.0_dp, f9=9/16.0_dp
279 hnc = ishft(box_c%n_cell, -1)
280 ix_offset = a2_get_child_offset(box_c)
281 add_to = .false.;
if (
present(add)) add_to = add
282 ivc = iv;
if (
present(iv_to)) ivc = iv_to
284 if (.not. add_to)
then 285 box_c%cc(1:nc, 1:nc, ivc) = 0
289 j_c = j + ix_offset(2)
292 i_c = i + ix_offset(1)
295 f0 = f9 * box_p%cc(i_c, j_c, iv)
296 flx = f3 * box_p%cc(i_c-1, j_c, iv)
297 fhx = f3 * box_p%cc(i_c+1, j_c, iv)
298 fly = f3 * box_p%cc(i_c, j_c-1, iv)
299 fhy = f3 * box_p%cc(i_c, j_c+1, iv)
300 fll = f1 * box_p%cc(i_c-1, j_c-1, iv)
301 fhl = f1 * box_p%cc(i_c+1, j_c-1, iv)
302 flh = f1 * box_p%cc(i_c-1, j_c+1, iv)
303 fhh = f1 * box_p%cc(i_c+1, j_c+1, iv)
305 box_c%cc(i_f, j_f, ivc) = f0 + flx + fly + fll &
306 + box_c%cc(i_f, j_f, ivc)
307 box_c%cc(i_f+1, j_f, ivc) = f0 + fhx + fly + fhl &
308 + box_c%cc(i_f+1, j_f, ivc)
309 box_c%cc(i_f, j_f+1, ivc) = f0 + flx + fhy + flh &
310 + box_c%cc(i_f, j_f+1, ivc)
311 box_c%cc(i_f+1, j_f+1, ivc) = f0 + fhx + fhy + fhh &
312 + box_c%cc(i_f+1, j_f+1, ivc)
315 end subroutine a2_prolong_linear
This module contains the basic types and constants that are used in the 2-dimensional version of Afiv...
This module contains the routines related to prolongation: going from coarse to fine variables...
The basic building block of afivo: a box with cell-centered and face centered data, and information about its position, neighbors, children etc.