sim_step_management Subroutine

private subroutine sim_step_management(me, err)

Type Bound

simulation_t

Arguments

Type IntentOptional Attributes Name
class(simulation_t), intent(inout) :: me
real(kind=dp), intent(in) :: err

Calls

proc~~sim_step_management~~CallsGraph proc~sim_step_management simulation_t%sim_step_management proc~filter filter proc~sim_step_management->proc~filter proc~signal_v0d signal_t%signal_v0d proc~sim_step_management->proc~signal_v0d proc~sim_print sim_print proc~sim_step_management->proc~sim_print proc~signal_v1d signal_t%signal_v1d proc~signal_v0d->proc~signal_v1d interface~to_str to_str proc~sim_print->interface~to_str proc~s_to_str s_to_str proc~sim_print->proc~s_to_str proc~str_from_int str_from_int interface~to_str->proc~str_from_int proc~str_from_real str_from_real interface~to_str->proc~str_from_real

Called by

proc~~sim_step_management~~CalledByGraph proc~sim_step_management simulation_t%sim_step_management proc~main_loop main_loop proc~main_loop->proc~sim_step_management program~reims_p reims_p program~reims_p->proc~main_loop

Source Code

subroutine sim_step_management(me,err)
    class(simulation_t), intent(inout) :: me
    real(dp), intent(in) :: err
    real(dp) :: c1, ratio, new_dt
    integer  :: i
    me%step = me%step + 1

    if(me%explicit) then
        ! compute pressure criterium to switch from explicit to implicit
        me%expl_steps = me%expl_steps - 1
        me%explicit = err >= me%expl_tol .or. me%expl_steps > 0
        if (me%in_recovery) then
            me%recovery_steps_left = me%recovery_steps_left - 1
            if (me%recovery_steps_left == 0) me%in_recovery = .false.
        end if
        me%rejected = .false.
        new_dt = me%dt_exp
    else
        ! implicit step calculation and test for step rejection
        c1 = me%impl_tol%v0d() / max(err, sim_delta)
        ratio = filter(abs(me%c0 - 1.0_dp) < 1.0e-8_dp, c1, me%c0, me%kValue)
        me%c0 = c1
        me%rejected = ratio < 0.8_dp
        if (.not. me%rejected) me%consecutive_rollbacks = 0
        new_dt = ratio * me%dt
    endif

    if(me%rejected) then
        me%c0 = 1.0_dp
    else
        me%t = me%t + me%dt
        me%dtPrev5 = me%dtPrev4
        me%dtPrev4 = me%dtPrev3
        me%dtPrev3 = me%dtPrev2
        me%dtPrev2 = me%dtPrev1
        me%dtPrev1 = me%dt
    endif
    
    ! search for correct time event indicated by index: `i` shows next event
    i = 1; do while (me%events_time(i) < me%t + sim_delta); i = i + 1; enddo

    ! `dt` calculation by reducing step due to max_step or event
    me%dt = min(new_dt, me%max_step, me%events_time(i) - me%t)

    ! switch to explicit due to too small time step
    if(.not.me%explicit) then
        me%explicit = me%dt < me%dt_exp
        if(me%explicit) me%expl_steps = 3
    endif

    ! switch to explicit if current event requires it
    i = max(1,i-1) ! `i` shows current event
    if(abs(me%t - me%events_time(i)) < sim_delta .and. me%events_expl(i)) then
        me%expl_steps = max(me%expl_steps,3)
        me%explicit = .true. 
    endif

    if(me%explicit) then
        me%c0 = 1.0_dp
        me%dt = me%dt_exp
    endif

    call sim_print(me)
end subroutine sim_step_management