@@ -43,6 +43,13 @@ The fields are:
4343 inside this interval, dt is held constant.
4444- `failfactor`: post-Newton-failure shrink factor used by
4545 [`post_newton_controller!`](@ref).
46+ - 'discontinuity_detection': If `discontinuity_detection` is set to true, the algorithm will run the autonomous
47+ discontinuity detection to predict the best next timestep after step rejection.
48+ Otherwise, it follows the default step rejection algorithm. This feature is currently
49+ defaulted off.
50+ - `disco_probs`: If `discontinuity_detection` is set to true, this field holds the vector of
51+ `IntervalNonlinearProblem`s used for discontinuity detection. Otherwise, it can be left empty.
52+
4653
4754User-supplied overrides flow through controllers as a `NamedTuple` of
4855keyword arguments (whatever subset the user passed). At
@@ -506,10 +513,6 @@ the interval `[qmin, qmax]`.
506513A step will be accepted whenever the estimated error `get_EEst(integrator)` is
507514less than or equal to unity. Otherwise, the step is rejected and re-tried with
508515the predicted step size.
509- If `discontinuity_detection` is set to true, the algorithm will run the autonomous
510- discontinuity detection to predict the best next timestep after step rejection.
511- Otherwise, it follows the default step rejection algorithm. This feature is currently
512- defaulted off.
513516
514517## References
515518
@@ -563,18 +566,26 @@ end
563566
564567# TODO change signature to remove the q input
565568function step_accept_controller! (integrator, cache:: IControllerCache , alg, q)
566- (; qsteady_min, qsteady_max) = cache. controller. basic
569+ (; qsteady_min, qsteady_max, discontinuity_detection ) = cache. controller. basic
567570
568571 if qsteady_min <= q <= qsteady_max
569572 q = one (q)
570573 end
574+ if discontinuity_detection && integrator. curr_discontinuity != - 1 &&
575+ integrator. tdir * integrator. t >= integrator. tdir * integrator. disco_checkpoint
576+ integrator. curr_discontinuity = - 1
577+ end
571578 return integrator. dt / q # new dt
572579end
573580
574581function step_reject_controller! (integrator, cache:: IControllerCache , alg)
575582 discontinuity_detection = cache. controller. basic. discontinuity_detection
576583 if discontinuity_detection
584+ no_prior_discontinuity = (integrator. curr_discontinuity == - 1 )
577585 disco_dt = set_discontinuity (integrator. u, integrator. uprev, integrator)
586+ if no_prior_discontinuity && disco_dt > zero (disco_dt)
587+ add_tstop! (integrator, integrator. disco_checkpoint)
588+ end
578589 if disco_dt > zero (disco_dt)
579590 integrator. dt = disco_dt
580591 return integrator. dt
@@ -611,10 +622,7 @@ the interval `[qmin, qmax]`.
611622A step will be accepted whenever the estimated error `get_EEst(integrator)` is
612623less than or equal to unity. Otherwise, the step is rejected and re-tried with
613624the predicted step size.
614- If `discontinuity_detection` is set to true, the algorithm will run the autonomous
615- discontinuity detection to predict the best next timestep after step rejection.
616- Otherwise, it follows the default step rejection algorithm. This feature is currently
617- defaulted off.
625+
618626!!! note
619627
620628 The coefficients `beta1, beta2` are not scaled by the order of the method,
@@ -703,25 +711,35 @@ end
703711
704712function step_accept_controller! (integrator, cache:: PIControllerCache , alg, q)
705713 (; controller) = cache
706- (; qsteady_min, qsteady_max) = controller. basic
714+ (; qsteady_min, qsteady_max, discontinuity_detection ) = controller. basic
707715 qoldinit = controller. qoldinit
708716 EEst = DiffEqBase. value (get_EEst (integrator))
709717
710718 if qsteady_min <= q <= qsteady_max
711719 q = one (q)
712720 end
713- cache. errold = max (EEst, qoldinit)
721+
722+ if discontinuity_detection && integrator. curr_discontinuity != - 1 &&
723+ integrator. tdir * integrator. t >= integrator. tdir * integrator. disco_checkpoint
724+ integrator. curr_discontinuity = - 1
725+ cache. errold = qoldinit
726+ else
727+ cache. errold = max (EEst, qoldinit)
728+ end
714729 return integrator. dt / q # new dt
715730end
716731
717732function step_reject_controller! (integrator, cache:: PIControllerCache , alg)
718733 (; controller, q11) = cache
719734 (; qmin, gamma, discontinuity_detection) = controller. basic
720735 if discontinuity_detection
736+ no_prior_discontinuity = (integrator. curr_discontinuity == - 1 )
721737 disco_dt = set_discontinuity (integrator. u, integrator. uprev, integrator)
738+ if no_prior_discontinuity && disco_dt > zero (disco_dt) # found a discontinuity
739+ add_tstop! (integrator, integrator. disco_checkpoint)
740+ end
722741 if disco_dt > zero (disco_dt)
723- integrator. dt = disco_dt
724- return integrator. dt
742+ return integrator. dt = disco_dt
725743 end
726744 end
727745 return integrator. dt /= min (inv (qmin), q11 / gamma)
@@ -776,11 +794,6 @@ Some standard controller parameters suggested in the literature are
776794| H211PI | `1//6` | `1//6` | `0` |
777795| H312PID | `1//18` | `1//9` | `1//18` |
778796
779- If `discontinuity_detection` is set to true, the algorithm will run the autonomous
780- discontinuity detection to predict the best next timestep after step rejection.
781- Otherwise, it follows the default step rejection algorithm. This feature is currently
782- defaulted off.
783-
784797!!! note
785798
786799 In contrast to the [`PIController`](@ref), the coefficients `beta1, beta2, beta3`
@@ -940,22 +953,35 @@ end
940953
941954function step_accept_controller! (integrator, cache:: PIDControllerCache , alg, dt_factor)
942955 (; controller) = cache
943- (; qsteady_min, qsteady_max) = controller. basic
956+ (; qsteady_min, qsteady_max, discontinuity_detection ) = controller. basic
944957
945958 if qsteady_min <= inv (dt_factor) <= qsteady_max
946959 dt_factor = one (dt_factor)
947960 end
948- @inbounds begin
949- cache. err[3 ] = cache. err[2 ]
950- cache. err[2 ] = cache. err[1 ]
961+ if discontinuity_detection && integrator. curr_discontinuity != - 1 &&
962+ integrator. tdir * integrator. t >= integrator. tdir * integrator. disco_checkpoint
963+ integrator. curr_discontinuity = - 1
964+ @inbounds begin
965+ cache. err[3 ] = one (eltype (cache. err))
966+ cache. err[2 ] = cache. err[1 ]
967+ end
968+ else
969+ @inbounds begin
970+ cache. err[3 ] = cache. err[2 ]
971+ cache. err[2 ] = cache. err[1 ]
972+ end
951973 end
952974 return integrator. dt * dt_factor # new dt
953975end
954976
955977function step_reject_controller! (integrator, cache:: PIDControllerCache , alg)
956978 discontinuity_detection = cache. controller. basic. discontinuity_detection
957979 if discontinuity_detection
980+ no_prior_discontinuity = (integrator. curr_discontinuity == - 1 )
958981 disco_dt = set_discontinuity (integrator. u, integrator. uprev, integrator)
982+ if no_prior_discontinuity && disco_dt > zero (disco_dt)
983+ add_tstop! (integrator, integrator. disco_checkpoint)
984+ end
959985 if disco_dt > zero (disco_dt)
960986 integrator. dt = disco_dt
961987 return integrator. dt
@@ -1020,10 +1046,6 @@ integrator.dt / qacc
10201046```
10211047
10221048When it rejects, it's the same as the [`IController`](@ref):
1023- If `discontinuity_detection` is set to true, the algorithm will run the autonomous
1024- discontinuity detection to predict the best next timestep after step rejection.
1025- Otherwise, it follows the default step rejection algorithm. This feature is currently
1026- defaulted off.
10271049```julia
10281050if integrator.success_iter == 0
10291051 integrator.dt *= 0.1
@@ -1119,8 +1141,15 @@ function step_accept_controller!(integrator, cache::PredictiveControllerCache, a
11191141 if qsteady_min <= qacc <= qsteady_max
11201142 qacc = one (qacc)
11211143 end
1122- cache. dtacc = DiffEqBase. value (integrator. dt)
1123- cache. erracc = max (1.0e-2 , EEst)
1144+ if cache. controller. basic. discontinuity_detection && integrator. curr_discontinuity != - 1 &&
1145+ integrator. tdir * integrator. t >= integrator. tdir * integrator. disco_checkpoint
1146+ integrator. curr_discontinuity = - 1
1147+ cache. dtacc = DiffEqBase. value (integrator. dt)
1148+ cache. erracc = one (EEst)
1149+ else
1150+ cache. dtacc = DiffEqBase. value (integrator. dt)
1151+ cache. erracc = max (1.0e-2 , EEst)
1152+ end
11241153
11251154 return integrator. dt / qacc
11261155end
@@ -1130,7 +1159,11 @@ function step_reject_controller!(integrator, cache::PredictiveControllerCache, a
11301159 (; qold) = cache
11311160 discontinuity_detection = cache. controller. basic. discontinuity_detection
11321161 if discontinuity_detection
1162+ no_prior_discontinuity = (integrator. curr_discontinuity == - 1 )
11331163 disco_dt = set_discontinuity (integrator. u, integrator. uprev, integrator)
1164+ if no_prior_discontinuity && disco_dt > zero (disco_dt)
1165+ add_tstop! (integrator, integrator. disco_checkpoint)
1166+ end
11341167 if disco_dt > zero (disco_dt)
11351168 integrator. dt = disco_dt
11361169 return integrator. dt
0 commit comments