26 subroutine af_add_cc_variable(tree, name, write_out, n_copies, &
29 type(
af_t),
intent(inout) :: tree
31 character(len=*),
intent(in) :: name
33 logical,
intent(in),
optional :: write_out
35 logical,
intent(in),
optional :: write_binary
37 integer,
intent(in),
optional :: n_copies
39 integer,
intent(out),
optional :: ix
42 logical :: writeout, writebin
44 ncpy = 1;
if (
present(n_copies)) ncpy = n_copies
45 writeout = .true.;
if (
present(write_out)) writeout = write_out
46 writebin = .true.;
if (
present(write_binary)) writebin = write_binary
48 if (ncpy < 1) error stop
"af_add_cc_variable: n_copies < 1"
50 if (tree%n_var_cell + ncpy > af_max_num_vars)
then
51 print *,
"af_max_num_vars:", af_max_num_vars
52 print *,
"Cannot add ", name
53 error stop
"Too many cc variables"
57 tree%n_var_cell = tree%n_var_cell + 1
59 if (
present(ix)) ix = tree%n_var_cell
60 tree%cc_names(tree%n_var_cell) = name
61 tree%cc_write_output(tree%n_var_cell) = writeout
62 tree%cc_write_binary(tree%n_var_cell) = writebin
63 tree%cc_num_copies(tree%n_var_cell) = ncpy
65 write(tree%cc_names(tree%n_var_cell),
"(A,I0)") &
67 tree%cc_write_output(tree%n_var_cell) = .false.
68 tree%cc_write_binary(tree%n_var_cell) = .false.
69 tree%cc_num_copies(tree%n_var_cell) = 0
138 subroutine af_init(tree, n_cell, r_max, grid_size, periodic, r_min, coord, &
139 mem_limit_gb, box_limit)
140 type(
af_t),
intent(inout) :: tree
141 integer,
intent(in) :: n_cell
142 real(dp),
intent(in) :: r_max(ndim)
143 integer,
intent(in) :: grid_size(ndim)
144 logical,
intent(in),
optional :: periodic(ndim)
145 real(dp),
intent(in),
optional :: r_min(ndim)
146 integer,
intent(in),
optional :: coord
147 real(dp),
intent(in),
optional :: mem_limit_gb
149 integer,
intent(in),
optional :: box_limit
151 real(dp) :: r_min_a(ndim), gb_limit
152 integer :: lvl, coord_a, box_bytes
155 r_min_a = 0.0_dp;
if (
present(r_min)) r_min_a = r_min
156 coord_a = af_xyz;
if (
present(coord)) coord_a = coord
157 gb_limit = 4;
if (
present(mem_limit_gb)) gb_limit = mem_limit_gb
159 if (tree%ready) stop
"af_init: tree was already initialized"
160 if (n_cell < 2) stop
"af_init: n_cell should be >= 2"
161 if (btest(n_cell, 0)) stop
"af_init: n_cell should be even"
162 if (gb_limit <= 0) stop
"af_init: mem_limit_gb should be > 0"
163 if (coord_a == af_cyl .and. ndim /= 2) stop
"af_init: cyl. coords only in 2d"
164 if (tree%n_var_cell <= 0) stop
"af_init: no cell-centered variables present"
166 do lvl = af_min_lvl, af_max_lvl
167 allocate(tree%lvls(lvl)%ids(0))
168 allocate(tree%lvls(lvl)%leaves(0))
169 allocate(tree%lvls(lvl)%parents(0))
173 tree%r_base = r_min_a
174 tree%dr_base = (r_max - r_min_a) / grid_size
177 tree%coord_t = coord_a
179 if (
present(box_limit))
then
180 if (box_limit <= 0) stop
"af_init: box_limit should be > 0"
181 tree%box_limit = box_limit
184 box_bytes = af_box_bytes(n_cell, tree%n_var_cell, tree%n_var_face)
185 tree%box_limit = nint(gb_limit * 2.0_dp**30 / box_bytes)
189 allocate(tree%boxes(tree%box_limit))
192 tree%n_removed_ids = 0
193 allocate(tree%removed_ids(tree%box_limit))
196 if (.not.
allocated(tree%cc_auto_vars)) &
197 allocate(tree%cc_auto_vars(0))
198 if (.not.
allocated(tree%cc_func_vars)) &
199 allocate(tree%cc_func_vars(0))
201 call af_set_coarse_grid(tree, grid_size, periodic)
206 subroutine af_set_coarse_grid(tree, coarse_grid_size, periodic_dims)
208 type(
af_t),
intent(inout) :: tree
210 integer,
intent(in) :: coarse_grid_size(NDIM)
212 logical,
intent(in),
optional :: periodic_dims(NDIM)
213 logical :: periodic(NDIM)
214 integer :: nx(NDIM), ix(NDIM), IJK, id, n_boxes, nb
216 integer,
allocatable :: id_array(DTIMES(:))
218 if (tree%highest_id > 0) &
219 error stop
"af_set_coarse_grid: this tree already has boxes"
220 if (.not.
allocated(tree%boxes)) &
221 error stop
"af_set_coarse_grid: tree not initialized"
222 if (any(coarse_grid_size < tree%n_cell)) &
223 error stop
"af_set_coarse_grid: coarse_grid_size < tree%n_cell"
224 if (any(modulo(coarse_grid_size, tree%n_cell) /= 0)) &
225 error stop
"af_set_coarse_grid: coarse_grid_size not divisible by tree%n_cell"
227 periodic(:) = .false.;
if (
present(periodic_dims)) periodic = periodic_dims
229 tree%coarse_grid_size(1:ndim) = coarse_grid_size
230 tree%periodic(1:ndim) = periodic
233 nx = coarse_grid_size / tree%n_cell
234 n_boxes = product(nx)
237 call create_index_array(nx, periodic, id_array)
240 if (n_boxes >
size(tree%boxes(:))) &
241 error stop
"Not enough memory available for coarse grid"
244 deallocate(tree%lvls(1)%ids)
245 allocate(tree%lvls(1)%ids(n_boxes))
248 call get_free_ids(tree, tree%lvls(1)%ids)
249 tree%lvls(1)%leaves = tree%lvls(1)%ids
255 tree%boxes(id)%lvl = 1
256 tree%boxes(id)%ix = [ijk]
257 tree%boxes(id)%dr = tree%dr_base
258 tree%boxes(id)%r_min = tree%r_base + &
259 (tree%boxes(id)%ix - 1) * tree%dr_base * tree%n_cell
260 tree%boxes(id)%n_cell = tree%n_cell
261 tree%boxes(id)%coord_t = tree%coord_t
263 tree%boxes(id)%parent = af_no_box
264 tree%boxes(id)%children(:) = af_no_box
267 do nb = 1, af_num_neighbors
268 ix = [ijk] + af_neighb_dix(:, nb)
269 tree%boxes(id)%neighbors(nb) = id_array(ix(1))
271 tree%boxes(id)%neighbor_mat = id_array(i-1:i+1)
273 call af_init_box(tree, id)
279 tree%boxes(id)%lvl = 1
280 tree%boxes(id)%ix = [ijk]
281 tree%boxes(id)%dr = tree%dr_base
282 tree%boxes(id)%r_min = tree%r_base + &
283 (tree%boxes(id)%ix - 1) * tree%dr_base * tree%n_cell
284 tree%boxes(id)%n_cell = tree%n_cell
285 tree%boxes(id)%coord_t = tree%coord_t
287 tree%boxes(id)%parent = af_no_box
288 tree%boxes(id)%children(:) = af_no_box
291 do nb = 1, af_num_neighbors
292 ix = [ijk] + af_neighb_dix(:, nb)
293 tree%boxes(id)%neighbors(nb) = id_array(ix(1), ix(2))
295 tree%boxes(id)%neighbor_mat = id_array(i-1:i+1, j-1:j+1)
297 call af_init_box(tree, id)
305 tree%boxes(id)%lvl = 1
306 tree%boxes(id)%ix = [ijk]
307 tree%boxes(id)%dr = tree%dr_base
308 tree%boxes(id)%r_min = tree%r_base + &
309 (tree%boxes(id)%ix - 1) * tree%dr_base * tree%n_cell
310 tree%boxes(id)%n_cell = tree%n_cell
311 tree%boxes(id)%coord_t = tree%coord_t
313 tree%boxes(id)%parent = af_no_box
314 tree%boxes(id)%children(:) = af_no_box
317 do nb = 1, af_num_neighbors
318 ix = [ijk] + af_neighb_dix(:, nb)
319 tree%boxes(id)%neighbors(nb) = id_array(ix(1), ix(2), ix(3))
321 tree%boxes(id)%neighbor_mat = id_array(i-1:i+1, j-1:j+1, k-1:k+1)
323 call af_init_box(tree, id)
332 do i = 1,
size(tree%lvls(1)%ids)
333 id = tree%lvls(1)%ids(i)
334 do n = 1,
size(tree%cc_func_vars)
335 iv = tree%cc_func_vars(n)
336 call tree%cc_methods(iv)%funcval(tree%boxes(id), iv)
343 subroutine af_set_cc_methods(tree, iv, bc, rb, prolong, restrict, &
344 bc_custom, funcval, prolong_limiter)
349 type(
af_t),
intent(inout) :: tree
350 integer,
intent(in) :: iv
358 integer,
intent(in),
optional :: prolong_limiter
361 if (tree%has_cc_method(iv))
then
362 print *,
"Cannot call af_set_cc_methods twice for ", &
363 trim(tree%cc_names(iv))
368 do i = iv, iv + tree%cc_num_copies(iv) - 1
369 if (
present(bc))
then
370 tree%cc_methods(i)%bc => bc
371 else if (
present(bc_custom))
then
372 tree%cc_methods(i)%bc_custom => bc_custom
373 else if (.not.
present(funcval))
then
374 error stop
"af_set_cc_methods: bc, bc_custom or funcval required"
377 if (
present(funcval))
then
378 tree%cc_methods(i)%funcval => funcval
381 if (
present(rb))
then
382 tree%cc_methods(i)%rb => rb
384 tree%cc_methods(i)%rb => af_gc_interp
387 if (
present(prolong))
then
388 tree%cc_methods(i)%prolong => prolong
390 tree%cc_methods(i)%prolong => af_prolong_linear
393 if (
present(restrict))
then
394 tree%cc_methods(i)%restrict => restrict
396 tree%cc_methods(i)%restrict => af_restrict_box
399 if (
present(prolong_limiter))
then
400 tree%cc_methods(i)%prolong_limiter = prolong_limiter
401 else if (ndim < 3)
then
402 tree%cc_methods(i)%prolong_limiter = af_limiter_mc_t
407 tree%cc_methods(i)%prolong_limiter = af_limiter_gminmod43_t
410 tree%has_cc_method(i) = .true.
413 if (.not.
allocated(tree%cc_auto_vars)) &
414 allocate(tree%cc_auto_vars(0))
415 if (.not.
allocated(tree%cc_func_vars)) &
416 allocate(tree%cc_func_vars(0))
421 if (
present(funcval))
then
422 tree%cc_func_vars = [tree%cc_func_vars, iv]
424 tree%cc_auto_vars = [tree%cc_auto_vars, iv]
436 subroutine create_index_array(nx, periodic, id_array)
437 integer,
intent(in) :: nx(NDIM)
438 logical,
intent(in) :: periodic(NDIM)
439 integer,
intent(inout),
allocatable :: id_array(DTIMES(:))
443 allocate(id_array(0:nx(1)+1))
445 allocate(id_array(0:nx(1)+1, 0:nx(2)+1))
447 allocate(id_array(0:nx(1)+1, 0:nx(2)+1, 0:nx(3)+1))
450 id_array = af_phys_boundary
457 if (periodic(1))
then
458 id_array(0) = id_array(nx(1))
459 id_array(nx(1)+1) = id_array(1)
464 id_array(i, j) = (j-1) * nx(1) + i
468 if (periodic(1))
then
469 id_array(0, :) = id_array(nx(1), :)
470 id_array(nx(1)+1, :) = id_array(1, :)
473 if (periodic(2))
then
474 id_array(:, 0) = id_array(:, nx(2))
475 id_array(:, nx(2)+1) = id_array(:, 1)
481 id_array(i, j, k) = (k-1) * nx(2) * nx(1) + (j-1) * nx(1) + i
486 if (periodic(1))
then
487 id_array(0, :, :) = id_array(nx(1), :, :)
488 id_array(nx(1)+1, :, :) = id_array(1, :, :)
491 if (periodic(2))
then
492 id_array(:, 0, :) = id_array(:, nx(2), :)
493 id_array(:, nx(2)+1, :) = id_array(:, 1, :)
496 if (periodic(3))
then
497 id_array(:, :, 0) = id_array(:, :, nx(3))
498 id_array(:, :, nx(3)+1) = id_array(:, :, 1)
595 subroutine set_neighbs(boxes, id)
596 type(box_t),
intent(inout) :: boxes(:)
597 integer,
intent(in) :: id
598 integer :: nb, nb_id, IJK
601 if (boxes(id)%neighbor_mat(ijk) == af_no_box)
then
602 nb_id = find_neighb(boxes, id, [ijk])
603 if (nb_id > af_no_box)
then
604 boxes(id)%neighbor_mat(ijk) = nb_id
606 boxes(nb_id)%neighbor_mat(-i) = id
608 boxes(nb_id)%neighbor_mat(-i, -j) = id
610 boxes(nb_id)%neighbor_mat(-i, -j, -k) = id
616 do nb = 1, af_num_neighbors
617 if (boxes(id)%neighbors(nb) == af_no_box)
then
619 nb_id = boxes(id)%neighbor_mat(af_neighb_dix(1, nb))
621 nb_id = boxes(id)%neighbor_mat(af_neighb_dix(1, nb), &
622 af_neighb_dix(2, nb))
624 nb_id = boxes(id)%neighbor_mat(af_neighb_dix(1, nb), &
625 af_neighb_dix(2, nb), af_neighb_dix(3, nb))
627 if (nb_id > af_no_box)
then
628 boxes(id)%neighbors(nb) = nb_id
629 boxes(nb_id)%neighbors(af_neighb_rev(nb)) = id
690 subroutine af_adjust_refinement(tree, ref_subr, ref_info, ref_buffer, &
692 type(af_t),
intent(inout) :: tree
693 procedure(af_subr_ref) :: ref_subr
694 type(ref_info_t),
intent(inout) :: ref_info
695 integer,
intent(in),
optional :: ref_buffer
697 integer,
intent(in),
optional :: ref_links(:, :)
698 integer :: lvl, id, i, c_ids(af_num_children), i_ch
699 integer :: i_add, i_rm, n_ch, n_add
700 integer,
allocatable :: ref_flags(:)
701 integer :: ref_buffer_val
703 if (.not. tree%ready) stop
"Tree not ready"
706 if (
present(ref_buffer)) ref_buffer_val = ref_buffer
708 if (ref_buffer_val < 0) &
709 error stop
"af_adjust_refinement: ref_buffer < 0"
710 if (ref_buffer_val > tree%n_cell) &
711 error stop
"af_adjust_refinement: ref_buffer > tree%n_cell"
713 allocate(ref_flags(tree%highest_id))
717 call consistent_ref_flags(tree, ref_flags, ref_subr, &
718 ref_buffer_val, ref_links)
721 n_ch = af_num_children
722 ref_info%n_rm = n_ch * count(ref_flags == af_derefine)
723 if (
allocated(ref_info%rm))
deallocate(ref_info%rm)
724 allocate(ref_info%rm(ref_info%n_rm))
727 ref_info%n_add = n_ch * count(ref_flags == af_refine)
728 if (
allocated(ref_info%lvls))
deallocate(ref_info%lvls)
729 allocate(ref_info%lvls(tree%highest_lvl+1))
732 allocate(ref_info%lvls(1)%add(0))
734 do lvl = 1, tree%highest_lvl
736 n_add = n_ch * count(ref_flags(tree%lvls(lvl)%ids) == af_refine)
737 allocate(ref_info%lvls(lvl+1)%add(n_add))
742 do lvl = 1, af_max_lvl-1
745 do i = 1,
size(tree%lvls(lvl)%ids)
746 id = tree%lvls(lvl)%ids(i)
748 if (id >
size(ref_flags))
then
750 else if (ref_flags(id) == af_refine)
then
752 call get_free_ids(tree, c_ids)
753 call add_children(tree, id, c_ids)
754 ref_info%lvls(lvl+1)%add(i_add+1:i_add+n_ch) = &
755 tree%boxes(id)%children
757 else if (ref_flags(id) == af_derefine)
then
759 call auto_restrict(tree, id)
760 ref_info%rm(i_rm+1:i_rm+n_ch) = tree%boxes(id)%children
762 call remove_children(tree, id)
767 call set_leaves_parents(tree%boxes, tree%lvls(lvl))
770 call set_child_ids(tree%lvls(lvl)%parents, &
771 tree%lvls(lvl+1)%ids, tree%boxes)
774 do i = 1,
size(tree%lvls(lvl)%parents)
775 id = tree%lvls(lvl)%parents(i)
776 if (ref_flags(id) == af_refine)
then
777 do i_ch = 1, af_num_children
778 call set_neighbs(tree%boxes, tree%boxes(id)%children(i_ch))
783 if (
size(tree%lvls(lvl+1)%ids) == 0)
exit
786 tree%highest_lvl = lvl
790 i = tree%n_removed_ids
791 tree%removed_ids(i+1:i+ref_info%n_rm) = ref_info%rm(:)
792 tree%n_removed_ids = tree%n_removed_ids + ref_info%n_rm
795 do id = tree%highest_id, 1, -1
796 if (tree%boxes(id)%in_use)
exit
801 i_rm = tree%n_removed_ids
802 i = count(tree%removed_ids(1:i_rm) <= tree%highest_id)
803 tree%removed_ids(1:i) = pack(tree%removed_ids(1:i_rm), &
804 mask=tree%removed_ids(1:i_rm) <= tree%highest_id)
805 tree%n_removed_ids = i
810 lvl = min(lvl+1, af_max_lvl)
811 call set_leaves_parents(tree%boxes, tree%lvls(lvl))
813 call auto_prolong(tree, ref_info)
836 subroutine auto_prolong(tree, ref_info)
838 type(af_t),
intent(inout) :: tree
839 type(ref_info_t),
intent(in) :: ref_info
840 integer :: lvl, i, n, iv, id, p_id
843 if (.not. any(tree%has_cc_method(:)) .or. ref_info%n_add == 0)
then
848 do lvl = 1, tree%highest_lvl
850 do i = 1,
size(ref_info%lvls(lvl)%add)
851 id = ref_info%lvls(lvl)%add(i)
852 p_id = tree%boxes(id)%parent
854 do n = 1,
size(tree%cc_auto_vars)
855 iv = tree%cc_auto_vars(n)
856 call tree%cc_methods(iv)%prolong(tree%boxes(p_id), &
857 tree%boxes(id), iv, limiter=tree%cc_methods(iv)%prolong_limiter)
859 do n = 1,
size(tree%cc_func_vars)
860 iv = tree%cc_func_vars(n)
861 call tree%cc_methods(iv)%funcval(tree%boxes(id), iv)
867 do i = 1,
size(ref_info%lvls(lvl)%add)
868 id = ref_info%lvls(lvl)%add(i)
869 call af_gc_box(tree, id, [tree%cc_auto_vars])
922 subroutine consistent_ref_flags(tree, ref_flags, ref_subr, &
923 ref_buffer, ref_links)
924 use omp_lib,
only: omp_get_max_threads, omp_get_thread_num
925 type(af_t),
intent(inout) :: tree
926 integer,
intent(inout) :: ref_flags(:)
927 procedure(af_subr_ref) :: ref_subr
928 integer,
intent(in) :: ref_buffer
930 integer,
intent(in),
optional :: ref_links(:, :)
931 integer :: lvl, i, i_ch, ch_id, id
934 integer,
allocatable :: tmp_flags(:, :)
935 integer :: cell_flags(DTIMES(tree%n_cell))
936 integer,
parameter :: unset_flag = -huge(1)
940 allocate(tmp_flags(
size(ref_flags), omp_get_max_threads()))
942 tmp_flags(:, :) = unset_flag
948 thread_id = omp_get_thread_num() + 1
950 do lvl = 1, tree%highest_lvl
952 do i = 1,
size(tree%lvls(lvl)%leaves)
953 id = tree%lvls(lvl)%leaves(i)
955 call ref_subr(tree%boxes(id), cell_flags)
956 call cell_to_ref_flags(cell_flags, tree%n_cell, &
957 tmp_flags(:, thread_id), tree, id, ref_buffer)
961 if (tree%boxes(id)%lvl > 1)
then
962 p_id = tree%boxes(id)%parent
963 do i_ch = 1, af_ix_to_ichild(tree%boxes(id)%ix)-1
964 ch_id = tree%boxes(p_id)%children(i_ch)
965 if (.not. af_has_children(tree%boxes(ch_id)))
exit
968 if (i_ch == af_ix_to_ichild(tree%boxes(id)%ix))
then
970 call ref_subr(tree%boxes(p_id), cell_flags)
971 call cell_to_ref_flags(cell_flags, tree%n_cell, &
972 tmp_flags(:, thread_id), tree, p_id, ref_buffer)
981 do i = 1,
size(ref_flags)
982 ref_flags(i) = maxval(tmp_flags(i, :))
983 if (ref_flags(i) == unset_flag) ref_flags(i) = af_keep_ref
986 if (maxval(ref_flags) > af_do_ref .or. minval(ref_flags) < af_rm_ref) &
987 stop
"af_adjust_refinement: invalid refinement flag given"
990 do i = 1,
size(tree%lvls(af_max_lvl)%ids)
991 id = tree%lvls(af_max_lvl)%ids(i)
992 if (ref_flags(id) == af_do_ref) ref_flags(id) = af_keep_ref
995 call ensure_two_one_balance(tree, ref_flags)
996 call handle_derefinement_flags(tree, ref_flags)
998 if (
present(ref_links))
then
999 do i = 1,
size(ref_links, 2)
1000 ref_flags(ref_links(:, i)) = maxval(ref_flags(ref_links(:, i)))
1002 call ensure_two_one_balance(tree, ref_flags)
1003 call handle_derefinement_flags(tree, ref_flags)
1088 subroutine cell_to_ref_flags(cell_flags, nc, ref_flags, tree, id, &
1091 integer,
intent(in) :: nc
1092 integer,
intent(in) :: cell_flags(DTIMES(nc))
1093 integer,
intent(inout) :: ref_flags(:)
1094 type(af_t),
intent(in) :: tree
1095 integer,
intent(in) :: id
1096 integer,
intent(in) :: ref_buffer
1097 integer :: ix0(NDIM), ix1(NDIM), IJK, nb_id
1099 if (minval(cell_flags) < af_rm_ref .or. &
1100 maxval(cell_flags) > af_do_ref)
then
1101 error stop
"Error: invalid cell flags given"
1105 if (any(cell_flags == af_do_ref))
then
1106 ref_flags(id) = af_do_ref
1107 else if (any(cell_flags == af_keep_ref))
then
1108 ref_flags(id) = max(ref_flags(id), af_keep_ref)
1110 ref_flags(id) = max(ref_flags(id), af_rm_ref)
1113 if (ref_buffer <= 0)
return
1118 if (all([ijk] == 0)) cycle
1120 nb_id = tree%boxes(id)%neighbor_mat(ijk)
1123 if (nb_id <= af_no_box) cycle
1129 ix0 = nc - ref_buffer + 1
1131 elsewhere ([ijk] == -1)
1136 if (any(cell_flags(dslice(ix0, ix1)) == af_do_ref))
then
1137 ref_flags(nb_id) = af_do_ref
1181 subroutine add_children(tree, id, c_ids)
1182 type(af_t),
intent(inout) :: tree
1183 integer,
intent(in) :: id
1184 integer,
intent(in) :: c_ids(af_num_children)
1185 integer :: i, nb, child_nb(2**(NDIM-1))
1186 integer :: c_id, c_ix_base(NDIM), dix(NDIM)
1188 associate(boxes => tree%boxes)
1189 boxes(id)%children = c_ids
1190 c_ix_base = 2 * boxes(id)%ix - 1
1192 do i = 1, af_num_children
1194 boxes(c_id)%ix = c_ix_base + af_child_dix(:,i)
1195 boxes(c_id)%lvl = boxes(id)%lvl+1
1196 boxes(c_id)%parent = id
1197 boxes(c_id)%tag = af_init_tag
1198 boxes(c_id)%children = af_no_box
1199 boxes(c_id)%neighbors = af_no_box
1200 boxes(c_id)%neighbor_mat = af_no_box
1201 boxes(c_id)%neighbor_mat(dtimes(0)) = c_id
1202 boxes(c_id)%n_cell = boxes(id)%n_cell
1203 boxes(c_id)%coord_t = boxes(id)%coord_t
1204 boxes(c_id)%dr = 0.5_dp * boxes(id)%dr
1205 boxes(c_id)%r_min = boxes(id)%r_min + 0.5_dp * boxes(id)%dr * &
1206 af_child_dix(:,i) * boxes(id)%n_cell
1210 do nb = 1, af_num_neighbors
1211 if (boxes(id)%neighbors(nb) < af_no_box)
then
1212 child_nb = c_ids(af_child_adj_nb(:, nb))
1213 boxes(child_nb)%neighbors(nb) = boxes(id)%neighbors(nb)
1214 dix = af_neighb_dix(:, nb)
1215 boxes(child_nb)%neighbor_mat(dindex(dix)) = &
1216 boxes(id)%neighbors(nb)
1222 do i = 1, af_num_children
1223 call af_init_box(tree, c_ids(i))
1279 subroutine flux_from_children(boxes, id, nb, f_ixs)
1280 type(box_t),
intent(inout) :: boxes(:)
1281 integer,
intent(in) :: id
1282 integer,
intent(in) :: nb
1283 integer,
intent(in) :: f_ixs(:)
1284 integer :: nc, nch, c_id, i_ch, i, ic, d
1285 integer :: n_chnb, nb_id, i_nb
1287 integer :: ioff(NDIM)
1295 nc = boxes(id)%n_cell
1297 d = af_neighb_dim(nb)
1298 n_chnb = 2**(ndim-1)
1299 nb_id = boxes(id)%neighbors(nb)
1301 if (af_neighb_low(nb))
then
1314 i_ch = af_child_adj_nb(ic, nb)
1315 c_id = boxes(id)%children(i_ch)
1316 boxes(nb_id)%fc(i_nb, 1, f_ixs) = boxes(c_id)%fc(i, 1, f_ixs)
1322 i_ch = af_child_adj_nb(ic, nb)
1323 c_id = boxes(id)%children(i_ch)
1325 ioff = nch*af_child_dix(:, i_ch)
1326 boxes(nb_id)%fc(i_nb, ioff(2)+1:ioff(2)+nch, 1, f_ixs) = 0.5_dp * ( &
1327 boxes(c_id)%fc(i, 1:nc:2, 1, f_ixs) + &
1328 boxes(c_id)%fc(i, 2:nc:2, 1, f_ixs))
1331 if (boxes(nb_id)%coord_t == af_cyl)
then
1334 i_ch = af_child_adj_nb(ic, nb)
1335 c_id = boxes(id)%children(i_ch)
1336 ioff = nch*af_child_dix(:, i_ch)
1339 call af_cyl_child_weights(boxes(nb_id), ioff(1)+n, w1, w2)
1340 boxes(nb_id)%fc(ioff(1)+n, i_nb, 2, f_ixs) = 0.5_dp * (&
1341 w1 * boxes(c_id)%fc(2*n-1, i, 2, f_ixs) + &
1342 w2 * boxes(c_id)%fc(2*n, i, 2, f_ixs))
1348 i_ch = af_child_adj_nb(ic, nb)
1349 c_id = boxes(id)%children(i_ch)
1350 ioff = nch*af_child_dix(:, i_ch)
1351 boxes(nb_id)%fc(ioff(1)+1:ioff(1)+nch, i_nb, 2, f_ixs) = 0.5_dp * ( &
1352 boxes(c_id)%fc(1:nc:2, i, 2, f_ixs) + &
1353 boxes(c_id)%fc(2:nc:2, i, 2, f_ixs))
1359 i_ch = af_child_adj_nb(ic, nb)
1360 c_id = boxes(id)%children(i_ch)
1361 ioff = nch*af_child_dix(:, i_ch)
1362 boxes(nb_id)%fc(i_nb, ioff(2)+1:ioff(2)+nch, &
1363 ioff(3)+1:ioff(3)+nch, 1, f_ixs) = 0.25_dp * ( &
1364 boxes(c_id)%fc(i, 1:nc:2, 1:nc:2, 1, f_ixs) + &
1365 boxes(c_id)%fc(i, 2:nc:2, 1:nc:2, 1, f_ixs) + &
1366 boxes(c_id)%fc(i, 1:nc:2, 2:nc:2, 1, f_ixs) + &
1367 boxes(c_id)%fc(i, 2:nc:2, 2:nc:2, 1, f_ixs))
1371 i_ch = af_child_adj_nb(ic, nb)
1372 c_id = boxes(id)%children(i_ch)
1373 ioff = nch*af_child_dix(:, i_ch)
1374 boxes(nb_id)%fc(ioff(1)+1:ioff(1)+nch, i_nb, &
1375 ioff(3)+1:ioff(3)+nch, 2, f_ixs) = 0.25_dp * ( &
1376 boxes(c_id)%fc(1:nc:2, i, 1:nc:2, 2, f_ixs) + &
1377 boxes(c_id)%fc(2:nc:2, i, 1:nc:2, 2, f_ixs) + &
1378 boxes(c_id)%fc(1:nc:2, i, 2:nc:2, 2, f_ixs) + &
1379 boxes(c_id)%fc(2:nc:2, i, 2:nc:2, 2, f_ixs))
1383 i_ch = af_child_adj_nb(ic, nb)
1384 c_id = boxes(id)%children(i_ch)
1385 ioff = nch*af_child_dix(:, i_ch)
1386 boxes(nb_id)%fc(ioff(1)+1:ioff(1)+nch, &
1387 ioff(2)+1:ioff(2)+nch, i_nb, 3, f_ixs) = 0.25_dp * ( &
1388 boxes(c_id)%fc(1:nc:2, 1:nc:2, i, 3, f_ixs) + &
1389 boxes(c_id)%fc(2:nc:2, 1:nc:2, i, 3, f_ixs) + &
1390 boxes(c_id)%fc(1:nc:2, 2:nc:2, i, 3, f_ixs) + &
1391 boxes(c_id)%fc(2:nc:2, 2:nc:2, i, 3, f_ixs))