@@ -140,7 +140,10 @@ case SIMCODE(modelInfo = MODELINFO(varInfo = vi as VARINFO(__))) then
140140 bool atEvent;
141141 // Helping variables for when clauses
142142 bool helpVars[<%vi.numHelpVars%>], helpVars_saved[<%vi.numHelpVars%>];
143- const int numHelpVars() const { return <% vi.numHelpVars%> ; }
143+ int numHelpVars() const { return <% vi.numHelpVars%> ; }
144+ // Zero crossing variables
145+ int zc[<%vi.numZeroCrossings%>];
146+ int numZeroCrossings() const { return <% vi.numZeroCrossings%> ; }
144147
145148 void save_vars();
146149 void restore_vars();
@@ -220,7 +223,6 @@ case SIMCODE(modelInfo = MODELINFO(vars = vars as SIMVARS(__))) then
220223 <%(vars.paramVars |> SIMVAR(__) => 'double <%cref(name)%>;') ;separator="\n"%>
221224 <%(vars.intParamVars |> SIMVAR(__) => 'int <%cref(name)%>;') ;separator="\n"%>
222225 <%(vars.boolParamVars |> SIMVAR(__) => 'bool <%cref(name)%>;') ;separator="\n"%>
223- <%(zeroCrossings |> ZERO_CROSSING(__) hasindex i0 => 'int zc<%i0%>;') ; separator="\n"%>
224226 >>
225227end makeMemberVariables;
226228
@@ -258,9 +260,17 @@ case SIMCODE(modelInfo = MODELINFO(varInfo = vi as VARINFO(__))) then
258260 #define Adevs_GreaterEq(exp1,exp2) ((exp1)-(exp2))
259261 // True to false transitions occur at zero,
260262 // False to true transitions at positive epsilon
261- #define ADEVS_ZEROCROSSING(index,expr) z[ index ] = expr-(!zc##index)*epsilon
262- #define ADEVS_RELATIONTOZC(var,exp1,exp2,index,OpSym) if (zc##index == -1) zc##index=((exp1) OpSym (exp2)); var=zc##index
263- #define ADEVS_SAVEZEROCROSS(var,exp1,exp2,index,OpSym) if (zc##index == -1) zc##index=((exp1) OpSym (exp2)); var=zc##index
263+ #define ADEVS_ZEROCROSSING(index,expr) z[index] = expr-(!zc[index])*epsilon
264+ #define ADEVS_RELATIONTOZC(var,exp1,exp2,index,OpSym) \
265+ if (0 <= index) { \
266+ if (zc[index] == -1) zc[index]=((exp1) OpSym (exp2)); \
267+ var= zc[index]; \
268+ } else var=((exp1) OpSym (exp2))
269+ #define ADEVS_SAVEZEROCROSS(var,exp1,exp2,index,OpSym) \
270+ if (0 <= index) { \
271+ if (zc[index] == -1) zc[index]=((exp1) OpSym (exp2)); \
272+ var= zc[index]; \
273+ } else var=((exp1) OpSym (exp2))
264274
265275 <%lastIdentOfPath(modelInfo.name)%>::<%lastIdentOfPath(modelInfo.name)%>(int extra_state_events):
266276 ode_system<OMC _ADEVS_IO_TYPE >(
@@ -361,16 +371,17 @@ case SIMCODE(modelInfo = MODELINFO(vars = vars as SIMVARS(__))) then
361371 void <%lastIdentOfPath(modelInfo.name)%>::internal_event(double* q, const bool* state_event)
362372 {
363373 atEvent = true ;
364- <% (zeroCrossings |> ZERO_CROSSING(__) hasindex i0 =>
365- ' if (state_event[<%i0%>]) zc<%i0%> = !zc<%i0%>;' ) ; separator= " \n " %>
374+ // Switch the state event variables
375+ for (int i = 0; i < numZeroCrossings(); i++)
376+ if (state_event[i]) zc[i] = ! zc[i];
366377 // Record the values of the when clauses before the event
367378 for (int i = 0; i < numHelpVars(); i++)
368379 helpVars_saved[i] = helpVars[i];
369380 save_vars();
370381 calc_vars(q);
371382 // Update the values of the when clauses to the new values
372383 for (int i = 0; i < numHelpVars(); i++)
373- helpVars [i] = helpVars_saved [i];
384+ helpVars_saved [i] = helpVars [i];
374385 // Reinitialize state variables that need to be reinitialized
375386 <% (vars.stateVars |> SIMVAR(__) => ' q[<%index%>]=<%cref(name)%>;' ) ;separator= " \n " %>
376387 atEvent = false ;
@@ -431,7 +442,7 @@ case SIMCODE(modelInfo = MODELINFO(vars = vars as SIMVARS(__))) then
431442 <<
432443 void <%lastIdentOfPath(modelInfo.name)%>::clear_event_flags()
433444 {
434- <% (zeroCrossings | > ZERO_CROSSING(__) hasindex i0 = > ' zc<%i0%> = -1;' ) ; separator= " \n " %>
445+ for (int i = 0; i < numZeroCrossings(); i++) zc[i] = -1;
435446 }
436447
437448 void <%lastIdentOfPath(modelInfo.name)%>::init(double* q)
@@ -448,6 +459,8 @@ case SIMCODE(modelInfo = MODELINFO(vars = vars as SIMVARS(__))) then
448459 <% initVals(vars.paramVars)%>
449460 <% initVals(vars.intParamVars)%>
450461 <% initVals(vars.boolParamVars)%>
462+ // Save these to the old values so that pre() and edge() work
463+ save_vars();
451464 for (int i = 0; i < numHelpVars(); i++)
452465 helpVars_saved[i] = false ;
453466 // Calculate any equations that provide initial values
@@ -456,7 +469,7 @@ case SIMCODE(modelInfo = MODELINFO(vars = vars as SIMVARS(__))) then
456469 calc_vars();
457470 // Set initial state and helper variable values for the integrator
458471 for (int i = 0; i < numHelpVars(); i++)
459- helpVars [i] = helpVars_saved [i];
472+ helpVars_saved [i] = helpVars [i];
460473 <% (vars.stateVars |> SIMVAR(__) => ' q[<%index%>]=<%cref(name)%>;' ) ;separator= " \n " %>
461474 }
462475 >>
@@ -532,7 +545,7 @@ case SIMCODE(modelInfo = MODELINFO(vars = vars as SIMVARS(__))) then
532545 }
533546 // Calculate the odes
534547 <%allEqns(allEquations,whenClauses)%>
535- if (iterate) calc_vars(q ,true);
548+ if (iterate) calc_vars(NULL ,true);
536549 }
537550 >>
538551end makeDerFuncCalculator;
@@ -1386,9 +1399,10 @@ if reinits then
13861399//Reinit inside whenclause index: <%int%>
13871400<%preExp%>
13881401<%helpInits%>
1389- if (<%helpIf%>) {
1390- <% ifthen%>
1391- iterate = true ;
1402+ if (atEvent) {
1403+ if (<% helpIf%> ) {
1404+ <% ifthen%>
1405+ }
13921406}
13931407>>
13941408end genreinits;
@@ -1405,7 +1419,9 @@ template functionWhenReinitStatementThen(list<WhenOperator> reinits, Text &varDe
14051419 &preExp /*BUFC*/, &varDecls /*BUFD*/)
14061420 <<
14071421 <%preExp%>
1422+ double <%cref(stateVar)%>_tmp = <%cref(stateVar)%>;
14081423 <%cref(stateVar)%> = <%val%>;
1424+ iterate = iterate || (<%cref(stateVar)%>_tmp != <%cref(stateVar)%>);
14091425 >>
14101426 case TERMINATE(__) then
14111427 let &preExp = buffer "" /*BUFD*/
@@ -2220,11 +2236,13 @@ case SES_WHEN(left=left, right=right,conditions=conditions,elseWhen = NONE()) th
22202236 <<
22212237 <%preExp%>
22222238 <%helpInits%>
2223- if (<%helpIf%>) {
2224- <% preExp2%>
2225- <% cref(left)%> = <% exp%> ;
2226- } else {
2227- <% cref(left)%> = $P $old <% cref(left)%> ;
2239+ if (atEvent) {
2240+ if (<% helpIf%> ) {
2241+ <% preExp2%>
2242+ <% cref(left)%> = <% exp%> ;
2243+ } else {
2244+ <% cref(left)%> = $P $old <% cref(left)%> ;
2245+ }
22282246 }
22292247 >>
22302248 case SES_WHEN(left=left, right=right,conditions=conditions,elseWhen = SOME(elseWhenEq)) then
@@ -2241,13 +2259,15 @@ case SES_WHEN(left=left, right=right,conditions=conditions,elseWhen = NONE()) th
22412259 <<
22422260 <%preExp%>
22432261 <%helpInits%>
2244- if (<%helpIf%>) {
2245- <% preExp2%>
2246- <% cref(left)%> = <% exp%> ;
2247- }
2248- <%elseWhen%>
2249- else {
2250- <% cref(left)%> = $P $old <% cref(left)%> ;
2262+ if (atEvent) {
2263+ if (<% helpIf%> ) {
2264+ <% preExp2%>
2265+ <% cref(left)%> = <% exp%> ;
2266+ }
2267+ <%elseWhen%>
2268+ else {
2269+ <% cref(left)%> = $P $old <% cref(left)%> ;
2270+ }
22512271 }
22522272 >>
22532273end equationWhen;
@@ -5183,11 +5203,11 @@ template daeExpCall(Exp call, Context context, Text &preExp /*BUFP*/,
51835203 case CALL(path=IDENT(name="pre"), expLst={ arg} ) then
51845204 daeExpCallPre(arg, context, preExp, varDecls)
51855205 case CALL(path=IDENT(name="edge"), expLst={ arg as CREF(__)} ) then
5186- '(atEvent && <%cref(arg.componentRef)%> && !$P$old<%cref(arg.componentRef)%>)'
5206+ '(<%cref(arg.componentRef)%> && !$P$old<%cref(arg.componentRef)%>)'
51875207 case CALL(path=IDENT(name="edge"), expLst={ exp} ) then
51885208 error(sourceInfo(), 'Code generation does not support edge(<%printExpStr(exp)%>)')
51895209 case CALL(path=IDENT(name="change"), expLst={ arg as CREF(__)} ) then
5190- '(atEvent && <%cref(arg.componentRef)%> != $P$old<%cref(arg.componentRef)%>)'
5210+ '(<%cref(arg.componentRef)%> != $P$old<%cref(arg.componentRef)%>)'
51915211 case CALL(path=IDENT(name="change"), expLst={ exp} ) then
51925212 error(sourceInfo(), 'Code generation does not support change(<%printExpStr(exp)%>)')
51935213
0 commit comments