Line data Source code
1 : const MAXTRIES = 100 2 : 3 869953 : function step!(solver::Solver{N, T, S}, dy) where {N, T, S} 4 0 : @massert issuccess(solver.state) 5 : 6 1727706 : solver.tnew = reachdestination(solver) 7 869953 : solver.absh = abs(solver.tnew - solver.t) 8 : 9 869953 : minh = hmin(solver) 10 : # TODO [alg] update on change of solver.t? 11 : 12 869953 : solver.nsteps += 1 13 869953 : n = 0 14 : 15 : # Note: The rejected attribute is used to 16 : # 1. prevent an increase after a step that was first rejected 17 : # 2. prevent an increase during an "outer" bisection 18 : # (due to rejection of a successful step by the output() 19 : # callback). 20 : 21 1283875 : while n < MAXTRIES 22 1283875 : result = _step!(solver, dy, solver.t, stepsize(solver)) 23 : 24 1283875 : n += 1 25 : 26 1283875 : if issuccess(result) 27 879285 : yerr = result[] 28 : 29 879285 : setrelativeerror!(solver, yerr) 30 : 31 879285 : if isacceptable(solver) 32 : # Don't increase step size if last step was rejected. 33 869714 : if !solver.rejected 34 513811 : solver.absh = increasedstepsize(solver) 35 : end 36 : 37 869714 : solver.rejected = false 38 : 39 869714 : return state(result) 40 : else 41 9571 : solver.rejected = true 42 9571 : solver.absh = max(decreasedstepsize(solver), minh) 43 : # TODO: [alg] Matlab ode54 uses absh/2 after first increase ("failure") 44 : end 45 : else 46 0 : @massert(state(result) == Failed || state(result) == OutOfDomain, 47 : "dy($(solver.t),$(solver.y)) may only indicate Failed or OutOfDomain!") 48 404590 : solver.rejected = true 49 404590 : solver.absh = bisectedstepsize(solver) 50 : end 51 : 52 414161 : solver.tnew = solver.t + stepsize(solver) 53 : 54 414161 : if solver.absh <= minh 55 478 : issuccess(result) || return state(result) 56 : 57 0 : @warn "integration tolerance not met (t=$(solver.absh), hmin=$(minh))" 58 : # No more progress in t! 59 : 60 0 : return OutOfTolerance 61 : end 62 413922 : end 63 : 64 0 : @warn "Exceeded MAXTRIES=$(n) for integration step." 65 : 66 0 : return Failed 67 : end