4 #include "cpp_macros.h"
5 use iso_c_binding,
only: c_ptr
11 integer,
parameter :: dp = kind(0.0d0)
14 integer,
parameter :: af_max_lvl = 30
17 integer,
parameter :: af_min_lvl = 1
20 integer,
parameter :: af_max_num_vars = 1024
23 integer,
parameter :: af_rm_ref = -1
26 integer,
parameter :: af_keep_ref = 0
29 integer,
parameter :: af_do_ref = 1
32 integer,
parameter :: af_derefine = -2
35 integer,
parameter :: af_refine = 2
38 integer,
parameter :: af_no_box = 0
41 integer,
parameter :: af_phys_boundary = -1
45 integer,
parameter :: af_init_tag = -huge(1)
48 integer,
parameter :: af_xyz = 1
51 integer,
parameter :: af_cyl = 2
54 character(len=*),
parameter :: af_coord_names(2) = &
55 [
"Cartesian ",
"Cylindrical"]
58 integer,
parameter :: af_bc_dirichlet = -10
61 integer,
parameter :: af_bc_neumann = -11
64 integer,
parameter :: af_bc_continuous = -12
69 integer,
parameter :: af_bc_dirichlet_copy = -13
72 integer,
parameter :: af_nlen = 20
77 integer,
allocatable :: ids(:)
78 integer,
allocatable :: leaves(:)
79 integer,
allocatable :: parents(:)
84 integer,
allocatable :: add(:)
91 integer,
allocatable :: rm(:)
97 integer,
parameter :: af_num_children = 2
100 integer,
parameter :: af_child_dix(1, 2) = reshape([0,1], [1,2])
102 integer,
parameter :: af_child_adj_nb(1, 2) = reshape([1,2], [1,2])
104 logical,
parameter :: af_child_low(1, 2) = reshape([.true., .false.], [1, 2])
108 integer,
parameter :: af_num_neighbors = 2
110 integer,
parameter :: af_neighb_lowx = 1
112 integer,
parameter :: af_neighb_highx = 2
115 integer,
parameter :: af_neighb_dix(1, 2) = reshape([-1,1], [1,2])
117 logical,
parameter :: af_neighb_low(2) = [.true., .false.]
119 integer,
parameter :: af_low_neighbs(1) = [1]
121 integer,
parameter :: af_high_neighbs(1) = [2]
123 integer,
parameter :: af_neighb_high_pm(2) = [-1, 1]
126 integer,
parameter :: af_neighb_rev(2) = [2, 1]
128 integer,
parameter :: af_neighb_dim(2) = [1, 1]
131 integer,
parameter :: af_num_children = 4
134 integer,
parameter :: af_child_dix(2, 4) = reshape([0,0,1,0,0,1,1,1], [2,4])
136 integer,
parameter :: af_child_adj_nb(2, 4) = reshape([1,3,2,4,1,2,3,4], [2,4])
138 logical,
parameter :: af_child_low(2, 4) = reshape([.true., .true., &
139 .false., .true., .true., .false., .false., .false.], [2, 4])
142 integer,
parameter :: af_num_neighbors = 4
144 integer,
parameter :: af_neighb_lowx = 1
146 integer,
parameter :: af_neighb_highx = 2
148 integer,
parameter :: af_neighb_lowy = 3
150 integer,
parameter :: af_neighb_highy = 4
153 integer,
parameter :: af_neighb_dix(2, 4) = reshape([-1,0,1,0,0,-1,0,1], [2,4])
155 logical,
parameter :: af_neighb_low(4) = [.true., .false., .true., .false.]
157 integer,
parameter :: af_low_neighbs(2) = [1, 3]
159 integer,
parameter :: af_high_neighbs(2) = [2, 4]
161 integer,
parameter :: af_neighb_high_pm(4) = [-1, 1, -1, 1]
164 integer,
parameter :: af_neighb_rev(4) = [2, 1, 4, 3]
166 integer,
parameter :: af_neighb_dim(4) = [1, 1, 2, 2]
169 integer,
parameter :: af_num_children = 8
172 integer,
parameter :: af_child_dix(3, 8) = reshape( &
173 [0,0,0, 1,0,0, 0,1,0, 1,1,0, &
174 0,0,1, 1,0,1, 0,1,1, 1,1,1], [3,8])
176 integer,
parameter :: af_child_adj_nb(4, 6) = reshape( &
177 [1,3,5,7, 2,4,6,8, 1,2,5,6, 3,4,7,8, 1,2,3,4, 5,6,7,8], [4,6])
179 logical,
parameter :: af_child_low(3, 8) = reshape([ &
180 .true., .true., .true., .false., .true., .true., &
181 .true., .false., .true., .false., .false., .true., &
182 .true., .true., .false., .false., .true., .false., &
183 .true., .false., .false., .false., .false., .false.], [3, 8])
186 integer,
parameter :: af_num_neighbors = 6
188 integer,
parameter :: af_neighb_lowx = 1
190 integer,
parameter :: af_neighb_highx = 2
192 integer,
parameter :: af_neighb_lowy = 3
194 integer,
parameter :: af_neighb_highy = 4
196 integer,
parameter :: af_neighb_lowz = 5
198 integer,
parameter :: af_neighb_highz = 6
200 integer,
parameter :: af_neighb_dix(3, 6) = reshape( &
201 [-1,0,0, 1,0,0, 0,-1,0, 0,1,0, 0,0,-1, 0,0,1], [3,6])
203 logical,
parameter :: af_neighb_low(6) = &
204 [.true., .false., .true., .false., .true., .false.]
206 integer,
parameter :: af_low_neighbs(3) = [1, 3, 5]
208 integer,
parameter :: af_high_neighbs(3) = [2, 4, 6]
210 integer,
parameter :: af_neighb_high_pm(6) = [-1, 1, -1, 1, -1, 1]
212 integer,
parameter :: af_neighb_rev(6) = [2, 1, 4, 3, 6, 5]
214 integer,
parameter :: af_neighb_dim(6) = [1, 1, 2, 2, 3, 3]
217 integer,
parameter :: af_num_edges = 12
219 integer,
parameter :: af_edge_dim(12) = &
220 [1,1,1,1, 2,2,2,2, 3,3,3,3]
222 integer,
parameter :: af_edge_dir(3, 12) = reshape( &
223 [0,-1,-1, 0,1,-1, 0,-1,1, 0,1,1, &
224 -1,0,-1, 1,0,-1, -1,0,1, 1,0,1, &
225 -1,-1,0, 1,-1,0, -1,1,0, 1,1,0], [3, 12])
227 integer,
parameter :: af_nb_adj_edge(2, 12) = reshape( &
228 [3,5, 4,5, 3,6, 4,6, &
229 1,5, 2,5, 1,6, 2,6, &
230 1,3, 2,3, 1,4, 2,4], [2,12])
232 integer,
parameter :: af_edge_min_ix(3, 12) = reshape( &
233 [0,0,0, 0,1,0, 0,0,1, 0,1,1, &
234 0,0,0, 1,0,0, 0,0,1, 1,0,1, &
235 0,0,0, 1,0,0, 0,1,0, 1,1,0], [3,12])
253 integer :: prolong_limiter = -1
257 integer,
parameter :: af_stencil_none = 0
262 integer :: key = af_stencil_none
264 integer :: shape = af_stencil_none
266 integer :: stype = -1
268 logical :: cylindrical_gradient = .false.
270 real(dp),
allocatable :: c(:)
272 real(dp),
allocatable :: v(:, dtimes(:))
275 real(dp),
allocatable :: f(dtimes(:))
277 real(dp),
allocatable :: bc_correction(dtimes(:))
279 integer,
allocatable :: sparse_ix(:, :)
281 real(dp),
allocatable :: sparse_v(:, :)
288 logical :: in_use=.false.
289 integer :: tag=af_init_tag
293 integer :: children(af_num_children)
295 integer :: neighbors(af_num_neighbors)
297 integer :: neighbor_mat(dtimes(-1:1))
300 real(dp) :: r_min(ndim)
302 real(dp),
allocatable :: cc(dtimes(:), :)
303 real(dp),
allocatable :: fc(dtimes(:), :, :)
308 integer,
allocatable :: bc_index_to_nb(:)
310 integer :: nb_to_bc_index(af_num_neighbors)
312 integer,
allocatable :: bc_type(:, :)
314 real(dp),
allocatable :: bc_val(:, :, :)
316 real(dp),
allocatable :: bc_coords(:, :, :)
319 integer :: n_stencils = 0
327 logical :: ready = .false.
329 integer :: highest_lvl = 0
330 integer :: highest_id = 0
332 integer :: n_var_cell = 0
333 integer :: n_var_face = 0
335 integer :: coarse_grid_size(ndim) = -1
336 logical :: periodic(ndim) = .false.
337 real(dp) :: r_base(ndim)
338 real(dp) :: dr_base(ndim)
341 character(len=af_nlen) :: cc_names(af_max_num_vars)
344 character(len=af_nlen) :: fc_names(af_max_num_vars)
347 integer :: cc_num_copies(af_max_num_vars) = 1
350 logical :: cc_write_output(af_max_num_vars) = .true.
353 logical :: cc_write_binary(af_max_num_vars) = .true.
356 logical :: fc_write_binary(af_max_num_vars) = .true.
362 integer :: n_stencil_keys_stored = 0
365 logical :: has_cc_method(af_max_num_vars) = .false.
368 integer,
allocatable :: cc_auto_vars(:)
371 integer,
allocatable :: cc_func_vars(:)
374 type(
lvl_t) :: lvls(af_min_lvl:af_max_lvl)
377 type(
box_t),
allocatable :: boxes(:)
380 integer,
allocatable :: removed_ids(:)
383 integer :: n_removed_ids = 0
386 integer :: mg_i_eps = -1
389 integer :: mg_i_lsf = -1
392 integer :: mg_current_operator_mask = -1
398 integer :: ix(ndim) = -1
405 type(
box_t),
intent(in) :: box
407 integer,
intent(out) :: cell_flags(DTIMES(box%n_cell))
413 type(
box_t),
intent(inout) :: box
419 type(
box_t),
intent(inout) :: box
420 real(dp),
intent(in) :: rarg(:)
426 type(
box_t),
intent(inout) :: boxes(:)
427 integer,
intent(in) :: id
433 type(
box_t),
intent(inout) :: boxes(:)
434 integer,
intent(in) :: id
435 real(dp),
intent(in) :: rarg(:)
441 type(
af_t),
intent(inout) :: tree
442 integer,
intent(in) :: id
448 type(
af_t),
intent(inout) :: tree
449 integer,
intent(in) :: id
450 real(dp),
intent(in) :: rarg(:)
456 type(
box_t),
intent(inout) :: boxes(:)
457 integer,
intent(in) :: id
458 integer,
intent(in) :: nb
459 integer,
intent(in) :: iv
460 integer,
intent(in) :: op_mask
466 type(
box_t),
intent(in) :: box
467 integer,
intent(in) :: nb
468 integer,
intent(in) :: iv
469 real(dp),
intent(in) :: coords(NDIM, box%n_cell**(NDIM-1))
470 real(dp),
intent(out) :: bc_val(box%n_cell**(NDIM-1))
471 integer,
intent(out) :: bc_type
479 type(
box_t),
intent(inout) :: box
480 integer,
intent(in) :: nb
481 integer,
intent(in) :: iv
482 integer,
intent(in) :: n_gc
484 real(dp),
intent(inout),
optional :: &
485 cc(DTIMES(1-n_gc:box%n_cell+n_gc))
493 type(
box_t),
intent(inout) :: box
494 integer,
intent(in) :: iv
500 type(
box_t),
intent(in) :: box_p
501 type(
box_t),
intent(inout) :: box_c
502 integer,
intent(in) :: iv
503 integer,
intent(in),
optional :: iv_to
504 logical,
intent(in),
optional :: add
505 integer,
intent(in),
optional :: limiter
511 type(
box_t),
intent(in) :: box_c
512 type(
box_t),
intent(inout) :: box_p
513 integer,
intent(in) :: ivs(:)
515 logical,
intent(in),
optional :: use_geometry
523 integer,
parameter :: mg_normal_operator = 1
524 integer,
parameter :: mg_lsf_operator = 2
525 integer,
parameter :: mg_eps_operator = 3
526 integer,
parameter :: mg_auto_operator = 4
528 integer,
parameter :: mg_normal_box = 0
529 integer,
parameter :: mg_lsf_box = 1
530 integer,
parameter :: mg_veps_box = 2
531 integer,
parameter :: mg_ceps_box = 4
533 integer,
parameter :: mg_prolong_linear = 17
534 integer,
parameter :: mg_prolong_sparse = 18
535 integer,
parameter :: mg_prolong_auto = 19
538 integer,
parameter :: mg_lsf_distance_key = 31
540 integer,
parameter :: mg_lsf_mask_key = 32
543 integer,
parameter :: mg_cycle_down = 1
544 integer,
parameter :: mg_cycle_up = 3
548 type(c_ptr) :: matrix
551 type(c_ptr) :: solver
555 real(dp),
allocatable :: bc_to_rhs(:, :, :)
558 real(dp),
allocatable :: lsf_fac(dtimes(:), :)
560 integer :: symmetric = 1
561 integer :: solver_type = -1
562 integer :: max_iterations = 50
563 integer :: n_cycle_down = 1
564 integer :: n_cycle_up = 1
565 real(dp) :: tolerance = 1e-6_dp
568 integer :: min_unknowns_for_openmp = 10*1000
574 integer :: i_phi = -1
576 integer :: i_rhs = -1
578 integer :: i_tmp = -1
581 integer :: operator_mask = -1
583 integer :: i_eps = -1
585 integer :: i_lsf = -1
588 integer :: n_cycle_down = 2
590 integer :: n_cycle_up = 2
593 logical :: initialized = .false.
595 logical :: use_corners = .false.
597 logical :: subtract_mean = .false.
600 real(dp) :: helmholtz_lambda = 0.0_dp
604 real(dp) :: lsf_boundary_value = 0.0_dp
607 real(dp) :: lsf_gradient_safety_factor = 1.5_dp
610 real(dp) :: lsf_length_scale = 1e100_dp
613 real(dp) :: lsf_tol = 1e-8_dp
616 real(dp) :: lsf_min_rel_distance = 1e-4_dp
619 logical :: lsf_use_custom_prolongation = .false.
628 procedure(
mg_func_lsf),
pointer,
nopass :: lsf_boundary_function => null()
637 procedure(
mg_box_op),
pointer,
nopass :: box_op => null()
640 integer :: operator_type = mg_auto_operator
643 integer :: operator_key = af_stencil_none
646 integer :: prolongation_type = mg_prolong_auto
649 integer :: prolongation_key = af_stencil_none
671 type(
box_t),
intent(inout) :: box
672 type(
mg_t),
intent(in) :: mg
673 integer,
intent(in) :: i_out
679 type(
box_t),
intent(inout) :: box
680 type(
mg_t),
intent(in) :: mg
681 integer,
intent(in) :: redblack_cntr
686 type(
box_t),
intent(inout) :: box_c
687 type(
box_t),
intent(in) :: box_p
688 type(
mg_t),
intent(in) :: mg
693 type(
box_t),
intent(in) :: box_c
694 type(
box_t),
intent(inout) :: box_p
695 integer,
intent(in) :: iv
696 type(
mg_t),
intent(in) :: mg
701 type(
box_t),
intent(in) :: box
702 type(
mg_t),
intent(in) :: mg
703 real(dp),
intent(inout) :: stencil(2*NDIM+1, DTIMES(box%n_cell))
704 real(dp),
intent(inout) :: bc_to_rhs(box%n_cell**(NDIM-1), af_num_neighbors)
705 real(dp),
intent(inout) :: lsf_fac(DTIMES(box%n_cell))
711 real(dp),
intent(in) :: rr(ndim)
718 real(dp),
intent(in) :: a(ndim)
719 real(dp),
intent(in) :: b(ndim)
720 type(
mg_t),
intent(in) :: mg
727 integer function af_get_max_threads()
728 use omp_lib,
only: omp_get_max_threads
729 af_get_max_threads = omp_get_max_threads()
730 end function af_get_max_threads
733 subroutine af_print_info(tree)
734 type(
af_t),
intent(in) :: tree
735 character(len=15) :: fmt_string
737 if (.not.
allocated(tree%boxes))
then
738 print *,
"af_init has not been called for this tree"
739 else if (.not. tree%ready)
then
740 print *,
"af_set_base has not been called for this tree"
743 write(*,
"(A)")
" *** af_print_info(tree) ***"
744 write(*,
"(A,I10)")
" Current maximum level: ", tree%highest_lvl
745 write(*,
"(A,I10)")
" Number of boxes used: ", af_num_boxes_used(tree)
746 write(*,
"(A,I10)")
" Number of leaves used: ", af_num_leaves_used(tree)
747 write(*,
"(A,I10)")
" Memory limit(boxes): ", tree%box_limit
748 write(*,
"(A,E10.2)")
" Memory limit(GByte): ", &
749 tree%box_limit * 0.5_dp**30 * &
750 af_box_bytes(tree%n_cell, tree%n_var_cell, tree%n_var_face)
751 write(*,
"(A,I10)")
" Highest id in box list: ", tree%highest_id
752 write(*,
"(A,I10)")
" Size of box list: ",
size(tree%boxes)
753 write(*,
"(A,I10)")
" Box size (cells): ", tree%n_cell
754 write(*,
"(A,I10)")
" Number of cc variables: ", tree%n_var_cell
755 write(*,
"(A,I10)")
" Number of fc variables: ", tree%n_var_face
756 write(*,
"(A,A15)")
" Type of coordinates: ", &
757 af_coord_names(tree%coord_t)
758 write(fmt_string,
"(A,I0,A)")
"(A,", ndim,
"E10.2)"
759 write(*, fmt_string)
" min. coords: ", tree%r_base
760 write(*, fmt_string)
" dr at level one: ", tree%dr_base
761 write(*,
"(A,E10.2)")
" minval(dr): ", af_min_dr(tree)
764 end subroutine af_print_info
766 pure function af_box_bytes(n_cell, n_var_cell, n_var_face)
result(box_bytes)
767 integer,
intent(in) :: n_cell
768 integer,
intent(in) :: n_var_cell
769 integer,
intent(in) :: n_var_face
771 type(
box_t) :: dummy_box
773 box_bytes = 8 * n_var_cell * (n_cell + 2)**ndim + &
774 8 * n_var_face * (n_cell + 1) * n_cell**(ndim-1) + &
775 int(storage_size(dummy_box) / 8)
776 end function af_box_bytes
778 pure function af_num_boxes_used(tree)
result(n_boxes)
779 type(
af_t),
intent(in) :: tree
780 integer :: n_boxes, lvl
783 do lvl = 1, tree%highest_lvl
784 n_boxes = n_boxes +
size(tree%lvls(lvl)%ids)
786 end function af_num_boxes_used
788 pure function af_num_leaves_used(tree)
result(n_boxes)
789 type(
af_t),
intent(in) :: tree
790 integer :: n_boxes, lvl
793 do lvl = 1, tree%highest_lvl
794 n_boxes = n_boxes +
size(tree%lvls(lvl)%leaves)
796 end function af_num_leaves_used
798 pure function af_num_cells_used(tree)
result(n_cells)
799 type(
af_t),
intent(in) :: tree
802 n_cells = af_num_leaves_used(tree) * tree%n_cell**ndim
803 end function af_num_cells_used
805 pure function af_total_volume(tree)
result(vol)
806 type(
af_t),
intent(in) :: tree
809 real(dp) :: r0, r1, box_len(ndim)
810 real(dp),
parameter :: pi = acos(-1.0_dp)
812 box_len = tree%n_cell * tree%dr_base
814 if (ndim == 2 .and. tree%coord_t == af_cyl)
then
816 do i = 1,
size(tree%lvls(1)%ids)
817 id = tree%lvls(1)%ids(i)
818 r0 = tree%boxes(id)%r_min(1)
820 vol = vol + pi * (r1**2 - r0**2) * box_len(ndim)
823 vol =
size(tree%lvls(1)%ids) * product(box_len)
825 end function af_total_volume
828 elemental logical function af_has_children(box)
829 type(
box_t),
intent(in) :: box
833 af_has_children = (box%children(1) /= af_no_box)
834 end function af_has_children
840 pure function af_is_phys_boundary(boxes, id, nbs)
result(boundary)
841 type(
box_t),
intent(in) :: boxes(:)
842 integer,
intent(in) :: id
843 integer,
intent(in) :: nbs(:)
844 logical :: boundary(size(nbs))
845 integer :: n, nb, p_id, nb_id, dim, dix
849 nb_id = boxes(id)%neighbors(nb)
851 if (nb_id < af_no_box)
then
854 dim = af_neighb_dim(nb)
856 if (nb_id == af_no_box)
then
859 p_id = boxes(id)%parent
860 nb_id = boxes(p_id)%neighbors(nb)
861 dix = boxes(nb_id)%ix(dim) - boxes(p_id)%ix(dim)
864 dix = boxes(nb_id)%ix(dim) - boxes(id)%ix(dim)
867 if (dix /= af_neighb_high_pm(nb))
then
872 boundary(n) = .false.
877 end function af_is_phys_boundary
881 pure logical function af_is_ref_boundary(boxes, id, nb)
882 type(
box_t),
intent(in) :: boxes(:)
883 integer,
intent(in) :: id
884 integer,
intent(in) :: nb
887 af_is_ref_boundary = .false.
888 nb_id = boxes(id)%neighbors(nb)
890 if (nb_id == af_no_box)
then
891 af_is_ref_boundary = .true.
892 else if (nb_id > af_no_box)
then
893 if (.not. af_has_children(boxes(id)) .and. &
894 af_has_children(boxes(nb_id)))
then
895 af_is_ref_boundary = .true.
898 end function af_is_ref_boundary
903 pure function af_get_child_offset(box, nb)
result(ix_offset)
904 type(
box_t),
intent(in) :: box
905 integer,
intent(in),
optional :: nb
906 integer :: ix_offset(ndim)
908 ix_offset = iand(box%ix-1, 1) * ishft(box%n_cell, -1)
909 if (
present(nb)) ix_offset = ix_offset - af_neighb_dix(:, nb) * box%n_cell
910 end function af_get_child_offset
913 pure function af_get_ix_on_parent(box, ix)
result(p_ix)
914 type(
box_t),
intent(in) :: box
915 integer,
intent(in) :: ix(ndim)
916 integer :: p_ix(ndim)
917 p_ix = af_get_child_offset(box) + ishft(ix+1, -1)
918 end function af_get_ix_on_parent
921 pure function af_get_ix_on_neighb(box, ix, nb)
result(nb_ix)
922 type(
box_t),
intent(in) :: box
923 integer,
intent(in) :: ix(ndim)
924 integer,
intent(in) :: nb
925 integer :: nb_ix(ndim), nb_dim
927 nb_dim = af_neighb_dim(nb)
929 nb_ix(nb_dim) = nb_ix(nb_dim) - af_neighb_high_pm(nb) * box%n_cell
930 end function af_get_ix_on_neighb
933 pure function af_neighb_offset(nbs)
result(dix)
934 integer,
intent(in) :: nbs(:)
935 integer :: n, dim, dix(ndim)
939 dim = af_neighb_dim(nbs(n))
940 dix(dim) = dix(dim) + af_neighb_high_pm(nbs(n))
942 end function af_neighb_offset
945 subroutine af_get_index_bc_inside(nb, nc, n_gc, lo, hi)
946 integer,
intent(in) :: nb
947 integer,
intent(in) :: nc
948 integer,
intent(in) :: n_gc
949 integer,
intent(out) :: lo(NDIM)
950 integer,
intent(out) :: hi(NDIM)
954 nb_dim = af_neighb_dim(nb)
957 if (af_neighb_low(nb))
then
961 lo(nb_dim) = nc - n_gc + 1
964 end subroutine af_get_index_bc_inside
967 subroutine af_get_index_bc_outside(nb, nc, n_gc, lo, hi)
968 integer,
intent(in) :: nb
969 integer,
intent(in) :: nc
970 integer,
intent(in) :: n_gc
971 integer,
intent(out) :: lo(NDIM)
972 integer,
intent(out) :: hi(NDIM)
976 nb_dim = af_neighb_dim(nb)
979 if (af_neighb_low(nb))
then
980 lo(nb_dim) = 1 - n_gc
984 hi(nb_dim) = nc + n_gc
986 end subroutine af_get_index_bc_outside
989 subroutine af_get_index_bface_inside(nb, nc, n_gc, lo, hi)
990 integer,
intent(in) :: nb
991 integer,
intent(in) :: nc
992 integer,
intent(in) :: n_gc
993 integer,
intent(out) :: lo(NDIM)
994 integer,
intent(out) :: hi(NDIM)
998 nb_dim = af_neighb_dim(nb)
1001 if (af_neighb_low(nb))
then
1005 lo(nb_dim) = nc - n_gc + 2
1008 end subroutine af_get_index_bface_inside
1012 pure integer function af_ix_to_ichild(ix)
1013 integer,
intent(in) :: ix(ndim)
1016 af_ix_to_ichild = 2 - iand(ix(1), 1)
1018 af_ix_to_ichild = 4 - 2 * iand(ix(2), 1) - iand(ix(1), 1)
1021 8 - 4 * iand(ix(3), 1) - 2 * iand(ix(2), 1) - iand(ix(1), 1)
1023 end function af_ix_to_ichild
1027 pure function af_cc_ix(box, r)
result(cc_ix)
1028 type(
box_t),
intent(in) :: box
1029 real(dp),
intent(in) :: r(ndim)
1030 integer :: cc_ix(ndim)
1031 cc_ix = ceiling((r - box%r_min) / box%dr)
1032 end function af_cc_ix
1035 pure function af_r_cc(box, cc_ix)
result(r)
1036 type(
box_t),
intent(in) :: box
1037 integer,
intent(in) :: cc_ix(ndim)
1039 r = box%r_min + (cc_ix-0.5_dp) * box%dr
1040 end function af_r_cc
1043 pure function af_r_fc(box, dim, fc_ix)
result(r)
1044 type(
box_t),
intent(in) :: box
1045 integer,
intent(in) :: dim
1046 integer,
intent(in) :: fc_ix(ndim)
1048 r = box%r_min + (fc_ix-0.5_dp) * box%dr
1049 r(dim) = r(dim) - 0.5_dp * box%dr(dim)
1050 end function af_r_fc
1053 pure function af_rr_cc(box, cc_ix)
result(r)
1054 type(
box_t),
intent(in) :: box
1055 real(dp),
intent(in) :: cc_ix(ndim)
1057 r = box%r_min + (cc_ix-0.5_dp) * box%dr
1058 end function af_rr_cc
1061 pure function af_r_center(box)
result(r_center)
1062 type(
box_t),
intent(in) :: box
1063 real(dp) :: r_center(ndim)
1064 r_center = box%r_min + 0.5_dp * box%n_cell * box%dr
1065 end function af_r_center
1068 pure function af_min_dr(tree)
result(dr)
1069 type(
af_t),
intent(in) :: tree
1071 dr = minval(af_lvl_dr(tree, tree%highest_lvl))
1072 end function af_min_dr
1075 pure function af_lvl_dr(tree, lvl)
result(dr)
1076 type(
af_t),
intent(in) :: tree
1077 integer,
intent(in) :: lvl
1078 real(dp) :: dr(ndim)
1079 dr = tree%dr_base * 0.5_dp**(lvl-1)
1080 end function af_lvl_dr
1082 subroutine af_set_box_gc(box, nb, iv, gc_scalar, gc_array)
1083 type(
box_t),
intent(inout) :: box
1084 integer,
intent(in) :: nb
1085 integer,
intent(in) :: iv
1086 real(dp),
optional,
intent(in) :: gc_scalar
1088 real(dp),
optional,
intent(in) :: gc_array(1)
1090 real(dp),
optional,
intent(in) :: gc_array(box%n_cell)
1093 real(dp),
optional,
intent(in) :: gc_array(box%n_cell, box%n_cell)
1099 if (
present(gc_array))
then
1102 case (af_neighb_lowx)
1103 box%cc(0, iv) = gc_array(1)
1104 case (af_neighb_highx)
1105 box%cc(nc+1, iv) = gc_array(1)
1107 case (af_neighb_lowx)
1108 box%cc(0, 1:nc, iv) = gc_array
1109 case (af_neighb_highx)
1110 box%cc(nc+1, 1:nc, iv) = gc_array
1111 case (af_neighb_lowy)
1112 box%cc(1:nc, 0, iv) = gc_array
1113 case (af_neighb_highy)
1114 box%cc(1:nc, nc+1, iv) = gc_array
1116 case (af_neighb_lowx)
1117 box%cc(0, 1:nc, 1:nc, iv) = gc_array
1118 case (af_neighb_highx)
1119 box%cc(nc+1, 1:nc, 1:nc, iv) = gc_array
1120 case (af_neighb_lowy)
1121 box%cc(1:nc, 0, 1:nc, iv) = gc_array
1122 case (af_neighb_highy)
1123 box%cc(1:nc, nc+1, 1:nc, iv) = gc_array
1124 case (af_neighb_lowz)
1125 box%cc(1:nc, 1:nc, 0, iv) = gc_array
1126 case (af_neighb_highz)
1127 box%cc(1:nc, 1:nc, nc+1, iv) = gc_array
1130 else if (
present(gc_scalar))
then
1133 case (af_neighb_lowx)
1134 box%cc(0, iv) = gc_scalar
1135 case (af_neighb_highx)
1136 box%cc(nc+1, iv) = gc_scalar
1138 case (af_neighb_lowx)
1139 box%cc(0, 1:nc, iv) = gc_scalar
1140 case (af_neighb_highx)
1141 box%cc(nc+1, 1:nc, iv) = gc_scalar
1142 case (af_neighb_lowy)
1143 box%cc(1:nc, 0, iv) = gc_scalar
1144 case (af_neighb_highy)
1145 box%cc(1:nc, nc+1, iv) = gc_scalar
1147 case (af_neighb_lowx)
1148 box%cc(0, 1:nc, 1:nc, iv) = gc_scalar
1149 case (af_neighb_highx)
1150 box%cc(nc+1, 1:nc, 1:nc, iv) = gc_scalar
1151 case (af_neighb_lowy)
1152 box%cc(1:nc, 0, 1:nc, iv) = gc_scalar
1153 case (af_neighb_highy)
1154 box%cc(1:nc, nc+1, 1:nc, iv) = gc_scalar
1155 case (af_neighb_lowz)
1156 box%cc(1:nc, 1:nc, 0, iv) = gc_scalar
1157 case (af_neighb_highz)
1158 box%cc(1:nc, 1:nc, nc+1, iv) = gc_scalar
1162 stop
"af_set_box_gc: requires gc_scalar or gc_array"
1164 end subroutine af_set_box_gc
1168 pure function af_cyl_radius_cc(box, i)
result(r)
1169 type(
box_t),
intent(in) :: box
1170 integer,
intent(in) :: i
1172 r = box%r_min(1) + (i-0.5_dp) * box%dr(1)
1173 end function af_cyl_radius_cc
1176 pure function af_cyl_volume_cc(box, i)
result(dvol)
1177 type(
box_t),
intent(in) :: box
1178 integer,
intent(in) :: i
1179 real(dp),
parameter :: two_pi = 2 * acos(-1.0_dp)
1181 dvol = two_pi * (box%r_min(1) + (i-0.5_dp) * box%dr(1)) * product(box%dr)
1182 end function af_cyl_volume_cc
1187 subroutine af_cyl_child_weights(box, i, inner, outer)
1188 type(
box_t),
intent(in) :: box
1189 integer,
intent(in) :: i
1190 real(dp),
intent(out) :: inner, outer
1193 tmp = 0.25_dp * box%dr(1) / af_cyl_radius_cc(box, i)
1196 end subroutine af_cyl_child_weights
1199 subroutine af_cyl_flux_factors(box, flux_factors)
1200 type(
box_t),
intent(in) :: box
1201 real(dp),
intent(out) :: flux_factors(2, box%n_cell)
1203 real(dp) :: r, inv_r
1205 do i = 1, box%n_cell
1206 r = af_cyl_radius_cc(box, i)
1208 flux_factors(1, i) = (r - 0.5_dp * box%dr(1)) * inv_r
1209 flux_factors(2, i) = (r + 0.5_dp * box%dr(1)) * inv_r
1211 end subroutine af_cyl_flux_factors
1215 subroutine af_get_face_coords(box, nb, coords)
1216 type(
box_t),
intent(in) :: box
1217 integer,
intent(in) :: nb
1218 real(dp),
intent(out) :: coords(NDIM, box%n_cell**(NDIM-1))
1219 integer :: i, nb_dim, bc_dim(NDIM-1)
1220 integer,
parameter :: all_dims(NDIM) = [(i, i = 1, ndim)]
1221 real(dp) :: rmin(NDIM)
1226 nb_dim = af_neighb_dim(nb)
1227 bc_dim = pack(all_dims, all_dims /= nb_dim)
1228 rmin(bc_dim) = box%r_min(bc_dim) + 0.5_dp * box%dr(bc_dim)
1230 if (af_neighb_low(nb))
then
1231 rmin(nb_dim) = box%r_min(nb_dim)
1233 rmin(nb_dim) = box%r_min(nb_dim) + box%n_cell * box%dr(nb_dim)
1237 coords(nb_dim, 1) = rmin(nb_dim)
1239 do i = 1, box%n_cell
1240 coords(bc_dim, i) = rmin(bc_dim) + (i-1) * box%dr(bc_dim)
1241 coords(nb_dim, i) = rmin(nb_dim)
1245 do j = 1, box%n_cell
1246 do i = 1, box%n_cell
1248 coords(bc_dim, ix) = rmin(bc_dim) + [i-1, j-1] * box%dr(bc_dim)
1249 coords(nb_dim, ix) = rmin(nb_dim)
1253 end subroutine af_get_face_coords
Subroutine that gets a box and an array of reals.
To fill ghost cells near physical boundaries in a custom way. If the number of ghost cells to fill is...
To fill ghost cells near physical boundaries.
Subroutine that gets a list of boxes, an id and an array of reals.
Subroutine that gets a list of boxes and a box id.
To set cell-centered variables based on a user-defined function. This can be useful to avoid recomput...
Subroutine for prolongation.
To fill ghost cells near refinement boundaries.
Subroutine for setting refinement flags.
Subroutine for restriction.
Subroutine that gets a tree, a box id and an array of reals.
Subroutine that gets a tree and a box id.
Subroutine that gets a box.
Subroutine that performs Gauss-Seidel relaxation.
Subroutine that performs A * cc(..., i_in) = cc(..., i_out)
Compute distance to boundary starting at point a going to point b, in the range from [0,...
This module contains the basic types and constants that are used in the NDIM-dimensional version of A...
Collection of methods for a cell-centered variable.
Type specifying the location of a cell.
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,...
Generic type for the coarse grid solver.
Type which contains the indices of all boxes at a refinement level, as well as a list with all the "l...
Type to store multigrid options in.
Type that contains the refinement changes in a tree.
Type that contains the refinement changes in a level.
Type for storing a numerical stencil for a box.