The following example shows two functionally identical versions of the same WhenEvent. The two versions rely on two conditions Condition A and Condition B being satisfied and differ only in the order of the two conditions in the test:
event1: WhenEvent[Condition A && Condition B, actions]
event2: WhenEvent[Condition B && Condition A, actions]
event1 catches the event. event2 does not. Specifically:
event1 = WhenEvent[Evaluate[(toggle[t] == 1) &&
(f[S[3][t]][3][t] - f[s[2][t]][2][t] -
f[S[3][t]][2][t] + f[s[2][t]][2][t] < 1/100)],
Print[Row[{"End at ", t}]]; Endt = t; "StopIntegration"];
event2 = WhenEvent[Evaluate[(f[S[3][t]][3][t] - f[s[2][t]][2][t] -
f[S[3][t]][2][t] + f[s[2][t]][2][t] < 1/100) &&
(toggle[t] == 1)],
Print[Row[{"End at ", t}]]; Endt = t; "StopIntegration"];
The behavior is not consistent. In some cases, putting the toggle first, fails in others, as here, putting it second fails.
The example relies on an InterpolatingFunctions and requires precision beyond $MachinePrecision
The variables are:
vars = {s[2], S[3], Cee[3], toggle};
with discrete variables:
dvars = {toggle};
The initial conditions are: (sorry, the example relies on precision beyond Machine Precision)
initconds = {s[2][
2.144916158191085905678582630234886355478648729751836407222758673\
1192795799034279814104188519292500682575419414653357410794722550959999\
4740103335481901550805513733884265574044`150.] == 0,
S[3][2.144916158191085905678582630234886355478648729751836407222758\
6731192795799034279814104188519292500682575419414653357410794722550959\
9994740103335481901550805513733884265574044`150.] ==
0.5141981056084164574889912336386378969597921282604537374345128696\
7276225511023895075588192194971707237837697231024424087411575040786155\
697463394392200504350102087030477646296`150.,
Cee[3][2.\
1449161581910859056785826302348863554786487297518364072227586731192795\
7990342798141041885192925006825754194146533574107947225509599994740103\
335481901550805513733884265574044`150.] == \
-3.7705276082859175241150830989671843407151051321395010246298084465953\
1541552336488269236183953197224497473620271066746924871297392088887135\
59000071618940582406013351697741357`150.72211305893404,
toggle[2.\
1449161581910859056785826302348863554786487297518364072227586731192795\
7990342798141041885192925006825754194146533574107947225509599994740103\
335481901550805513733884265574044`150.] == 0};
The structural equations are:
eqns = {1/6 + E^(-4 s[2][t]) Derivative[1][Cee[2]][t] -
E^(-6 s[2][t]) Derivative[1][Cee[3]][t] -
1/6 Derivative[1][s[2]][t] -
4 E^(-4 s[2][t]) Cee[2][t] Derivative[1][s[2]][t] +
6 E^(-6 s[2][t]) Cee[3][t] Derivative[1][s[2]][t] == 0,
1/3 + Derivative[1][Cee[3]][t] == 0,
Derivative[1][S[3]][t] == (1 + 1/3 (-1 + E^(-6 S[3][t])) +
E^(-2 S[3][t]) Derivative[1][Cee[1]][t]) /
(2/3 + 2 E^(-2 S[3][t]) Cee[1][t] - 6 E^(-6 S[3][t]) Cee[3][t]) (1 - toggle[t]) +
(1/2 + 1/3 (-1 + E^(-6 S[3][t])) + E^(-4 S[3][t]) Derivative[1][Cee[2]][t])/
(1/6 + 4 E^(-4 S[3][t]) Cee[2][t] - 6 E^(-6 S[3][t]) Cee[3][t])toggle[t]};
The values of Cee1[t], Cee1[t], s1[t] and S[2][t] are given by (interpolating) functions ( trimmed these down for simplicity ):
Cee[1][t_] := (E^2 (3 - 2 t))/2;
c2points = \
{{1.907617896260767860011475497054036028318446809225144603058751249769\
4806815561571210736776933039564694633481296201461582370798924245736942\
3524758084468476006289788603675904564`150., \
-1.6831025439612610072201840729072758709522572250885761853047264124789\
1694241040816825546302252301433218634695817852766422718211647004164240\
745029965081096221365240085691615911`148.69639563085175}, \
{2.0413599262202311288072004258652563764328000038571304180020184499212\
4962733206272105034877743504054988781268826264296400206168659646195075\
76239092536031285484207595334058418`150., \
-2.9802757705333724103451089062908125112436423335851539685538595957120\
2338717379906886248580943245246548769431104777619881113407633292773814\
612688264309365198046850807694808338`150.}, \
{2.1394604850920685589650768423895210777029979995549773439374302764608\
0056809835998881873742408196150766674393824047905104371427542515405132\
966977252364434006623176591046317048`150., \
-4.1290963519258740800612276198173942460010650856221724269232975381140\
4900572369657119634822748960849090051135145287106739101240762847312401\
951640176423245809950065109807886723`150.}, \
{2.1433148556815212671537742657567336649611712343085516174662774029292\
7460921208246166328403525510432875056666575741050789208701128187287638\
520397966617725098222519176200496852`150., \
-4.1773462467078870788521151457077965227474892220344787423604223110122\
2726494814089345409587051196090635066927105048223158578001067150156773\
688524331255056708978911047703185954`150.}, \
{2.1449020728573698382827764277176392396912721240247133546700032241770\
6876700338027284581284655739244983125293596229770212201148191454691173\
642596838659032585171623606134361551`150., \
-4.1972810022299009595088425923374635051700681629514865849548865245995\
9246305764261381958227988898592942518117173506455750283004345251488660\
317405946505439657136177859108646252`150.}, \
{2.1524976456510253553962129239426156378722267983024141518610312867259\
7452105861449613310586508219833000268794054716280380487156080986214508\
113456303415163509006374736040187426`150., \
-4.2012488228255126776981064619713078189361133991512070759305156433629\
8726052930724806655293254109916500134397027358140190243578040493107254\
056728151707581754503187368028951726`150.}, \
{2.1704528697691028131628080771602455975585625465337067996509753587849\
0582284287752664906109596552119666892247042888895590631488377717233411\
383140967127700376963250532987180038`150., \
-4.2102264348845514065814040385801227987792812732668533998254876793924\
5291142143876332453054798276059833446123521444447795315744188858616705\
69157048356385018848162526650020244`150.}, \
{2.1997385373007056885504600897448336068263923196982653614879777587903\
7527453125485508254295651193074534301956318153762896616668903160238654\
423316201040305376342962332116725601`150., \
-4.2248692686503528442752300448724168034131961598491326807439888793951\
8763726562742754127147825596537267150978159076881448308334451580119327\
211658100520152688171481166059616834`150.}, \
{2.2426677524724705445204419922936684446643779334834943318368757760847\
7341792656130123831289308271205103044971736676542624140572644717873036\
922204315569577969701784100632101874`150., \
-4.2463338762362352722602209961468342223321889667417471659184378880423\
8670896328065061915644654135602551522485868338271312070286322358936518\
461102157784788984850892050316050932`150.}, \
{2.2772837446481053037681387264688332430308241721896523291778067433461\
6942613300774020831581745654555806249277125056899052504484167960112328\
376380723793629828293879072055725864`150., \
-4.2636418723240526518840693632344166215154120860948261645889033716730\
8471306650387010415790872827277903124638562528449526252242083980056164\
188190361896814914146939536027862927`150.}, \
{2.2825727937800136574760942092141594475729150546101098966785798733491\
8875391625084559228420170724077132249695456997820494325046387000946429\
985522474100794875187322697576350482`150., \
-4.2662863968900068287380471046070797237864575273050549483392899366745\
9437695812542279614210085362038566124847728498910247162523193500473214\
992761237050397437593661348788175241`150.}};
Cee[2] = Interpolation[c2points];
s1points = \
{{1.907617896260767860011475497054036028318446809225144603058751249769\
4806815561571210736776933039564694633481296201461582370798924245736942\
3524758084468476006289788603675904564`150.,
2.0552220905714129556973373980828549801740262538921295191524341804\
9357017940349356907852781700252741951426269368691848649449318994193148\
135437153310684034`128.62020399867365*^-21}, \
{2.0413599262202311288072004258652563764328000038571304180020184499212\
4962733206272105034877743504054988781268826264296400206168659646195075\
76239092536031285484207595334058418`150.,
0.1438911828442204935725243878882738952493618527856549839220804593\
5625748917823332280795156471990694299579743967873377464043981372658187\
524781886978853732783626102783057079565`150.}, \
{2.1394604850920685589650768423895210777029979995549773439374302764608\
0056809835998881873742408196150766674393824047905104371427542515405132\
966977252364434006623176591046317048`150.,
0.2234978924877639547733243542118064814045564346472745970093807492\
3106902407513938078883672651374541881865391290691918123330278702259751\
423488704780286016712273654093855760828`150.}, \
{2.1433148556815212671537742657567336649611712343085516174662774029292\
7460921208246166328403525510432875056666575741050789208701128187287638\
520397966617725098222519176200496852`150.,
0.2262938229965847979922893729604833117843691848353531586328403386\
0486328621807791334911808768322184596347570247516659382434374484076681\
633773206568249700412229013808699810722`150.}, \
{2.1449020728573698382827764277176392396912721240247133546700032241770\
6876700338027284581284655739244983125293596229770212201148191454691173\
642596838659032585171623606134361551`150.,
0.2274386983268234349722641495898086400088320534399941587258955730\
5406110760801461717549401883533381074453413492879710513146814248351680\
41226531551182106648792918210844384504`150.}, \
{2.1524976456510253553962129239426156378722267983024141518610312867259\
7452105861449613310586508219833000268794054716280380487156080986214508\
113456303415163509006374736040187426`150.,
0.2046194556266479114894462269693918112977027039898001156890038526\
2565704565770804156414009373920895948170755267352449123979716471628646\
757660551036602908857693542011191711511`150.}, \
{2.1704528697691028131628080771602455975585625465337067996509753587849\
0582284287752664906109596552119666892247042888895590631488377717233411\
383140967127700376963250532987180038`150.,
0.1613330783228310701053250413789435602236932564847625997844096722\
8734393416493934926628151042712058371531306154120554045894457390890492\
011488656451096244233403803609571098293`150.}, \
{2.1997385373007056885504600897448336068263923196982653614879777587903\
7527453125485508254295651193074534301956318153762896616668903160238654\
423316201040305376342962332116725601`150.,
0.1072742122004427274716358126528535424620851032575048041371412699\
6926598049700959551847229520969989786682939626764366707779527657393690\
074470140594612486017532911281477680022`150.}, \
{2.2426677524724705445204419922936684446643779334834943318368757760847\
7341792656130123831289308271205103044971736676542624140572644717873036\
922204315569577969701784100632101874`150.,
0.0461581812070294184757151282685988408076323405225660223909810006\
8259742850683984420496093581369244617360175653055392146635436195290941\
716705040628010198357611733708446053393`150.}, \
{2.2772837446481053037681387264688332430308241721896523291778067433461\
6942613300774020831581745654555806249277125056899052504484167960112328\
376380723793629828293879072055725864`150.,
0.0057055457060056295448370160812683374085937984973857263036062713\
4059080640127104859541121073382728776777258674316217064121230695841395\
818832069770391596715596071342029335437`150.}, \
{2.2825727937800136574760942092141594475729150546101098966785798733491\
8875391625084559228420170724077132249695456997820494325046387000946429\
985522474100794875187322697576350482`150.,
0.0000164205526152212166032480779119018332708249265010096431085712\
5736237769346524344259994646299987529478525153698171936862785409026397\
3395186010914832598911887191079997827526871447302897069324`150.}};
s[1] = Interpolation[s1points];
S2points = \
{{1.907617896260767860011475497054036028318446809225144603058751249769\
4806815561571210736776933039564694633481296201461582370798924245736942\
3524758084468476006289788603675904564`150.,
0.2555972772662321381648526908078933136183388957477167001636844734\
8106055126214072298836985577295125918675149302587323259236044938508514\
08136012742005788664176488519436371095`148.6888889906263}, \
{2.0413599262202311288072004258652563764328000038571304180020184499212\
4962733206272105034877743504054988781268826264296400206168659646195075\
76239092536031285484207595334058418`150.,
0.3999868938550802741951986141677280118318714064484576040266690718\
5426342229089866502111739344909276314161774503913459055657635665039189\
236127563582095935477123023992146439785`150.}, \
{2.1394604850920685589650768423895210777029979995549773439374302764608\
0056809835998881873742408196150766674393824047905104371427542515405132\
966977252364434006623176591046317048`150.,
0.4786883136209545792859937066712261354487123832746058194147770848\
9476802055809089568124582464557017161429451151946658066813533189216531\
161719436988864538022072595642290059281`150.}, \
{2.1433148556815212671537742657567336649611712343085516174662774029292\
7460921208246166328403525510432875056666575741050789208701128187287638\
520397966617725098222519176200496852`150.,
0.4814328302943097155888637601093749856568653260556738826950734954\
1428100138210863079268986240945507210792842670431641423429828289097095\
435224906310845297605899884630887554937`150.}, \
{2.1449020728573698382827764277176392396912721240247133546700032241770\
6876700338027284581284655739244983125293596229770212201148191454691173\
642596838659032585171623606134361551`150.,
0.4825562314583134967424318439985141484171820541242716736730865677\
4775559791157070311649761481292739413011096464080394070060557858837201\
550684616671990166917913854807197380287`150.}, \
{2.1524976456510253553962129239426156378722267983024141518610312867259\
7452105861449613310586508219833000268794054716280380487156080986214508\
113456303415163509006374736040187426`150.,
0.5049446981665887677211361351007665672082848309076926933805753238\
0844959149718694228670770833245587891243111649979967964839562076167648\
703690230083593851202554304237309283617`150.}, \
{2.1704528697691028131628080771602455975585625465337067996509753587849\
0582284287752664906109596552119666892247042888895590631488377717233411\
383140967127700376963250532987180038`150.,
0.5471155211735693496040709470801262540842240615192902139672243256\
2667020191603502168031800239131106228156059140677344800835317639098258\
510839323365008647966856963668557884889`150.}, \
{2.1997385373007056885504600897448336068263923196982653614879777587903\
7527453125485508254295651193074534301956318153762896616668903160238654\
423316201040305376342962332116725601`150.,
0.5992196256999047609374999588954923738405068718024291297459980081\
9872182816586916310037570042577026988538056540954459830320780335184626\
701872248236090193240415654537092937973`150.}, \
{2.2426677524724705445204419922936684446643779334834943318368757760847\
7341792656130123831289308271205103044971736676542624140572644717873036\
922204315569577969701784100632101874`150.,
0.6571975539248695315054172282033106166532344527205321922749750742\
2786060606343431743664022280579770911400633855278635579856002294580584\
273623182129252075459227931295787830937`150.}, \
{2.2772837446481053037681387264688332430308241721896523291778067433461\
6942613300774020831581745654555806249277125056899052504484167960112328\
376380723793629828293879072055725864`150.,
0.6949121779118717653475440036590601284112194802917932849675618170\
4633427302282746532760537267282667430336368821047010698945410350813400\
592488862761056162417239350916136729806`150.}, \
{2.2825727937800136574760942092141594475729150546101098966785798733491\
8875391625084559228420170724077132249695456997820494325046387000946429\
985522474100794875187322697576350482`150.,
0.7001682321237943327529007467937328937872073090037677451471472609\
5449029110817622825435024260497168894490291415805249103115677923448857\
534581655219099259204098776288774974834`150.}};
S[2] = Interpolation[S2points];
The Event trigger is defined by :
f[S[3][t]][3][t]- f[s[2][t]][3][t] - f[S[3][t]][2][t] + f[s[2][t]][2][t] < 1/100 when toggle[3][2] == 1, where
f[x_][i_][t_] := x + x /(2 i^2) - x^2/(2 i) + (x t)/i - (E^(-2 x i) Cee[i][t])/(2 i);
There are two flavors of events:
toggle events trigger a change in the discrete variable toggle[t]
toggleevent = WhenEvent[Evaluate[(S[3][t] < S[2][t])], {Print[Row[{"toggle event at ", t}]], toggle[t] -> 1, "RemoveEvent"}];
The event triggered by f can be written testing the toggle first or testing the toggle second:
event1 = WhenEvent[Evaluate[(toggle[t] ==1) &&
(f[S[3][t]][3][t] - f[s[2][t]][2][t] - f[S[3][t]][2][t] + f[s[2][t]][2][t] < 1/100)],
Print[Row[{"End at ", t}]]; Endt = t; "StopIntegration"];
event2 = WhenEvent[Evaluate[(f[S[3][t]][3][t] - f[s[2][t]][2][t] - f[S[3][t]][2][t] + f[s[2][t]][2][t] < 1/100) &&
(toggle[t] == 1)],
Print[Row[{"End at ", t}]]; Endt = t; "StopIntegration"];
Testing the toggle first
Dynamic[dynreport]
startt = 2.14491615819108590567858263023488635547864872975183640722275867311927957990342798141041885192925006825754194146533574107947225509599994740103335481901550805513733884265574044`150.;
Print[f[S[3][t]][3][t] - f[s[2][t]][3][t] - f[S[3][t]][2][t] + f[s[2][t]][2][t] /.t -> startt /. (initconds /. Equal -> Rule)];
sol1 = First[NDSolve[Join[eqns, initconds, {toggleevent, event1}], vars,
{t, -\[Infinity], startt}, DiscreteVariables ->dvars,
EvaluationMonitor :> {Pause[0.005];
dynreport = Column[{Row[{"Stop Criterion = ", Style[f[S[3][t]][3][t] - f[s[2][t]][3][t] - f[S[3][t]][2][t] + f[s[2][t]][2][t],
If[f[S[3][t]][3][t] - f[s[2][t]][2][t] - f[S[3][t]][2][t] + f[s[2][t]][2][t] < 1/100, Red, Black]]}],
Row[{"t = ", t}],
Row[{"s[2] = ", s[2][t]}],
Row[{"S[3] = ", Style[S[3][t], If[S[3][t] <= S[2][t], Green, Black]]}],
Row[{"C[3] = ", Cee[3][t]}],
Row[{"toggle = ", toggle[t]}]
}]}]];
Print[f[S[3][t]][3][t] - f[s[2][t]][3][t] - f[S[3][t]][2][t] + f[s[2][t]][2][t] /. sol1 /. t -> Endt];
This yields roughly the expected result:
(Output)
0.1180039500392493987880273545540440553287906640253476084874518519607305453545644587291707233055968411834327367482888605333490514238621090923567733881
toggle event at 2.09444
End at 2.09444
0.0212756
The precision of the event location is pretty poor (probably due to the trimmed InterpolatingFunctions), but it did capture the event.
Testing the toggle second does not work:
Endt = -\[Infinity]; startt =2.14491615819108590567858263023488635547864872975183640722275867311927957990342798141041885192925006825754194146533574107947225509599994740103335481901550805513733884265574044`150.;
Print[f[S[3][t]][3][t] - f[s[2][t]][3][t] - f[S[3][t]][2][t] + f[s[2][t]][2][t] /.t -> startt /. (initconds /. Equal -> Rule)];
sol2 = First[NDSolve[Join[eqns, initconds, {toggleevent, event2}], vars,
{t, -\[Infinity], startt}, DiscreteVariables ->dvars,
EvaluationMonitor :> {Pause[0.005];
dynreport2 =
Column[{Row[{"Stop Criterion = ", Style[f[S[3][t]][3][t] - f[s[2][t]][3][t] - f[S[3][t]][2][t] + f[s[2][t]][2][t],
If[f[S[3][t]][3][t] - f[s[2][t]][2][t] - f[S[3][t]][2][t] +f[s[2][t]][2][t] < 1/100, Red, Black]]}],
Row[{"t = ", t}],
Row[{"s[2] = ", s[2][t]}],
Row[{"S[3] = ", Style[S[3][t], If[S[3][t] <= S[2][t], Green, Black]]}],
Row[{"C[3] = ", Cee[3][t]}],
Row[{"toggle = ", toggle[t]}]
}]}]];
Print[Endt];
That yields
(Output)
0.1180039500392493987880273545540440553287906640253476084874518519607305453545644587291707233055968411834327367482888605333490514238621090923567733881
toggle event at 2.09444
NDSolve::ndsz: At t == 2.0667528920546507`, step size is effectively zero; singularity or stiff system suspected. >>
-\[Infinity]
event2 did not catch a point at which toggle[t]==1 and the function value was less than 1
A plot of the toggle value, the f test value and the cut off
Plot[{f[S[3][t]][3][t] - f[s[2][t]][3][t] - f[S[3][t]][2][t] + f[s[2][t]][2][t] /. sol2 /. t -> time,
toggle[t] /. sol2 /. t -> time, 1/100},
{time, 2.06676, startt},
PlotLegends -> {"f trigger value", "toggle value", "f trigger target"}]
Dt
is an internal,Protected
symbol. I cannot set it to a value at all. $\endgroup$WhenEvent
is incomplete. it has an odd number of[
brackets. $\endgroup$WhenEvent[<event>, <single action code>]
orWhenEvent[< event>, {<single action>, <single action>,...}]
. What you have is not a list of codes, but a single code that evaluates to a list of actions. The problem has nothing to do specifically withIf[]
: even,Null; {Dt = t, Dtoggle[t] -> 1, "RemoveEvent"}
fails. I guess you would need to repeat theIf[]
test for each action. $\endgroup$WhenEvent[event && condition, action]
is discussed here $\endgroup$WhenEvent[expr < 1/100 && condition, action]
triggers an event only when the value ofexpr
changes from greater than1/100
to less than1/100
. Yourf
trigger value does not do that in the last plot. PerhapsWhenEvent[expr == 1/100 && condition, action]
is what you're after. $\endgroup$