I need to force a whenevent action to be evaluated numerically all the times the event happens.
The fact is that I use very complicated matrices and I need to invert them so the system requires a lot of time to work. Is there a way to make whenevent work only with numerical values in order to go faster?
I post a sort of toy model to represent what would I want to do:
Attributes[WhenEvent] = {};
ser[t_] = {x1[t], x2[t]};
Aw = {{-1, 2}, {0, -4}};
fun := Inverse[{{x1[t]*x2[t]^2, 37}, {x1[t]*Cos[x2[t]], 2} }];
eqinn = ser[0] == {1, 1};
eqdyn = D[ser[t], t] == Aw.ser[t];
eqinn = ser[0] == {1, 1};
ev = WhenEvent[
Mod[t, 1], {ser[t] -> fun.ser[t], "RestartIntegration"}]
sol = NDSolveValue[{eqdyn, eqinn, ev}, ser[t], {t, 0, 4}];
Plot[sol, {t, 0, 4}]
Now If I execute ev I obtain:
ev
(*WhenEvent[
Mod[t, 1], {{x1[t],
x2[t]} -> {(2 x1[t])/(-37 Cos[x2[t]] x1[t] + 2 x1[t] x2[t]^2) - (
37 x2[t])/(-37 Cos[x2[t]] x1[t] + 2 x1[t] x2[t]^2), -((
Cos[x2[t]] x1[t]^2)/(-37 Cos[x2[t]] x1[t] +
2 x1[t] x2[t]^2)) + (
x1[t] x2[t]^3)/(-37 Cos[x2[t]] x1[t] + 2 x1[t] x2[t]^2)},
"RestartIntegration"}]*)
Just because it evaluates fun. In the real problem I can't do this way. A solution is to use the pattern test _?NumericQ, but I ask if is there another way because the function arguments would be too much in too much functions so I wouldn't write them every time as function arguments
So my goal is to have:
ev
(*WhenEvent[
Mod[t, 1], {{x1[t],
x2[t]} -> fun.ser[t]},
"RestartIntegration"}]*)
I would want that every time event happens It substitutes symbolic values with numerical values and then go on with matrix inversion