src/gray_core.f90: refine realtime termination check

In some very rare cases the residual power check can stop the
integration too early.

For example, this extremely unlikely chain of events was observed in a
few cases while performing a parameter sweep (~3000 simulations):

  1. n⊥ converges on wrong branch ⇒ α jumps ⇒ dP/ds jumps (common)
  2. dP/ds jumps close to the peak (unlikely)
  3. the peak of dP/ds is close to 0.6P₀ (unlikely)
  4. dP/ds jumps to dP/ds_max + 10⁻¹² ⇒ wrong peak found (very unlikely)
  5. peak is at exactly the current point
     ⇒ three-point interpolation fails (unlikely)
This commit is contained in:
Michele Guerini Rocco 2024-04-05 14:04:04 +02:00
parent ffed0dc1c5
commit 7eeb34c7dc
Signed by: rnhmjoj
GPG Key ID: BFBAF4C975F76450

View File

@ -529,7 +529,16 @@ contains
end do end do
end if end if
if (params%raytracing%realtime .and. pow <= 0.4_wp_*p0ray(1)) then if (params%raytracing%realtime) then
! Check whether we are past the absorption peak
block
logical :: past_peak
integer :: tail
! We assume so if dP/ds has been decreasing in the last 8 steps
tail = max(2, i-8)
past_peak = i > 8 .and. all(dpds(tail:i) - dpds(tail-1:i-1) < 0)
if (past_peak .or. pow <= 0.1_wp_*p0ray(1)) then
! Compute the approximate position of the absorption peak ! Compute the approximate position of the absorption peak
block block
use utils, only : vmax, parabola_vertex use utils, only : vmax, parabola_vertex
@ -549,6 +558,9 @@ contains
exit exit
end if end if
end block
end if
! print ray positions for j=nrayr in local reference system ! print ray positions for j=nrayr in local reference system
if(mod(i,params%output%istpr) == 0) then if(mod(i,params%output%istpr) == 0) then
if(params%raytracing%nray > 1 .and. all(.not.iwait)) & if(params%raytracing%nray > 1 .and. all(.not.iwait)) &