Skip to content

Commit 08f4798

Browse files
committed
More work on when clauses for the adevs backend
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@9523 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent 372af65 commit 08f4798

File tree

1 file changed

+48
-28
lines changed

1 file changed

+48
-28
lines changed

Compiler/susan_codegen/SimCode/SimCodeAdevs.tpl

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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
>>
225227
end 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
>>
538551
end 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
>>
13941408
end 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
>>
22532273
end 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

Comments
 (0)