3 #include "cpp_macros.h"
10 integer,
parameter :: stencil_list_initial_size = 10
12 integer,
parameter,
public :: stencil_constant = 1
13 integer,
parameter,
public :: stencil_variable = 2
14 integer,
parameter,
public :: stencil_sparse = 3
17 integer,
parameter,
private :: num_shapes = 5
20 integer,
parameter,
public :: af_stencil_357 = 1
23 integer,
parameter,
public :: af_stencil_p234 = 2
26 integer,
parameter,
public :: af_stencil_p248 = 3
29 integer,
parameter,
public :: af_stencil_246 = 4
32 integer,
parameter,
public :: af_stencil_mask = 5
35 integer,
parameter,
public :: af_stencil_sizes(num_shapes) = &
36 [2*ndim+1, ndim+1, 2**ndim, 2*ndim, 1]
42 type(
box_t),
intent(in) :: box
47 public :: af_stencil_print_info
48 public :: af_stencil_index
49 public :: af_stencil_prepare_store
50 public :: af_stencil_remove
51 public :: af_stencil_store_box
52 public :: af_stencil_check_box
53 public :: af_stencil_allocate_coeff
54 public :: af_stencil_store
55 public :: af_stencil_apply
56 public :: af_stencil_apply_box
57 public :: af_stencil_gsrb_box
58 public :: af_stencil_prolong_box
59 public :: af_stencil_get_box
60 public :: af_stencil_try_constant
65 subroutine af_stencil_print_info(tree)
66 type(
af_t),
intent(in) :: tree
67 integer :: id, n_stencils_stored
68 integer :: n_boxes_with_stencils
69 integer :: n_constant_stored, n_variable_stored
70 integer :: n, n_stencils, n_sparse_stored
76 n_boxes_with_stencils = 0
78 do id = 1, tree%highest_id
79 if (.not. tree%boxes(id)%in_use) cycle
81 n_stencils = tree%boxes(id)%n_stencils
82 if (n_stencils > 0)
then
83 n_boxes_with_stencils = n_boxes_with_stencils + 1
84 n_stencils_stored = n_stencils_stored + n_stencils
87 select case (tree%boxes(id)%stencils(n)%stype)
88 case (stencil_constant)
89 n_constant_stored = n_constant_stored + 1
90 case (stencil_variable)
91 n_variable_stored = n_variable_stored + 1
93 n_sparse_stored = n_sparse_stored + 1
100 write(*,
'(A)')
' ** Information about stencils **'
101 write(*,
'(A, I0)')
' #boxes with stencils: ', n_boxes_with_stencils
102 write(*,
'(A, I0)')
' #stencils stored: ', n_stencils_stored
103 write(*,
'(A, I0)')
' #constant stencils: ', n_constant_stored
104 write(*,
'(A, I0)')
' #variable stencils: ', n_variable_stored
105 write(*,
'(A, I0)')
' #sparse stencils: ', n_sparse_stored
106 end subroutine af_stencil_print_info
109 pure integer function af_stencil_index(box, key)
110 type(
box_t),
intent(in) :: box
111 integer,
intent(in) :: key
114 af_stencil_index = af_stencil_none
115 do i = 1, box%n_stencils
116 if (box%stencils(i)%key == key)
then
121 end function af_stencil_index
124 subroutine af_stencil_store(tree, key, set_stencil)
125 type(
af_t),
intent(inout) :: tree
126 integer,
intent(in) :: key
129 integer :: lvl, i, id
132 do lvl = 1, tree%highest_lvl
134 do i = 1,
size(tree%lvls(lvl)%ids)
135 id = tree%lvls(lvl)%ids(i)
136 call af_stencil_store_box(tree%boxes(id), key, set_stencil)
141 end subroutine af_stencil_store
144 subroutine af_stencil_prepare_store(box, key, ix)
145 type(
box_t),
intent(inout) :: box
146 integer,
intent(in) :: key
147 integer,
intent(out) :: ix
150 ix = af_stencil_index(box, key)
152 if (ix == af_stencil_none)
then
154 if (.not.
allocated(box%stencils))
then
155 allocate(box%stencils(stencil_list_initial_size))
156 else if (box%n_stencils ==
size(box%stencils))
then
157 allocate(tmp(2 * box%n_stencils))
158 tmp(1:box%n_stencils) = box%stencils
159 call move_alloc(tmp, box%stencils)
162 box%n_stencils = box%n_stencils + 1
164 box%stencils(ix)%key = key
166 error stop
"Stencil with this key has already been stored"
168 end subroutine af_stencil_prepare_store
171 subroutine af_stencil_allocate_coeff(stencil, nc, use_f, n_sparse)
172 type(
stencil_t),
intent(inout) :: stencil
174 integer,
intent(in) :: nc
177 logical,
intent(in),
optional :: use_f
179 integer,
intent(in),
optional :: n_sparse
180 logical :: allocate_f
183 allocate_f = .false.;
if (
present(use_f)) allocate_f = use_f
184 if (stencil%shape < 1 .or. stencil%shape > num_shapes) &
185 error stop
"Unknown stencil shape"
187 n_coeff = af_stencil_sizes(stencil%shape)
189 select case (stencil%stype)
190 case (stencil_constant)
191 if (.not.
allocated(stencil%c))
then
192 allocate(stencil%c(n_coeff))
193 else if (
size(stencil%c) /= n_coeff)
then
194 deallocate(stencil%c)
195 allocate(stencil%c(n_coeff))
199 if (
allocated(stencil%v))
deallocate(stencil%v)
200 if (
allocated(stencil%f))
deallocate(stencil%f, stencil%bc_correction)
201 if (
allocated(stencil%sparse_v)) &
202 deallocate(stencil%sparse_v, stencil%sparse_ix)
203 case (stencil_variable)
204 if (.not.
allocated(stencil%v))
then
205 allocate(stencil%v(n_coeff, dtimes(nc)))
206 else if (
size(stencil%v, 1) /= n_coeff)
then
207 deallocate(stencil%v)
208 allocate(stencil%v(n_coeff, dtimes(nc)))
211 if (allocate_f .and. .not.
allocated(stencil%f))
then
212 allocate(stencil%f(dtimes(nc)))
213 allocate(stencil%bc_correction(dtimes(nc)))
214 else if (.not. allocate_f .and.
allocated(stencil%f))
then
215 deallocate(stencil%f, stencil%bc_correction)
219 if (
allocated(stencil%c))
deallocate(stencil%c)
220 if (
allocated(stencil%sparse_v)) &
221 deallocate(stencil%sparse_v, stencil%sparse_ix)
222 case (stencil_sparse)
223 if (.not.
present(n_sparse)) error stop
"n_sparse required"
225 if (.not.
allocated(stencil%sparse_v))
then
226 allocate(stencil%sparse_ix(ndim, n_sparse))
227 allocate(stencil%sparse_v(n_coeff, n_sparse))
228 else if (any(
size(stencil%sparse_v) /= [n_coeff, n_sparse]))
then
229 deallocate(stencil%sparse_v)
230 deallocate(stencil%sparse_ix)
231 allocate(stencil%sparse_ix(ndim, n_sparse))
232 allocate(stencil%sparse_v(n_coeff, n_sparse))
236 if (
allocated(stencil%c))
deallocate(stencil%c)
237 if (
allocated(stencil%v))
deallocate(stencil%v)
238 if (
allocated(stencil%f))
deallocate(stencil%f, stencil%bc_correction)
240 error stop
"Unknow stencil%stype"
242 end subroutine af_stencil_allocate_coeff
245 subroutine af_stencil_remove(tree, key)
246 type(
af_t),
intent(inout) :: tree
247 integer,
intent(in) :: key
248 integer :: lvl, i, id
251 do lvl = 1, tree%highest_lvl
253 do i = 1,
size(tree%lvls(lvl)%ids)
254 id = tree%lvls(lvl)%ids(i)
255 call af_stencil_remove_box(tree%boxes(id), key)
260 end subroutine af_stencil_remove
263 subroutine af_stencil_store_box(box, key, set_stencil)
264 type(
box_t),
intent(inout) :: box
265 integer,
intent(in) :: key
270 call af_stencil_prepare_store(box, key, ix)
271 call set_stencil(box, box%stencils(ix))
272 end subroutine af_stencil_store_box
275 subroutine af_stencil_remove_box(box, key)
276 type(
box_t),
intent(inout) :: box
277 integer,
intent(in) :: key
281 ix = af_stencil_index(box, key)
282 if (ix == af_stencil_none) error stop
"Stencil not present"
285 if (ix == box%n_stencils)
then
286 box%stencils(ix) = empty_stencil
288 box%stencils(ix) = box%stencils(box%n_stencils)
289 box%stencils(box%n_stencils) = empty_stencil
292 box%n_stencils = box%n_stencils - 1
293 end subroutine af_stencil_remove_box
296 subroutine af_stencil_check_box(box, key, ix)
297 type(
box_t),
intent(in) :: box
298 integer,
intent(in) :: key
299 integer,
intent(in) :: ix
301 if (key == af_stencil_none) &
302 error stop
"key == af_stencil_none"
304 if (af_stencil_index(box, key) /= ix) &
305 error stop
"Stencil with key not found at index"
307 associate(stencil => box%stencils(ix))
308 if (stencil%shape < 1 .or. stencil%shape > num_shapes) &
309 error stop
"Unknown stencil shape"
310 select case (stencil%stype)
311 case (stencil_constant)
312 if (.not.
allocated(stencil%c)) &
313 error stop
"stencil%c not allocated"
314 case (stencil_variable)
315 if (.not.
allocated(stencil%v)) &
316 error stop
"stencil%v not allocated"
317 case (stencil_sparse)
318 if (.not.
allocated(stencil%sparse_ix)) &
319 error stop
"stencil%sparse_ix not allocated"
320 if (.not.
allocated(stencil%sparse_v)) &
321 error stop
"stencil%sparse_v not allocated"
323 error stop
"Unknow stencil%stype"
326 end subroutine af_stencil_check_box
328 subroutine af_stencil_apply(tree, key, iv, i_out)
329 type(af_t),
intent(inout) :: tree
330 integer,
intent(in) :: key
331 integer,
intent(in) :: iv
332 integer,
intent(in) :: i_out
334 integer :: lvl, i, id
337 do lvl = 1, tree%highest_lvl
339 do i = 1,
size(tree%lvls(lvl)%ids)
340 id = tree%lvls(lvl)%ids(i)
341 call af_stencil_apply_box(tree%boxes(id), key, iv, i_out)
346 end subroutine af_stencil_apply
348 subroutine af_stencil_apply_box(box, key, iv, i_out)
349 type(box_t),
intent(inout) :: box
350 integer,
intent(in) :: key
351 integer,
intent(in) :: iv
352 integer,
intent(in) :: i_out
355 i = af_stencil_index(box, key)
356 if (i == af_stencil_none) error stop
"Stencil not stored"
358 select case (box%stencils(i)%shape)
359 case (af_stencil_357)
360 call stencil_apply_357(box, box%stencils(i), iv, i_out)
362 error stop
"Unknown stencil"
364 end subroutine af_stencil_apply_box
367 subroutine stencil_apply_357(box, stencil, iv, i_out)
368 type(box_t),
intent(inout) :: box
369 type(stencil_t),
intent(in) :: stencil
370 integer,
intent(in) :: iv
371 integer,
intent(in) :: i_out
372 real(dp) :: c(2*NDIM+1)
375 real(dp) :: rfac(2, box%n_cell), c_cyl(2*NDIM+1)
376 real(dp) :: cc_cyl(2*NDIM+1, box%n_cell)
379 if (iv == i_out) error stop
"Cannot have iv == i_out"
380 if (stencil%stype == stencil_sparse) error stop
"sparse not implemented"
382 associate(cc => box%cc, nc => box%n_cell)
385 if (stencil%stype == stencil_constant)
then
389 c(1) * cc(i, iv) + c(2) * cc(i-1, iv) + c(3) * cc(i+1, iv)
393 c = stencil%v(:, ijk)
395 c(1) * cc(i, iv) + c(2) * cc(i-1, iv) + c(3) * cc(i+1, iv)
399 if (stencil%cylindrical_gradient)
then
402 call af_cyl_flux_factors(box, rfac)
404 if (stencil%stype == stencil_constant)
then
409 cc_cyl(2:3, i) = rfac(1:2, i) * c(2:3)
410 cc_cyl(1, i) = c(1) - (cc_cyl(2, i) - c(2)) &
411 - (cc_cyl(3, i) - c(3))
412 cc_cyl(4:, i) = c(4:)
417 cc_cyl(1, i) * cc(i, j, iv) + &
418 cc_cyl(2, i) * cc(i-1, j, iv) + &
419 cc_cyl(3, i) * cc(i+1, j, iv) + &
420 cc_cyl(4, i) * cc(i, j-1, iv) + &
421 cc_cyl(5, i) * cc(i, j+1, iv)
426 c = stencil%v(:, ijk)
427 c_cyl(2:3) = rfac(1:2, i) * c(2:3)
428 c_cyl(1) = c(1) - (c_cyl(2) - c(2)) - (c_cyl(3) - c(3))
431 c_cyl(1) * cc(i, j, iv) + &
432 c_cyl(2) * cc(i-1, j, iv) + &
433 c_cyl(3) * cc(i+1, j, iv) + &
434 c_cyl(4) * cc(i, j-1, iv) + &
435 c_cyl(5) * cc(i, j+1, iv)
440 if (stencil%stype == stencil_constant)
then
444 c(1) * cc(i, j, iv) + &
445 c(2) * cc(i-1, j, iv) + &
446 c(3) * cc(i+1, j, iv) + &
447 c(4) * cc(i, j-1, iv) + &
448 c(5) * cc(i, j+1, iv)
452 c = stencil%v(:, ijk)
454 c(1) * cc(i, j, iv) + &
455 c(2) * cc(i-1, j, iv) + &
456 c(3) * cc(i+1, j, iv) + &
457 c(4) * cc(i, j-1, iv) + &
458 c(5) * cc(i, j+1, iv)
463 if (stencil%stype == stencil_constant)
then
466 cc(i, j, k, i_out) = &
467 c(1) * cc(i, j, k, iv) + &
468 c(2) * cc(i-1, j, k, iv) + &
469 c(3) * cc(i+1, j, k, iv) + &
470 c(4) * cc(i, j-1, k, iv) + &
471 c(5) * cc(i, j+1, k, iv) + &
472 c(6) * cc(i, j, k-1, iv) + &
473 c(7) * cc(i, j, k+1, iv)
477 c = stencil%v(:, ijk)
478 cc(i, j, k, i_out) = &
479 c(1) * cc(i, j, k, iv) + &
480 c(2) * cc(i-1, j, k, iv) + &
481 c(3) * cc(i+1, j, k, iv) + &
482 c(4) * cc(i, j-1, k, iv) + &
483 c(5) * cc(i, j+1, k, iv) + &
484 c(6) * cc(i, j, k-1, iv) + &
485 c(7) * cc(i, j, k+1, iv)
490 if (
allocated(stencil%bc_correction))
then
491 cc(dtimes(1:nc), i_out) = cc(dtimes(1:nc), i_out) - &
492 stencil%bc_correction
496 end subroutine stencil_apply_357
552 subroutine af_stencil_prolong_box(box_p, box_c, key, iv, iv_to, add)
553 type(box_t),
intent(in) :: box_p
554 type(box_t),
intent(inout) :: box_c
555 integer,
intent(in) :: key
556 integer,
intent(in) :: iv
557 integer,
intent(in) :: iv_to
558 logical,
intent(in),
optional :: add
563 if (
present(add)) add_to = add
565 i = af_stencil_index(box_c, key)
566 if (i == af_stencil_none) error stop
"Stencil not stored"
568 select case (box_c%stencils(i)%shape)
569 case (af_stencil_p234)
570 call stencil_prolong_234(box_p, box_c, box_c%stencils(i), &
572 case (af_stencil_p248)
573 call stencil_prolong_248(box_p, box_c, box_c%stencils(i), &
576 print *,
"box_c%stencils(i)%shape: ", box_c%stencils(i)%shape
577 error stop
"Unknown stencil"
579 end subroutine af_stencil_prolong_box
582 subroutine stencil_prolong_234(box_p, box_c, stencil, iv, iv_to, add)
583 type(box_t),
intent(in) :: box_p
584 type(box_t),
intent(inout) :: box_c
585 type(stencil_t),
intent(in) :: stencil
586 integer,
intent(in) :: iv
587 integer,
intent(in) :: iv_to
588 logical,
intent(in) :: add
590 integer :: nc, ix_offset(NDIM), IJK
591 integer :: IJK_(c1), IJK_(c2)
592 real(dp) :: c(NDIM+1)
595 ix_offset = af_get_child_offset(box_c)
596 if (stencil%stype == stencil_sparse) error stop
"sparse not implemented"
597 if (.not. add) box_c%cc(dtimes(1:nc), iv_to) = 0
602 if (stencil%stype == stencil_constant)
then
605 i_c1 = ix_offset(1) + ishft(i+1, -1)
606 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
607 box_c%cc(ijk, iv_to) = box_c%cc(ijk, iv_to) + &
608 c(1) * box_p%cc(i_c1, iv) + &
609 c(2) * box_p%cc(i_c2, iv)
613 c = stencil%v(:, ijk)
614 i_c1 = ix_offset(1) + ishft(i+1, -1)
615 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
616 box_c%cc(ijk, iv_to) = box_c%cc(ijk, iv_to) + &
617 c(1) * box_p%cc(i_c1, iv) + &
618 c(2) * box_p%cc(i_c2, iv)
622 if (stencil%stype == stencil_constant)
then
625 j_c1 = ix_offset(2) + ishft(j+1, -1)
626 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
628 i_c1 = ix_offset(1) + ishft(i+1, -1)
629 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
630 box_c%cc(ijk, iv_to) = box_c%cc(ijk, iv_to) + &
631 c(1) * box_p%cc(i_c1, j_c1, iv) + &
632 c(2) * box_p%cc(i_c2, j_c1, iv) + &
633 c(3) * box_p%cc(i_c1, j_c2, iv)
638 j_c1 = ix_offset(2) + ishft(j+1, -1)
639 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
641 i_c1 = ix_offset(1) + ishft(i+1, -1)
642 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
643 c = stencil%v(:, ijk)
644 box_c%cc(ijk, iv_to) = box_c%cc(ijk, iv_to) + &
645 c(1) * box_p%cc(i_c1, j_c1, iv) + &
646 c(2) * box_p%cc(i_c2, j_c1, iv) + &
647 c(3) * box_p%cc(i_c1, j_c2, iv)
652 if (stencil%stype == stencil_constant)
then
655 k_c1 = ix_offset(3) + ishft(k+1, -1)
656 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
658 j_c1 = ix_offset(2) + ishft(j+1, -1)
659 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
661 i_c1 = ix_offset(1) + ishft(i+1, -1)
662 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
663 box_c%cc(ijk, iv_to) = box_c%cc(ijk, iv_to) + &
664 c(1) * box_p%cc(i_c1, j_c1, k_c1, iv) + &
665 c(2) * box_p%cc(i_c2, j_c1, k_c1, iv) + &
666 c(3) * box_p%cc(i_c1, j_c2, k_c1, iv) + &
667 c(4) * box_p%cc(i_c1, j_c1, k_c2, iv)
673 k_c1 = ix_offset(3) + ishft(k+1, -1)
674 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
676 j_c1 = ix_offset(2) + ishft(j+1, -1)
677 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
679 i_c1 = ix_offset(1) + ishft(i+1, -1)
680 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
681 c = stencil%v(:, ijk)
682 box_c%cc(ijk, iv_to) = box_c%cc(ijk, iv_to) + &
683 c(1) * box_p%cc(i_c1, j_c1, k_c1, iv) + &
684 c(2) * box_p%cc(i_c2, j_c1, k_c1, iv) + &
685 c(3) * box_p%cc(i_c1, j_c2, k_c1, iv) + &
686 c(4) * box_p%cc(i_c1, j_c1, k_c2, iv)
692 end subroutine stencil_prolong_234
695 subroutine stencil_prolong_248(box_p, box_c, stencil, iv, iv_to, add)
696 type(box_t),
intent(in) :: box_p
697 type(box_t),
intent(inout) :: box_c
698 type(stencil_t),
intent(in) :: stencil
699 integer,
intent(in) :: iv
700 integer,
intent(in) :: iv_to
701 logical,
intent(in) :: add
703 integer :: nc, ix_offset(NDIM), IJK
704 integer :: IJK_(c1), IJK_(c2)
705 real(dp) :: c(2**NDIM)
708 ix_offset = af_get_child_offset(box_c)
709 if (stencil%stype == stencil_sparse) error stop
"sparse not implemented"
710 if (.not. add) box_c%cc(dtimes(1:nc), iv_to) = 0
715 if (stencil%stype == stencil_constant)
then
718 i_c1 = ix_offset(1) + ishft(i+1, -1)
719 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
720 box_c%cc(ijk, iv_to) = box_c%cc(ijk, iv_to) + &
721 c(1) * box_p%cc(i_c1, iv) + &
722 c(2) * box_p%cc(i_c2, iv)
726 c = stencil%v(:, ijk)
727 i_c1 = ix_offset(1) + ishft(i+1, -1)
728 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
729 box_c%cc(ijk, iv_to) = box_c%cc(ijk, iv_to) + &
730 c(1) * box_p%cc(i_c1, iv) + &
731 c(2) * box_p%cc(i_c2, iv)
735 if (stencil%stype == stencil_constant)
then
738 j_c1 = ix_offset(2) + ishft(j+1, -1)
739 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
741 i_c1 = ix_offset(1) + ishft(i+1, -1)
742 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
743 box_c%cc(ijk, iv_to) = box_c%cc(ijk, iv_to) + &
744 c(1) * box_p%cc(i_c1, j_c1, iv) + &
745 c(2) * box_p%cc(i_c2, j_c1, iv) + &
746 c(3) * box_p%cc(i_c1, j_c2, iv) + &
747 c(4) * box_p%cc(i_c2, j_c2, iv)
752 j_c1 = ix_offset(2) + ishft(j+1, -1)
753 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
755 i_c1 = ix_offset(1) + ishft(i+1, -1)
756 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
757 c = stencil%v(:, ijk)
758 box_c%cc(ijk, iv_to) = box_c%cc(ijk, iv_to) + &
759 c(1) * box_p%cc(i_c1, j_c1, iv) + &
760 c(2) * box_p%cc(i_c2, j_c1, iv) + &
761 c(3) * box_p%cc(i_c1, j_c2, iv) + &
762 c(4) * box_p%cc(i_c2, j_c2, iv)
767 if (stencil%stype == stencil_constant)
then
770 k_c1 = ix_offset(3) + ishft(k+1, -1)
771 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
773 j_c1 = ix_offset(2) + ishft(j+1, -1)
774 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
776 i_c1 = ix_offset(1) + ishft(i+1, -1)
777 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
778 box_c%cc(ijk, iv_to) = box_c%cc(ijk, iv_to) + &
779 c(1) * box_p%cc(i_c1, j_c1, k_c1, iv) + &
780 c(2) * box_p%cc(i_c2, j_c1, k_c1, iv) + &
781 c(3) * box_p%cc(i_c1, j_c2, k_c1, iv) + &
782 c(4) * box_p%cc(i_c2, j_c2, k_c1, iv) + &
783 c(5) * box_p%cc(i_c1, j_c1, k_c2, iv) + &
784 c(6) * box_p%cc(i_c2, j_c1, k_c2, iv) + &
785 c(7) * box_p%cc(i_c1, j_c2, k_c2, iv) + &
786 c(8) * box_p%cc(i_c2, j_c2, k_c2, iv)
792 k_c1 = ix_offset(3) + ishft(k+1, -1)
793 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
795 j_c1 = ix_offset(2) + ishft(j+1, -1)
796 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
798 i_c1 = ix_offset(1) + ishft(i+1, -1)
799 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
800 c = stencil%v(:, ijk)
801 box_c%cc(ijk, iv_to) = box_c%cc(ijk, iv_to) + &
802 c(1) * box_p%cc(i_c1, j_c1, k_c1, iv) + &
803 c(2) * box_p%cc(i_c2, j_c1, k_c1, iv) + &
804 c(3) * box_p%cc(i_c1, j_c2, k_c1, iv) + &
805 c(4) * box_p%cc(i_c2, j_c2, k_c1, iv) + &
806 c(5) * box_p%cc(i_c1, j_c1, k_c2, iv) + &
807 c(6) * box_p%cc(i_c2, j_c1, k_c2, iv) + &
808 c(7) * box_p%cc(i_c1, j_c2, k_c2, iv) + &
809 c(8) * box_p%cc(i_c2, j_c2, k_c2, iv)
815 end subroutine stencil_prolong_248
818 subroutine af_stencil_gsrb_box(box, key, redblack, iv, i_rhs)
819 type(box_t),
intent(inout) :: box
820 integer,
intent(in) :: key
821 integer,
intent(in) :: redblack
822 integer,
intent(in) :: iv
823 integer,
intent(in) :: i_rhs
826 i = af_stencil_index(box, key)
827 if (i == af_stencil_none) error stop
"Stencil not stored"
829 select case (box%stencils(i)%shape)
830 case (af_stencil_357)
831 call stencil_gsrb_357(box, box%stencils(i), redblack, iv, i_rhs)
833 error stop
"Unknown stencil"
835 end subroutine af_stencil_gsrb_box
838 subroutine stencil_gsrb_357(box, stencil, redblack, iv, i_rhs)
839 type(box_t),
intent(inout) :: box
840 type(stencil_t),
intent(in) :: stencil
841 integer,
intent(in) :: redblack
842 integer,
intent(in) :: iv
843 integer,
intent(in) :: i_rhs
845 real(dp) :: c(2*NDIM+1), inv_c1
846 integer :: IJK, i0, nc
848 real(dp) :: rfac(2, box%n_cell), c_cyl(2*NDIM+1)
849 real(dp) :: cc_cyl(2*NDIM+1, box%n_cell), inv_cc1(box%n_cell)
852 if (stencil%stype == stencil_sparse) error stop
"sparse not implemented"
855 associate(cc => box%cc, nc => box%n_cell)
856 if (
allocated(stencil%bc_correction))
then
857 cc(dtimes(1:nc), i_rhs) = cc(dtimes(1:nc), i_rhs) + &
858 stencil%bc_correction
862 i0 = 2 - iand(redblack, 1)
863 if (stencil%stype == stencil_constant)
then
868 cc(ijk, iv) = (cc(ijk, i_rhs) &
869 - c(2) * cc(i-1, iv) &
870 - c(3) * cc(i+1, iv)) * inv_c1
874 c = stencil%v(:, ijk)
875 cc(ijk, iv) = (cc(ijk, i_rhs) &
876 - c(2) * cc(i-1, iv) &
877 - c(3) * cc(i+1, iv)) / c(1)
881 if (stencil%cylindrical_gradient)
then
884 call af_cyl_flux_factors(box, rfac)
886 if (stencil%stype == stencil_constant)
then
891 cc_cyl(2:3, i) = rfac(1:2, i) * c(2:3)
892 cc_cyl(1, i) = c(1) - (cc_cyl(2, i) - c(2)) &
893 - (cc_cyl(3, i) - c(3))
894 cc_cyl(4:, i) = c(4:)
895 inv_cc1(i) = 1 / cc_cyl(1, i)
899 i0 = 2 - iand(ieor(redblack, j), 1)
901 cc(ijk, iv) = (cc(ijk, i_rhs) &
902 - cc_cyl(2, i) * cc(i-1, j, iv) &
903 - cc_cyl(3, i) * cc(i+1, j, iv) &
904 - cc_cyl(4, i) * cc(i, j-1, iv) &
905 - cc_cyl(5, i) * cc(i, j+1, iv)) * inv_cc1(i)
911 i0 = 2 - iand(ieor(redblack, j), 1)
913 c = stencil%v(:, ijk)
914 c_cyl(2:3) = rfac(1:2, i) * c(2:3)
915 c_cyl(1) = c(1) - (c_cyl(2) - c(2)) - (c_cyl(3) - c(3))
918 cc(ijk, iv) = (cc(ijk, i_rhs) &
919 - c_cyl(2) * cc(i-1, j, iv) &
920 - c_cyl(3) * cc(i+1, j, iv) &
921 - c_cyl(4) * cc(i, j-1, iv) &
922 - c_cyl(5) * cc(i, j+1, iv)) / c_cyl(1)
927 if (stencil%stype == stencil_constant)
then
932 i0 = 2 - iand(ieor(redblack, j), 1)
934 cc(ijk, iv) = (cc(ijk, i_rhs) &
935 - c(2) * cc(i-1, j, iv) &
936 - c(3) * cc(i+1, j, iv) &
937 - c(4) * cc(i, j-1, iv) &
938 - c(5) * cc(i, j+1, iv)) * inv_c1
943 i0 = 2 - iand(ieor(redblack, j), 1)
945 c = stencil%v(:, ijk)
946 cc(ijk, iv) = (cc(ijk, i_rhs) &
947 - c(2) * cc(i-1, j, iv) &
948 - c(3) * cc(i+1, j, iv) &
949 - c(4) * cc(i, j-1, iv) &
950 - c(5) * cc(i, j+1, iv)) / c(1)
956 if (stencil%stype == stencil_constant)
then
962 i0 = 2 - iand(ieor(redblack, k+j), 1)
964 cc(ijk, iv) = (cc(ijk, i_rhs) &
965 - c(2) * cc(i-1, j, k, iv) &
966 - c(3) * cc(i+1, j, k, iv) &
967 - c(4) * cc(i, j-1, k, iv) &
968 - c(5) * cc(i, j+1, k, iv) &
969 - c(6) * cc(i, j, k-1, iv) &
970 - c(7) * cc(i, j, k+1, iv)) * inv_c1
977 i0 = 2 - iand(ieor(redblack, k+j), 1)
979 c = stencil%v(:, ijk)
980 cc(ijk, iv) = (cc(ijk, i_rhs) &
981 - c(2) * cc(i-1, j, k, iv) &
982 - c(3) * cc(i+1, j, k, iv) &
983 - c(4) * cc(i, j-1, k, iv) &
984 - c(5) * cc(i, j+1, k, iv) &
985 - c(6) * cc(i, j, k-1, iv) &
986 - c(7) * cc(i, j, k+1, iv)) / c(1)
993 if (
allocated(stencil%bc_correction))
then
994 cc(dtimes(1:nc), i_rhs) = cc(dtimes(1:nc), i_rhs) - &
995 stencil%bc_correction
998 end subroutine stencil_gsrb_357
1001 subroutine af_stencil_try_constant(box, ix, abs_tol, success)
1002 type(box_t),
intent(inout) :: box
1003 integer,
intent(in) :: ix
1004 real(dp),
intent(in) :: abs_tol
1006 integer :: ijk, nc, n_coeff
1008 if (box%stencils(ix)%stype == stencil_sparse) &
1009 error stop
"sparse not implemented"
1010 if (.not.
allocated(box%stencils(ix)%v)) &
1011 error stop
"No variable stencil present"
1018 if (any(abs(box%stencils(ix)%v(:, ijk) - &
1019 box%stencils(ix)%v(:, dtimes(1))) > abs_tol))
return
1022 box%stencils(ix)%stype = stencil_constant
1023 n_coeff =
size(box%stencils(ix)%v, 1)
1024 allocate(box%stencils(ix)%c(n_coeff))
1025 box%stencils(ix)%c = box%stencils(ix)%v(:, dtimes(1))
1026 deallocate(box%stencils(ix)%v)
1028 end subroutine af_stencil_try_constant
1031 subroutine af_stencil_get_box(box, key, v)
1032 type(box_t),
intent(inout) :: box
1033 integer,
intent(in) :: key
1035 real(dp),
intent(inout) :: v(:, dtimes(:))
1038 i = af_stencil_index(box, key)
1039 if (i == af_stencil_none) error stop
"Stencil not stored"
1041 select case (box%stencils(i)%shape)
1042 case (af_stencil_357)
1043 call stencil_get_357(box, box%stencils(i), v)
1045 error stop
"Unknown stencil"
1047 end subroutine af_stencil_get_box
1050 subroutine stencil_get_357(box, stencil, v)
1051 type(box_t),
intent(inout) :: box
1052 type(stencil_t),
intent(in) :: stencil
1054 real(dp),
intent(inout) :: v(:, DTIMES(:))
1056 real(dp) :: c_cyl(size(v, 1)), rfac(2, box%n_cell)
1062 if (
size(v, 1) /= af_stencil_sizes(stencil%shape)) &
1063 error stop
"Argument v has wrong size"
1065 if (stencil%stype == stencil_constant)
then
1067 v(:, ijk) = stencil%c
1074 if (stencil%cylindrical_gradient)
then
1077 call af_cyl_flux_factors(box, rfac)
1079 c_cyl(2:3) = rfac(1:2, i) * v(2:3, ijk)
1080 c_cyl(1) = v(1, ijk) - (c_cyl(2) - v(2, ijk)) &
1081 - (c_cyl(3) - v(3, ijk))
1082 c_cyl(4:) = v(4:, ijk)
1087 end subroutine stencil_get_357
Subroutine for setting a stencil on a box.
This module contains functionality for dealing with numerical stencils.
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,...
Type for storing a numerical stencil for a box.