43 } casadi_ivp_event_phase_t;
59 if (status != IVP_SUCCESS) d->
status = status;
69 T1 theta = (t - d->
t0) / d->
h, th = 1. / d->
h;
71 for (q = 0; q < p->
n_dense; ++q) {
76 casadi_clear(ydot, p->
ny);
86 casadi_int i, k, ind = -1;
87 T1 H = d->
ev_tb - d->
ev_ta, c[4], sa, sb, s, v, t_i;
88 for (i = 0; i < p->
ne; ++i) {
89 if (d->
e_mask[i] == 0 || !(d->
e1[i] < 0))
continue;
92 c[1] = H * d->
edot0[i];
93 c[2] = 3 * (d->
e1[i] - d->
e0[i]) - H * (2 * d->
edot0[i] + d->
edot1[i]);
94 c[3] = 2 * (d->
e0[i] - d->
e1[i]) + H * (d->
edot0[i] + d->
edot1[i]);
98 for (k = 1; k <= 8; ++k) {
99 s =
static_cast<T1
>(k) / 8;
100 if (c[0] + s * (c[1] + s * (c[2] + s * c[3])) < 0) {
106 for (k = 0; k < 60 && sb - sa > 1e-15; ++k) {
108 v = c[0] + s * (c[1] + s * (c[2] + s * c[3]));
115 t_i = d->
ev_ta + sb * H;
116 if (ind < 0 || t_i < *t) {
125 template<
typename T1>
133 casadi_ivp_interpolate(d, t, d->
y_out);
135 casadi_ivp_dense_derivative(d, t, d->
ydot);
139 return casadi_ivp_event_request(d, IVP_EVAL_ZERO, phase);
143 template<
typename T1>
154 return casadi_ivp_event_done(d, IVP_SUCCESS);
158 template<
typename T1>
166 template<
typename T1>
171 d->
record = IVP_RECORD_EVENT;
174 return casadi_ivp_event_restart(d);
178 template<
typename T1>
183 return casadi_ivp_event_done(d, IVP_TOO_MANY_EVENTS);
188 casadi_ivp_interpolate(d, d->
t_ev, d->
y_out);
192 casadi_ivp_event_select(d, d->
ev_fired);
196 return casadi_ivp_event_request(d, IVP_EVAL_JUMP, IVP_EV_POST);
200 template<
typename T1>
213 if (d->
nom->ev_fired < 0)
return casadi_ivp_event_done(d, IVP_SUCCESS);
216 return casadi_ivp_event_fire(d);
219 if (!d->
e_valid)
return casadi_ivp_event_eval(d, d->
t0, IVP_EV_START);
220 return casadi_ivp_event_eval(d, d->
t, IVP_EV_END);
222 if (d->
fail)
return casadi_ivp_event_done(d, IVP_EVAL_FAILED);
223 casadi_copy(d->
em, p->
ne, d->
e0);
229 for (i = 0; i < p->
ne; ++i) {
230 if (fabs(d->
e0[i]) > 10 * fabs(d->
edot0[i]) * d->
ev_dt)
continue;
235 return casadi_ivp_event_eval(d, d->
t, IVP_EV_END);
237 if (d->
fail)
return casadi_ivp_event_done(d, IVP_EVAL_FAILED);
238 casadi_copy(d->
em, p->
ne, d->
e1);
242 for (i = 0; i < p->
ne; ++i) {
247 casadi_copy(d->
e1, p->
ne, d->
e0);
250 return casadi_ivp_event_done(d, IVP_SUCCESS);
255 casadi_ivp_event_hermite(d, &tn);
256 return casadi_ivp_event_eval(d, tn, IVP_EV_TRIAL);
258 if (d->
fail)
return casadi_ivp_event_done(d, IVP_EVAL_FAILED);
261 for (i = 0; i < p->
ne; ++i)
if (d->
e_mask[i] != 0 && d->
em[i] < 0)
any = 1;
264 casadi_copy(d->
em, p->
ne, d->
e1);
268 casadi_copy(d->
em, p->
ne, d->
e0);
272 ind = casadi_ivp_event_hermite(d, &tn);
273 dt = fabs(tn - d->
ev_tm);
278 return casadi_ivp_event_done(d, IVP_EVENT_FAILED);
283 return casadi_ivp_event_fire(d);
285 return casadi_ivp_event_eval(d, tn, IVP_EV_TRIAL);
287 if (d->
fail)
return casadi_ivp_event_done(d, IVP_EVAL_FAILED);
288 return casadi_ivp_event_post(d);
290 return casadi_ivp_event_done(d, IVP_EVENT_FAILED);
295 template<
typename T1>
305 casadi_ivp_event_select(d,
static_cast<casadi_int
>(d->
h));
306 casadi_ivp_clear_vjp(d);
310 return casadi_ivp_event_request(d, IVP_EVAL_JUMP_ADJ, IVP_EV_BACK_SEED);
313 return casadi_ivp_event_adj(d);
314 case IVP_EV_BACK_SEED:
315 if (d->
fail)
return casadi_ivp_event_done(d, IVP_EVAL_FAILED);
318 casadi_clear(d->
ry, p->
nrx + p->
nrz);
319 casadi_ivp_add_vjp(d, d->
ry);
322 if (casadi_ivp_tape_pop(d) || d->
record != IVP_RECORD_STEP) {
323 return casadi_ivp_event_done(d, IVP_EVENT_FAILED);
328 casadi_clear(d->
ry, p->
nr);
329 casadi_ivp_interpolate(d, d->
t_ev, d->
y_out);
330 casadi_ivp_seed_stages(d);
333 return casadi_ivp_event_done(d, IVP_SUCCESS);
335 return casadi_ivp_event_done(d, IVP_EVENT_FAILED);
bool any(const std::vector< bool > &v)
Check if any arguments are true.
casadi_ivp_record_t record
const casadi_ivp_prob< T1 > * prob
casadi_ivp_data< T1 > * nom
casadi_int max_event_iter