[?] Avoid troubles when using WhenEvent?

Dear Friends

I am implementing a digital controller using the function WhenEvent

SolH = NDSolve[{EqnsC, InitsC, control}, VarsC, {t, 0, tf}, 
   DiscreteVariables -> \[ScriptD][t]];
Plot[{Subscript[\[ScriptI], \[ScriptL]][t], \[ScriptD][t]} /. 
  SolH, {t, 0.0025, tf}]

the control input is updated every h seconds

h = 0.00001;
control = WhenEvent[Mod[t, h] == 0, \[ScriptD][t] -> ucontrol];

The simulation develops well when ucontrol= constant but it does not when I plug in my design function. It seem that the control which a large function of systems states reminds unevaluated. What I am doing wrong? I have followed the documentation.

Hopefully someone out there will have a suggestion.

I am including a notebook that contains the system specifications.

Best regards

Jesus

It’s a tricky feature of WhenEvent that it has the attribute HoldAll and, further, that the event action is calculated based on the literal code: that is, only values of t and the other variables that literally appear in the code \[ScriptD][t] -> ucontrol as written will be used and affected. Since the unevaluated ucontrol is a simple symbol, \[ScriptD][t] will be replaced by ucontrol, without evaluating ucontrol and without replacing the variables in its definition with their current values at the time step of the integration. In effect, \[ScriptD][t] is replaced by a function of t and other variables, while NDSolve expects it to be locally constant, with only discrete changes.

The proper way to use ucontrol in this setup is to inject its value into WhenEvent, one way being to use With as follows:

control = With[{ucontrol = ucontrol}, WhenEvent[Mod[t, h] == 0, \[ScriptD][t] -> ucontrol]]

Michael

Thank you very much! Your correction did solve my problems.
The solution is not intuitive or something that can be easily inferred from the documentation. So, thanks. I really appreciate it.!

Jesus

Jesus,

It’s not obvious, nor is it easy to explain!

You’re welcome & best wishes,

Michael