logical function handle_numerical_error() integer :: i handle_numerical_error = (sim_error > 0) if (sim_error == 0) return do i = 1, min(sim_error, MAX_SIM_ERRORS) print*, trim(sim_error_msg(i)) enddo if (sim%in_recovery) then call close_hdf5_files() error stop trim(sim_error_msg(1)) end if sim%consecutive_rollbacks = sim%consecutive_rollbacks + 1 if (sim%consecutive_rollbacks > 3) then print*, 'Too many consecutive rollbacks (', sim%consecutive_rollbacks, ')' call close_hdf5_files() error stop trim(sim_error_msg(1)) end if ! 3-step rollback: restart from n-3 (= Old4) ! new Old=n-3, Old2=n-4, Old3=n-5 (BDF2 + LTE history) channels%StVar = channels%StVarOld4 channels%StVarOld = channels%StVarOld4 channels%StVarOld2 = channels%StVarOld5 channels%StVarOld3 = channels%StVarOld6 strands%StVar = strands%StVarOld4 strands%StVarOld = strands%StVarOld4 strands%StVarOld2 = strands%StVarOld5 strands%StVarOld3 = strands%StVarOld6 solids%StVar = solids%StVarOld4 solids%StVarOld = solids%StVarOld4 solids%StVarOld2 = solids%StVarOld5 solids%StVarOld3 = solids%StVarOld6 mesh2Ds%StVar = mesh2Ds%StVarOld4 mesh2Ds%StVarOld = mesh2Ds%StVarOld4 mesh2Ds%StVarOld2 = mesh2Ds%StVarOld5 mesh2Ds%StVarOld3 = mesh2Ds%StVarOld6 sim%t = sim%t - sim%dtPrev1 - sim%dtPrev2 - sim%dtPrev3 sim%dtPrev1 = sim%dtPrev4 sim%dtPrev2 = sim%dtPrev5 sim%explicit = .true. sim%expl_steps = 3 sim%rollback = .true. sim%in_recovery = .true. sim%recovery_steps_left = 3 sim_error = 0 end function handle_numerical_error