Perform FAS-FMG cycle (full approximation scheme, full multigrid).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(mg_t), | intent(inout) | :: | mg | |||
| logical, | intent(in) | :: | have_guess |
If false, start from phi = 0 |
||
| real(kind=dp), | intent(out), | optional | :: | max_res |
Store max(abs(residual)) |
subroutine mg_fas_fmg(mg, have_guess, max_res) type(mg_t), intent(inout) :: mg logical, intent(in) :: have_guess !< If false, start from phi = 0 real(dp), intent(out), optional :: max_res !< Store max(abs(residual)) integer :: lvl, i, id call check_methods(mg) if (timer_smoother == -1) call mg_add_timers(mg) call mg_timer_start(mg%timers(timer_total_fmg)) if (.not. have_guess) then do lvl = mg%highest_lvl, mg%lowest_lvl, -1 do i = 1, size(mg%lvls(lvl)%my_ids) id = mg%lvls(lvl)%my_ids(i) mg%boxes(id)%cc(:, :, :, mg_iphi) = 0.0_dp end do end do end if ! Ensure ghost cells are filled correctly call mg_fill_ghost_cells_lvl(mg, mg%highest_lvl, mg_iphi) do lvl = mg%highest_lvl, mg%lowest_lvl+1, -1 ! Set rhs on coarse grid and restrict phi call mg_timer_start(mg%timers(timer_update_coarse)) call update_coarse(mg, lvl) call mg_timer_end(mg%timers(timer_update_coarse)) end do if (mg%subtract_mean) then ! For fully periodic solutions, the mean source term has to be zero call subtract_mean(mg, mg_irhs, .false.) end if do lvl = mg%lowest_lvl, mg%highest_lvl ! Store phi_old do i = 1, size(mg%lvls(lvl)%my_ids) id = mg%lvls(lvl)%my_ids(i) mg%boxes(id)%cc(:, :, :, mg_iold) = mg%boxes(id)%cc(:, :, :,& mg_iphi) end do if (lvl > mg%lowest_lvl) then ! Correct solution at this lvl using lvl-1 data ! phi = phi + prolong(phi_coarse - phi_old_coarse) call mg_timer_start(mg%timers(timer_correct)) call correct_children(mg, lvl-1) call mg_timer_end(mg%timers(timer_correct)) ! Update ghost cells call mg_fill_ghost_cells_lvl(mg, lvl, mg_iphi) end if ! Perform V-cycle, possibly set residual on last iteration if (lvl == mg%highest_lvl) then call mg_fas_vcycle(mg, lvl, max_res, standalone=.false.) else call mg_fas_vcycle(mg, lvl, standalone=.false.) end if end do call mg_timer_end(mg%timers(timer_total_fmg)) end subroutine mg_fas_fmg