Perform Gauss-Seidel relaxation on box for a Laplacian operator
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(mg_t), | intent(inout) | :: | mg | |||
| integer, | intent(in) | :: | id | |||
| integer, | intent(in) | :: | nc | |||
| integer, | intent(in) | :: | redblack_cntr |
Iteration counter |
subroutine box_gs_vlpl(mg, id, nc, redblack_cntr) type(mg_t), intent(inout) :: mg integer, intent(in) :: id integer, intent(in) :: nc integer, intent(in) :: redblack_cntr !< Iteration counter integer :: i, j, k, i0, di logical :: redblack real(dp) :: idr2(2*3), u(2*3) real(dp) :: a0, a(2*3), c(2*3) ! Duplicate 1/dr^2 array to multiply neighbor values idr2(1:2*3:2) = 1/mg%dr(:, mg%boxes(id)%lvl)**2 idr2(2:2*3:2) = idr2(1:2*3:2) i0 = 1 redblack = (mg%smoother_type == mg_smoother_gsrb) if (redblack) then di = 2 else di = 1 end if ! The parity of redblack_cntr determines which cells we use. If ! redblack_cntr is even, we use the even cells and vice versa. associate (cc => mg%boxes(id)%cc, n => mg_iphi, i_eps => mg_iveps) do k = 1, nc do j = 1, nc if (redblack) i0 = 2 - iand(ieor(redblack_cntr, k+j), 1) do i = i0, nc, di a0 = cc(i, j, k, i_eps) u(1:2) = cc(i-1:i+1:2, j, k, n) a(1:2) = cc(i-1:i+1:2, j, k, i_eps) u(3:4) = cc(i, j-1:j+1:2, k, n) a(3:4) = cc(i, j-1:j+1:2, k, i_eps) u(5:6) = cc(i, j, k-1:k+1:2, n) a(5:6) = cc(i, j, k-1:k+1:2, i_eps) c(:) = 2 * a0 * a(:) / (a0 + a(:)) * idr2 cc(i, j, k, n) = (sum(c(:) * u(:)) - cc(i, j, k,& mg_irhs)) / sum(c(:)) end do end do end do end associate end subroutine box_gs_vlpl