13 public :: af_bc_dirichlet_zero
14 public :: af_bc_neumann_zero
15 public :: af_bc_set_continuous
16 public :: af_gc_interp
17 public :: af_gc_prolong_copy
18 public :: af_gc_interp_lim
25 subroutine af_gc_tree(tree, ivs, corners, leaves_only)
26 type(
af_t),
intent(inout) :: tree
27 integer,
intent(in) :: ivs(:)
28 logical,
intent(in),
optional :: corners
29 logical,
intent(in),
optional :: leaves_only
33 if (.not. tree%ready) error stop
"af_gc_tree: tree not ready"
35 if (
present(leaves_only)) all_ids = .not. leaves_only
38 do lvl = 1, tree%highest_lvl
39 call af_gc_lvl(tree, lvl, ivs, corners)
42 do lvl = 1, tree%highest_lvl
43 call af_gc_lvl(tree, lvl, ivs, corners)
46 end subroutine af_gc_tree
49 subroutine af_gc_lvl(tree, lvl, ivs, corners)
50 type(
af_t),
intent(inout) :: tree
51 integer,
intent(in) :: lvl
52 integer,
intent(in) :: ivs(:)
53 logical,
intent(in),
optional :: corners
57 do i = 1,
size(tree%lvls(lvl)%ids)
58 call af_gc_box(tree, tree%lvls(lvl)%ids(i), ivs, corners)
61 end subroutine af_gc_lvl
64 subroutine af_gc_box(tree, id, ivs, corners)
65 type(
af_t),
intent(inout) :: tree
66 integer,
intent(in) :: id
67 integer,
intent(in) :: ivs(:)
68 logical,
intent(in),
optional :: corners
71 integer :: nb, nb_id, bc_type, ix
72 integer :: lo(ndim), hi(ndim), dnb(ndim)
73 real(dp) :: bc_val(tree%n_cell**(ndim-1))
76 if (
present(corners)) do_corners = corners
80 if (.not. tree%has_cc_method(iv))
then
81 print *,
"For variable ", trim(tree%cc_names(iv))
82 error stop
"af_gc_box: no methods stored"
86 do nb = 1, af_num_neighbors
87 nb_id = tree%boxes(id)%neighbors(nb)
89 if (nb_id > af_no_box)
then
91 call af_get_index_bc_outside(nb, tree%boxes(id)%n_cell, 1, lo, hi)
92 dnb = af_neighb_offset([nb])
93 call copy_from_nb(tree%boxes(id), tree%boxes(nb_id), dnb, lo, hi, ivs)
94 else if (nb_id == af_no_box)
then
98 call tree%cc_methods(iv)%rb(tree%boxes, id, nb, iv, &
99 tree%mg_current_operator_mask)
104 if (
associated(tree%cc_methods(iv)%bc_custom))
then
105 call tree%cc_methods(iv)%bc_custom(tree%boxes(id), &
108 ix = tree%boxes(id)%nb_to_bc_index(nb)
109 call tree%cc_methods(iv)%bc(tree%boxes(id), nb, iv, &
110 tree%boxes(id)%bc_coords(:, :, ix), bc_val, bc_type)
111 call bc_to_gc(tree%boxes(id), nb, iv, bc_val, bc_type)
112 tree%boxes(id)%bc_val(:, iv, ix) = bc_val
113 tree%boxes(id)%bc_type(iv, ix) = bc_type
119 if (do_corners)
call af_gc_box_corner(tree%boxes, id, ivs)
120 end subroutine af_gc_box
125 subroutine af_gc_box_corner(boxes, id, ivs)
126 type(
box_t),
intent(inout) :: boxes(:)
127 integer,
intent(in) :: id
128 integer,
intent(in) :: ivs(:)
129 integer :: n, nb_id, dnb(NDIM), lo(NDIM)
131 integer :: hi(NDIM), dim
136 do n = 1, af_num_edges
140 nb_id = boxes(id)%neighbor_mat(af_edge_dir(1, n), &
141 af_edge_dir(2, n), af_edge_dir(3, n))
143 lo = af_edge_min_ix(:, n) * (boxes(id)%n_cell + 1)
146 if (nb_id > af_no_box)
then
148 hi(dim) = boxes(id)%n_cell
149 dnb = af_neighb_offset(af_nb_adj_edge(:, n))
150 call copy_from_nb(boxes(id), boxes(nb_id), dnb, lo, hi, ivs)
152 call af_edge_gc_extrap(boxes(id), lo, dim, ivs)
157 do n = 1, af_num_children
159 dnb = 2 * af_child_dix(:, n) - 1
161 nb_id = boxes(id)%neighbor_mat(dindex(dnb))
162 lo = af_child_dix(:, n) * (boxes(id)%n_cell + 1)
164 if (nb_id > af_no_box)
then
165 call copy_from_nb(boxes(id), boxes(nb_id), dnb, lo, lo, ivs)
167 call af_corner_gc_extrap(boxes(id), lo, ivs)
170 end subroutine af_gc_box_corner
173 subroutine bc_to_gc(box, nb, iv, bc_val, bc_type)
174 type(
box_t),
intent(inout) :: box
175 integer,
intent(in) :: iv
176 integer,
intent(in) :: nb
177 real(dp),
intent(in) :: bc_val(box%n_cell**(NDIM-1))
178 integer,
intent(in) :: bc_type
179 real(dp) :: c0, c1, c2
192 select case (bc_type)
193 case (af_bc_dirichlet)
198 c0 = box%dr(af_neighb_dim(nb)) * af_neighb_high_pm(nb)
201 case (af_bc_continuous)
205 case (af_bc_dirichlet_copy)
210 stop
"fill_bc: unknown boundary condition"
215 case (af_neighb_lowx)
218 c1 * box%cc(1, iv) + &
220 case (af_neighb_highx)
223 c1 * box%cc(nc, iv) + &
224 c2 * box%cc(nc-1, iv)
226 case (af_neighb_lowx)
227 box%cc(0, 1:nc, iv) = &
229 c1 * box%cc(1, 1:nc, iv) + &
230 c2 * box%cc(2, 1:nc, iv)
231 case (af_neighb_highx)
232 box%cc(nc+1, 1:nc, iv) = &
234 c1 * box%cc(nc, 1:nc, iv) + &
235 c2 * box%cc(nc-1, 1:nc, iv)
236 case (af_neighb_lowy)
237 box%cc(1:nc, 0, iv) = &
239 c1 * box%cc(1:nc, 1, iv) + &
240 c2 * box%cc(1:nc, 2, iv)
241 case (af_neighb_highy)
242 box%cc(1:nc, nc+1, iv) = &
244 c1 * box%cc(1:nc, nc, iv) + &
245 c2 * box%cc(1:nc, nc-1, iv)
247 case (af_neighb_lowx)
248 box%cc(0, 1:nc, 1:nc, iv) = &
249 c0 * reshape(bc_val, [nc, nc]) + &
250 c1 * box%cc(1, 1:nc, 1:nc, iv) + &
251 c2 * box%cc(2, 1:nc, 1:nc, iv)
252 case (af_neighb_highx)
253 box%cc(nc+1, 1:nc, 1:nc, iv) = &
254 c0 * reshape(bc_val, [nc, nc]) + &
255 c1 * box%cc(nc, 1:nc, 1:nc, iv) + &
256 c2 * box%cc(nc-1, 1:nc, 1:nc, iv)
257 case (af_neighb_lowy)
258 box%cc(1:nc, 0, 1:nc, iv) = &
259 c0 * reshape(bc_val, [nc, nc]) + &
260 c1 * box%cc(1:nc, 1, 1:nc, iv) + &
261 c2 * box%cc(1:nc, 2, 1:nc, iv)
262 case (af_neighb_highy)
263 box%cc(1:nc, nc+1, 1:nc, iv) = &
264 c0 * reshape(bc_val, [nc, nc]) + &
265 c1 * box%cc(1:nc, nc, 1:nc, iv) + &
266 c2 * box%cc(1:nc, nc-1, 1:nc, iv)
267 case (af_neighb_lowz)
268 box%cc(1:nc, 1:nc, 0, iv) = &
269 c0 * reshape(bc_val, [nc, nc]) + &
270 c1 * box%cc(1:nc, 1:nc, 1, iv) + &
271 c2 * box%cc(1:nc, 1:nc, 2, iv)
272 case (af_neighb_highz)
273 box%cc(1:nc, 1:nc, nc+1, iv) = &
274 c0 * reshape(bc_val, [nc, nc]) + &
275 c1 * box%cc(1:nc, 1:nc, nc, iv) + &
276 c2 * box%cc(1:nc, 1:nc, nc-1, iv)
279 end subroutine bc_to_gc
282 subroutine bc_to_gc2(nc, cc, nb, bc_val, bc_type, dr)
283 integer,
intent(in) :: nc
284 real(dp),
intent(inout) :: cc(DTIMES(-1:nc+2))
285 integer,
intent(in) :: nb
286 real(dp),
intent(in) :: bc_val(nc**(NDIM-1))
287 integer,
intent(in) :: bc_type
288 real(dp),
intent(in) :: dr(NDIM)
289 real(dp) :: c0, c1, c2
300 select case (bc_type)
301 case (af_bc_dirichlet)
306 c0 = dr(af_neighb_dim(nb)) * af_neighb_high_pm(nb)
309 case (af_bc_dirichlet_copy)
314 stop
"fill_bc: unknown boundary condition"
319 case (af_neighb_lowx)
320 cc(0) = c0 * bc_val(1) + c1 * cc(1)
321 cc(-1) = c2 * bc_val(1) + c1 * cc(2)
322 case (af_neighb_highx)
323 cc(nc+1) = c0 * bc_val(1) + c1 * cc(nc)
324 cc(nc+2) = c2 * bc_val(1) + c1 * cc(nc-1)
326 case (af_neighb_lowx)
327 cc(0, 1:nc) = c0 * bc_val + c1 * cc(1, 1:nc)
328 cc(-1, 1:nc) = c2 * bc_val + c1 * cc(2, 1:nc)
329 case (af_neighb_highx)
330 cc(nc+1, 1:nc) = c0 * bc_val + c1 * cc(nc, 1:nc)
331 cc(nc+2, 1:nc) = c2 * bc_val + c1 * cc(nc-1, 1:nc)
332 case (af_neighb_lowy)
333 cc(1:nc, 0) = c0 * bc_val + c1 * cc(1:nc, 1)
334 cc(1:nc, -1) = c2 * bc_val + c1 * cc(1:nc, 2)
335 case (af_neighb_highy)
336 cc(1:nc, nc+1) = c0 * bc_val + c1 * cc(1:nc, nc)
337 cc(1:nc, nc+2) = c2 * bc_val + c1 * cc(1:nc, nc-1)
339 case (af_neighb_lowx)
340 cc(0, 1:nc, 1:nc) = c0 * reshape(bc_val, [nc, nc]) + &
341 c1 * cc(1, 1:nc, 1:nc)
342 cc(-1, 1:nc, 1:nc) = c2 * reshape(bc_val, [nc, nc]) + &
343 c1 * cc(2, 1:nc, 1:nc)
344 case (af_neighb_highx)
345 cc(nc+1, 1:nc, 1:nc) = c0 * reshape(bc_val, [nc, nc]) + &
346 c1 * cc(nc, 1:nc, 1:nc)
347 cc(nc+2, 1:nc, 1:nc) = c2 * reshape(bc_val, [nc, nc]) + &
348 c1 * cc(nc-1, 1:nc, 1:nc)
349 case (af_neighb_lowy)
350 cc(1:nc, 0, 1:nc) = c0 * reshape(bc_val, [nc, nc]) + &
351 c1 * cc(1:nc, 1, 1:nc)
352 cc(1:nc, -1, 1:nc) = c2 * reshape(bc_val, [nc, nc]) + &
353 c1 * cc(1:nc, 2, 1:nc)
354 case (af_neighb_highy)
355 cc(1:nc, nc+1, 1:nc) = c0 * reshape(bc_val, [nc, nc]) + &
356 c1 * cc(1:nc, nc, 1:nc)
357 cc(1:nc, nc+2, 1:nc) = c0 * reshape(bc_val, [nc, nc]) + &
358 c1 * cc(1:nc, nc-1, 1:nc)
359 case (af_neighb_lowz)
360 cc(1:nc, 1:nc, 0) = c0 * reshape(bc_val, [nc, nc]) + &
361 c1 * cc(1:nc, 1:nc, 1)
362 cc(1:nc, 1:nc, -1) = c2 * reshape(bc_val, [nc, nc]) + &
363 c1 * cc(1:nc, 1:nc, 2)
364 case (af_neighb_highz)
365 cc(1:nc, 1:nc, nc+1) = c0 * reshape(bc_val, [nc, nc]) + &
366 c1 * cc(1:nc, 1:nc, nc)
367 cc(1:nc, 1:nc, nc+2) = c2 * reshape(bc_val, [nc, nc]) + &
368 c1 * cc(1:nc, 1:nc, nc-1)
371 end subroutine bc_to_gc2
374 subroutine af_gc_prolong_copy(boxes, id, nb, iv, op_mask)
376 type(
box_t),
intent(inout) :: boxes(:)
377 integer,
intent(in) :: id
378 integer,
intent(in) :: iv
379 integer,
intent(in) :: nb
380 integer,
intent(in) :: op_mask
381 integer :: p_id, lo(ndim), hi(ndim)
383 p_id = boxes(id)%parent
384 call af_get_index_bc_outside(nb, boxes(id)%n_cell, 1, lo, hi)
385 call af_prolong_copy(boxes(p_id), boxes(id), iv, low=lo, high=hi)
386 end subroutine af_gc_prolong_copy
390 subroutine af_gc_interp(boxes, id, nb, iv, op_mask)
391 type(
box_t),
intent(inout) :: boxes(:)
392 integer,
intent(in) :: id
393 integer,
intent(in) :: nb
394 integer,
intent(in) :: iv
395 integer,
intent(in) :: op_mask
396 integer :: nc, ix, ix_c, ix_f
398 integer :: p_id, ix_offset(ndim)
399 real(dp),
parameter :: third = 1/3.0_dp
401 real(dp),
parameter :: sixth = 1/6.0_dp
402 integer :: i_c1, i_c2, j_c1, j_c2, i, j
405 integer :: k_c1, k_c2, k
408 nc = boxes(id)%n_cell
409 p_id = boxes(id)%parent
410 p_nb_id = boxes(p_id)%neighbors(nb)
411 ix_offset = af_get_child_offset(boxes(id), nb)
413 if (af_neighb_low(nb))
then
423 select case (af_neighb_dim(nb))
426 boxes(id)%cc(ix, iv) = &
427 2 * third * boxes(p_nb_id)%cc(ix_c, iv) + &
428 third * boxes(id)%cc(ix_f, iv)
432 j_c1 = ix_offset(2) + ishft(j+1, -1)
433 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
434 boxes(id)%cc(ix, j, iv) = &
435 0.5_dp * boxes(p_nb_id)%cc(ix_c, j_c1, iv) + &
436 sixth * boxes(p_nb_id)%cc(ix_c, j_c2, iv) + &
437 third * boxes(id)%cc(ix_f, j, iv)
441 i_c1 = ix_offset(1) + ishft(i+1, -1)
442 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
443 boxes(id)%cc(i, ix, iv) = &
444 0.5_dp * boxes(p_nb_id)%cc(i_c1, ix_c, iv) + &
445 sixth * boxes(p_nb_id)%cc(i_c2, ix_c, iv) + &
446 third * boxes(id)%cc(i, ix_f, iv)
451 k_c1 = ix_offset(3) + ishft(k+1, -1)
452 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
454 j_c1 = ix_offset(2) + ishft(j+1, -1)
455 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
456 boxes(id)%cc(ix, j, k, iv) = &
457 third * boxes(p_nb_id)%cc(ix_c, j_c1, k_c1, iv) + &
458 sixth * boxes(p_nb_id)%cc(ix_c, j_c2, k_c1, iv) + &
459 sixth * boxes(p_nb_id)%cc(ix_c, j_c1, k_c2, iv) + &
460 third * boxes(id)%cc(ix_f, j, k, iv)
465 k_c1 = ix_offset(3) + ishft(k+1, -1)
466 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
468 i_c1 = ix_offset(1) + ishft(i+1, -1)
469 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
470 boxes(id)%cc(i, ix, k, iv) = &
471 third * boxes(p_nb_id)%cc(i_c1, ix_c, k_c1, iv) + &
472 sixth * boxes(p_nb_id)%cc(i_c2, ix_c, k_c1, iv) + &
473 sixth * boxes(p_nb_id)%cc(i_c1, ix_c, k_c2, iv) + &
474 third * boxes(id)%cc(i, ix_f, k, iv)
479 j_c1 = ix_offset(2) + ishft(j+1, -1)
480 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
482 i_c1 = ix_offset(1) + ishft(i+1, -1)
483 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
484 boxes(id)%cc(i, j, ix, iv) = &
485 third * boxes(p_nb_id)%cc(i_c1, j_c1, ix_c, iv) + &
486 sixth * boxes(p_nb_id)%cc(i_c1, j_c2, ix_c, iv) + &
487 sixth * boxes(p_nb_id)%cc(i_c2, j_c1, ix_c, iv) + &
488 third * boxes(id)%cc(i, j, ix_f, iv)
494 end subroutine af_gc_interp
499 subroutine af_gc_interp_lim(boxes, id, nb, iv, op_mask)
500 type(
box_t),
intent(inout) :: boxes(:)
501 integer,
intent(in) :: id
502 integer,
intent(in) :: nb
503 integer,
intent(in) :: iv
504 integer,
intent(in) :: op_mask
505 integer :: nc, ix, ix_c, ix_f
506 integer :: p_id, ix_offset(ndim), p_nb_id
508 real(dp),
parameter :: third = 1/3.0_dp
510 integer :: ijk, ijk_(c1), ijk_(c2)
511 real(dp),
parameter :: sixth = 1/6.0_dp
514 nc = boxes(id)%n_cell
515 p_id = boxes(id)%parent
516 p_nb_id = boxes(p_id)%neighbors(nb)
517 ix_offset = af_get_child_offset(boxes(id), nb)
519 if (af_neighb_low(nb))
then
529 select case (af_neighb_dim(nb))
532 c(1) = boxes(p_nb_id)%cc(ix_c, iv)
533 boxes(id)%cc(ix, iv) = (2 * c(1) + boxes(id)%cc(ix_f, iv)) * third
534 if (boxes(id)%cc(ix, iv) > 2 * c(1)) boxes(id)%cc(ix, iv) = 2 * c(1)
538 j_c1 = ix_offset(2) + ishft(j+1, -1)
539 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
540 c(1) = boxes(p_nb_id)%cc(ix_c, j_c1, iv)
541 c(2) = boxes(p_nb_id)%cc(ix_c, j_c2, iv)
542 boxes(id)%cc(ix, j, iv) = 0.5_dp * c(1) + sixth * c(2) + &
543 third * boxes(id)%cc(ix_f, j, iv)
544 if (boxes(id)%cc(ix, j, iv) > 2 * c(1)) boxes(id)%cc(ix, j, iv) = 2 * c(1)
548 i_c1 = ix_offset(1) + ishft(i+1, -1)
549 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
550 c(1) = boxes(p_nb_id)%cc(i_c1, ix_c, iv)
551 c(2) = boxes(p_nb_id)%cc(i_c2, ix_c, iv)
552 boxes(id)%cc(i, ix, iv) = 0.5_dp * c(1) + sixth * c(2) + &
553 third * boxes(id)%cc(i, ix_f, iv)
554 if (boxes(id)%cc(i, ix, iv) > 2 * c(1)) boxes(id)%cc(i, ix, iv) = 2 * c(1)
559 k_c1 = ix_offset(3) + ishft(k+1, -1)
560 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
562 j_c1 = ix_offset(2) + ishft(j+1, -1)
563 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
564 c(1) = boxes(p_nb_id)%cc(ix_c, j_c1, k_c1, iv)
565 c(2) = boxes(p_nb_id)%cc(ix_c, j_c2, k_c1, iv)
566 c(3) = boxes(p_nb_id)%cc(ix_c, j_c1, k_c2, iv)
567 boxes(id)%cc(ix, j, k, iv) = third * c(1) + sixth * c(2) + &
568 sixth * c(3) + third * boxes(id)%cc(ix_f, j, k, iv)
569 if (boxes(id)%cc(ix, j, k, iv) > 2 * c(1)) &
570 boxes(id)%cc(ix, j, k, iv) = 2 * c(1)
575 k_c1 = ix_offset(3) + ishft(k+1, -1)
576 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
578 i_c1 = ix_offset(1) + ishft(i+1, -1)
579 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
580 c(1) = boxes(p_nb_id)%cc(i_c1, ix_c, k_c1, iv)
581 c(2) = boxes(p_nb_id)%cc(i_c2, ix_c, k_c1, iv)
582 c(3) = boxes(p_nb_id)%cc(i_c1, ix_c, k_c2, iv)
583 boxes(id)%cc(i, ix, k, iv) = third * c(1) + sixth * c(2) + &
584 sixth * c(3) + third * boxes(id)%cc(i, ix_f, k, iv)
585 if (boxes(id)%cc(i, ix, k, iv) > 2 * c(1)) &
586 boxes(id)%cc(i, ix, k, iv) = 2 * c(1)
591 j_c1 = ix_offset(2) + ishft(j+1, -1)
592 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
594 i_c1 = ix_offset(1) + ishft(i+1, -1)
595 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
596 c(1) = boxes(p_nb_id)%cc(i_c1, j_c1, ix_c, iv)
597 c(2) = boxes(p_nb_id)%cc(i_c1, j_c2, ix_c, iv)
598 c(3) = boxes(p_nb_id)%cc(i_c2, j_c1, ix_c, iv)
599 boxes(id)%cc(i, j, ix, iv) = third * c(1) + sixth * c(2) + &
600 sixth * c(3) + third * boxes(id)%cc(i, j, ix_f, iv)
601 if (boxes(id)%cc(i, j, ix, iv) > 2 * c(1)) &
602 boxes(id)%cc(i, j, ix, iv) = 2 * c(1)
608 end subroutine af_gc_interp_lim
611 subroutine af_bc_neumann_zero(box, nb, iv, coords, bc_val, bc_type)
612 type(
box_t),
intent(in) :: box
613 integer,
intent(in) :: nb
614 integer,
intent(in) :: iv
615 real(dp),
intent(in) :: coords(ndim, box%n_cell**(ndim-1))
616 real(dp),
intent(out) :: bc_val(box%n_cell**(ndim-1))
617 integer,
intent(out) :: bc_type
619 bc_type = af_bc_neumann
621 end subroutine af_bc_neumann_zero
624 subroutine af_bc_dirichlet_zero(box, nb, iv, coords, bc_val, bc_type)
625 type(
box_t),
intent(in) :: box
626 integer,
intent(in) :: nb
627 integer,
intent(in) :: iv
628 real(dp),
intent(in) :: coords(ndim, box%n_cell**(ndim-1))
629 real(dp),
intent(out) :: bc_val(box%n_cell**(ndim-1))
630 integer,
intent(out) :: bc_type
632 bc_type = af_bc_dirichlet
634 end subroutine af_bc_dirichlet_zero
637 subroutine af_bc_set_continuous(box, nb, iv, coords, bc_val, bc_type)
638 type(
box_t),
intent(in) :: box
639 integer,
intent(in) :: nb
640 integer,
intent(in) :: iv
641 real(dp),
intent(in) :: coords(ndim, box%n_cell**(ndim-1))
642 real(dp),
intent(out) :: bc_val(box%n_cell**(ndim-1))
643 integer,
intent(out) :: bc_type
645 bc_type = af_bc_continuous
648 end subroutine af_bc_set_continuous
650 subroutine copy_from_nb(box, box_nb, dnb, lo, hi, ivs)
651 type(
box_t),
intent(inout) :: box
652 type(
box_t),
intent(in) :: box_nb
653 integer,
intent(in) :: dnb(NDIM)
654 integer,
intent(in) :: lo(NDIM)
655 integer,
intent(in) :: hi(NDIM)
656 integer,
intent(in) :: ivs(:)
657 integer :: nlo(NDIM), nhi(NDIM)
660 nlo = lo - dnb * box%n_cell
661 nhi = hi - dnb * box%n_cell
663 box%cc(dslice(lo, hi), ivs) = &
664 box_nb%cc(dslice(nlo, nhi), ivs)
665 end subroutine copy_from_nb
668 subroutine af_gc2_box(tree, id, ivs, cc)
669 type(
af_t),
intent(inout) :: tree
670 integer,
intent(in) :: id
671 integer,
intent(in) :: ivs(:)
672 real(dp),
intent(inout) :: cc(dtimes(-1:tree%n_cell+2), size(ivs))
673 integer :: i, iv, nb, nc, nb_id, bc_type, ix
674 integer :: lo(ndim), hi(ndim), dnb(ndim)
675 integer :: nlo(ndim), nhi(ndim)
676 real(dp) :: bc_val(tree%n_cell**(ndim-1))
684 cc(dtimes(0:nc+1), i) = tree%boxes(id)%cc(dtimes(:), iv)
686 if (.not. tree%has_cc_method(iv))
then
687 print *,
"For variable ", trim(tree%cc_names(iv))
688 error stop
"No methods stored"
692 do nb = 1, af_num_neighbors
693 nb_id = tree%boxes(id)%neighbors(nb)
695 if (nb_id > af_no_box)
then
697 call af_get_index_bc_outside(nb, tree%n_cell, 2, lo, hi)
699 dnb = af_neighb_offset([nb])
700 nlo = lo - dnb * tree%n_cell
701 nhi = hi - dnb * tree%n_cell
703 cc(dslice(lo, hi), :) = &
704 tree%boxes(nb_id)%cc(dslice(nlo, nhi), ivs)
706 else if (nb_id == af_no_box)
then
710 call gc2_prolong_rb(tree, id, nb, iv, tree%n_cell, &
717 if (
associated(tree%cc_methods(iv)%bc_custom))
then
718 call tree%cc_methods(iv)%bc_custom(tree%boxes(id), &
719 nb, iv, 2, cc(dtimes(:), i))
721 ix = tree%boxes(id)%nb_to_bc_index(nb)
722 call tree%cc_methods(iv)%bc(tree%boxes(id), nb, iv, &
723 tree%boxes(id)%bc_coords(:, :, ix), bc_val, bc_type)
724 call bc_to_gc2(nc, cc(dtimes(:), i), nb, bc_val, bc_type, &
726 tree%boxes(id)%bc_val(:, iv, ix) = bc_val
727 tree%boxes(id)%bc_type(iv, ix) = bc_type
737 tree%boxes(id)%cc(dtimes(:), iv) = cc(dtimes(0:nc+1), i)
740 end subroutine af_gc2_box
749 subroutine gc2_prolong_rb(tree, id, nb, iv, nc, cc)
751 type(
af_t),
intent(in) :: tree
752 integer,
intent(in) :: id
753 integer,
intent(in) :: nb
754 integer,
intent(in) :: iv
755 integer,
intent(in) :: nc
756 real(dp),
intent(inout) :: cc(DTIMES(-1:nc+2))
757 integer :: IJK, IJK_(f), p_id, p_nb_id
758 integer :: lo_c(NDIM), hi_c(NDIM), ix_offset(NDIM)
759 integer :: lo(NDIM), hi(NDIM)
760 real(dp) :: f(0:NDIM), slopes_a(NDIM), slopes_b(NDIM)
762 p_id = tree%boxes(id)%parent
763 p_nb_id = tree%boxes(p_id)%neighbors(nb)
766 call af_get_index_bc_outside(nb, nc, 2, lo, hi)
769 ix_offset = af_get_child_offset(tree%boxes(id))
770 lo_c = ix_offset + (lo+1)/2
771 hi_c = ix_offset + (hi+1)/2
775 lo_c = lo_c - af_neighb_dix(:, nb) * nc
776 hi_c = hi_c - af_neighb_dix(:, nb) * nc
778 associate(cc_p => tree%boxes(p_nb_id)%cc, &
779 limiter => tree%cc_methods(iv)%prolong_limiter)
781 do i = lo_c(1), hi_c(1)
782 i_f = lo(1) + 2 * (i - lo_c(1))
786 slopes_a = [cc_p(i, iv) - cc_p(i-1, iv)]
787 slopes_b = [cc_p(i+1, iv) - cc_p(i, iv)]
788 f(1:1) = 0.25_dp * af_limiter_apply(slopes_a, slopes_b, limiter)
791 cc(i_f) = f(0) - f(1)
792 cc(i_f+1) = f(0) + f(1)
795 do j = lo_c(2), hi_c(2)
796 j_f = lo(2) + 2 * (j - lo_c(2))
797 do i = lo_c(1), hi_c(1)
798 i_f = lo(1) + 2 * (i - lo_c(1))
801 f(0) = cc_p(i, j, iv)
802 slopes_a = [cc_p(i, j, iv) - cc_p(i-1, j, iv), &
803 cc_p(i, j, iv) - cc_p(i, j-1, iv)]
804 slopes_b = [cc_p(i+1, j, iv) - cc_p(i, j, iv), &
805 cc_p(i, j+1, iv) - cc_p(i, j, iv)]
806 f(1:2) = 0.25_dp * af_limiter_apply(slopes_a, slopes_b, limiter)
809 cc(i_f, j_f) = f(0) - f(1) - f(2)
810 cc(i_f, j_f+1) = f(0) - f(1) + f(2)
811 cc(i_f+1, j_f) = f(0) + f(1) - f(2)
812 cc(i_f+1, j_f+1) = f(0) + f(1) + f(2)
816 do k = lo_c(3), hi_c(3)
817 k_f = lo(3) + 2 * (k - lo_c(3))
818 do j = lo_c(2), hi_c(2)
819 j_f = lo(2) + 2 * (j - lo_c(2))
820 do i = lo_c(1), hi_c(1)
821 i_f = lo(1) + 2 * (i - lo_c(1))
824 f(0) = cc_p(i, j, k, iv)
825 slopes_a = [cc_p(i, j, k, iv) - cc_p(i-1, j, k, iv), &
826 cc_p(i, j, k, iv) - cc_p(i, j-1, k, iv), &
827 cc_p(i, j, k, iv) - cc_p(i, j, k-1, iv)]
828 slopes_b = [cc_p(i+1, j, k, iv) - cc_p(i, j, k, iv), &
829 cc_p(i, j+1, k, iv) - cc_p(i, j, k, iv), &
830 cc_p(i, j, k+1, iv) - cc_p(i, j, k, iv)]
831 f(1:3) = 0.25_dp * af_limiter_apply(slopes_a, slopes_b, limiter)
834 cc(i_f, j_f, k_f) = f(0) - f(1) - f(2) - f(3)
835 cc(i_f, j_f, k_f+1) = f(0) - f(1) - f(2) + f(3)
836 cc(i_f, j_f+1, k_f) = f(0) - f(1) + f(2) - f(3)
837 cc(i_f, j_f+1, k_f+1) = f(0) - f(1) + f(2) + f(3)
838 cc(i_f+1, j_f, k_f) = f(0) + f(1) - f(2) - f(3)
839 cc(i_f+1, j_f, k_f+1) = f(0) + f(1) - f(2) + f(3)
840 cc(i_f+1, j_f+1, k_f) = f(0) + f(1) + f(2) - f(3)
841 cc(i_f+1, j_f+1, k_f+1) = f(0) + f(1) + f(2) + f(3)
852 end subroutine gc2_prolong_rb
856 subroutine af_corner_gc_extrap(box, ix, ivs)
857 type(box_t),
intent(inout) :: box
858 integer,
intent(in) :: ix(NDIM)
859 integer,
intent(in) :: ivs(:)
862 di = 1 - 2 * iand(ix, 1)
865 box%cc(ix(1), ix(2), ivs) = box%cc(ix(1)+di(1), ix(2), ivs) &
866 + box%cc(ix(1), ix(2)+di(2), ivs) &
867 - box%cc(ix(1)+di(1), ix(2)+di(2), ivs)
869 box%cc(ix(1), ix(2), ix(3), ivs) = &
870 box%cc(ix(1), ix(2)+di(2), ix(3)+di(3), ivs) + &
871 box%cc(ix(1)+di(1), ix(2), ix(3)+di(3), ivs) + &
872 box%cc(ix(1)+di(1), ix(2)+di(2), ix(3), ivs) - 2 * &
873 box%cc(ix(1)+di(1), ix(2)+di(2), ix(3)+di(3), ivs)
875 end subroutine af_corner_gc_extrap
881 subroutine af_edge_gc_extrap(box, lo, dim, ivs)
882 type(box_t),
intent(inout) :: box
883 integer,
intent(in) :: lo(NDIM)
884 integer,
intent(in) :: dim
885 integer,
intent(in) :: ivs(:)
886 integer :: di(NDIM), ix(NDIM), ia(NDIM), ib(NDIM), ic(NDIM)
887 integer :: n, o_dims(NDIM-1)
890 o_dims = [1 + mod(dim, ndim), 1 + mod(dim + 1, ndim)]
893 di = 1 - 2 * iand(lo, 1)
898 ia(o_dims(1)) = ia(o_dims(1)) + di(o_dims(1))
902 ib(o_dims(2)) = ib(o_dims(2)) + di(o_dims(2))
914 box%cc(ix(1), ix(2), ix(3), ivs) = &
915 box%cc(ia(1), ia(2), ia(3), ivs) + &
916 box%cc(ib(1), ib(2), ib(3), ivs) - &
917 box%cc(ic(1), ic(2), ic(3), ivs)
920 end subroutine af_edge_gc_extrap
This module contains routines related to the filling of ghost cells. Note that corner ghost cells are...
Module containing slope limiters.
This module contains the routines related to prolongation: going from coarse to fine 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,...