diff --git a/src/integrators/controllers.jl b/src/integrators/controllers.jl index 416a6ea99d..a61328c65b 100644 --- a/src/integrators/controllers.jl +++ b/src/integrators/controllers.jl @@ -65,7 +65,7 @@ end q = inv(qmax) else expo = 1 / (get_current_adaptive_order(alg, integrator.cache) + 1) - qtmp = DiffEqBase.fastpow(EEst, expo) / gamma + qtmp = ^(EEst, expo) / gamma @fastmath q = DiffEqBase.value(max(inv(qmax), min(inv(qmin), qtmp))) # TODO: Shouldn't this be in `step_accept_controller!` as for the PI controller? integrator.qold = DiffEqBase.value(integrator.dt) / q @@ -138,8 +138,8 @@ end if iszero(EEst) q = inv(qmax) else - q11 = DiffEqBase.fastpow(EEst, float(beta1)) - q = q11 / DiffEqBase.fastpow(qold, float(beta2)) + q11 = ^(EEst, float(beta1)) + q = q11 / ^(qold, float(beta2)) integrator.q11 = q11 @fastmath q = max(inv(qmax), min(inv(qmin), q / gamma)) end @@ -412,7 +412,7 @@ end fac = min(gamma, (1 + 2 * maxiters) * gamma / (iter + 2 * maxiters)) end expo = 1 / (get_current_adaptive_order(alg, integrator.cache) + 1) - qtmp = DiffEqBase.fastpow(EEst, expo) / fac + qtmp = ^(EEst, expo) / fac @fastmath q = DiffEqBase.value(max(inv(qmax), min(inv(qmin), qtmp))) integrator.qold = q end @@ -426,7 +426,7 @@ function step_accept_controller!(integrator, controller::PredictiveController, a if integrator.success_iter > 0 expo = 1 / (get_current_adaptive_order(alg, integrator.cache) + 1) qgus = (integrator.dtacc / integrator.dt) * - DiffEqBase.fastpow((EEst^2) / integrator.erracc, expo) + ^((EEst^2) / integrator.erracc, expo) qgus = max(inv(qmax), min(inv(qmin), qgus / gamma)) qacc = max(q, qgus) else diff --git a/src/integrators/integrator_interface.jl b/src/integrators/integrator_interface.jl index 5bf13dc578..1242d8a0c9 100644 --- a/src/integrators/integrator_interface.jl +++ b/src/integrators/integrator_interface.jl @@ -480,7 +480,11 @@ function DiffEqBase.auto_dt_reset!(integrator::ODEIntegrator) integrator.opts.internalnorm, integrator.sol.prob, integrator) integrator.dtpropose = integrator.dt - integrator.stats.nf += 2 + increment_nf_from_initdt!(integrator.stats) +end + +function increment_nf_from_initdt!(stats) + stats.nf += 2 end function DiffEqBase.set_t!(integrator::ODEIntegrator, t::Real) diff --git a/src/integrators/integrator_utils.jl b/src/integrators/integrator_utils.jl index a3f45f456a..7abe83e6c9 100644 --- a/src/integrators/integrator_utils.jl +++ b/src/integrators/integrator_utils.jl @@ -231,57 +231,33 @@ function _loopfooter!(integrator) (integrator.opts.force_dtmin && abs(integrator.dt) <= timedepentdtmin(integrator)) if integrator.accept_step # Accept - integrator.stats.naccept += 1 + increment_accept!(integrator.stats) integrator.last_stepfail = false dtnew = DiffEqBase.value(step_accept_controller!(integrator, integrator.alg, q)) * oneunit(integrator.dt) integrator.tprev = integrator.t - integrator.t = if has_tstop(integrator) - tstop = integrator.tdir * first_tstop(integrator) - if abs(ttmp - tstop) < - 100eps(float(max(integrator.t, tstop) / oneunit(integrator.t))) * - oneunit(integrator.t) - tstop - else - ttmp - end - else - ttmp - end + integrator.t = fixed_t_for_floatingpoint_error!(integrator, ttmp) calc_dt_propose!(integrator, dtnew) handle_callbacks!(integrator) else # Reject + increment_reject!(integrator.stats) integrator.stats.nreject += 1 end elseif !integrator.opts.adaptive #Not adaptive - integrator.stats.naccept += 1 + increment_accept!(integrator.stats) integrator.tprev = integrator.t - integrator.t = if has_tstop(integrator) - tstop = integrator.tdir * first_tstop(integrator) - if abs(ttmp - tstop) < - 100eps(float(integrator.t / oneunit(integrator.t))) * oneunit(integrator.t) - tstop - else - ttmp - end - else - ttmp - end + integrator.t = fixed_t_for_floatingpoint_error!(integrator, ttmp) integrator.last_stepfail = false integrator.accept_step = true integrator.dtpropose = integrator.dt handle_callbacks!(integrator) end if integrator.opts.progress && integrator.iter % integrator.opts.progress_steps == 0 - t1, t2 = integrator.sol.prob.tspan - @logmsg(LogLevel(-1), - integrator.opts.progress_name, - _id=integrator.opts.progress_id, - message=integrator.opts.progress_message(integrator.dt, integrator.u, - integrator.p, integrator.t), - progress=(integrator.t - t1) / (t2 - t1)) + log_step!(integrator.opts.progress_name, integrator.opts.progress_id, + integrator.opts.progress_message, integrator.dt, integrator.u, + integrator.p, integrator.t, integrator.sol.prob.tspan) end # Take value because if t is dual then maxeig can be dual @@ -295,6 +271,37 @@ function _loopfooter!(integrator) nothing end +function increment_accept!(stats) + stats.naccept += 1 +end + +function increment_reject!(stats) + stats.nreject += 1 +end + +function log_step!(progress_name, progress_id, progress_message, dt, u, p, t, tspan) + t1, t2 = tspan + @logmsg(LogLevel(-1),progress_name, + _id=progress_id, + message=progress_message(dt, u, p, t), + progress=(t - t1) / (t2 - t1)) +end + +function fixed_t_for_floatingpoint_error!(integrator, ttmp) + if has_tstop(integrator) + tstop = integrator.tdir * first_tstop(integrator) + if abs(ttmp - tstop) < + 100eps(float(max(integrator.t, tstop) / oneunit(integrator.t))) * + oneunit(integrator.t) + tstop + else + ttmp + end + else + ttmp + end +end + # Use a generated function to call apply_callback! in a type-stable way @generated function apply_ith_callback!(integrator, time, upcrossing, event_idx, cb_idx, diff --git a/src/integrators/type.jl b/src/integrators/type.jl index a361302f9e..a3474ee785 100644 --- a/src/integrators/type.jl +++ b/src/integrators/type.jl @@ -177,7 +177,7 @@ mutable struct ODEIntegrator{algType <: Union{OrdinaryDiffEqAlgorithm, DAEAlgori do_error_check, event_last_time, vector_event_last_time, last_event_error, accept_step, isout, reeval_fsal, u_modified, reinitialize, isdae, - opts, stats, initializealg, differential_vars) # Leave off fsalfirst and last + opts, stats, initializealg, differential_vars, zero(u), zero(u)) end end diff --git a/src/perform_step/low_order_rk_perform_step.jl b/src/perform_step/low_order_rk_perform_step.jl index 8b8a0f63dd..f15fec13b9 100644 --- a/src/perform_step/low_order_rk_perform_step.jl +++ b/src/perform_step/low_order_rk_perform_step.jl @@ -797,10 +797,14 @@ function initialize!(integrator, cache::Tsit5Cache) integrator.k[6] = cache.k6 integrator.k[7] = cache.k7 integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 + increment_nf!(integrator.stats) return nothing end +function increment_nf!(stats) + stats.nf += 1 +end + @muladd function perform_step!(integrator, cache::Tsit5Cache, repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator T = constvalue(recursive_unitless_bottom_eltype(u)) @@ -832,7 +836,7 @@ end stage_limiter!(u, integrator, p, t + dt) step_limiter!(u, integrator, p, t + dt) f(k7, u, p, t + dt) - integrator.stats.nf += 6 + increment_nf_perform_step!(integrator.stats) if integrator.alg isa CompositeAlgorithm g7 = u g6 = tmp @@ -853,6 +857,10 @@ end return nothing end +function increment_nf_perform_step!(stats) + stats.nf += 6 +end + function initialize!(integrator, cache::DP5ConstantCache) integrator.kshortsize = 4 integrator.k = typeof(integrator.k)(undef, integrator.kshortsize)