On the use of WhenEvent[]

Friends from the community,

I am using the function WhenEvent as explained inder WhenEvent/Applications/Power electronics/Boost Converter. The model use there considers only one logical(discrete variable) q[t]. However, it is a nice but oversimplified example, though. A beter example muts consider two logical variables. Is this possible with WhenEvent[]? I have searched a case like that without any luck.

I have tiried this

tf = 0.03;
system = {vo'[t] == -vo[t]/(r c) + i[t] (1 - q[t])/c , 
   i'[t] == (-(1 - q[t]) vo[t]/l + vi/l) g[t], vo[0] == 0, 
   i[0] == 0};
control = {q[0] == 0, 
   WhenEvent[Mod[t, \[Tau]] == 0.695 \[Tau], q[t] -> 0], 
   WhenEvent[Mod[t, \[Tau]] == 0, q[t] -> 1]};
control1 = {g[0] == 0, WhenEvent[q[t] == 1, g[t] -> 1], 
   WhenEvent[q[t] == 0 && i[t] != 0, g[t] -> 1], 
   WhenEvent[q[t] == 0 && i[t] == 0, g[t] -> 0]};
pars = {vi -> 5, vd -> 16, r -> 15, l -> 50 10^-6, 
   c -> 100 10^-6, \[Tau] -> 1/50000};
sol = NDSolve[{system, control, control1} /. pars, {vo, i, q, g}, {t, 
    0, tf}, DiscreteVariables -> {q, g}, MaxSteps -> Infinity];
GraphicsColumn[{Plot[{vo[t] /. sol, vd /. pars}, {t, 0, tf}, 
   PlotRange -> All, PlotPoints -> 100], 
  Plot[{i[t] /. sol}, {t, 0, tf}, PlotRange -> All], 
  Plot[q[t] /. sol, {t, 0, .0004}]}]

Note that in this case q[t] and g[t] are related and must hold several constraints.

Can anyone help?

Thanks in advance.

Jesus

Jesus,

This code seems to work for me. What problem are you seeing? g[t] and q[t] are set separately. Since you never hit the case when q[t]==0 and i[t]==0, g[t] is never reset to 0. If you try this code, you will see that the concept works I set g[t] ->0 when q[t] is 0 and i[t] <5 (but clearly it is meaningless for your application).

tf = 0.03;
system = {vo'[t] == -vo[t]/(r c) + i[t] (1 - q[t])/c, 
   i'[t] == (-(1 - q[t]) vo[t]/l + vi/l) g[t], vo[0] == 0, 
   i[0] == 0};
control = {q[0] == 0, 
   WhenEvent[Mod[t, \[Tau]] == 0.695 \[Tau], q[t] -> 0], 
   WhenEvent[Mod[t, \[Tau]] == 0, q[t] -> 1]};
control1 = {g[0] == 0, WhenEvent[q[t] == 1, g[t] -> 1], 
   WhenEvent[(q[t] == 0) && (i[t] != 0), g[t] -> 1], 
   WhenEvent[(q[t] == 0) && (i[t] < 5), g[t] -> 0]};
pars = {vi -> 5, vd -> 16, r -> 15, l -> 50*^-6, 
   c -> 100*^-6, \[Tau] -> 1/50000};
sol = NDSolve[{system, control, control1} /. pars, {vo, i, q, g}, {t, 
    0, tf}, DiscreteVariables -> {q, g}, MaxSteps -> Infinity];
GraphicsColumn[{Plot[{vo[t] /. sol, vd /. pars}, {t, 0, tf}, 
   PlotRange -> All, PlotPoints -> 100], 
  Plot[{i[t] /. sol}, {t, 0, tf}, PlotRange -> All], 
  Plot[q[t] /. sol, {t, 0, .0004}], 
  Plot[{g[t] /. sol}, {t, 0, tf}, PlotRange -> All]}]

One other note:

Mathematica notation for scientific notation is 50*^-6 to mean 50E-6 or 50 x 10^-6

Regards,

Neil

Dear Neil,
Based on you observation I have changed my code to be

tf = 0.003;
system = {vo'[t] == -vo[t]/(r c) + i[t] (1 - q[t])/c, 
   i'[t] == (-(1 - q[t]) vo[t]/l + vi/l) g[t], vo[0] == 0, 
   i[0] == 0};
control = {q[0] == 0, 
   WhenEvent[Mod[t, \[Tau]] == 0.695 \[Tau], q[t] -> 0], 
   WhenEvent[Mod[t, \[Tau]] == 0, q[t] -> 1]};
control1 = {g[0] == 0, WhenEvent[q[t] == 1, g[t] -> 1], 
   WhenEvent[(q[t] == 0) && (i[t] != 0), g[t] -> 1], 
   WhenEvent[(q[t] == 0) && (i[t] <= 0), g[t] -> 0]};
pars = {vi -> 5, vd -> 16, r -> 15, l -> 50*^-6, 
   c -> 100*^-6, \[Tau] -> 1/50000};
sol = NDSolve[{system, control, control1} /. pars, {vo, i, q, g}, {t, 
    0, tf}, DiscreteVariables -> {q, g}, MaxSteps -> Infinity];
{Plot[{vo[t] /. sol, vd /. pars}, {t, 0, tf}, PlotRange -> All, 
  PlotPoints -> 100], 
 Plot[{i[t] /. sol}, {t, 0, tf}, PlotRange -> All], 
 Plot[q[t] /. sol, {t, 0, .0004}], 
 Plot[{g[t] /. sol}, {t, 0, tf}, PlotRange -> All]}

The response

is closer to what is should be. See what happens in SystemModeler

It seems that some additional tuning is required but WhenEvent[] does a good job.
Any ideas to improve the response to equate the WSM solution?

Regards,

Jesus