Trinity convergence condition - simple and experimental look for the averaged differential of the summed averaged heat flux to drop below a threshold
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer, | intent(in) | :: | istep | |||
real, | intent(in) | :: | heat_flux | |||
logical, | intent(inout) | :: | exit |
subroutine check_nonlin_convergence(istep, heat_flux, exit)
use gs2_time, only: user_time
use mp, only: proc0, broadcast, job
logical, intent(inout) :: exit
integer, intent(in) :: istep
real, intent(in) :: heat_flux
real :: heat_av_new, heat_av_diff
integer :: place, iwrite, nwrite_av
logical, parameter :: debug = .false.
if(proc0 .and. .not. (trin_istep /= 0 .and. istep == 0)) then
if(istep > 0) trin_istep = trin_istep + nwrite ! Total number of steps including restarted trinity runs
iwrite = trin_istep/nwrite ! Number of diagnostic write steps written
nwrite_av = conv_nstep_av/nwrite ! Number of diagnostic write steps to average over
heat_sum_av = (heat_sum_av * iwrite + heat_flux) / (iwrite+1) ! Cumulative average of heat flux
place = mod(trin_istep,conv_nstep_av)/nwrite
conv_heat(place) = heat_flux
if (debug) write(6,'(A,I5,A,e11.4,A,I6,I6)') 'Job ',job, &
' time = ',user_time, ' step = ',trin_istep
if (debug) write(6,'(A,I5,A,e11.4,A,e11.4)') 'Job ',job, &
' heat = ',heat_flux, ' heatsumav = ',heat_av
if (trin_istep >= conv_nstep_av) then
heat_av_new = sum(conv_heat) / nwrite_av
heat_av_diff = heat_av_new - heat_av
if(debug) write(6,'(A,I5,A,e11.4,A,e11.4)') 'Job ',job, &
' heat_sum_av_diff = ',heat_sum_av
heat_av = heat_av_new
! Convergence test - needs to be met conv_nsteps_converged/nwrite times in succession
if (abs(heat_av_diff) < heat_av_test) then
conv_isteps_converged = conv_isteps_converged + 1
else
conv_isteps_converged = 0
heat_av_test = heat_sum_av * conv_test_multiplier
endif
if ((conv_isteps_converged >= conv_nsteps_converged/nwrite) .and. &
(trin_istep >= conv_min_step)) then
if (debug) write(6,'(A,I5,A,I6,I3)')'Job ',job, &
' Reached convergence condition after step ',trin_istep
exit = .true. .and. exit_when_converged
endif
if(trin_istep > conv_max_step) then
write(6,'(A,I5,A,I7)') '*** Warning. Job ',job, &
' did not meet the convergence condition after ',trin_istep
exit = .true. .and. exit_when_converged
endif
endif
endif
call broadcast(exit)
end subroutine check_nonlin_convergence