| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(simulation_t), | intent(inout) | :: | me | |||
| real(kind=dp), | intent(in) | :: | err |
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