Subroutine to check if the current processor has converged and to update the next processor on the status Note that if the previous processor hasn't converged yet (pstatus), the current processor can't be converged yet either Check to see if tolerances are met
Until I hear the previous processor is done, recieve it's status
Check to see if I am converged Assign status and send it forward
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(pf_pfasst_t), | intent(inout) | :: | pf | |||
integer, | intent(in) | :: | send_tag | identifier for status send and receive |
subroutine pf_check_convergence_block(pf, send_tag)
type(pf_pfasst_t), intent(inout) :: pf
integer, intent(in) :: send_tag !! identifier for status send and receive
logical :: residual_converged, converged
! Shortcut for fixed iteration mode
if (pf%abs_res_tol == 0 .and. pf%rel_res_tol == 0) then
pf%state%pstatus = PF_STATUS_ITERATING
pf%state%status = PF_STATUS_ITERATING
return
end if
call call_hooks(pf, 1, PF_PRE_CONVERGENCE)
!> Check to see if tolerances are met
call pf_check_residual(pf, residual_converged)
!> Until I hear the previous processor is done, recieve it's status
if (pf%state%pstatus /= PF_STATUS_CONVERGED) call pf_recv_status(pf, send_tag)
!> Check to see if I am converged
converged = .false.
if (residual_converged) then
if (pf%rank == 0) then
converged = .true.
else ! I am not the first processor, so I need to check the previous one
if (pf%state%pstatus == PF_STATUS_CONVERGED) converged = .true.
end if
end if ! (residual_converged)
!> Assign status and send it forward
if (converged) then
if (pf%state%status == PF_STATUS_ITERATING) then
! If I am converged for the first time
! then flip my flag and send the last status update
pf%state%status = PF_STATUS_CONVERGED
call pf_send_status(pf, send_tag)
end if
else
! I am not converged, send the news
pf%state%status = PF_STATUS_ITERATING
call pf_send_status(pf, send_tag)
end if
call call_hooks(pf, 1, PF_POST_CONVERGENCE)
end subroutine pf_check_convergence_block