294 subroutine mg_sides_rb(boxes, id, nb, iv)
295 type(
box_t),
intent(inout) :: boxes(:)
296 integer,
intent(in) :: id
297 integer,
intent(in) :: nb
298 integer,
intent(in) :: iv
299 integer :: nc, ix, dix, ijk, di, co(ndim)
300 integer :: hnc, p_id, p_nb_id
306 real(dp) :: tmp(0:boxes(id)%n_cell/2+1)
307 real(dp) :: gc(boxes(id)%n_cell)
310 real(dp) :: tmp(0:boxes(id)%n_cell/2+1, 0:boxes(id)%n_cell/2+1)
311 real(dp) :: gc(boxes(id)%n_cell, boxes(id)%n_cell)
314 real(dp) :: grad(ndim-1)
317 nc = boxes(id)%n_cell
320 p_id = boxes(id)%parent
321 p_nb_id = boxes(p_id)%neighbors(nb)
322 co = af_get_child_offset(boxes(id))
324 associate(box => boxes(p_nb_id))
328 case (af_neighb_lowx)
330 case (af_neighb_highx)
333 case (af_neighb_lowx)
334 tmp = box%cc(nc, co(2):co(2)+hnc+1, iv)
335 case (af_neighb_highx)
336 tmp = box%cc(1, co(2):co(2)+hnc+1, iv)
337 case (af_neighb_lowy)
338 tmp = box%cc(co(1):co(1)+hnc+1, nc, iv)
339 case (af_neighb_highy)
340 tmp = box%cc(co(1):co(1)+hnc+1, 1, iv)
342 case (af_neighb_lowx)
343 tmp = box%cc(nc, co(2):co(2)+hnc+1, co(3):co(3)+hnc+1, iv)
344 case (af_neighb_highx)
345 tmp = box%cc(1, co(2):co(2)+hnc+1, co(3):co(3)+hnc+1, iv)
346 case (af_neighb_lowy)
347 tmp = box%cc(co(1):co(1)+hnc+1, nc, co(3):co(3)+hnc+1, iv)
348 case (af_neighb_highy)
349 tmp = box%cc(co(1):co(1)+hnc+1, 1, co(3):co(3)+hnc+1, iv)
350 case (af_neighb_lowz)
351 tmp = box%cc(co(1):co(1)+hnc+1, co(2):co(2)+hnc+1, nc, iv)
352 case (af_neighb_highz)
353 tmp = box%cc(co(1):co(1)+hnc+1, co(2):co(2)+hnc+1, 1, iv)
356 error stop
"mg_sides_rb: wrong argument for nb"
366 grad(1) = 0.125_dp * (tmp(i+1) - tmp(i-1))
367 gc(2*i-1) = tmp(i) - grad(1)
368 gc(2*i) = tmp(i) + grad(1)
373 grad(1) = 0.125_dp * (tmp(i+1, j) - tmp(i-1, j))
374 grad(2) = 0.125_dp * (tmp(i, j+1) - tmp(i, j-1))
375 gc(2*i-1, 2*j-1) = tmp(i, j) - grad(1) - grad(2)
376 gc(2*i, 2*j-1) = tmp(i, j) + grad(1) - grad(2)
377 gc(2*i-1, 2*j) = tmp(i, j) - grad(1) + grad(2)
378 gc(2*i, 2*j) = tmp(i, j) + grad(1) + grad(2)
383 if (af_neighb_low(nb))
then
391 select case (af_neighb_dim(nb))
396 boxes(id)%cc(i-di, iv) = 0.5_dp * gc &
397 + 0.75_dp * boxes(id)%cc(i, iv) &
398 - 0.25_dp * boxes(id)%cc(i+di, iv)
404 dj = -1 + 2 * iand(j, 1)
405 boxes(id)%cc(i-di, j, iv) = 0.5_dp * gc(j) &
406 + 0.75_dp * boxes(id)%cc(i, j, iv) &
407 - 0.25_dp * boxes(id)%cc(i+di, j, iv)
413 di = -1 + 2 * iand(i, 1)
414 boxes(id)%cc(i, j-dj, iv) = 0.5_dp * gc(i) &
415 + 0.75_dp * boxes(id)%cc(i, j, iv) &
416 - 0.25_dp * boxes(id)%cc(i, j+dj, iv)
423 dk = -1 + 2 * iand(k, 1)
425 dj = -1 + 2 * iand(j, 1)
426 boxes(id)%cc(i-di, j, k, iv) = &
427 0.5_dp * gc(j, k) + &
428 0.75_dp * boxes(id)%cc(i, j, k, iv) - &
429 0.25_dp * boxes(id)%cc(i+di, j, k, iv)
436 dk = -1 + 2 * iand(k, 1)
438 di = -1 + 2 * iand(i, 1)
439 boxes(id)%cc(i, j-dj, k, iv) = &
440 0.5_dp * gc(i, k) + &
441 0.75_dp * boxes(id)%cc(i, j, k, iv) - &
442 0.25_dp * boxes(id)%cc(i, j+dj, k, iv)
449 dj = -1 + 2 * iand(j, 1)
451 di = -1 + 2 * iand(i, 1)
452 boxes(id)%cc(i, j, k-dk, iv) = &
453 0.5_dp * gc(i, j) + &
454 0.75_dp * boxes(id)%cc(i, j, k, iv) - &
455 0.25_dp * boxes(id)%cc(i, j, k+dk, iv)
468 subroutine mg_sides_rb_extrap(boxes, id, nb, iv)
469 type(box_t),
intent(inout) :: boxes(:)
470 integer,
intent(in) :: id
471 integer,
intent(in) :: nb
472 integer,
intent(in) :: iv
473 integer :: nc, ix, dix, IJK, di
481 nc = boxes(id)%n_cell
483 if (af_neighb_low(nb))
then
491 call af_gc_prolong_copy(boxes, id, nb, iv, 0)
493 select case (af_neighb_dim(nb))
498 boxes(id)%cc(i-di, iv) = 0.5_dp * boxes(id)%cc(i-di, iv) &
499 + 0.75_dp * boxes(id)%cc(i, iv) &
500 - 0.25_dp * boxes(id)%cc(i+di, iv)
506 dj = -1 + 2 * iand(j, 1)
509 boxes(id)%cc(i-di, j, iv) = 0.5_dp * boxes(id)%cc(i-di, j, iv) + &
510 1.125_dp * boxes(id)%cc(i, j, iv) - 0.375_dp * &
511 (boxes(id)%cc(i+di, j, iv) + boxes(id)%cc(i, j+dj, iv)) &
512 + 0.125_dp * boxes(id)%cc(i+di, j+dj, iv)
528 di = -1 + 2 * iand(i, 1)
531 boxes(id)%cc(i, j-dj, iv) = 0.5_dp * boxes(id)%cc(i, j-dj, iv) + &
532 1.125_dp * boxes(id)%cc(i, j, iv) - 0.375_dp * &
533 (boxes(id)%cc(i+di, j, iv) + boxes(id)%cc(i, j+dj, iv)) &
534 + 0.125_dp * boxes(id)%cc(i+di, j+dj, iv)
546 dk = -1 + 2 * iand(k, 1)
548 dj = -1 + 2 * iand(j, 1)
562 boxes(id)%cc(i-di, j, k, iv) = &
563 0.5_dp * boxes(id)%cc(i-di, j, k, iv) + &
564 0.75_dp * boxes(id)%cc(i, j, k, iv) - &
565 0.25_dp * boxes(id)%cc(i+di, j+dj, k+dk, iv)
572 dk = -1 + 2 * iand(k, 1)
574 di = -1 + 2 * iand(i, 1)
587 boxes(id)%cc(i, j-dj, k, iv) = &
588 0.5_dp * boxes(id)%cc(i, j-dj, k, iv) + &
589 0.75_dp * boxes(id)%cc(i, j, k, iv) - &
590 0.25_dp * boxes(id)%cc(i+di, j+dj, k+dk, iv)
597 dj = -1 + 2 * iand(j, 1)
599 di = -1 + 2 * iand(i, 1)
612 boxes(id)%cc(i, j, k-dk, iv) = &
613 0.5_dp * boxes(id)%cc(i, j, k-dk, iv) + &
614 0.75_dp * boxes(id)%cc(i, j, k, iv) - &
615 0.25_dp * boxes(id)%cc(i+di, j+dj, k+dk, iv)
862 subroutine mg_store_prolongation_stencil(tree, id, mg)
863 type(af_t),
intent(inout) :: tree
864 integer,
intent(in) :: id
865 type(mg_t),
intent(in) :: mg
868 call af_stencil_prepare_store(tree%boxes(id), mg%prolongation_key, ix)
870 p_id = tree%boxes(id)%parent
871 if (p_id <= af_no_box) error stop
"Box does not have parent"
873 select case (mg%prolongation_type)
874 case (mg_prolong_linear)
875 call mg_box_prolong_linear_stencil(tree%boxes(id), &
876 tree%boxes(p_id), mg, ix)
877 case (mg_prolong_sparse)
878 call mg_box_prolong_sparse_stencil(tree%boxes(id), &
879 tree%boxes(p_id), mg, ix)
880 case (mg_prolong_auto)
882 associate(box=>tree%boxes(id), box_p=>tree%boxes(p_id))
883 select case (iand(box%tag, mg%operator_mask))
884 case (mg_normal_box, mg_ceps_box)
885 call mg_box_prolong_linear_stencil(box, box_p, mg, ix)
886 case (mg_lsf_box, mg_ceps_box+mg_lsf_box)
887 if (mg%lsf_use_custom_prolongation)
then
888 call mg_box_prolong_lsf_stencil(box, box_p, mg, ix)
890 call mg_box_prolong_linear_stencil(box, box_p, mg, ix)
892 case (mg_veps_box, mg_veps_box + mg_lsf_box)
893 call mg_box_prolong_eps_stencil(box, box_p, mg, ix)
895 error stop
"mg_store_prolongation_stencil: unknown box tag"
899 error stop
"mg_store_prolongation_stencil: unknown mg%prolongation_type"
902 call af_stencil_check_box(tree%boxes(id), mg%prolongation_key, ix)
977 subroutine store_lsf_distance_matrix(box, nc, mg, boundary)
978 type(box_t),
intent(inout) :: box
979 integer,
intent(in) :: nc
980 type(mg_t),
intent(in) :: mg
981 logical,
intent(out) :: boundary
982 logical :: root_mask(DTIMES(nc))
983 real(dp) :: dd(2*NDIM), a(NDIM)
984 integer :: ixs(NDIM, nc**NDIM), IJK, ix, n
986 real(dp) :: v(2*NDIM, nc**NDIM)
988 integer :: nb, dim, i_step, n_steps
989 real(dp) :: dist, gradient(NDIM), dvec(NDIM)
990 real(dp) :: x(NDIM), step_size(NDIM), min_dr
992 min_dr = minval(box%dr)
998 call get_possible_lsf_root_mask(box, nc, norm2(box%dr), mg, root_mask)
999 n_mask = count(root_mask)
1001 if (n_mask > 0)
then
1003 call af_stencil_prepare_store(box, mg_lsf_mask_key, ix)
1004 box%stencils(ix)%stype = stencil_sparse
1005 box%stencils(ix)%shape = af_stencil_mask
1006 call af_stencil_allocate_coeff(box%stencils(ix), box%n_cell, &
1011 if (root_mask(ijk))
then
1013 box%stencils(ix)%sparse_ix(:, m) = [ijk]
1022 if (root_mask(ijk))
then
1023 a = af_r_cc(box, [ijk])
1025 dd(1) = mg%lsf_dist(a, af_r_cc(box, [i-1]), mg)
1026 dd(2) = mg%lsf_dist(a, af_r_cc(box, [i+1]), mg)
1028 dd(1) = mg%lsf_dist(a, af_r_cc(box, [i-1, j]), mg)
1029 dd(2) = mg%lsf_dist(a, af_r_cc(box, [i+1, j]), mg)
1030 dd(3) = mg%lsf_dist(a, af_r_cc(box, [i, j-1]), mg)
1031 dd(4) = mg%lsf_dist(a, af_r_cc(box, [i, j+1]), mg)
1033 dd(1) = mg%lsf_dist(a, af_r_cc(box, [i-1, j, k]), mg)
1034 dd(2) = mg%lsf_dist(a, af_r_cc(box, [i+1, j, k]), mg)
1035 dd(3) = mg%lsf_dist(a, af_r_cc(box, [i, j-1, k]), mg)
1036 dd(4) = mg%lsf_dist(a, af_r_cc(box, [i, j+1, k]), mg)
1037 dd(5) = mg%lsf_dist(a, af_r_cc(box, [i, j, k-1]), mg)
1038 dd(6) = mg%lsf_dist(a, af_r_cc(box, [i, j, k+1]), mg)
1044 if (min_dr > mg%lsf_length_scale .and. all(dd >= 1))
then
1045 n_steps = ceiling(min_dr/mg%lsf_length_scale)
1046 step_size = sign(mg%lsf_length_scale, box%cc(ijk, mg%i_lsf))
1049 do i_step = 1, n_steps
1050 gradient = numerical_gradient(mg%lsf, x)
1051 gradient = gradient/max(norm2(gradient), 1e-50_dp)
1054 x = x - gradient * step_size
1055 if (mg%lsf(x) * box%cc(ijk, mg%i_lsf) <= 0)
exit
1058 dist = mg%lsf_dist(a, x, mg)
1062 dist = dist * norm2(x - a)/min_dr
1066 dim = maxloc(abs(dvec), dim=1)
1068 if (dvec(dim) > 0) nb = nb + 1
1079 if (any(dd < 1.0_dp))
then
1088 call af_stencil_prepare_store(box, mg_lsf_distance_key, ix)
1089 box%stencils(ix)%stype = stencil_sparse
1090 box%stencils(ix)%shape = af_stencil_246
1091 call af_stencil_allocate_coeff(box%stencils(ix), box%n_cell, &
1093 box%stencils(ix)%sparse_ix(:, :) = ixs(:, 1:n)
1094 box%stencils(ix)%sparse_v(:, :) = v(:, 1:n)
1308 subroutine mg_box_prolong_eps_stencil(box, box_p, mg, ix)
1309 type(box_t),
intent(inout) :: box
1310 type(box_t),
intent(in) :: box_p
1311 type(mg_t),
intent(in) :: mg
1312 integer,
intent(in) :: ix
1313 real(dp) :: a0, a(NDIM)
1314 integer :: i_eps, nc
1316 integer :: IJK, IJK_(c1)
1317 integer :: IJK_(c2), ix_offset(NDIM)
1319 real(dp),
parameter :: third = 1/3.0_dp
1323 box%stencils(ix)%shape = af_stencil_p234
1324 box%stencils(ix)%stype = stencil_variable
1325 ix_offset = af_get_child_offset(box)
1326 call af_stencil_allocate_coeff(box%stencils(ix), box%n_cell)
1330 associate(v => box%stencils(ix)%v)
1335 i_c1 = ix_offset(1) + ishft(i+1, -1)
1336 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
1338 a0 = box_p%cc(i_c1, i_eps)
1339 a(1) = box_p%cc(i_c2, i_eps)
1342 v(:, ijk) = [a0, a(1)] / (a0 + a(1))
1346 j_c1 = ix_offset(2) + ishft(j+1, -1)
1347 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
1349 i_c1 = ix_offset(1) + ishft(i+1, -1)
1350 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
1352 a0 = box_p%cc(i_c1, j_c1, i_eps)
1353 a(1) = box_p%cc(i_c2, j_c1, i_eps)
1354 a(2) = box_p%cc(i_c1, j_c2, i_eps)
1357 v(1, ijk) = 0.5_dp * sum(a0 / (a0 + a(:)))
1358 v(2:, ijk) = 0.5_dp * a(:) / (a0 + a(:))
1363 k_c1 = ix_offset(3) + ishft(k+1, -1)
1364 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
1366 j_c1 = ix_offset(2) + ishft(j+1, -1)
1367 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
1369 i_c1 = ix_offset(1) + ishft(i+1, -1)
1370 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
1372 a0 = box_p%cc(i_c1, j_c1, k_c1, i_eps)
1373 a(1) = box_p%cc(i_c2, j_c1, k_c1, i_eps)
1374 a(2) = box_p%cc(i_c1, j_c2, k_c1, i_eps)
1375 a(3) = box_p%cc(i_c1, j_c1, k_c2, i_eps)
1378 v(1, ijk) = third * sum((a0 - 0.5_dp * a(:))/(a0 + a(:)))
1379 v(2:, ijk) = 0.5_dp * a(:) / (a0 + a(:))
1386 call af_stencil_try_constant(box, ix, epsilon(1.0_dp), success)
1392 subroutine mg_box_prolong_lsf_stencil(box, box_p, mg, ix)
1393 type(box_t),
intent(inout) :: box
1394 type(box_t),
intent(in) :: box_p
1395 type(mg_t),
intent(in) :: mg
1396 integer,
intent(in) :: ix
1397 real(dp) :: dd(NDIM+1), a(NDIM)
1398 integer :: i_lsf, nc, ix_mask
1400 integer :: IJK, IJK_(c1), n, n_mask
1401 integer :: IJK_(c2), ix_offset(NDIM)
1404 box%stencils(ix)%shape = af_stencil_p234
1405 box%stencils(ix)%stype = stencil_variable
1406 ix_offset = af_get_child_offset(box)
1408 call af_stencil_allocate_coeff(box%stencils(ix), box%n_cell)
1410 ix_mask = af_stencil_index(box, mg_lsf_mask_key)
1411 if (ix_mask == af_stencil_none) error stop
"No LSF root mask stored"
1412 n_mask =
size(box%stencils(ix_mask)%sparse_ix, 2)
1414 associate(v => box%stencils(ix)%v)
1422 i = box%stencils(ix_mask)%sparse_ix(1, n)
1423 i_c1 = ix_offset(1) + ishft(i+1, -1)
1424 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
1426 a = af_r_cc(box, [ijk])
1427 dd(1) = mg%lsf_dist(a, af_r_cc(box_p, [i_c1]), mg)
1428 dd(2) = mg%lsf_dist(a, af_r_cc(box_p, [i_c2]), mg)
1430 v(:, ijk) = [3 * dd(2), dd(1)]
1431 v(:, ijk) = v(:, ijk) / sum(v(:, ijk))
1432 where (dd < 1) v(:, ijk) = 0
1436 v(2, :, :) = 0.25_dp
1437 v(3, :, :) = 0.25_dp
1440 i = box%stencils(ix_mask)%sparse_ix(1, n)
1441 j = box%stencils(ix_mask)%sparse_ix(2, n)
1443 j_c1 = ix_offset(2) + ishft(j+1, -1)
1444 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
1445 i_c1 = ix_offset(1) + ishft(i+1, -1)
1446 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
1448 a = af_r_cc(box, [ijk])
1449 dd(1) = mg%lsf_dist(a, af_r_cc(box_p, [i_c1, j_c1]), mg)
1450 dd(2) = mg%lsf_dist(a, af_r_cc(box_p, [i_c2, j_c1]), mg)
1451 dd(3) = mg%lsf_dist(a, af_r_cc(box_p, [i_c1, j_c2]), mg)
1453 v(:, ijk) = [2 * dd(2) * dd(3), dd(1) * dd(3), dd(1) * dd(2)]
1454 v(:, ijk) = v(:, ijk) / sum(v(:, ijk))
1455 where (dd < 1) v(:, ijk) = 0
1458 v(:, :, :, :) = 0.25_dp
1461 i = box%stencils(ix_mask)%sparse_ix(1, n)
1462 j = box%stencils(ix_mask)%sparse_ix(2, n)
1463 k = box%stencils(ix_mask)%sparse_ix(3, n)
1465 k_c1 = ix_offset(3) + ishft(k+1, -1)
1466 k_c2 = k_c1 + 1 - 2 * iand(k, 1)
1467 j_c1 = ix_offset(2) + ishft(j+1, -1)
1468 j_c2 = j_c1 + 1 - 2 * iand(j, 1)
1469 i_c1 = ix_offset(1) + ishft(i+1, -1)
1470 i_c2 = i_c1 + 1 - 2 * iand(i, 1)
1472 a = af_r_cc(box, [ijk])
1473 dd(1) = mg%lsf_dist(a, af_r_cc(box_p, [i_c1, j_c1, k_c1]), mg)
1474 dd(2) = mg%lsf_dist(a, af_r_cc(box_p, [i_c2, j_c1, k_c1]), mg)
1475 dd(3) = mg%lsf_dist(a, af_r_cc(box_p, [i_c1, j_c2, k_c1]), mg)
1476 dd(4) = mg%lsf_dist(a, af_r_cc(box_p, [i_c1, j_c1, k_c2]), mg)
1478 v(:, ijk) = [dd(2) * dd(3) * dd(4), &
1479 dd(1) * dd(3) * dd(4), dd(1) * dd(2) * dd(4), &
1480 dd(1) * dd(2) * dd(3)]
1481 v(:, ijk) = v(:, ijk) / sum(v(:, ijk))
1482 where (dd < 1) v(:, ijk) = 0
1487 call af_stencil_try_constant(box, ix, epsilon(1.0_dp), success)
1493 subroutine mg_box_lpld_stencil(box, mg, ix)
1494 type(box_t),
intent(inout) :: box
1495 type(mg_t),
intent(in) :: mg
1496 integer,
intent(in) :: ix
1498 real(dp) :: idr2(2*NDIM), a0, a(2*NDIM)
1502 idr2(1:2*ndim:2) = 1/box%dr**2
1503 idr2(2:2*ndim:2) = idr2(1:2*ndim:2)
1505 box%stencils(ix)%shape = af_stencil_357
1506 box%stencils(ix)%stype = stencil_variable
1507 box%stencils(ix)%cylindrical_gradient = (box%coord_t == af_cyl)
1508 call af_stencil_allocate_coeff(box%stencils(ix), box%n_cell)
1510 associate(cc => box%cc, n => mg%i_phi, i_eps => mg%i_eps)
1513 a0 = box%cc(i, i_eps)
1514 a(1:2) = box%cc(i-1:i+1:2, i_eps)
1516 a0 = box%cc(i, j, i_eps)
1517 a(1:2) = box%cc(i-1:i+1:2, j, i_eps)
1518 a(3:4) = box%cc(i, j-1:j+1:2, i_eps)
1520 a0 = box%cc(i, j, k, i_eps)
1521 a(1:2) = box%cc(i-1:i+1:2, j, k, i_eps)
1522 a(3:4) = box%cc(i, j-1:j+1:2, k, i_eps)
1523 a(5:6) = box%cc(i, j, k-1:k+1:2, i_eps)
1525 box%stencils(ix)%v(2:, ijk) = idr2 * 2 * a0*a(:)/(a0 + a(:))
1526 box%stencils(ix)%v(1, ijk) = -sum(box%stencils(ix)%v(2:, ijk))
1530 call af_stencil_try_constant(box, ix, epsilon(1.0_dp), success)
1535 subroutine mg_box_lpld_lsf_stencil(box, mg, ix)
1536 type(box_t),
intent(inout) :: box
1537 type(mg_t),
intent(in) :: mg
1538 integer,
intent(in) :: ix
1540 real(dp) :: idr2(2*NDIM), a0, a(2*NDIM), dr2(NDIM)
1541 integer :: n, m, idim, s_ix(NDIM), ix_dist
1542 real(dp) :: dd(2*NDIM)
1543 real(dp),
allocatable :: all_distances(:, DTIMES(:))
1550 idr2(1:2*ndim:2) = 1/box%dr**2
1551 idr2(2:2*ndim:2) = idr2(1:2*ndim:2)
1554 box%stencils(ix)%shape = af_stencil_357
1555 box%stencils(ix)%stype = stencil_variable
1557 box%stencils(ix)%cylindrical_gradient = .false.
1558 call af_stencil_allocate_coeff(box%stencils(ix), box%n_cell, use_f=.true.)
1559 allocate(all_distances(2*ndim, dtimes(nc)))
1561 box%stencils(ix)%f = 0.0_dp
1563 all_distances = 1.0_dp
1565 ix_dist = af_stencil_index(box, mg_lsf_distance_key)
1566 if (ix_dist == af_stencil_none) error stop
"No distances stored"
1569 do n = 1,
size(box%stencils(ix_dist)%sparse_ix, 2)
1570 s_ix = box%stencils(ix_dist)%sparse_ix(:, n)
1571 all_distances(:, dindex(s_ix)) = &
1572 box%stencils(ix_dist)%sparse_v(:, n)
1575 associate(cc => box%cc, n => mg%i_phi, i_eps => mg%i_eps)
1577 dd = all_distances(:, ijk)
1580 a0 = box%cc(i, i_eps)
1581 a(1:2) = box%cc(i-1:i+1:2, i_eps)
1583 a0 = box%cc(i, j, i_eps)
1584 a(1:2) = box%cc(i-1:i+1:2, j, i_eps)
1585 a(3:4) = box%cc(i, j-1:j+1:2, i_eps)
1587 a0 = box%cc(i, j, k, i_eps)
1588 a(1:2) = box%cc(i-1:i+1:2, j, k, i_eps)
1589 a(3:4) = box%cc(i, j-1:j+1:2, k, i_eps)
1590 a(5:6) = box%cc(i, j, k-1:k+1:2, i_eps)
1594 box%stencils(ix)%v(1+2*idim-1, ijk) = 1 / &
1595 (0.5_dp * dr2(idim) * (dd(2*idim-1) + dd(2*idim)) * &
1597 box%stencils(ix)%v(1+2*idim, ijk) = 1 / &
1598 (0.5_dp * dr2(idim) * (dd(2*idim-1) + dd(2*idim)) * &
1604 where (dd(:) < 1.0_dp) a(:) = a0
1606 box%stencils(ix)%v(2:, ijk) = box%stencils(ix)%v(2:, ijk) * &
1607 2 * a0*a(:)/(a0 + a(:))
1610 if (box%coord_t == af_cyl)
then
1613 tmp = a0/(box%dr(1) * (dd(1) + dd(2)) * af_cyl_radius_cc(box, i))
1614 box%stencils(ix)%v(2, ijk) = box%stencils(ix)%v(2, ijk) - tmp
1615 box%stencils(ix)%v(3, ijk) = box%stencils(ix)%v(3, ijk) + tmp
1619 box%stencils(ix)%v(1, ijk) = -sum(box%stencils(ix)%v(2:, ijk))
1623 if (dd(m) < 1.0_dp)
then
1624 box%stencils(ix)%f(ijk) = box%stencils(ix)%f(ijk) - &
1625 box%stencils(ix)%v(m+1, ijk)
1626 box%stencils(ix)%v(m+1, ijk) = 0.0_dp
1632 call af_stencil_try_constant(box, ix, epsilon(1.0_dp), success)
1793 subroutine mg_box_lsf_stencil(box, mg, ix)
1794 type(box_t),
intent(inout) :: box
1795 type(mg_t),
intent(in) :: mg
1796 integer,
intent(in) :: ix
1797 integer :: IJK, n, nc, idim
1798 integer :: s_ix(NDIM), ix_dist
1799 real(dp) :: dd(2*NDIM), dr2(NDIM)
1800 real(dp),
allocatable :: all_distances(:, DTIMES(:))
1808 ix_dist = af_stencil_index(box, mg_lsf_distance_key)
1809 if (ix_dist == af_stencil_none) error stop
"No distances stored"
1812 box%stencils(ix)%shape = af_stencil_357
1813 box%stencils(ix)%stype = stencil_variable
1815 box%stencils(ix)%cylindrical_gradient = .false.
1816 call af_stencil_allocate_coeff(box%stencils(ix), box%n_cell, use_f=.true.)
1817 box%stencils(ix)%f = 0.0_dp
1819 allocate(all_distances(2*ndim, dtimes(nc)))
1822 all_distances = 1.0_dp
1825 do n = 1,
size(box%stencils(ix_dist)%sparse_ix, 2)
1826 s_ix = box%stencils(ix_dist)%sparse_ix(:, n)
1827 all_distances(:, dindex(s_ix)) = &
1828 box%stencils(ix_dist)%sparse_v(:, n)
1832 dd = all_distances(:, ijk)
1836 box%stencils(ix)%v(1+2*idim-1, ijk) = 1 / &
1837 (0.5_dp * dr2(idim) * (dd(2*idim-1) + dd(2*idim)) * &
1839 box%stencils(ix)%v(1+2*idim, ijk) = 1 / &
1840 (0.5_dp * dr2(idim) * (dd(2*idim-1) + dd(2*idim)) * &
1845 if (box%coord_t == af_cyl)
then
1848 tmp = 1/(box%dr(1) * (dd(1) + dd(2)) * af_cyl_radius_cc(box, i))
1849 box%stencils(ix)%v(2, ijk) = box%stencils(ix)%v(2, ijk) - tmp
1850 box%stencils(ix)%v(3, ijk) = box%stencils(ix)%v(3, ijk) + tmp
1853 box%stencils(ix)%v(1, ijk) = -sum(box%stencils(ix)%v(2:, ijk))
1857 if (dd(n) < 1.0_dp)
then
1858 box%stencils(ix)%f(ijk) = box%stencils(ix)%f(ijk) - &
1859 box%stencils(ix)%v(n+1, ijk)
1860 box%stencils(ix)%v(n+1, ijk) = 0.0_dp
1913 subroutine mg_box_lpl_gradient(tree, id, mg, i_fc, fac)
1914 type(af_t),
intent(inout) :: tree
1915 integer,
intent(in) :: id
1916 type(mg_t),
intent(in) :: mg
1917 integer,
intent(in) :: i_fc
1918 real(dp),
intent(in) :: fac
1919 integer :: nc, i_phi, i_eps
1920 real(dp) :: inv_dr(ndim)
1922 associate(box => tree%boxes(id), cc => tree%boxes(id)%cc)
1925 inv_dr = fac / box%dr
1928 box%fc(1:nc+1, 1, i_fc) = inv_dr(1) * &
1929 (cc(1:nc+1, i_phi) - cc(0:nc, i_phi))
1931 box%fc(1:nc+1, 1:nc, 1, i_fc) = inv_dr(1) * &
1932 (cc(1:nc+1, 1:nc, i_phi) - cc(0:nc, 1:nc, i_phi))
1933 box%fc(1:nc, 1:nc+1, 2, i_fc) = inv_dr(2) * &
1934 (cc(1:nc, 1:nc+1, i_phi) - cc(1:nc, 0:nc, i_phi))
1936 box%fc(1:nc+1, 1:nc, 1:nc, 1, i_fc) = inv_dr(1) * &
1937 (cc(1:nc+1, 1:nc, 1:nc, i_phi) - &
1938 cc(0:nc, 1:nc, 1:nc, i_phi))
1939 box%fc(1:nc, 1:nc+1, 1:nc, 2, i_fc) = inv_dr(2) * &
1940 (cc(1:nc, 1:nc+1, 1:nc, i_phi) - &
1941 cc(1:nc, 0:nc, 1:nc, i_phi))
1942 box%fc(1:nc, 1:nc, 1:nc+1, 3, i_fc) = inv_dr(3) * &
1943 (cc(1:nc, 1:nc, 1:nc+1, i_phi) - &
1944 cc(1:nc, 1:nc, 0:nc, i_phi))
1947 if (iand(box%tag, mg%operator_mask) == mg_veps_box)
then
1952 box%fc(1, 1, i_fc) = 2 * inv_dr(1) * &
1953 (cc(1, i_phi) - cc(0, i_phi)) * &
1955 (cc(1, i_eps) + cc(0, i_eps))
1956 box%fc(nc+1, 1, i_fc) = 2 * inv_dr(1) * &
1957 (cc(nc+1, i_phi) - cc(nc, i_phi)) * &
1959 (cc(nc+1, i_eps) + cc(nc, i_eps))
1961 box%fc(1, 1:nc, 1, i_fc) = 2 * inv_dr(1) * &
1962 (cc(1, 1:nc, i_phi) - cc(0, 1:nc, i_phi)) * &
1963 cc(0, 1:nc, i_eps) / &
1964 (cc(1, 1:nc, i_eps) + cc(0, 1:nc, i_eps))
1965 box%fc(nc+1, 1:nc, 1, i_fc) = 2 * inv_dr(1) * &
1966 (cc(nc+1, 1:nc, i_phi) - cc(nc, 1:nc, i_phi)) * &
1967 cc(nc+1, 1:nc, i_eps) / &
1968 (cc(nc+1, 1:nc, i_eps) + cc(nc, 1:nc, i_eps))
1969 box%fc(1:nc, 1, 2, i_fc) = 2 * inv_dr(2) * &
1970 (cc(1:nc, 1, i_phi) - cc(1:nc, 0, i_phi)) * &
1971 cc(1:nc, 0, i_eps) / &
1972 (cc(1:nc, 1, i_eps) + cc(1:nc, 0, i_eps))
1973 box%fc(1:nc, nc+1, 2, i_fc) = 2 * inv_dr(2) * &
1974 (cc(1:nc, nc+1, i_phi) - cc(1:nc, nc, i_phi)) * &
1975 cc(1:nc, nc+1, i_eps) / &
1976 (cc(1:nc, nc+1, i_eps) + cc(1:nc, nc, i_eps))
1978 box%fc(1, 1:nc, 1:nc, 1, i_fc) = 2 * inv_dr(1) * &
1979 (cc(1, 1:nc, 1:nc, i_phi) - cc(0, 1:nc, 1:nc, i_phi)) * &
1980 cc(0, 1:nc, 1:nc, i_eps) / &
1981 (cc(1, 1:nc, 1:nc, i_eps) + cc(0, 1:nc, 1:nc, i_eps))
1982 box%fc(nc+1, 1:nc, 1:nc, 1, i_fc) = 2 * inv_dr(1) * &
1983 (cc(nc+1, 1:nc, 1:nc, i_phi) - cc(nc, 1:nc, 1:nc, i_phi)) * &
1984 cc(nc+1, 1:nc, 1:nc, i_eps) / &
1985 (cc(nc+1, 1:nc, 1:nc, i_eps) + cc(nc, 1:nc, 1:nc, i_eps))
1986 box%fc(1:nc, 1, 1:nc, 2, i_fc) = 2 * inv_dr(2) * &
1987 (cc(1:nc, 1, 1:nc, i_phi) - cc(1:nc, 0, 1:nc, i_phi)) * &
1988 cc(1:nc, 0, 1:nc, i_eps) / &
1989 (cc(1:nc, 1, 1:nc, i_eps) + cc(1:nc, 0, 1:nc, i_eps))
1990 box%fc(1:nc, nc+1, 1:nc, 2, i_fc) = 2 * inv_dr(2) * &
1991 (cc(1:nc, nc+1, 1:nc, i_phi) - cc(1:nc, nc, 1:nc, i_phi)) * &
1992 cc(1:nc, nc+1, 1:nc, i_eps) / &
1993 (cc(1:nc, nc+1, 1:nc, i_eps) + cc(1:nc, nc, 1:nc, i_eps))
1994 box%fc(1:nc, 1:nc, 1, 3, i_fc) = 2 * inv_dr(3) * &
1995 (cc(1:nc, 1:nc, 1, i_phi) - cc(1:nc, 1:nc, 0, i_phi)) * &
1996 cc(1:nc, 1:nc, 0, i_eps) / &
1997 (cc(1:nc, 1:nc, 1, i_eps) + cc(1:nc, 1:nc, 0, i_eps))
1998 box%fc(1:nc, 1:nc, nc+1, 3, i_fc) = 2 * inv_dr(3) * &
1999 (cc(1:nc, 1:nc, nc+1, i_phi) - cc(1:nc, 1:nc, nc, i_phi)) * &
2000 cc(1:nc, 1:nc, nc+1, i_eps) / &
2001 (cc(1:nc, 1:nc, nc+1, i_eps) + cc(1:nc, 1:nc, nc, i_eps))
2026 subroutine mg_box_field_norm(tree, id, i_fc, i_norm)
2027 type(af_t),
intent(inout) :: tree
2028 integer,
intent(in) :: id
2029 integer,
intent(in) :: i_fc
2031 integer,
intent(in) :: i_norm
2034 associate(box => tree%boxes(id))
2037 box%cc(1:nc, i_norm) = 0.5_dp * sqrt(&
2038 (box%fc(1:nc, 1, i_fc) + &
2039 box%fc(2:nc+1, 1, i_fc))**2)
2041 box%cc(1:nc, 1:nc, i_norm) = 0.5_dp * sqrt(&
2042 (box%fc(1:nc, 1:nc, 1, i_fc) + &
2043 box%fc(2:nc+1, 1:nc, 1, i_fc))**2 + &
2044 (box%fc(1:nc, 1:nc, 2, i_fc) + &
2045 box%fc(1:nc, 2:nc+1, 2, i_fc))**2)
2047 box%cc(1:nc, 1:nc, 1:nc, i_norm) = 0.5_dp * sqrt(&
2048 (box%fc(1:nc, 1:nc, 1:nc, 1, i_fc) + &
2049 box%fc(2:nc+1, 1:nc, 1:nc, 1, i_fc))**2 + &
2050 (box%fc(1:nc, 1:nc, 1:nc, 2, i_fc) + &
2051 box%fc(1:nc, 2:nc+1, 1:nc, 2, i_fc))**2 + &
2052 (box%fc(1:nc, 1:nc, 1:nc, 3, i_fc) + &
2053 box%fc(1:nc, 1:nc, 2:nc+1, 3, i_fc))**2)
2061 subroutine mg_box_lpllsf_gradient(tree, id, mg, i_fc, fac)
2062 type(af_t),
intent(inout) :: tree
2063 integer,
intent(in) :: id
2064 type(mg_t),
intent(in) :: mg
2065 integer,
intent(in) :: i_fc
2066 real(dp),
intent(in) :: fac
2068 integer :: n, nc, i_phi, ix_dist
2069 real(dp) :: inv_dr(NDIM), dd(2*NDIM)
2070 real(dp) :: bc(DTIMES(tree%n_cell))
2073 call mg_box_lpl_gradient(tree, id, mg, i_fc, fac)
2075 ix_dist = af_stencil_index(tree%boxes(id), mg_lsf_distance_key)
2076 if (ix_dist == af_stencil_none) error stop
"No distances stored"
2078 associate(box => tree%boxes(id), cc => tree%boxes(id)%cc)
2081 inv_dr = fac / box%dr
2082 bc = mg_lsf_boundary_value(box, mg)
2085 do n = 1,
size(box%stencils(ix_dist)%sparse_ix, 2)
2086 dd = box%stencils(ix_dist)%sparse_v(:, n)
2089 i = box%stencils(ix_dist)%sparse_ix(1, n)
2091 if (dd(1) < 1 .and. cc(ijk, mg%i_lsf) >= 0)
then
2092 box%fc(i, 1, i_fc) = inv_dr(1) * &
2093 (cc(i, i_phi) - bc(ijk)) / dd(1)
2095 if (dd(2) < 1 .and. cc(ijk, mg%i_lsf) >= 0)
then
2096 box%fc(i+1, 1, i_fc) = inv_dr(1) * &
2097 (bc(ijk) - cc(i, i_phi)) / dd(2)
2100 i = box%stencils(ix_dist)%sparse_ix(1, n)
2101 j = box%stencils(ix_dist)%sparse_ix(2, n)
2103 if (dd(1) < 1 .and. cc(ijk, mg%i_lsf) >= 0)
then
2104 box%fc(i, j, 1, i_fc) = inv_dr(1) * &
2105 (cc(i, j, i_phi) - bc(ijk)) / dd(1)
2107 if (dd(2) < 1 .and. cc(ijk, mg%i_lsf) >= 0)
then
2108 box%fc(i+1, j, 1, i_fc) = inv_dr(1) * &
2109 (bc(ijk) - cc(i, j, i_phi)) / dd(2)
2111 if (dd(3) < 1 .and. cc(ijk, mg%i_lsf) >= 0)
then
2112 box%fc(i, j, 2, i_fc) = inv_dr(2) * &
2113 (cc(i, j, i_phi) - bc(ijk)) / dd(3)
2115 if (dd(4) < 1 .and. cc(ijk, mg%i_lsf) >= 0)
then
2116 box%fc(i, j+1, 2, i_fc) = inv_dr(2) * &
2117 (bc(ijk) - cc(i, j, i_phi)) / dd(4)
2120 i = box%stencils(ix_dist)%sparse_ix(1, n)
2121 j = box%stencils(ix_dist)%sparse_ix(2, n)
2122 k = box%stencils(ix_dist)%sparse_ix(3, n)
2124 if (dd(1) < 1 .and. cc(ijk, mg%i_lsf) >= 0)
then
2125 box%fc(i, j, k, 1, i_fc) = inv_dr(1) * &
2126 (cc(ijk, i_phi) - bc(ijk)) / dd(1)
2128 if (dd(2) < 1 .and. cc(ijk, mg%i_lsf) >= 0)
then
2129 box%fc(i+1, j, k, 1, i_fc) = inv_dr(1) * &
2130 (bc(ijk) - cc(ijk, i_phi)) / dd(2)
2132 if (dd(3) < 1 .and. cc(ijk, mg%i_lsf) >= 0)
then
2133 box%fc(i, j, k, 2, i_fc) = inv_dr(2) * &
2134 (cc(ijk, i_phi) - bc(ijk)) / dd(3)
2136 if (dd(4) < 1 .and. cc(ijk, mg%i_lsf) >= 0)
then
2137 box%fc(i, j+1, k, 2, i_fc) = inv_dr(2) * &
2138 (bc(ijk) - cc(ijk, i_phi)) / dd(4)
2140 if (dd(5) < 1 .and. cc(ijk, mg%i_lsf) >= 0)
then
2141 box%fc(i, j, k, 3, i_fc) = inv_dr(3) * &
2142 (cc(ijk, i_phi) - bc(ijk)) / dd(5)
2144 if (dd(6) < 1 .and. cc(ijk, mg%i_lsf) >= 0)
then
2145 box%fc(i, j, k+1, 3, i_fc) = inv_dr(3) * &
2146 (bc(ijk) - cc(ijk, i_phi)) / dd(6)