4 #include "cpp_macros.h"
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
304 select case (bc_type)
305 case (af_bc_dirichlet)
310 c0 = dr(af_neighb_dim(nb)) * af_neighb_high_pm(nb)
313 case (af_bc_dirichlet_copy)
318 stop
"fill_bc: unknown boundary condition"
323 case (af_neighb_lowx)
324 cc(0) = c0 * bc_val(1) + c1 * cc(1)
325 cc(-1) = c2 * bc_val(1) + c1 * cc(2)
326 case (af_neighb_highx)
327 cc(nc+1) = c0 * bc_val(1) + c1 * cc(nc)
328 cc(nc+2) = c2 * bc_val(1) + c1 * cc(nc-1)
330 case (af_neighb_lowx)
331 cc(0, 1:nc) = c0 * bc_val + c1 * cc(1, 1:nc)
332 cc(-1, 1:nc) = c2 * bc_val + c1 * cc(2, 1:nc)
333 case (af_neighb_highx)
334 cc(nc+1, 1:nc) = c0 * bc_val + c1 * cc(nc, 1:nc)
335 cc(nc+2, 1:nc) = c2 * bc_val + c1 * cc(nc-1, 1:nc)
336 case (af_neighb_lowy)
337 cc(1:nc, 0) = c0 * bc_val + c1 * cc(1:nc, 1)
338 cc(1:nc, -1) = c2 * bc_val + c1 * cc(1:nc, 2)
339 case (af_neighb_highy)
340 cc(1:nc, nc+1) = c0 * bc_val + c1 * cc(1:nc, nc)
341 cc(1:nc, nc+2) = c2 * bc_val + c1 * cc(1:nc, nc-1)
343 case (af_neighb_lowx)
344 cc(0, 1:nc, 1:nc) = c0 * reshape(bc_val, [nc, nc]) + &
345 c1 * cc(1, 1:nc, 1:nc)
346 cc(-1, 1:nc, 1:nc) = c2 * reshape(bc_val, [nc, nc]) + &
347 c1 * cc(2, 1:nc, 1:nc)
348 case (af_neighb_highx)
349 cc(nc+1, 1:nc, 1:nc) = c0 * reshape(bc_val, [nc, nc]) + &
350 c1 * cc(nc, 1:nc, 1:nc)
351 cc(nc+2, 1:nc, 1:nc) = c2 * reshape(bc_val, [nc, nc]) + &
352 c1 * cc(nc-1, 1:nc, 1:nc)
353 case (af_neighb_lowy)
354 cc(1:nc, 0, 1:nc) = c0 * reshape(bc_val, [nc, nc]) + &
355 c1 * cc(1:nc, 1, 1:nc)
356 cc(1:nc, -1, 1:nc) = c2 * reshape(bc_val, [nc, nc]) + &
357 c1 * cc(1:nc, 2, 1:nc)
358 case (af_neighb_highy)
359 cc(1:nc, nc+1, 1:nc) = c0 * reshape(bc_val, [nc, nc]) + &
360 c1 * cc(1:nc, nc, 1:nc)
361 cc(1:nc, nc+2, 1:nc) = c0 * reshape(bc_val, [nc, nc]) + &
362 c1 * cc(1:nc, nc-1, 1:nc)
363 case (af_neighb_lowz)
364 cc(1:nc, 1:nc, 0) = c0 * reshape(bc_val, [nc, nc]) + &
365 c1 * cc(1:nc, 1:nc, 1)
366 cc(1:nc, 1:nc, -1) = c2 * reshape(bc_val, [nc, nc]) + &
367 c1 * cc(1:nc, 1:nc, 2)
368 case (af_neighb_highz)
369 cc(1:nc, 1:nc, nc+1) = c0 * reshape(bc_val, [nc, nc]) + &
370 c1 * cc(1:nc, 1:nc, nc)
371 cc(1:nc, 1:nc, nc+2) = c2 * reshape(bc_val, [nc, nc]) + &
372 c1 * cc(1:nc, 1:nc, nc-1)
375 end subroutine bc_to_gc2
378 subroutine af_gc_prolong_copy(boxes, id, nb, iv, op_mask)
380 type(
box_t),
intent(inout) :: boxes(:)
381 integer,
intent(in) :: id
382 integer,
intent(in) :: iv
383 integer,
intent(in) :: nb
384 integer,
intent(in) :: op_mask
385 integer :: p_id, lo(ndim), hi(ndim)
387 p_id = boxes(id)%parent
388 call af_get_index_bc_outside(nb, boxes(id)%n_cell, 1, lo, hi)
389 call af_prolong_copy(boxes(p_id), boxes(id), iv, low=lo, high=hi)
390 end subroutine af_gc_prolong_copy
394 subroutine af_gc_interp(boxes, id, nb, iv, op_mask)
395 type(
box_t),
intent(inout) :: boxes(:)
396 integer,
intent(in) :: id
397 integer,
intent(in) :: nb
398 integer,
intent(in) :: iv
399 integer,
intent(in) :: op_mask
400 integer :: nc, ix, ix_c, ix_f
402 integer :: p_id, ix_offset(ndim)
403 real(dp),
parameter :: third = 1/3.0_dp
405 real(dp),
parameter :: sixth = 1/6.0_dp
406 integer :: i_c1, i_c2, j_c1, j_c2, i, j
409 integer :: k_c1, k_c2, k
412 nc = boxes(id)%n_cell
413 p_id = boxes(id)%parent
414 p_nb_id = boxes(p_id)%neighbors(nb)
415 ix_offset = af_get_child_offset(boxes(id), nb)
417 if (af_neighb_low(nb))
then
427 select case (af_neighb_dim(nb))
430 boxes(id)%cc(ix, iv) = &
431 2 * third * boxes(p_nb_id)%cc(ix_c, iv) + &
432 third * boxes(id)%cc(ix_f, iv)
436 j_c1 = ix_offset(2) + ishft(j+1, -1)
437 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
438 boxes(id)%cc(ix, j, iv) = &
439 0.5_dp * boxes(p_nb_id)%cc(ix_c, j_c1, iv) + &
440 sixth * boxes(p_nb_id)%cc(ix_c, j_c2, iv) + &
441 third * boxes(id)%cc(ix_f, j, iv)
445 i_c1 = ix_offset(1) + ishft(i+1, -1)
446 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
447 boxes(id)%cc(i, ix, iv) = &
448 0.5_dp * boxes(p_nb_id)%cc(i_c1, ix_c, iv) + &
449 sixth * boxes(p_nb_id)%cc(i_c2, ix_c, iv) + &
450 third * boxes(id)%cc(i, ix_f, iv)
455 k_c1 = ix_offset(3) + ishft(k+1, -1)
456 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
458 j_c1 = ix_offset(2) + ishft(j+1, -1)
459 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
460 boxes(id)%cc(ix, j, k, iv) = &
461 third * boxes(p_nb_id)%cc(ix_c, j_c1, k_c1, iv) + &
462 sixth * boxes(p_nb_id)%cc(ix_c, j_c2, k_c1, iv) + &
463 sixth * boxes(p_nb_id)%cc(ix_c, j_c1, k_c2, iv) + &
464 third * boxes(id)%cc(ix_f, j, k, iv)
469 k_c1 = ix_offset(3) + ishft(k+1, -1)
470 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
472 i_c1 = ix_offset(1) + ishft(i+1, -1)
473 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
474 boxes(id)%cc(i, ix, k, iv) = &
475 third * boxes(p_nb_id)%cc(i_c1, ix_c, k_c1, iv) + &
476 sixth * boxes(p_nb_id)%cc(i_c2, ix_c, k_c1, iv) + &
477 sixth * boxes(p_nb_id)%cc(i_c1, ix_c, k_c2, iv) + &
478 third * boxes(id)%cc(i, ix_f, k, iv)
483 j_c1 = ix_offset(2) + ishft(j+1, -1)
484 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
486 i_c1 = ix_offset(1) + ishft(i+1, -1)
487 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
488 boxes(id)%cc(i, j, ix, iv) = &
489 third * boxes(p_nb_id)%cc(i_c1, j_c1, ix_c, iv) + &
490 sixth * boxes(p_nb_id)%cc(i_c1, j_c2, ix_c, iv) + &
491 sixth * boxes(p_nb_id)%cc(i_c2, j_c1, ix_c, iv) + &
492 third * boxes(id)%cc(i, j, ix_f, iv)
498 end subroutine af_gc_interp
503 subroutine af_gc_interp_lim(boxes, id, nb, iv, op_mask)
504 type(
box_t),
intent(inout) :: boxes(:)
505 integer,
intent(in) :: id
506 integer,
intent(in) :: nb
507 integer,
intent(in) :: iv
508 integer,
intent(in) :: op_mask
509 integer :: nc, ix, ix_c, ix_f
510 integer :: p_id, ix_offset(ndim), p_nb_id
512 real(dp),
parameter :: third = 1/3.0_dp
514 integer :: ijk, ijk_(c1), ijk_(c2)
515 real(dp),
parameter :: sixth = 1/6.0_dp
518 nc = boxes(id)%n_cell
519 p_id = boxes(id)%parent
520 p_nb_id = boxes(p_id)%neighbors(nb)
521 ix_offset = af_get_child_offset(boxes(id), nb)
523 if (af_neighb_low(nb))
then
533 select case (af_neighb_dim(nb))
536 c(1) = boxes(p_nb_id)%cc(ix_c, iv)
537 boxes(id)%cc(ix, iv) = (2 * c(1) + boxes(id)%cc(ix_f, iv)) * third
538 if (boxes(id)%cc(ix, iv) > 2 * c(1)) boxes(id)%cc(ix, iv) = 2 * c(1)
542 j_c1 = ix_offset(2) + ishft(j+1, -1)
543 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
544 c(1) = boxes(p_nb_id)%cc(ix_c, j_c1, iv)
545 c(2) = boxes(p_nb_id)%cc(ix_c, j_c2, iv)
546 boxes(id)%cc(ix, j, iv) = 0.5_dp * c(1) + sixth * c(2) + &
547 third * boxes(id)%cc(ix_f, j, iv)
548 if (boxes(id)%cc(ix, j, iv) > 2 * c(1)) boxes(id)%cc(ix, j, iv) = 2 * c(1)
552 i_c1 = ix_offset(1) + ishft(i+1, -1)
553 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
554 c(1) = boxes(p_nb_id)%cc(i_c1, ix_c, iv)
555 c(2) = boxes(p_nb_id)%cc(i_c2, ix_c, iv)
556 boxes(id)%cc(i, ix, iv) = 0.5_dp * c(1) + sixth * c(2) + &
557 third * boxes(id)%cc(i, ix_f, iv)
558 if (boxes(id)%cc(i, ix, iv) > 2 * c(1)) boxes(id)%cc(i, ix, iv) = 2 * c(1)
563 k_c1 = ix_offset(3) + ishft(k+1, -1)
564 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
566 j_c1 = ix_offset(2) + ishft(j+1, -1)
567 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
568 c(1) = boxes(p_nb_id)%cc(ix_c, j_c1, k_c1, iv)
569 c(2) = boxes(p_nb_id)%cc(ix_c, j_c2, k_c1, iv)
570 c(3) = boxes(p_nb_id)%cc(ix_c, j_c1, k_c2, iv)
571 boxes(id)%cc(ix, j, k, iv) = third * c(1) + sixth * c(2) + &
572 sixth * c(3) + third * boxes(id)%cc(ix_f, j, k, iv)
573 if (boxes(id)%cc(ix, j, k, iv) > 2 * c(1)) &
574 boxes(id)%cc(ix, j, k, iv) = 2 * c(1)
579 k_c1 = ix_offset(3) + ishft(k+1, -1)
580 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
582 i_c1 = ix_offset(1) + ishft(i+1, -1)
583 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
584 c(1) = boxes(p_nb_id)%cc(i_c1, ix_c, k_c1, iv)
585 c(2) = boxes(p_nb_id)%cc(i_c2, ix_c, k_c1, iv)
586 c(3) = boxes(p_nb_id)%cc(i_c1, ix_c, k_c2, iv)
587 boxes(id)%cc(i, ix, k, iv) = third * c(1) + sixth * c(2) + &
588 sixth * c(3) + third * boxes(id)%cc(i, ix_f, k, iv)
589 if (boxes(id)%cc(i, ix, k, iv) > 2 * c(1)) &
590 boxes(id)%cc(i, ix, k, iv) = 2 * c(1)
595 j_c1 = ix_offset(2) + ishft(j+1, -1)
596 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
598 i_c1 = ix_offset(1) + ishft(i+1, -1)
599 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
600 c(1) = boxes(p_nb_id)%cc(i_c1, j_c1, ix_c, iv)
601 c(2) = boxes(p_nb_id)%cc(i_c1, j_c2, ix_c, iv)
602 c(3) = boxes(p_nb_id)%cc(i_c2, j_c1, ix_c, iv)
603 boxes(id)%cc(i, j, ix, iv) = third * c(1) + sixth * c(2) + &
604 sixth * c(3) + third * boxes(id)%cc(i, j, ix_f, iv)
605 if (boxes(id)%cc(i, j, ix, iv) > 2 * c(1)) &
606 boxes(id)%cc(i, j, ix, iv) = 2 * c(1)
612 end subroutine af_gc_interp_lim
615 subroutine af_bc_neumann_zero(box, nb, iv, coords, bc_val, bc_type)
616 type(
box_t),
intent(in) :: box
617 integer,
intent(in) :: nb
618 integer,
intent(in) :: iv
619 real(dp),
intent(in) :: coords(ndim, box%n_cell**(ndim-1))
620 real(dp),
intent(out) :: bc_val(box%n_cell**(ndim-1))
621 integer,
intent(out) :: bc_type
623 bc_type = af_bc_neumann
625 end subroutine af_bc_neumann_zero
628 subroutine af_bc_dirichlet_zero(box, nb, iv, coords, bc_val, bc_type)
629 type(
box_t),
intent(in) :: box
630 integer,
intent(in) :: nb
631 integer,
intent(in) :: iv
632 real(dp),
intent(in) :: coords(ndim, box%n_cell**(ndim-1))
633 real(dp),
intent(out) :: bc_val(box%n_cell**(ndim-1))
634 integer,
intent(out) :: bc_type
636 bc_type = af_bc_dirichlet
638 end subroutine af_bc_dirichlet_zero
641 subroutine af_bc_set_continuous(box, nb, iv, coords, bc_val, bc_type)
642 type(
box_t),
intent(in) :: box
643 integer,
intent(in) :: nb
644 integer,
intent(in) :: iv
645 real(dp),
intent(in) :: coords(ndim, box%n_cell**(ndim-1))
646 real(dp),
intent(out) :: bc_val(box%n_cell**(ndim-1))
647 integer,
intent(out) :: bc_type
649 bc_type = af_bc_continuous
652 end subroutine af_bc_set_continuous
654 subroutine copy_from_nb(box, box_nb, dnb, lo, hi, ivs)
655 type(
box_t),
intent(inout) :: box
656 type(
box_t),
intent(in) :: box_nb
657 integer,
intent(in) :: dnb(NDIM)
658 integer,
intent(in) :: lo(NDIM)
659 integer,
intent(in) :: hi(NDIM)
660 integer,
intent(in) :: ivs(:)
661 integer :: nlo(NDIM), nhi(NDIM)
664 nlo = lo - dnb * box%n_cell
665 nhi = hi - dnb * box%n_cell
667 box%cc(dslice(lo, hi), ivs) = &
668 box_nb%cc(dslice(nlo, nhi), ivs)
669 end subroutine copy_from_nb
672 subroutine af_gc2_box(tree, id, ivs, cc)
673 type(
af_t),
intent(inout) :: tree
674 integer,
intent(in) :: id
675 integer,
intent(in) :: ivs(:)
676 real(dp),
intent(inout) :: cc(dtimes(-1:tree%n_cell+2), size(ivs))
677 integer :: i, iv, nb, nc, nb_id, bc_type, ix
678 integer :: lo(ndim), hi(ndim), dnb(ndim)
679 integer :: nlo(ndim), nhi(ndim)
680 real(dp) :: bc_val(tree%n_cell**(ndim-1))
688 cc(dtimes(0:nc+1), i) = tree%boxes(id)%cc(dtimes(:), iv)
690 if (.not. tree%has_cc_method(iv))
then
691 print *,
"For variable ", trim(tree%cc_names(iv))
692 error stop
"No methods stored"
696 do nb = 1, af_num_neighbors
697 nb_id = tree%boxes(id)%neighbors(nb)
699 if (nb_id > af_no_box)
then
701 call af_get_index_bc_outside(nb, tree%n_cell, 2, lo, hi)
703 dnb = af_neighb_offset([nb])
704 nlo = lo - dnb * tree%n_cell
705 nhi = hi - dnb * tree%n_cell
707 cc(dslice(lo, hi), :) = &
708 tree%boxes(nb_id)%cc(dslice(nlo, nhi), ivs)
710 else if (nb_id == af_no_box)
then
714 call gc2_prolong_rb(tree, id, nb, iv, tree%n_cell, &
721 if (
associated(tree%cc_methods(iv)%bc_custom))
then
722 call tree%cc_methods(iv)%bc_custom(tree%boxes(id), &
723 nb, iv, 2, cc(dtimes(:), i))
725 ix = tree%boxes(id)%nb_to_bc_index(nb)
726 call tree%cc_methods(iv)%bc(tree%boxes(id), nb, iv, &
727 tree%boxes(id)%bc_coords(:, :, ix), bc_val, bc_type)
728 call bc_to_gc2(nc, cc(dtimes(:), i), nb, bc_val, bc_type, &
730 tree%boxes(id)%bc_val(:, iv, ix) = bc_val
731 tree%boxes(id)%bc_type(iv, ix) = bc_type
741 tree%boxes(id)%cc(dtimes(:), iv) = cc(dtimes(0:nc+1), i)
744 end subroutine af_gc2_box
753 subroutine gc2_prolong_rb(tree, id, nb, iv, nc, cc)
755 type(
af_t),
intent(in) :: tree
756 integer,
intent(in) :: id
757 integer,
intent(in) :: nb
758 integer,
intent(in) :: iv
759 integer,
intent(in) :: nc
760 real(dp),
intent(inout) :: cc(DTIMES(-1:nc+2))
761 integer :: IJK, IJK_(f), p_id, p_nb_id
762 integer :: lo_c(NDIM), hi_c(NDIM), ix_offset(NDIM)
763 integer :: lo(NDIM), hi(NDIM)
764 real(dp) :: f(0:NDIM), slopes_a(NDIM), slopes_b(NDIM)
766 p_id = tree%boxes(id)%parent
767 p_nb_id = tree%boxes(p_id)%neighbors(nb)
770 call af_get_index_bc_outside(nb, nc, 2, lo, hi)
773 ix_offset = af_get_child_offset(tree%boxes(id))
774 lo_c = ix_offset + (lo+1)/2
775 hi_c = ix_offset + (hi+1)/2
779 lo_c = lo_c - af_neighb_dix(:, nb) * nc
780 hi_c = hi_c - af_neighb_dix(:, nb) * nc
782 associate(cc_p => tree%boxes(p_nb_id)%cc, &
783 limiter => tree%cc_methods(iv)%prolong_limiter)
785 do i = lo_c(1), hi_c(1)
786 i_f = lo(1) + 2 * (i - lo_c(1))
790 slopes_a = [cc_p(i, iv) - cc_p(i-1, iv)]
791 slopes_b = [cc_p(i+1, iv) - cc_p(i, iv)]
792 f(1:1) = 0.25_dp * af_limiter_apply(slopes_a, slopes_b, limiter)
795 cc(i_f) = f(0) - f(1)
796 cc(i_f+1) = f(0) + f(1)
799 do j = lo_c(2), hi_c(2)
800 j_f = lo(2) + 2 * (j - lo_c(2))
801 do i = lo_c(1), hi_c(1)
802 i_f = lo(1) + 2 * (i - lo_c(1))
805 f(0) = cc_p(i, j, iv)
806 slopes_a = [cc_p(i, j, iv) - cc_p(i-1, j, iv), &
807 cc_p(i, j, iv) - cc_p(i, j-1, iv)]
808 slopes_b = [cc_p(i+1, j, iv) - cc_p(i, j, iv), &
809 cc_p(i, j+1, iv) - cc_p(i, j, iv)]
810 f(1:2) = 0.25_dp * af_limiter_apply(slopes_a, slopes_b, limiter)
813 cc(i_f, j_f) = f(0) - f(1) - f(2)
814 cc(i_f, j_f+1) = f(0) - f(1) + f(2)
815 cc(i_f+1, j_f) = f(0) + f(1) - f(2)
816 cc(i_f+1, j_f+1) = f(0) + f(1) + f(2)
820 do k = lo_c(3), hi_c(3)
821 k_f = lo(3) + 2 * (k - lo_c(3))
822 do j = lo_c(2), hi_c(2)
823 j_f = lo(2) + 2 * (j - lo_c(2))
824 do i = lo_c(1), hi_c(1)
825 i_f = lo(1) + 2 * (i - lo_c(1))
828 f(0) = cc_p(i, j, k, iv)
829 slopes_a = [cc_p(i, j, k, iv) - cc_p(i-1, j, k, iv), &
830 cc_p(i, j, k, iv) - cc_p(i, j-1, k, iv), &
831 cc_p(i, j, k, iv) - cc_p(i, j, k-1, iv)]
832 slopes_b = [cc_p(i+1, j, k, iv) - cc_p(i, j, k, iv), &
833 cc_p(i, j+1, k, iv) - cc_p(i, j, k, iv), &
834 cc_p(i, j, k+1, iv) - cc_p(i, j, k, iv)]
835 f(1:3) = 0.25_dp * af_limiter_apply(slopes_a, slopes_b, limiter)
838 cc(i_f, j_f, k_f) = f(0) - f(1) - f(2) - f(3)
839 cc(i_f, j_f, k_f+1) = f(0) - f(1) - f(2) + f(3)
840 cc(i_f, j_f+1, k_f) = f(0) - f(1) + f(2) - f(3)
841 cc(i_f, j_f+1, k_f+1) = f(0) - f(1) + f(2) + f(3)
842 cc(i_f+1, j_f, k_f) = f(0) + f(1) - f(2) - f(3)
843 cc(i_f+1, j_f, k_f+1) = f(0) + f(1) - f(2) + f(3)
844 cc(i_f+1, j_f+1, k_f) = f(0) + f(1) + f(2) - f(3)
845 cc(i_f+1, j_f+1, k_f+1) = f(0) + f(1) + f(2) + f(3)
856 end subroutine gc2_prolong_rb
860 subroutine af_corner_gc_extrap(box, ix, ivs)
861 type(box_t),
intent(inout) :: box
862 integer,
intent(in) :: ix(NDIM)
863 integer,
intent(in) :: ivs(:)
866 di = 1 - 2 * iand(ix, 1)
869 box%cc(ix(1), ix(2), ivs) = box%cc(ix(1)+di(1), ix(2), ivs) &
870 + box%cc(ix(1), ix(2)+di(2), ivs) &
871 - box%cc(ix(1)+di(1), ix(2)+di(2), ivs)
873 box%cc(ix(1), ix(2), ix(3), ivs) = &
874 box%cc(ix(1), ix(2)+di(2), ix(3)+di(3), ivs) + &
875 box%cc(ix(1)+di(1), ix(2), ix(3)+di(3), ivs) + &
876 box%cc(ix(1)+di(1), ix(2)+di(2), ix(3), ivs) - 2 * &
877 box%cc(ix(1)+di(1), ix(2)+di(2), ix(3)+di(3), ivs)
879 end subroutine af_corner_gc_extrap
885 subroutine af_edge_gc_extrap(box, lo, dim, ivs)
886 type(box_t),
intent(inout) :: box
887 integer,
intent(in) :: lo(NDIM)
888 integer,
intent(in) :: dim
889 integer,
intent(in) :: ivs(:)
890 integer :: di(NDIM), ix(NDIM), ia(NDIM), ib(NDIM), ic(NDIM)
891 integer :: n, o_dims(NDIM-1)
894 o_dims = [1 + mod(dim, ndim), 1 + mod(dim + 1, ndim)]
897 di = 1 - 2 * iand(lo, 1)
902 ia(o_dims(1)) = ia(o_dims(1)) + di(o_dims(1))
906 ib(o_dims(2)) = ib(o_dims(2)) + di(o_dims(2))
918 box%cc(ix(1), ix(2), ix(3), ivs) = &
919 box%cc(ia(1), ia(2), ia(3), ivs) + &
920 box%cc(ib(1), ib(2), ib(3), ivs) - &
921 box%cc(ic(1), ic(2), ic(3), ivs)
924 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,...