Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 69.7% 428 / 0 / 614
Functions: -% 0 / 1 / 1
Branches: 48.7% 115 / 0 / 236

OMCompiler/Compiler/BackEnd/FindZeroCrossings.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package FindZeroCrossings
37 " file: FindZeroCrossings.mo
38 package: FindZeroCrossings
39 description: This package contains all the functions to find zero crossings
40 inside BackendDAE.
41
42 "
43
44 import Absyn;
45 import BackendDAE;
46 import DAE;
47 import DoubleEnded;
48
49 protected
50 import BackendDAEUtil;
51 import BackendDump;
52 import BackendEquation;
53 import BackendVariable;
54 import CheckModel;
55 import ComponentReference;
56 protected import ComponentReferenceBasics;
57 import DAEDump;
58 import DAEUtil;
59 import Error;
60 import Expression;
61 import ExpressionSimplify;
62 import Flags;
63 import HashTableExpToIndex;
64 import List;
65 import MetaModelica.Dangerous;
66 import SCode;
67 import SynchronousFeatures;
68 import Util;
69 import ZeroCrossings;
70 import MetaModelica.Dangerous.listReverseInPlace;
71 import ExpressionBasics;
72 import Config;
73
74 type ZCArgType = tuple<tuple<BackendDAE.ZeroCrossingSet, BackendDAE.ZeroCrossingSet, BackendDAE.ZeroCrossingSet, Integer>, tuple<Integer, BackendDAE.Variables, BackendDAE.Variables>, Option<list<BackendDAE.SimIterator>>>;
75 type ForArgType = tuple<DAE.Exp, list<DAE.Exp>, DAE.Exp, tuple<BackendDAE.ZeroCrossingSet, BackendDAE.ZeroCrossingSet, BackendDAE.ZeroCrossingSet, Integer>, tuple<Integer, BackendDAE.Variables, BackendDAE.Variables>>;
76 // =============================================================================
77 // section for preOptModule >>encapsulateWhenConditions<<
78 //
79 // This module encapsulates each when-condition in a boolean-variable
80 // $whenConditionsN and generates to each of these variables an equation
81 // $whenConditions = whenConditions
82 // =============================================================================
83
84 public function encapsulateWhenConditions "author: lochel"
85 input BackendDAE.BackendDAE inDAE;
86 output BackendDAE.BackendDAE outDAE;
87 protected
88 BackendDAE.EqSystems systs;
89 BackendDAE.EqSystem syst;
90 BackendDAE.Shared shared;
91 Integer index;
92 HashTableExpToIndex.HashTable ht "is used to avoid redundant condition-variables";
93 DoubleEnded.MutableList<BackendDAE.Var> vars;
94 DoubleEnded.MutableList<BackendDAE.Equation> eqns;
95 BackendDAE.Variables vars_;
96 BackendDAE.EquationArray eqns_, removedEqs;
97 algorithm
98 1074 BackendDAE.DAE(systs, shared) := inDAE;
99
100 1074 ht := HashTableExpToIndex.emptyHashTable();
101 1074 (systs, index, ht) := List.mapFold2(systs, encapsulateWhenConditions_EqSystem, 1, ht);
102
103 // shared removedEqns
104 1074 (removedEqs, vars, eqns, index, _) :=
105 BackendEquation.traverseEquationArray(shared.removedEqs, encapsulateWhenConditions_Equation,
106 (BackendEquation.emptyEqnsSized(BackendEquation.getNumberOfEquations(shared.removedEqs)), DoubleEnded.fromList({}), DoubleEnded.fromList({}), index, ht) );
107 1074 shared.removedEqs := removedEqs;
108 1074 eqns_ := BackendEquation.listEquation(DoubleEnded.toListNoCopyNoClear(eqns));
109 1074 vars_ := BackendVariable.listVar(DoubleEnded.toListNoCopyNoClear(vars));
110 1074 syst := BackendDAEUtil.createEqSystem(vars_, eqns_, {}, BackendDAE.UNSPECIFIED_PARTITION(), BackendEquation.emptyEqns());
111 1074 systs := List.appendElt(syst, systs);
112
113 1074 outDAE := BackendDAE.DAE(systs, shared);
114
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 855 times.
1074 if index > 1 then
115 219 outDAE := SynchronousFeatures.contPartitioning(outDAE);
116 end if;
117
118
1/2
✓ Branch 1 taken 1074 times.
✗ Branch 2 not taken.
1074 if Flags.isSet(Flags.DUMP_ENCAPSULATECONDITIONS) then
119 ✗ BackendDump.dumpBackendDAE(outDAE, "DAE after PreOptModule >>encapsulateWhenConditions<<");
120 end if;
121 end encapsulateWhenConditions;
122
123 protected function encapsulateWhenConditions_EqSystem "author: lochel"
124 input BackendDAE.EqSystem inEqSystem;
125 input Integer inIndex;
126 input HashTableExpToIndex.HashTable inHT;
127 output BackendDAE.EqSystem outEqSystem;
128 output Integer outIndex;
129 output HashTableExpToIndex.HashTable outHT;
130 algorithm
131 outEqSystem := match inEqSystem
132 local
133 BackendDAE.Variables orderedVars;
134 BackendDAE.EquationArray orderedEqs, removedEqs;
135 BackendDAE.EqSystem syst;
136 DoubleEnded.MutableList<BackendDAE.Var> varLst;
137 DoubleEnded.MutableList<BackendDAE.Equation> eqnLst;
138 case syst as BackendDAE.EQSYSTEM(orderedVars=orderedVars, orderedEqs=orderedEqs)
139 algorithm
140 1573 (orderedEqs, varLst, eqnLst, outIndex, outHT) :=
141 BackendEquation.traverseEquationArray( orderedEqs, encapsulateWhenConditions_Equation,
142 (BackendEquation.emptyEqnsSized(BackendEquation.getNumberOfEquations(orderedEqs)), DoubleEnded.fromList({}), DoubleEnded.fromList({}), inIndex, inHT) );
143
144 // removed equations
145 1573 (removedEqs, varLst, eqnLst, outIndex, outHT) :=
146 BackendEquation.traverseEquationArray( syst.removedEqs, encapsulateWhenConditions_Equation,
147 (BackendEquation.emptyEqnsSized(BackendEquation.getNumberOfEquations(syst.removedEqs)), varLst, eqnLst, outIndex, outHT) );
148 1573 syst.removedEqs := removedEqs;
149
150 1573 syst.orderedVars := BackendVariable.addVars(DoubleEnded.toListNoCopyNoClear(varLst), orderedVars);
151 1573 syst.orderedEqs := BackendEquation.addList(DoubleEnded.toListNoCopyNoClear(eqnLst), orderedEqs);
152 1573 then BackendDAEUtil.clearEqSyst(syst);
153 end match;
154 end encapsulateWhenConditions_EqSystem;
155
156 protected function encapsulateWhenConditions_Equation "author: lochel"
157 input BackendDAE.Equation inEq;
158 input tuple<BackendDAE.EquationArray, DoubleEnded.MutableList<BackendDAE.Var>, DoubleEnded.MutableList<BackendDAE.Equation>, Integer, HashTableExpToIndex.HashTable> inTpl;
159 output BackendDAE.Equation outEq;
160 output tuple<BackendDAE.EquationArray, DoubleEnded.MutableList<BackendDAE.Var>, DoubleEnded.MutableList<BackendDAE.Equation>, Integer, HashTableExpToIndex.HashTable> outTpl;
161 algorithm
162 (outEq,outTpl) := match (inEq,inTpl)
163 local
164 BackendDAE.Equation eqn, eqn2;
165 DoubleEnded.MutableList<BackendDAE.Var> vars;
166 DoubleEnded.MutableList<BackendDAE.Equation> eqns;
167 list<BackendDAE.Var> vars1;
168 list<BackendDAE.Equation> eqns1;
169 BackendDAE.WhenEquation whenEquation;
170 DAE.ElementSource source;
171 Integer index, size, sizePre;
172 BackendDAE.EquationArray equationArray;
173 DAE.Algorithm alg_;
174 list<DAE.Statement> stmts, preStmts, allPreStmts, allStmts;
175 HashTableExpToIndex.HashTable ht;
176 DAE.Expand crefExpand;
177 BackendDAE.EquationAttributes attr;
178
179 // when equation
180 case (BackendDAE.WHEN_EQUATION(size=size, whenEquation=whenEquation, source=source, attr=attr), (equationArray, vars, eqns, index, ht)) algorithm
181 491 (whenEquation, vars1, eqns1, index, ht) := encapsulateWhenConditions_Equations(whenEquation, source, index, ht);
182 491 DoubleEnded.push_list_back(vars, vars1);
183 491 DoubleEnded.push_list_back(eqns, eqns1);
184 491 eqn := BackendDAE.WHEN_EQUATION(size, whenEquation, source, attr);
185 491 equationArray := BackendEquation.add(eqn, equationArray);
186 491 then (eqn, (equationArray, vars, eqns, index, ht));
187
188 // removed algorithm
189 case (BackendDAE.ALGORITHM(size=0, alg=alg_, source=source, expand=crefExpand, attr=attr), (equationArray, vars, eqns, index, ht)) algorithm
190 1809 DAE.ALGORITHM_STMTS(statementLst=stmts) := alg_;
191 size := -index;
192 allPreStmts := {};
193 allStmts := {};
194
2/2
✓ Branch 1 taken 1811 times.
✓ Branch 2 taken 1809 times.
3620 for stmt in stmts loop
195 1811 (stmts, preStmts, index) := encapsulateWhenConditions_Algorithms({stmt}, vars, index);
196 1811 allPreStmts := listAppend(preStmts,allPreStmts);
197 1811 allStmts := listAppend(stmts,allStmts);
198 end for;
199 1809 stmts := listReverse(allStmts);
200 1809 sizePre := listLength(allPreStmts);
201 1809 size := size+index-sizePre;
202
203 1809 alg_ := DAE.ALGORITHM_STMTS(stmts);
204 1809 eqn := BackendDAE.ALGORITHM(size, alg_, source, crefExpand, attr);
205 1809 equationArray := BackendEquation.add(eqn, equationArray);
206
207
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1801 times.
1809 if sizePre > 0 then
208 8 alg_ := DAE.ALGORITHM_STMTS(allPreStmts);
209 8 eqn2 := BackendDAE.ALGORITHM(sizePre, alg_, source, crefExpand, attr);
210 8 DoubleEnded.push_front(eqns, eqn2);
211 end if;
212 1809 then (eqn, (equationArray, vars, eqns, index, ht));
213
214 // algorithm
215 case (BackendDAE.ALGORITHM(size=size, alg=alg_, source=source, expand=crefExpand, attr=attr), (equationArray, vars, eqns, index, ht)) algorithm
216 218 DAE.ALGORITHM_STMTS(statementLst=stmts) := alg_;
217 218 size := size-index;
218 218 (stmts, preStmts, index) := encapsulateWhenConditions_Algorithms(stmts, vars, index);
219 218 size := size+index;
220
221 218 stmts := listAppend(preStmts, stmts);
222
223 218 alg_ := DAE.ALGORITHM_STMTS(stmts);
224 218 eqn := BackendDAE.ALGORITHM(size, alg_, source, crefExpand, attr);
225 218 equationArray := BackendEquation.add(eqn, equationArray);
226 218 then (eqn, (equationArray, vars, eqns, index, ht));
227
228 case (_, (equationArray, vars, eqns, index, ht)) algorithm
229 46449 equationArray := BackendEquation.add(inEq, equationArray);
230 46449 then (inEq, (equationArray, vars, eqns, index, ht));
231 end match;
232 end encapsulateWhenConditions_Equation;
233
234 protected function encapsulateWhenConditions_Equations "author: lochel"
235 input BackendDAE.WhenEquation inWhenEquation;
236 input DAE.ElementSource inSource;
237 input Integer inIndex;
238 input HashTableExpToIndex.HashTable inHT;
239 output BackendDAE.WhenEquation outWhenEquation;
240 output list<BackendDAE.Var> outVars;
241 output list<BackendDAE.Equation> outEqns;
242 output Integer outIndex;
243 output HashTableExpToIndex.HashTable outHT;
244 algorithm
245 (outWhenEquation, outVars, outEqns, outIndex, outHT) := match inWhenEquation
246 local
247 Integer index;
248 BackendDAE.WhenEquation elsewhenPart, whenEquation;
249 list<BackendDAE.Var> vars, vars1;
250 list<BackendDAE.Equation> eqns, eqns1;
251
252 DAE.Exp condition;
253
254 HashTableExpToIndex.HashTable ht;
255
256 list<BackendDAE.WhenOperator> whenStmtLst;
257
258 // when - stmts
259 case BackendDAE.WHEN_STMTS(condition=condition, whenStmtLst=whenStmtLst, elsewhenPart=NONE()) algorithm
260 491 (condition, vars, eqns, index, ht) := encapsulateWhenConditions_Equations1(condition, inSource, inIndex, inHT);
261 491 whenEquation := BackendDAE.WHEN_STMTS(condition, whenStmtLst, NONE());
262 491 then (whenEquation, vars, eqns, index, ht);
263
264 // when - stmts - elsewhen
265 case BackendDAE.WHEN_STMTS(condition=condition, whenStmtLst=whenStmtLst, elsewhenPart=SOME(elsewhenPart)) algorithm
266 8 (elsewhenPart, vars1, eqns1, index, ht) := encapsulateWhenConditions_Equations(elsewhenPart, inSource, inIndex, inHT);
267 8 (condition, vars, eqns, index, ht) := encapsulateWhenConditions_Equations1(condition, inSource, index, ht);
268 8 whenEquation := BackendDAE.WHEN_STMTS(condition, whenStmtLst, SOME(elsewhenPart));
269 8 vars1 := listAppend(vars, vars1);
270 8 eqns1 := listAppend(eqns, eqns1);
271 8 then (whenEquation, vars1, eqns1, index, ht);
272
273 else algorithm
274 ✗ Error.addInternalError(getInstanceName() + " failed.", sourceInfo());
275 ✗ then fail();
276 end match;
277 end encapsulateWhenConditions_Equations;
278
279 protected function encapsulateWhenConditions_Equations1 "author: lochel"
280 input DAE.Exp inCondition;
281 input DAE.ElementSource inSource;
282 input Integer inIndex;
283 input HashTableExpToIndex.HashTable inHT;
284 output DAE.Exp outCondition;
285 output list<BackendDAE.Var> outVars;
286 output list<BackendDAE.Equation> outEqns;
287 output Integer outIndex;
288 output HashTableExpToIndex.HashTable outHT;
289 algorithm
290 (outCondition, outVars, outEqns, outIndex, outHT) := match inCondition
291 local
292 Integer index, localIndex;
293 BackendDAE.Var var;
294 BackendDAE.Equation eqn;
295 list<BackendDAE.Var> vars;
296 list<BackendDAE.Equation> eqns;
297 String crStr;
298
299 DAE.Exp condition;
300 list<DAE.Exp> array;
301
302 DAE.Type ty;
303 Boolean scalar "scalar for codegen" ;
304
305 HashTableExpToIndex.HashTable ht;
306
307 // we do not replace initial()
308 case DAE.CALL(path=Absyn.IDENT(name="initial"))
309 then (inCondition, {}, {}, inIndex, inHT);
310
311 // we do not replace constant expressions
312 case _
313 guard Expression.isConst(inCondition)
314 then (inCondition, {}, {}, inIndex, inHT);
315
316 // array-condition
317 case DAE.ARRAY(ty=ty, scalar=scalar, array=array)
318 algorithm
319 146 (array, vars, eqns, index, ht) := encapsulateWhenConditions_EquationsWithArrayConditions(array, inSource, inIndex, inHT);
320
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 146 times.
146 then (DAE.ARRAY(ty, scalar, array), vars, eqns, index, ht);
321
322 // simple condition [already in ht]
323 case _
324 guard BaseHashTable.hasKey(inCondition, inHT)
325 algorithm
326 227 localIndex := BaseHashTable.get(inCondition, inHT);
327 227 crStr := "$whenCondition" + intString(localIndex);
328 227 condition := DAE.CREF(DAE.CREF_IDENT(crStr, DAE.T_BOOL_DEFAULT, {}), DAE.T_BOOL_DEFAULT);
329 then (condition, {}, {}, inIndex, inHT);
330
331 // simple condition [not yet in ht]
332 else
333 algorithm
334 343 ht := BaseHashTable.add((inCondition, inIndex), inHT);
335 343 crStr := "$whenCondition" + intString(inIndex);
336
337 1029 var := BackendDAE.VAR(DAE.CREF_IDENT(crStr, DAE.T_BOOL_DEFAULT, {}), BackendDAE.DISCRETE(), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_BOOL_DEFAULT, NONE(), NONE(), {}, inSource, DAEUtil.setProtectedAttr(SOME(DAE.emptyVarAttrBool), true), NONE(), SOME(DAE.BCONST(true)), SOME(SCode.COMMENT(NONE(), SOME(ExpressionBasics.printExpStr(inCondition)))), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), true, false, false);
338 343 var := BackendVariable.setVarFixed(var, true);
339 343 eqn := BackendDAE.EQUATION(DAE.CREF(DAE.CREF_IDENT(crStr, DAE.T_BOOL_DEFAULT, {}), DAE.T_BOOL_DEFAULT), inCondition, inSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
340
341 343 condition := DAE.CREF(DAE.CREF_IDENT(crStr, DAE.T_BOOL_DEFAULT, {}), DAE.T_BOOL_DEFAULT);
342 343 then (condition, {var}, {eqn}, inIndex+1, ht);
343
344 end match;
345 end encapsulateWhenConditions_Equations1;
346
347 protected function encapsulateWhenConditions_EquationsWithArrayConditions "author: lochel"
348 input list<DAE.Exp> inConditionList;
349 input DAE.ElementSource inSource;
350 input Integer inIndex;
351 input HashTableExpToIndex.HashTable inHT;
352 output list<DAE.Exp> outConditionList = {};
353 output list<BackendDAE.Var> outVars = {};
354 output list<BackendDAE.Equation> outEqns = {};
355 output Integer outIndex = inIndex;
356 output HashTableExpToIndex.HashTable outHT = inHT;
357 protected
358 list<BackendDAE.Var> vars1;
359 list<BackendDAE.Equation> eqns1;
360 algorithm
361
2/2
✓ Branch 0 taken 300 times.
✓ Branch 1 taken 146 times.
446 for condition in inConditionList loop
362 300 (condition, vars1, eqns1, outIndex, outHT) := encapsulateWhenConditions_Equations1(condition, inSource, outIndex, outHT);
363 300 outVars := List.append_reverse(vars1,outVars);
364 300 outEqns := List.append_reverse(eqns1,outEqns);
365 outConditionList := condition::outConditionList;
366 end for;
367 146 outVars := listReverse(outVars);
368 146 outEqns := listReverse(outEqns);
369 146 outConditionList := listReverse(outConditionList);
370 end encapsulateWhenConditions_EquationsWithArrayConditions;
371
372 protected function encapsulateWhenConditions_Algorithms "author: lochel"
373 input list<DAE.Statement> inStmts;
374 input DoubleEnded.MutableList<BackendDAE.Var> vars;
375 input Integer inIndex;
376 output list<DAE.Statement> outStmts;
377 output list<DAE.Statement> outPreStmts; // these are additional statements that should be inserted directly before a STMT_WHEN
378 output Integer outIndex;
379 algorithm
380 (outStmts, outPreStmts, outIndex) := match inStmts
381 local
382 DAE.Exp condition;
383 DAE.Statement stmt, stmt2, elseWhen;
384 list<DAE.Statement> stmts, rest, stmts1, stmts_, preStmts, preStmts2, elseWhenList;
385 Integer index;
386 DAE.ElementSource source;
387 list<BackendDAE.Var> vars1;
388 list<DAE.ComponentRef> conditions;
389 Boolean initialCall;
390
391 case {} then ({}, {}, inIndex);
392
393 // when statement
394 case DAE.STMT_WHEN(exp=condition, statementLst=stmts1, elseWhen=NONE(), source=source)::rest algorithm
395 132 (condition, vars1, preStmts, index) := encapsulateWhenConditions_Algorithms1(condition, source, inIndex);
396 132 (conditions, initialCall) := BackendDAEUtil.getConditionList(condition);
397 132 DoubleEnded.push_list_front(vars, vars1);
398
399
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 124 times.
132 if listEmpty(CheckModel.algorithmStatementListOutputs(stmts1, DAE.EXPAND())) then
400 // without outputs
401 8 (stmts, preStmts2, index) := encapsulateWhenConditions_Algorithms(rest, vars, index);
402 8 preStmts := listAppend(preStmts, preStmts2) annotation(__OpenModelica_DisableListAppendWarning=true);
403
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
16 stmts := DAE.STMT_WHEN(condition, conditions, initialCall, stmts1, NONE(), source)::stmts;
404 else
405 124 (stmts, stmts_, index) := encapsulateWhenConditions_Algorithms(rest, vars, index);
406
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 7 times.
241 stmts_ := DAE.STMT_WHEN(condition, conditions, initialCall, stmts1, NONE(), source)::stmts_;
407 124 stmts := listAppend(stmts_, stmts);
408 end if;
409 132 then (stmts, preStmts, index);
410
411 // when - elsewhen statement
412 case (stmt as DAE.STMT_WHEN(exp=condition, statementLst=stmts1, elseWhen=SOME(elseWhen), source=source))::rest algorithm
413 53 (condition, vars1, preStmts, index) := encapsulateWhenConditions_Algorithms1(condition, source, inIndex);
414 53 (conditions, initialCall) := BackendDAEUtil.getConditionList(condition);
415 53 DoubleEnded.push_list_front(vars, vars1);
416
417 53 (elseWhenList, preStmts2, index) := encapsulateWhenConditions_Algorithms({elseWhen}, vars, index);
418
419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
53 if listEmpty(elseWhenList) then
420 ✗ (stmts, preStmts, index) := encapsulateWhenConditions_Algorithms(rest, vars, inIndex);
421 ✗ stmts_ := stmt::listAppend(preStmts, stmts);
422 else
423 53 elseWhen := List.last(elseWhenList);
424
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 22 times.
84 stmt2 := DAE.STMT_WHEN(condition, conditions, initialCall, stmts1, SOME(elseWhen), source);
425
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 51 times.
53 if listEmpty(CheckModel.algorithmStatementListOutputs({stmt2}, DAE.EXPAND())) then
426 // without outputs: the elsewhen's condition assignments stay
427 // pre-statements too, like the when's own
428 2 preStmts2 := listAppend(List.stripLast(elseWhenList), preStmts2);
429 2 preStmts := listAppend(preStmts, preStmts2) annotation(__OpenModelica_DisableListAppendWarning=true);
430 2 (stmts, preStmts2, index) := encapsulateWhenConditions_Algorithms(rest, vars, index);
431 2 preStmts := listAppend(preStmts, preStmts2) annotation(__OpenModelica_DisableListAppendWarning=true);
432 2 stmts_ := stmt2::stmts;
433 elseif listLength(elseWhenList)==1 then
434 51 preStmts := listAppend(preStmts, preStmts2) annotation(__OpenModelica_DisableListAppendWarning=true);
435 51 (stmts, stmts_, index) := encapsulateWhenConditions_Algorithms(rest, vars, index);
436 102 stmts_ := stmt2::listAppend(stmts_, stmts) annotation(__OpenModelica_DisableListAppendWarning=true);
437 else
438 ✗ (stmts, preStmts, index) := encapsulateWhenConditions_Algorithms(rest, vars, inIndex);
439 ✗ stmts_ := listAppend(preStmts, stmts);
440 end if;
441 end if;
442 53 then (stmts_, preStmts, index);
443
444 // no when statement
445 case stmt::rest algorithm
446 2180 (stmts, preStmts, index) := encapsulateWhenConditions_Algorithms(rest, vars, inIndex);
447 2180 stmts := listAppend(preStmts, stmts);
448 2180 then (stmt::stmts, {}, index);
449
450 else algorithm
451 ✗ Error.addInternalError(getInstanceName() + " failed.", sourceInfo());
452 ✗ then fail();
453 end match;
454 end encapsulateWhenConditions_Algorithms;
455
456 protected function encapsulateWhenConditions_Algorithms1 "author: lochel"
457 input DAE.Exp inCondition;
458 input DAE.ElementSource inSource;
459 input Integer inIndex;
460 output DAE.Exp outCondition;
461 output list<BackendDAE.Var> outVars;
462 output list<DAE.Statement> outStmts;
463 output Integer outIndex;
464 algorithm
465 (outCondition, outVars, outStmts, outIndex) := match inCondition
466 local
467 Integer index;
468 BackendDAE.Var var;
469 DAE.Statement stmt;
470 list<BackendDAE.Var> vars;
471 list<DAE.Statement> stmts;
472 String crStr;
473
474 DAE.Exp condition;
475 list<DAE.Exp> array;
476
477 DAE.Type ty;
478 Boolean scalar "scalar for codegen" ;
479
480 // we do not replace initial()
481 case DAE.CALL(path=Absyn.IDENT(name="initial"))
482 then (inCondition, {}, {}, inIndex);
483
484 // we do not replace constant expressions
485 case _ guard(Expression.isConst(inCondition)) algorithm
486 then (inCondition, {}, {}, inIndex);
487
488 // array-condition
489 case DAE.ARRAY(array={condition}) algorithm
490 6 crStr := "$whenCondition" + intString(inIndex);
491
492 18 var := BackendDAE.VAR(DAE.CREF_IDENT(crStr, DAE.T_BOOL_DEFAULT, {}), BackendDAE.DISCRETE(), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_BOOL_DEFAULT, NONE(), NONE(), {}, inSource, DAEUtil.setProtectedAttr(SOME(DAE.emptyVarAttrBool), true), NONE(), SOME(DAE.BCONST(true)), SOME(SCode.COMMENT(NONE(), SOME(ExpressionBasics.printExpStr(inCondition)))), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), true, false, false);
493 6 var := BackendVariable.setVarFixed(var, true);
494 6 stmt := DAE.STMT_ASSIGN(DAE.T_BOOL_DEFAULT, DAE.CREF(DAE.CREF_IDENT(crStr, DAE.T_BOOL_DEFAULT, {}), DAE.T_BOOL_DEFAULT), condition, inSource);
495
496 6 condition := DAE.CREF(DAE.CREF_IDENT(crStr, DAE.T_BOOL_DEFAULT, {}), DAE.T_BOOL_DEFAULT);
497 6 then (condition, {var}, {stmt}, inIndex+1);
498
499 // array-condition
500 case DAE.ARRAY(ty=ty, scalar=scalar, array=array) algorithm
501 51 (array, vars, stmts, index) := encapsulateWhenConditions_AlgorithmsWithArrayConditions(array, inSource, inIndex);
502
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 then (DAE.ARRAY(ty, scalar, array), vars, stmts, index);
503
504 // simple condition
505 case _ algorithm
506 222 crStr := "$whenCondition" + intString(inIndex);
507
508 666 var := BackendDAE.VAR(DAE.CREF_IDENT(crStr, DAE.T_BOOL_DEFAULT, {}), BackendDAE.DISCRETE(), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_BOOL_DEFAULT, NONE(), NONE(), {}, inSource, DAEUtil.setProtectedAttr(SOME(DAE.emptyVarAttrBool), true), NONE(), SOME(DAE.BCONST(true)), SOME(SCode.COMMENT(NONE(), SOME(ExpressionBasics.printExpStr(inCondition)))), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), true, false, false);
509 222 var := BackendVariable.setVarFixed(var, true);
510 222 stmt := DAE.STMT_ASSIGN(DAE.T_BOOL_DEFAULT, DAE.CREF(DAE.CREF_IDENT(crStr, DAE.T_BOOL_DEFAULT, {}), DAE.T_BOOL_DEFAULT), inCondition, inSource);
511
512 222 condition := DAE.CREF(DAE.CREF_IDENT(crStr, DAE.T_BOOL_DEFAULT, {}), DAE.T_BOOL_DEFAULT);
513 222 then (condition, {var}, {stmt}, inIndex+1);
514
515 else algorithm
516 ✗ Error.addInternalError(getInstanceName() + " failed.", sourceInfo());Error.addInternalError(getInstanceName() + " failed.", sourceInfo());
517 ✗ then fail();
518 end match;
519 end encapsulateWhenConditions_Algorithms1;
520
521 protected function encapsulateWhenConditions_AlgorithmsWithArrayConditions "author: lochel"
522 input list<DAE.Exp> inConditionList;
523 input DAE.ElementSource inSource;
524 input Integer inIndex;
525 output list<DAE.Exp> outConditionList = {};
526 output list<BackendDAE.Var> outVars = {};
527 output list<DAE.Statement> outStmts = {};
528 output Integer outIndex = inIndex;
529 protected
530 list<BackendDAE.Var> vars1;
531 list<DAE.Statement> stmt1;
532 algorithm
533
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 51 times.
174 for condition in inConditionList loop
534 123 (condition, vars1, stmt1, outIndex) := encapsulateWhenConditions_Algorithms1(condition, inSource, outIndex);
535 123 outVars := List.append_reverse(vars1,outVars);
536 123 outStmts := List.append_reverse(stmt1,outStmts);
537 outConditionList := condition::outConditionList;
538 end for;
539 51 outVars := listReverse(outVars);
540 51 outStmts := listReverse(outStmts);
541 51 outConditionList := listReverse(outConditionList);
542 end encapsulateWhenConditions_AlgorithmsWithArrayConditions;
543
544
545 // =============================================================================
546 // section for zero crossings
547 //
548 // This section contains all the functions to find zero crossings inside
549 // BackendDAE.
550 // =============================================================================
551
552 public function findZeroCrossings "This function finds all zero crossings in the list of equations and
553 the list of when clauses."
554 input BackendDAE.BackendDAE inDAE;
555 output BackendDAE.BackendDAE outDAE;
556 algorithm
557 //BackendDump.dumpBackendDAE(inDAE, "findZeroCrossings: inDAE");
558 1072 outDAE := BackendDAEUtil.mapEqSystem(inDAE, findZeroCrossings1);
559 //BackendDump.dumpBackendDAE(outDAE, "findZeroCrossings: outDAE");
560 end findZeroCrossings;
561
562 protected function findZeroCrossings1 "
563 This function finds all zero-crossings in the list of equations and the list of when clauses."
564 input BackendDAE.EqSystem inSyst;
565 input BackendDAE.Shared inShared;
566 output BackendDAE.EqSystem outSyst = inSyst;
567 output BackendDAE.Shared outShared;
568 protected
569 BackendDAE.Variables vars;
570 BackendDAE.EquationArray eqns;
571 BackendDAE.StrongComponents comps;
572 array<Integer> ass1, ass2;
573 BackendDAE.Matching matching;
574 algorithm
575 3937 BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns, matching=matching ) := inSyst;
576 (outSyst, outShared) := match BackendDAEUtil.getSubClock(inSyst, inShared)
577 local
578 BackendDAE.Variables globalKnownVars;
579 BackendDAE.EquationArray eqns1;
580 BackendDAE.EventInfo einfo;
581 list<BackendDAE.Equation> eqs_lst, eqs_lst1;
582 list<BackendDAE.TimeEvent> timeEvents;
583 BackendDAE.ZeroCrossingSet zero_crossings, sampleLst;
584 BackendDAE.ZeroCrossingSet relations;
585 Integer countMathFunctions;
586 Option<String> solver;
587 //No zero crossing for clocked discrete partitions;
588 case SOME(BackendDAE.SUBCLOCK(solver = solver))
589 guard BackendDump.optionString(solver) <> "External"
590 then (inSyst, inShared);
591 else
592 algorithm
593 3876 BackendDAE.SHARED( globalKnownVars=globalKnownVars, eventInfo=einfo) := inShared;
594 3876 BackendDAE.EVENT_INFO( timeEvents=timeEvents, zeroCrossings=zero_crossings,
595 samples=sampleLst, relations=relations,
596 numberMathEvents=countMathFunctions ) := einfo;
597 3876 eqs_lst := BackendEquation.equationList(eqns);
598 3876 (zero_crossings, eqs_lst1, countMathFunctions, relations, sampleLst) :=
599 findZeroCrossings2( vars, globalKnownVars, eqs_lst, 0,
600 countMathFunctions, zero_crossings, relations, sampleLst, {});
601 3876 eqs_lst1 := listReverse(eqs_lst1);
602 3876 eqns1 := BackendEquation.listEquation(eqs_lst1);
603
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3876 times.
3876 if Flags.isSet(Flags.RELIDX) then
604 ✗ print("findZeroCrossings1 number of relations: " + intString(ZeroCrossings.count(relations)) + "\n");
605 ✗ print("findZeroCrossings1 sample index: " + intString(ZeroCrossings.length(sampleLst)) + "\n");
606 end if;
607 // replace zerocrossing expressions also in jacobian matrices
608 try
609
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 3875 times.
3876 BackendDAE.MATCHING(comps=comps, ass1=ass1, ass2=ass2) := matching;
610 3875 comps := findZeroCrossingsinJacobians(comps, zero_crossings, relations, sampleLst, vars, globalKnownVars);
611 3875 outSyst.orderedEqs := eqns1;
612 7750 outSyst.matching := BackendDAE.MATCHING(ass1, ass2, comps);
613 else
614 end try;
615 3876 einfo := BackendDAE.EVENT_INFO( timeEvents, zero_crossings, relations, sampleLst,
616 countMathFunctions );
617 3876 then (outSyst, BackendDAEUtil.setSharedEventInfo(inShared, einfo));
618 end match;
619 end findZeroCrossings1;
620
621 protected function findZeroCrossings2
622 input BackendDAE.Variables inVariables1;
623 input BackendDAE.Variables globalKnownVars;
624 input list<BackendDAE.Equation> inEquationLst2;
625 input Integer inEqnCount;
626 input Integer inNumberOfMathFunctions;
627 input BackendDAE.ZeroCrossingSet inZeroCrossingLst;
628 input BackendDAE.ZeroCrossingSet inRelationsLst;
629 input BackendDAE.ZeroCrossingSet inSamplesLst;
630 input list<BackendDAE.Equation> inEquationLstAccum;
631 output BackendDAE.ZeroCrossingSet outZeroCrossingLst;
632 output list<BackendDAE.Equation> outEquationLst;
633 output Integer outNumberOfMathFunctions;
634 output BackendDAE.ZeroCrossingSet outRelationsLst;
635 output BackendDAE.ZeroCrossingSet outSamplesLst;
636 algorithm
637 (outZeroCrossingLst, outEquationLst, outNumberOfMathFunctions, outRelationsLst, outSamplesLst) := match inEquationLst2
638 local
639 BackendDAE.ZeroCrossingSet zcs1, res, res1, sampleLst;
640 BackendDAE.ZeroCrossingSet relationsLst;
641 Integer size, eq_count, countMathFunctions;
642 BackendDAE.Equation e;
643 list<BackendDAE.Equation> xs, eq_reslst, eqnsAccum;
644 DAE.Exp e1, e2, eres1, eres2;
645 DAE.ElementSource source, source_;
646 list<DAE.Statement> stmts, stmts_1;
647 DAE.ComponentRef cref;
648 Option<Integer> recordSize;
649 list<Integer> dimsize;
650 BackendDAE.WhenEquation weqn;
651 DAE.Expand expand;
652 BackendDAE.EquationAttributes eqAttr;
653
654 case {}
655 then (inZeroCrossingLst, inEquationLstAccum, inNumberOfMathFunctions, inRelationsLst, inSamplesLst);
656
657 // all algorithm stmts are processed firstly
658 case BackendDAE.ALGORITHM(size=size, alg=DAE.ALGORITHM_STMTS(stmts), source=source_, expand=expand, attr=eqAttr)::xs algorithm
659 226 eq_count := inEqnCount + 1;
660 226 (stmts_1, (_, _, _, (res, relationsLst, sampleLst, countMathFunctions), _)) := traverseStmtsExps(stmts, (DAE.SCONST("$$$"), {}, DAE.RCONST(0.0), (inZeroCrossingLst, inRelationsLst, inSamplesLst, inNumberOfMathFunctions), (eq_count, inVariables1, globalKnownVars)), globalKnownVars);
661 226 eqnsAccum := BackendDAE.ALGORITHM(size, DAE.ALGORITHM_STMTS(stmts_1), source_, expand, eqAttr)::inEquationLstAccum;
662 226 (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst) := findZeroCrossings2(inVariables1, globalKnownVars, xs, eq_count, countMathFunctions, res, relationsLst, sampleLst, eqnsAccum);
663 then (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst);
664
665 // check when equation condition
666 case (BackendDAE.WHEN_EQUATION(size=size, whenEquation=weqn, source=source_, attr=eqAttr))::xs algorithm
667 428 eq_count := inEqnCount + 1;
668 428 (weqn, countMathFunctions, res, relationsLst, sampleLst) := findZeroCrossingsWhenEqns(weqn, inZeroCrossingLst, inRelationsLst, inSamplesLst, inNumberOfMathFunctions, eq_count, -1, inVariables1, globalKnownVars);
669 428 eqnsAccum := BackendDAE.WHEN_EQUATION(size, weqn, source_, eqAttr)::inEquationLstAccum;
670 428 (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst) := findZeroCrossings2(inVariables1, globalKnownVars, xs, eq_count, countMathFunctions, res, relationsLst, sampleLst, eqnsAccum);
671 then (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst);
672
673 // after all algorithms and when clauses are processed, all equations are processed
674 case (BackendDAE.EQUATION(exp=e1, scalar=e2, source=source_, attr=eqAttr))::xs algorithm
675 62893 eq_count := inEqnCount + 1;
676 62893 (eres1, countMathFunctions, zcs1, relationsLst, sampleLst) := findZeroCrossings3(e1, inZeroCrossingLst, inRelationsLst, inSamplesLst, inNumberOfMathFunctions, eq_count, -1, inVariables1, globalKnownVars);
677 62893 (eres2, countMathFunctions, res, relationsLst, sampleLst) := findZeroCrossings3(e2, zcs1, relationsLst, sampleLst, countMathFunctions, eq_count, -1, inVariables1, globalKnownVars);
678 62893 eqnsAccum := BackendDAE.EQUATION(eres1, eres2, source_, eqAttr)::inEquationLstAccum;
679 62893 (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst) := findZeroCrossings2(inVariables1, globalKnownVars, xs, eq_count, countMathFunctions, res, relationsLst, sampleLst, eqnsAccum);
680 then (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst);
681
682 case (BackendDAE.COMPLEX_EQUATION(size=size, left=e1, right=e2, source=source, attr=eqAttr))::xs algorithm
683 683 eq_count := inEqnCount + 1;
684 683 (eres1, countMathFunctions, zcs1, relationsLst, sampleLst) := findZeroCrossings3(e1, inZeroCrossingLst, inRelationsLst, inSamplesLst, inNumberOfMathFunctions, eq_count, -1, inVariables1, globalKnownVars);
685 683 (eres2, countMathFunctions, res, relationsLst, sampleLst) := findZeroCrossings3(e2, zcs1, relationsLst, sampleLst, countMathFunctions, eq_count, -1, inVariables1, globalKnownVars);
686 683 eqnsAccum := BackendDAE.COMPLEX_EQUATION(size, eres1, eres2, source, eqAttr)::inEquationLstAccum;
687 683 (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst) := findZeroCrossings2(inVariables1, globalKnownVars, xs, eq_count, countMathFunctions, res, relationsLst, sampleLst, eqnsAccum);
688 then (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst);
689
690 case (BackendDAE.ARRAY_EQUATION(dimSize=dimsize, left=e1, right=e2, source=source, attr=eqAttr, recordSize=recordSize))::xs algorithm
691 238 eq_count := inEqnCount + 1;
692 238 (eres1, countMathFunctions, zcs1, relationsLst, sampleLst) := findZeroCrossings3(e1, inZeroCrossingLst, inRelationsLst, inSamplesLst, inNumberOfMathFunctions, eq_count, -1, inVariables1, globalKnownVars);
693 238 (eres2, countMathFunctions, res, relationsLst, sampleLst) := findZeroCrossings3(e2, zcs1, relationsLst, sampleLst, countMathFunctions, eq_count, -1, inVariables1, globalKnownVars);
694 238 eqnsAccum := BackendDAE.ARRAY_EQUATION(dimsize, eres1, eres2, source, eqAttr, recordSize)::inEquationLstAccum;
695 238 (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst) := findZeroCrossings2(inVariables1, globalKnownVars, xs, eq_count, countMathFunctions, res, relationsLst, sampleLst, eqnsAccum);
696 then (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst);
697
698 case (BackendDAE.SOLVED_EQUATION(componentRef=cref, exp=e1, source=source_, attr=eqAttr))::xs algorithm
699 115 (eres1, countMathFunctions, res, relationsLst, sampleLst) := findZeroCrossings3(e1, inZeroCrossingLst, inRelationsLst, inSamplesLst, inNumberOfMathFunctions, inEqnCount, -1, inVariables1, globalKnownVars);
700 115 eqnsAccum := BackendDAE.SOLVED_EQUATION(cref, eres1, source_, eqAttr)::inEquationLstAccum;
701 115 (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst) := findZeroCrossings2(inVariables1, globalKnownVars, xs, inEqnCount, countMathFunctions, res, relationsLst, sampleLst, eqnsAccum);
702 then (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst);
703
704 case (BackendDAE.RESIDUAL_EQUATION(exp=e1, source=source_, attr=eqAttr))::xs algorithm
705 7061 eq_count := inEqnCount + 1;
706 7061 (eres1, countMathFunctions, res, relationsLst, sampleLst) := findZeroCrossings3(e1, inZeroCrossingLst, inRelationsLst, inSamplesLst, inNumberOfMathFunctions, eq_count, -1, inVariables1, globalKnownVars);
707 7061 eqnsAccum := BackendDAE.RESIDUAL_EQUATION(eres1, source_, eqAttr)::inEquationLstAccum;
708 7061 (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst) := findZeroCrossings2(inVariables1, globalKnownVars, xs, eq_count, countMathFunctions, res, relationsLst, sampleLst, eqnsAccum);
709 then (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst);
710
711 case (e as BackendDAE.IF_EQUATION())::xs algorithm
712 ✗ eq_count := inEqnCount + 1;
713 ✗ (e, countMathFunctions, res, relationsLst, sampleLst) := findZeroCrossingsIfEqns(e, inZeroCrossingLst, inRelationsLst, inSamplesLst, inNumberOfMathFunctions, eq_count, -1, inVariables1, globalKnownVars);
714 eqnsAccum := e::inEquationLstAccum;
715 ✗ (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst) := findZeroCrossings2(inVariables1, globalKnownVars, xs, eq_count, countMathFunctions, res, relationsLst, sampleLst, eqnsAccum);
716 then (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst);
717
718 // let when equation pass they are discrete and can't contain ZeroCrossings
719 case e::xs algorithm
720 6 eq_count := inEqnCount + 1;
721 eqnsAccum := e::inEquationLstAccum;
722 6 (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst) := findZeroCrossings2(inVariables1, globalKnownVars, xs, eq_count, inNumberOfMathFunctions, inZeroCrossingLst, inRelationsLst, inSamplesLst, eqnsAccum);
723 then (res1, eq_reslst, countMathFunctions, relationsLst, sampleLst);
724 end match;
725 end findZeroCrossings2;
726
727 protected function findZeroCrossingsWhenEqns
728 input BackendDAE.WhenEquation inWhenEqn;
729 input BackendDAE.ZeroCrossingSet inZeroCrossings;
730 input BackendDAE.ZeroCrossingSet inrelationsinZC;
731 input BackendDAE.ZeroCrossingSet inSamplesLst;
732 input Integer incountMathFunctions;
733 input Integer counteq;
734 input Integer countwc;
735 input BackendDAE.Variables vars;
736 input BackendDAE.Variables globalKnownVars;
737 output BackendDAE.WhenEquation oWhenEqn;
738 output Integer outCountMathFunctions;
739 output BackendDAE.ZeroCrossingSet outZeroCrossings;
740 output BackendDAE.ZeroCrossingSet outrelationsinZC;
741 output BackendDAE.ZeroCrossingSet outSamplesLst;
742 algorithm
743 (oWhenEqn, outCountMathFunctions, outZeroCrossings, outrelationsinZC, outSamplesLst) := match inWhenEqn
744 local
745 DAE.Exp cond;
746 BackendDAE.WhenEquation we;
747 BackendDAE.ZeroCrossingSet zc, samples;
748 BackendDAE.ZeroCrossingSet relations;
749 Integer countMathFunctions;
750 list<BackendDAE.WhenOperator> whenStmtLst;
751 Option<BackendDAE.WhenEquation> oweelse;
752
753 case BackendDAE.WHEN_STMTS(condition=cond, whenStmtLst = whenStmtLst, elsewhenPart=oweelse) algorithm
754
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 435 times.
435 if Flags.isSet(Flags.RELIDX) then
755 ✗ BackendDump.debugStrExpStr("processed when condition: ", cond, "\n");
756 end if;
757 435 (cond, countMathFunctions, zc, relations, samples) := findZeroCrossings3(cond, inZeroCrossings, inrelationsinZC, inSamplesLst, incountMathFunctions, counteq, countwc, vars, globalKnownVars);
758
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 428 times.
435 if isSome(oweelse) then
759 7 SOME(we) := oweelse;
760 7 (we, countMathFunctions, zc, relations, samples) := findZeroCrossingsWhenEqns(we, zc, relations, samples, countMathFunctions, counteq, countwc, vars, globalKnownVars);
761 oweelse := SOME(we);
762 else
763 oweelse := NONE();
764 end if;
765
1/2
✓ Branch 1 taken 435 times.
✗ Branch 2 not taken.
435 then (BackendDAE.WHEN_STMTS(cond, whenStmtLst, oweelse), countMathFunctions, zc, relations, samples);
766 end match;
767 end findZeroCrossingsWhenEqns;
768
769 protected function findZeroCrossingsIfEqns
770 input BackendDAE.Equation inIfEqn;
771 input BackendDAE.ZeroCrossingSet inZeroCrossings;
772 input BackendDAE.ZeroCrossingSet inrelationsinZC;
773 input BackendDAE.ZeroCrossingSet inSamplesLst;
774 input Integer incountMathFunctions;
775 input Integer counteq;
776 input Integer countwc;
777 input BackendDAE.Variables vars;
778 input BackendDAE.Variables globalKnownVars;
779 output BackendDAE.Equation outIfEqn;
780 output Integer outCountMathFunctions;
781 output BackendDAE.ZeroCrossingSet outZeroCrossings;
782 output BackendDAE.ZeroCrossingSet outrelationsinZC;
783 output BackendDAE.ZeroCrossingSet outSamplesLst;
784 algorithm
785 (outIfEqn, outCountMathFunctions, outZeroCrossings, outrelationsinZC, outSamplesLst) := match inIfEqn
786 local
787 DAE.Exp condition;
788 list<DAE.Exp> conditions, restconditions;
789 BackendDAE.Equation ifeqn;
790 list<BackendDAE.Equation> eqnstrue, elseeqns;
791 list<list<BackendDAE.Equation>> eqnsTrueLst, resteqns;
792 BackendDAE.ZeroCrossingSet zc, samples;
793 BackendDAE.ZeroCrossingSet relations;
794 Integer countMathFunctions;
795 DAE.ElementSource source_;
796 BackendDAE.EquationAttributes eqAttr;
797
798 case BackendDAE.IF_EQUATION(conditions={}, eqnstrue={}, eqnsfalse=elseeqns, source=source_, attr=eqAttr) algorithm
799 ✗ (zc, elseeqns, countMathFunctions, relations, samples) := findZeroCrossings2(vars, globalKnownVars, elseeqns, counteq, incountMathFunctions, inZeroCrossings, inrelationsinZC, inSamplesLst, {});
800 ✗ elseeqns := listReverse(elseeqns);
801 ✗ then (BackendDAE.IF_EQUATION({}, {}, elseeqns, source_, eqAttr), countMathFunctions, zc, relations, samples);
802
803 case BackendDAE.IF_EQUATION(conditions=condition::restconditions, eqnstrue=eqnstrue::resteqns, eqnsfalse=elseeqns, source=source_, attr=eqAttr) algorithm
804 ✗ (condition, countMathFunctions, zc, relations, samples) := findZeroCrossings3(condition, inZeroCrossings, inrelationsinZC, inSamplesLst, incountMathFunctions, counteq, countwc, vars, globalKnownVars);
805 ✗ (zc, eqnstrue, countMathFunctions, relations, samples) := findZeroCrossings2(vars, globalKnownVars, eqnstrue, counteq, countMathFunctions, zc, relations, samples, {});
806 ✗ eqnstrue := listReverse(eqnstrue);
807 ✗ ifeqn := BackendDAE.IF_EQUATION(restconditions, resteqns, elseeqns, source_, eqAttr);
808 ✗ (BackendDAE.IF_EQUATION(conditions=conditions, eqnstrue=eqnsTrueLst, eqnsfalse=elseeqns, source=source_), countMathFunctions, zc, relations, samples) := findZeroCrossingsIfEqns(ifeqn, zc, relations, samples, countMathFunctions, counteq, countwc, vars, globalKnownVars);
809 conditions := condition::conditions;
810 ✗ eqnsTrueLst := eqnstrue::eqnsTrueLst;
811 ✗ then (BackendDAE.IF_EQUATION(conditions, eqnsTrueLst, elseeqns, source_, eqAttr), countMathFunctions, zc, relations, samples);
812 end match;
813 end findZeroCrossingsIfEqns;
814
815 protected function findZeroCrossingsinJacobians
816 input BackendDAE.StrongComponents inStrongComponents;
817 input BackendDAE.ZeroCrossingSet zeroCrossingLst;
818 input BackendDAE.ZeroCrossingSet relationsLst;
819 input BackendDAE.ZeroCrossingSet samplesLst;
820 input BackendDAE.Variables allVariables;
821 input BackendDAE.Variables globalKnownVars;
822 output BackendDAE.StrongComponents strongComponents = {};
823 protected
824 BackendDAE.StrongComponent outComponent;
825 algorithm
826
2/2
✓ Branch 0 taken 52587 times.
✓ Branch 1 taken 4623 times.
57210 for component in inStrongComponents loop
827 outComponent := matchcontinue component
828 local
829 BackendDAE.StrongComponent comp;
830 BackendDAE.Jacobian jacobian;
831 BackendDAE.FullJacobian fullJacobian;
832 BackendDAE.SymbolicJacobian symJacobian;
833 BackendDAE.SparsePattern sparsePattern;
834 BackendDAE.NonlinearPattern nonlinearPattern;
835 BackendDAE.SparseColoring coloring;
836 BackendDAE.TearingSet tearingSet;
837 case comp as BackendDAE.EQUATIONSYSTEM(jac=BackendDAE.FULL_JACOBIAN(jacobian=fullJacobian))
838 algorithm
839 70 fullJacobian := replaceZCExpinFullJacobian(fullJacobian, zeroCrossingLst, relationsLst, samplesLst, allVariables, globalKnownVars);
840 134 comp.jac := BackendDAE.FULL_JACOBIAN(jacobian=fullJacobian);
841 then comp;
842 case comp as BackendDAE.EQUATIONSYSTEM(jac=jacobian as BackendDAE.GENERIC_JACOBIAN(jacobian=SOME(symJacobian),sparsePattern=sparsePattern, coloring=coloring, nonlinearPattern=nonlinearPattern))
843 algorithm
844 115 symJacobian := replaceZCExpinSymJacobian(symJacobian, zeroCrossingLst, relationsLst, samplesLst, allVariables, globalKnownVars);
845 230 comp.jac := BackendDAE.GENERIC_JACOBIAN(jacobian=SOME(symJacobian),sparsePattern=sparsePattern,coloring=coloring, nonlinearPattern=nonlinearPattern);
846 then comp;
847 case comp as BackendDAE.TORNSYSTEM(strictTearingSet=tearingSet as BackendDAE.TEARINGSET(jac=jacobian as BackendDAE.GENERIC_JACOBIAN(jacobian=SOME(symJacobian),sparsePattern=sparsePattern, coloring=coloring, nonlinearPattern=nonlinearPattern)))
848 algorithm
849 633 symJacobian := replaceZCExpinSymJacobian(symJacobian, zeroCrossingLst, relationsLst, samplesLst, allVariables, globalKnownVars);
850 1266 tearingSet.jac := BackendDAE.GENERIC_JACOBIAN(jacobian=SOME(symJacobian),sparsePattern=sparsePattern,coloring=coloring, nonlinearPattern=nonlinearPattern);
851 633 comp.strictTearingSet := tearingSet;
852 then comp;
853 51772 else then component;
854 end matchcontinue;
855 strongComponents := outComponent::strongComponents;
856 end for;
857 4623 strongComponents := listReverse(strongComponents);
858 end findZeroCrossingsinJacobians;
859
860 protected function replaceZCExpinFullJacobian
861 input BackendDAE.FullJacobian fullJac;
862 input BackendDAE.ZeroCrossingSet zeroCrossingLst;
863 input BackendDAE.ZeroCrossingSet relationsLst;
864 input BackendDAE.ZeroCrossingSet samplesLst;
865 input BackendDAE.Variables allVariables;
866 input BackendDAE.Variables globalKnownVars;
867 output BackendDAE.FullJacobian outFullJac;
868 protected
869 list<tuple<Integer, Integer, BackendDAE.Equation>> jac, outJac = {};
870 Integer i,j;
871 BackendDAE.Equation eqn;
872 tuple<Integer, Integer, BackendDAE.Equation> element;
873 algorithm
874 70 jac := Util.getOption(fullJac);
875
2/2
✓ Branch 0 taken 7061 times.
✓ Branch 1 taken 67 times.
7128 for element in jac loop
876 7061 (i,j,eqn) := element;
877
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 7061 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 7061 times.
7061 (_, {eqn}, _, _, _) :=
878 findZeroCrossings2( allVariables, globalKnownVars, {eqn}, 0,
879 0, zeroCrossingLst, relationsLst, samplesLst, {});
880 7061 outJac := (i,j,eqn)::outJac;
881 end for;
882 67 outJac := listReverse(outJac);
883 outFullJac := SOME(outJac);
884 end replaceZCExpinFullJacobian;
885
886 protected function replaceZCExpinSymJacobian
887 input BackendDAE.SymbolicJacobian symJac;
888 input BackendDAE.ZeroCrossingSet zeroCrossingLst;
889 input BackendDAE.ZeroCrossingSet relationsLst;
890 input BackendDAE.ZeroCrossingSet samplesLst;
891 input BackendDAE.Variables allVariables;
892 input BackendDAE.Variables globalKnownVars;
893 output BackendDAE.SymbolicJacobian outSymJac;
894 protected
895 BackendDAE.BackendDAE jacBDAE;
896 String name;
897 list<BackendDAE.Var> seedVars, tmpVars, resultVars;
898 list<DAE.ComponentRef> depCrefs;
899 algorithm
900 748 (jacBDAE, name, seedVars, tmpVars, resultVars, depCrefs) := symJac;
901 748 jacBDAE := replaceZeroCrossingsJacBackend(jacBDAE, zeroCrossingLst, relationsLst, samplesLst, allVariables, globalKnownVars);
902 748 outSymJac := (jacBDAE, name, seedVars, tmpVars, resultVars, depCrefs);
903 end replaceZCExpinSymJacobian;
904
905 protected function replaceZeroCrossingsJacBackend
906 input BackendDAE.BackendDAE inBackendDAE;
907 input BackendDAE.ZeroCrossingSet zeroCrossingLst;
908 input BackendDAE.ZeroCrossingSet relationsLst;
909 input BackendDAE.ZeroCrossingSet samplesLst;
910 input BackendDAE.Variables allVariables;
911 input BackendDAE.Variables globalKnownVars;
912 output BackendDAE.BackendDAE outBackendDAE;
913 protected
914 BackendDAE.EquationArray eqns;
915 BackendDAE.EqSystems eqs, outEqs = {};
916 list<BackendDAE.Equation> eqs_lst;
917 BackendDAE.Shared shared;
918 BackendDAE.StrongComponents comps;
919 array<Integer> ass1, ass2;
920 BackendDAE.Matching matching;
921 algorithm
922 748 BackendDAE.DAE(eqs, shared) := inBackendDAE;
923
2/2
✓ Branch 0 taken 748 times.
✓ Branch 1 taken 748 times.
1496 for system in eqs loop
924 748 eqs_lst := BackendEquation.equationList(system.orderedEqs);
925 748 (_, eqs_lst, _, _, _) :=
926 findZeroCrossings2(allVariables, globalKnownVars, eqs_lst, 0, 0, zeroCrossingLst, relationsLst, samplesLst, {});
927 748 eqns := BackendEquation.listEquation(listReverse(eqs_lst));
928
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 748 times.
748 system.orderedEqs := eqns;
929 // componenents of the jacobian
930
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 748 times.
748 BackendDAE.MATCHING(comps=comps, ass1=ass1, ass2=ass2) := system.matching;
931 748 comps := findZeroCrossingsinJacobians(comps, zeroCrossingLst, relationsLst, samplesLst, allVariables, globalKnownVars);
932 748 matching := BackendDAE.MATCHING(comps=comps, ass1=ass1, ass2=ass2);
933 748 system.matching := matching;
934 outEqs := system::outEqs;
935 end for;
936 748 outEqs := listReverse(outEqs);
937 748 outBackendDAE := BackendDAE.DAE(outEqs, shared);
938 end replaceZeroCrossingsJacBackend;
939
940 protected function findZeroCrossings3
941 input DAE.Exp e;
942 input BackendDAE.ZeroCrossingSet inZeroCrossings;
943 input BackendDAE.ZeroCrossingSet inrelationsinZC;
944 input BackendDAE.ZeroCrossingSet inSamplesLst;
945 input Integer incountMathFunctions;
946 input Integer counteq;
947 input Integer countwc;
948 input BackendDAE.Variables vars;
949 input BackendDAE.Variables globalKnownVars;
950 output DAE.Exp eres;
951 output Integer outCountMathFunctions;
952 output BackendDAE.ZeroCrossingSet outZeroCrossings;
953 output BackendDAE.ZeroCrossingSet outrelationsinZC;
954 output BackendDAE.ZeroCrossingSet outSamplesLst;
955 algorithm
956
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 135239 times.
135239 if Flags.isSet(Flags.RELIDX) then
957 ✗ BackendDump.debugStrExpStr("start: ", e, "\n");
958 end if;
959
1/2
✓ Branch 4 taken 135239 times.
✗ Branch 5 not taken.
135239 (eres, ((outZeroCrossings, outrelationsinZC, outSamplesLst, outCountMathFunctions), _, _)) := Expression.traverseExpTopDown(e, collectZC, ((inZeroCrossings, inrelationsinZC, inSamplesLst, incountMathFunctions), (counteq, vars, globalKnownVars), NONE()));
960 end findZeroCrossings3;
961
962 protected function operatorEventsSupported
963 "Whether the selected target's runtime implements the event handling of the
964 stateful operators, i.e. delayZeroCrossing() and
965 spatialDistributionZeroCrossing(). Only the C and WebAssembly runtimes do."
966 output Boolean supported;
967 protected
968 String target = Config.simCodeTarget();
969 algorithm
970
5/12
✓ Branch 0 taken 890747 times.
✓ Branch 1 taken 37361 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 890747 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37361 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 37361 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
928108 supported := target == "C" or target == "wasm-jit" or target == "wasm";
971 end operatorEventsSupported;
972
973 protected function collectZC
974 "Collects zero crossings in equations"
975 input DAE.Exp inExp;
976 input ZCArgType inTpl;
977 output DAE.Exp outExp;
978 output Boolean cont;
979 output ZCArgType outTpl;
980 algorithm
981 (outExp,cont,outTpl) := match (inExp, inTpl, operatorEventsSupported())
982 local
983 DAE.Exp e, e1, e2, e_1, e_2, eres, eres1;
984 DAE.Exp index, delay, delayMax, in0, in1, x, dir, initPnts, initVals;
985 BackendDAE.Variables vars, globalKnownVars;
986 BackendDAE.ZeroCrossingSet zeroCrossings, samples;
987 BackendDAE.ZeroCrossingSet relations;
988 DAE.Operator op;
989 Integer eq_count, itmp, numMathFunctions, oldNumRelations;
990 BackendDAE.ZeroCrossing zc;
991 DAE.CallAttributes attr;
992 DAE.Type ty;
993 tuple<Integer, BackendDAE.Variables, BackendDAE.Variables> tp1;
994 ZCArgType tpl;
995 Boolean empty;
996 Option<list<BackendDAE.SimIterator>> iters;
997
998 case (DAE.CALL(path=Absyn.IDENT(name="noEvent")), _, _)
999 then (inExp, false, inTpl);
1000
1001 case (DAE.CALL(path=Absyn.IDENT(name="smooth")), _, _)
1002 then (inExp, false, inTpl);
1003
1004 case (DAE.CALL(path=Absyn.IDENT(name="sample")), ((_, _, samples, _), (eq_count, _, _), iters), _) algorithm
1005 130 zc := createZeroCrossing(inExp, {eq_count}, iters);
1006 130 mergeZeroCrossings(zc, samples);
1007 //itmp = (listLength(zc_lst)-listLength(zeroCrossings));
1008 //indx = indx + (listLength(zc_lst) - listLength(zeroCrossings));
1009
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 130 times.
130 if Flags.isSet(Flags.RELIDX) then
1010 ✗ print("sample index: " + intString(ZeroCrossings.length(samples)) + "\n");
1011 end if;
1012 then (inExp, true, inTpl);
1013
1014 case (outExp as DAE.REDUCTION(), ((zeroCrossings, relations, samples, numMathFunctions), tp1, _) ,_) algorithm
1015 ✗ if Flags.isSet(Flags.RELIDX) then
1016 ✗ print("collectZC searching in: " + ExpressionBasics.printExpStr(inExp) + "\n");
1017 end if;
1018 ✗ iters := SOME(list(createIterator(iter) for iter in outExp.iterators));
1019 ✗ (e, ((zeroCrossings, relations, samples, numMathFunctions), tp1, _)) := Expression.traverseExpTopDown(outExp.expr, collectZC, ((zeroCrossings, relations, samples, numMathFunctions), tp1, iters));
1020 ✗ outExp.expr := e;
1021 ✗ then (outExp, false, ((zeroCrossings, relations, samples, numMathFunctions), tp1, NONE()));
1022
1023 // delay() can trigger events which are are handled individually via the function delayZeroCrossing() > 0
1024 case (DAE.CALL(path=Absyn.IDENT(name="delay"), expLst={index, e, delay, delayMax}, attr = attr), ((zeroCrossings, relations, samples, numMathFunctions), tp1 as (eq_count, _, _), iters), true)
1025 algorithm
1026 // traverse relevant arguments
1027 19 (e, ((_, relations, samples, numMathFunctions), tp1, iters)) := Expression.traverseExpTopDown(e, collectZC, ((ZeroCrossings.new(), relations, samples, numMathFunctions), tp1, iters));
1028 19 (delay, ((_, relations, samples, numMathFunctions), tp1, iters)) := Expression.traverseExpTopDown(delay, collectZC, ((ZeroCrossings.new(), relations, samples, numMathFunctions), tp1, iters));
1029
1030 // create zero crossing function
1031 38 eres1 := DAE.CALL(Absyn.IDENT("delayZeroCrossing"), {index, DAE.ICONST(ZeroCrossings.count(relations)), delay}, attr);
1032 19 e_1 := DAE.RELATION(eres1, DAE.GREATER(DAE.T_REAL_DEFAULT) ,DAE.RCONST(0.0), ZeroCrossings.count(relations), NONE());
1033 19 zc := createZeroCrossing(eres1, {eq_count}, iters);
1034 19 (eres, relations, _) := zcIndex(e_1, relations, ZeroCrossings.count(relations), zc);
1035 19 zc := createZeroCrossing(eres, {eq_count}, iters);
1036
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 19 times.
19 (DAE.RELATION(index=itmp), zeroCrossings, _) := zcIndex(eres, zeroCrossings, ZeroCrossings.count(relations), zc);
1037
1038
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
19 if Flags.isSet(Flags.RELIDX) then
1039 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + " index: " + intString(itmp) + "\n");
1040 end if;
1041
1042 19 then (DAE.CALL(Absyn.IDENT(name="delay"), {index, e, delay, delayMax}, attr), true, ((zeroCrossings, relations, samples, numMathFunctions), tp1, iters));
1043
1044 // spatialDistribution() can trigger events which are handled individually via the function spatialDistributionZeroCrossing() > 0
1045 case (DAE.CALL(path=Absyn.IDENT(name="spatialDistribution"), expLst = {index, in0, in1, x, dir, initPnts, initVals}, attr = attr), ((zeroCrossings, relations, samples, numMathFunctions), tp1 as (eq_count, _, _), iters), true)
1046 algorithm
1047 // traverse relevant arguments
1048 8 (in0, ((_, relations, samples, numMathFunctions), tp1, iters)) := Expression.traverseExpTopDown(in0, collectZC, ((ZeroCrossings.new(), relations, samples, numMathFunctions), tp1, iters));
1049 8 (in1, ((_, relations, samples, numMathFunctions), tp1, iters)) := Expression.traverseExpTopDown(in1, collectZC, ((ZeroCrossings.new(), relations, samples, numMathFunctions), tp1, iters));
1050 8 (x, ((_, relations, samples, numMathFunctions), tp1, iters)) := Expression.traverseExpTopDown(x, collectZC, ((ZeroCrossings.new(), relations, samples, numMathFunctions), tp1, iters));
1051 8 (dir, ((_, relations, samples, numMathFunctions), tp1 as (eq_count, _, _), iters)) := Expression.traverseExpTopDown(dir, collectZC, ((ZeroCrossings.new(), relations, samples, numMathFunctions), tp1, iters));
1052
1053 // create zero crossing function
1054 16 eres1 := DAE.CALL(Absyn.IDENT("spatialDistributionZeroCrossing"), {index, DAE.ICONST(ZeroCrossings.count(relations)), x, dir}, attr);
1055 8 e_1 := DAE.RELATION(eres1, DAE.GREATER(DAE.T_REAL_DEFAULT) ,DAE.RCONST(0.0), ZeroCrossings.count(relations), NONE());
1056 8 zc := createZeroCrossing(eres1, {eq_count}, iters);
1057 8 (eres, relations, _) := zcIndex(e_1, relations, ZeroCrossings.count(relations), zc);
1058 8 zc := createZeroCrossing(eres, {eq_count}, iters);
1059
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
8 (DAE.RELATION(index=itmp), zeroCrossings, _) := zcIndex(eres, zeroCrossings, ZeroCrossings.count(relations), zc);
1060
1061
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if Flags.isSet(Flags.RELIDX) then
1062 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + " index: " + intString(itmp) + "\n");
1063 end if;
1064
1065 8 then (DAE.CALL(Absyn.IDENT(name="spatialDistribution"), {index, in0, in1, x, dir, initPnts, initVals}, attr), true, ((zeroCrossings, relations, samples, numMathFunctions), tp1, iters));
1066
1067 // function with discrete expressions generate no zerocrossing
1068 case (DAE.LUNARY(exp=e1), ((_, relations, _, _), (_, vars, globalKnownVars), _), _)
1069 guard not BackendDAEUtil.hasExpContinuousParts(e1, vars, globalKnownVars)
1070 algorithm
1071
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 702 times.
702 if Flags.isSet(Flags.RELIDX) then
1072 ✗ print("discrete LUNARY: " + intString(ZeroCrossings.count(relations)) + "\n");
1073 end if;
1074 //fcall(Flags.RELIDX, BackendDump.debugExpStr, (inExp, "\n"));
1075 then (inExp, true, inTpl);
1076
1077 case (DAE.LBINARY(exp1=e1, exp2=e2), ((_, relations, _, _), (_, vars, globalKnownVars), _), _)
1078 guard not (BackendDAEUtil.hasExpContinuousParts(e1, vars, globalKnownVars) or BackendDAEUtil.hasExpContinuousParts(e2, vars, globalKnownVars))
1079 algorithm
1080
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2869 times.
2869 if Flags.isSet(Flags.RELIDX) then
1081 ✗ print("discrete LBINARY: " + intString(ZeroCrossings.count(relations)) + "\n");
1082 end if;
1083 //fcall(Flags.RELIDX, BackendDump.debugExpStr, (inExp, "\n"));
1084 then (inExp, true, inTpl);
1085
1086 // coditions that are zerocrossings.
1087 case (DAE.LUNARY(exp=e1, operator=op), ((zeroCrossings, relations, _, _), _, iters), _) algorithm
1088
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 66 times.
66 if Flags.isSet(Flags.RELIDX) then
1089 ✗ print("continues LUNARY: " + intString(ZeroCrossings.count(relations)) + "\n");
1090 end if;
1091 66 (e1, tpl as (_, (eq_count, _, _), _)) := Expression.traverseExpTopDown(e1, collectZC, inTpl);
1092 66 e_1 := DAE.LUNARY(op, e1);
1093 66 zc := createZeroCrossing(e_1, {eq_count}, iters);
1094 66 empty := not ZeroCrossings.contains(zeroCrossings, zc);
1095
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
66 if empty then
1096 66 ZeroCrossings.add(zeroCrossings, zc);
1097 end if;
1098
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 66 times.
66 if Flags.isSet(Flags.RELIDX) then
1099 ✗ BackendDump.debugExpStr(e_1, "\n");
1100 end if;
1101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 then (e_1, false, if empty then tpl else inTpl);
1102
1103 case (DAE.LBINARY(exp1=e1, operator=op, exp2=e2), ((zeroCrossings, relations, samples, numMathFunctions), tp1, iters), _) algorithm
1104
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 779 times.
779 if Flags.isSet(Flags.RELIDX) then
1105 ✗ print("continues LBINARY: " + String(ZeroCrossings.count(relations)) + "\n");
1106 ✗ BackendDump.debugExpStr(inExp, "\n");
1107 end if;
1108 779 oldNumRelations := ZeroCrossings.count(relations);
1109 779 (e_1, ((_, relations, samples, numMathFunctions), tp1, iters)) := Expression.traverseExpTopDown(e1, collectZC, ((ZeroCrossings.new(), relations, samples, numMathFunctions), tp1, iters));
1110 779 (e_2, ((_, relations, samples, numMathFunctions), tp1 as (eq_count, _, _), iters)) := Expression.traverseExpTopDown(e2, collectZC, ((ZeroCrossings.new(), relations, samples, numMathFunctions), tp1, iters));
1111
2/2
✓ Branch 1 taken 546 times.
✓ Branch 2 taken 233 times.
779 if intGt(ZeroCrossings.count(relations), oldNumRelations) then
1112 546 e_1 := DAE.LBINARY(e_1, op, e_2);
1113 546 zc := createZeroCrossing(e_1, {eq_count}, iters);
1114 546 empty := not ZeroCrossings.contains(zeroCrossings, zc);
1115 cont := false;
1116
1/2
✓ Branch 0 taken 546 times.
✗ Branch 1 not taken.
546 if empty then
1117 546 ZeroCrossings.add(zeroCrossings, zc);
1118 end if;
1119
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 546 times.
546 if Flags.isSet(Flags.RELIDX) then
1120 ✗ BackendDump.dumpZeroCrossingList(ZeroCrossings.toList(zeroCrossings), "LBINARY");
1121 end if;
1122 else
1123 empty := true;
1124 cont := true;
1125 end if;
1126
4/4
✓ Branch 0 taken 546 times.
✓ Branch 1 taken 233 times.
✓ Branch 4 taken 546 times.
✓ Branch 5 taken 233 times.
779 then (if cont then inExp else e_1, cont, if not cont and empty then ((zeroCrossings, relations, samples, numMathFunctions), tp1, iters) else inTpl);
1127
1128 // function with discrete expressions generate no zerocrossing
1129 case (DAE.RELATION(exp1=e1, exp2=e2), ((_, relations, _, _), (_, vars, globalKnownVars), _), _)
1130 guard not (BackendDAEUtil.hasExpContinuousParts(e1, vars, globalKnownVars) or BackendDAEUtil.hasExpContinuousParts(e2, vars, globalKnownVars))
1131 algorithm
1132
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 853 times.
853 if Flags.isSet(Flags.RELIDX) then
1133 ✗ print("discrete RELATION: " + intString(ZeroCrossings.count(relations)) + "\n");
1134 end if;
1135 then (inExp, true, inTpl);
1136
1137 // All other functions generate zerocrossing.
1138 case (DAE.RELATION(exp1=e1, operator=op, exp2=e2), ((zeroCrossings, relations, samples, numMathFunctions), tp1 as (eq_count, _, _), iters), _)
1139 guard Flags.isSet(Flags.EVENTS)
1140 algorithm
1141
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2139 times.
2139 if Flags.isSet(Flags.RELIDX) then
1142 ✗ print("start collectZC (2): " + ExpressionBasics.printExpStr(inExp) + " numRelations: " +intString(ZeroCrossings.count(relations)) + "\n");
1143 end if;
1144 2139 e_1 := DAE.RELATION(e1, op, e2, ZeroCrossings.count(relations), NONE());
1145 2139 zc := createZeroCrossing(e_1, {eq_count}, iters);
1146 2139 (eres, relations, _) := zcIndex(e_1, relations, ZeroCrossings.count(relations), zc);
1147 2139 zc := createZeroCrossing(eres, {eq_count}, iters);
1148
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 2139 times.
2139 (DAE.RELATION(index=itmp), zeroCrossings, _) := zcIndex(eres, zeroCrossings, ZeroCrossings.count(relations), zc);
1149
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2139 times.
2139 if Flags.isSet(Flags.RELIDX) then
1150 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + " index: " + intString(itmp) + "\n");
1151 end if;
1152 2139 then (eres, true, ((zeroCrossings, relations, samples, numMathFunctions), tp1, iters));
1153
1154 // math function that triggering events
1155 case (DAE.CALL(path=Absyn.IDENT("integer"), expLst={e1}, attr=attr), ((zeroCrossings, relations, samples, numMathFunctions), tp1 as (eq_count, _, _), iters), _)
1156 guard Flags.isSet(Flags.EVENTS)
1157 algorithm
1158
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 if Flags.isSet(Flags.RELIDX) then
1159 ✗ print("start collectZC: " + ExpressionBasics.printExpStr(inExp) + " numMathFunctions: " +intString(numMathFunctions) + "\n");
1160 end if;
1161
1162 96 e_1 := DAE.CALL(Absyn.IDENT("integer"), {e1, DAE.ICONST(numMathFunctions)}, attr);
1163
1164 48 zc := createZeroCrossing(e_1, {eq_count}, iters);
1165 48 (eres, zeroCrossings, numMathFunctions) := zcIndex(e_1, zeroCrossings, numMathFunctions, zc);
1166
1167
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 if Flags.isSet(Flags.RELIDX) then
1168 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + "\n");
1169 end if;
1170 48 then (eres, true, ((zeroCrossings, relations, samples, numMathFunctions), tp1, iters));
1171
1172 case (DAE.CALL(path=Absyn.IDENT("floor"), expLst={e1}, attr=attr), ((zeroCrossings, relations, samples, numMathFunctions), tp1 as (eq_count, _, _), iters), _)
1173 guard Flags.isSet(Flags.EVENTS)
1174 algorithm
1175
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if Flags.isSet(Flags.RELIDX) then
1176 ✗ print("start collectZC: " + ExpressionBasics.printExpStr(inExp) + " numMathFunctions: " +intString(numMathFunctions) + "\n");
1177 end if;
1178
1179 8 e_1 := DAE.CALL(Absyn.IDENT("floor"), {e1, DAE.ICONST(numMathFunctions)}, attr);
1180
1181 4 zc := createZeroCrossing(e_1, {eq_count}, iters);
1182 4 (eres, zeroCrossings, numMathFunctions) := zcIndex(e_1, zeroCrossings, numMathFunctions, zc);
1183
1184
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if Flags.isSet(Flags.RELIDX) then
1185 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + "\n");
1186 end if;
1187 4 then (eres, true, ((zeroCrossings, relations, samples, numMathFunctions), tp1, iters));
1188
1189 case (DAE.CALL(path=Absyn.IDENT("ceil"), expLst={e1}, attr=attr), ((zeroCrossings, relations, samples, numMathFunctions), tp1 as (eq_count, _, _), iters), _)
1190 guard Flags.isSet(Flags.EVENTS)
1191 algorithm
1192
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if Flags.isSet(Flags.RELIDX) then
1193 ✗ print("start collectZC: " + ExpressionBasics.printExpStr(inExp) + " numMathFunctions: " +intString(numMathFunctions) + "\n");
1194 end if;
1195
1196 6 e_1 := DAE.CALL(Absyn.IDENT("ceil"), {e1, DAE.ICONST(numMathFunctions)}, attr);
1197
1198 3 zc := createZeroCrossing(e_1, {eq_count}, iters);
1199 3 (eres, zeroCrossings, numMathFunctions) := zcIndex(e_1, zeroCrossings, numMathFunctions, zc);
1200
1201
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if Flags.isSet(Flags.RELIDX) then
1202 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + "\n");
1203 end if;
1204 3 then (eres, true, ((zeroCrossings, relations, samples, numMathFunctions), tp1, iters));
1205
1206 case (DAE.CALL(path=Absyn.IDENT("div"), expLst={e1, e2}, attr=attr), ((zeroCrossings, relations, samples, numMathFunctions), tp1 as (eq_count, _, _), iters), _)
1207 guard Flags.isSet(Flags.EVENTS)
1208 algorithm
1209
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 if Flags.isSet(Flags.RELIDX) then
1210 ✗ print("start collectZC: " + ExpressionBasics.printExpStr(inExp) + " numMathFunctions: " +intString(numMathFunctions) + "\n");
1211 end if;
1212
1213 10 e_1 := DAE.CALL(Absyn.IDENT("div"), {e1, e2, DAE.ICONST(numMathFunctions)}, attr);
1214
1215 5 zc := createZeroCrossing(e_1, {eq_count}, iters);
1216 5 (eres, zeroCrossings, numMathFunctions) := zcIndex(e_1, zeroCrossings, numMathFunctions, zc);
1217
1218
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 if Flags.isSet(Flags.RELIDX) then
1219 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + "\n");
1220 end if;
1221 5 then (eres, true, ((zeroCrossings, relations, samples, numMathFunctions), tp1, iters));
1222
1223 case (DAE.CALL(path=Absyn.IDENT("mod"), expLst={e1, e2}, attr=attr as DAE.CALL_ATTR()), ((zeroCrossings, relations, samples, numMathFunctions), tp1 as (eq_count, _, _), iters), _)
1224 guard Flags.isSet(Flags.EVENTS)
1225 algorithm
1226
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if Flags.isSet(Flags.RELIDX) then
1227 ✗ print("start collectZC: " + ExpressionBasics.printExpStr(inExp) + " numMathFunctions: " +intString(numMathFunctions) + "\n");
1228 end if;
1229
1230 8 e_1 := DAE.CALL(Absyn.IDENT("mod"), {e1, e2, DAE.ICONST(numMathFunctions)}, attr);
1231
1232 4 zc := createZeroCrossing(e_1, {eq_count}, iters);
1233 4 (eres, zeroCrossings, numMathFunctions) := zcIndex(e_1, zeroCrossings, numMathFunctions, zc);
1234
1235 // Add additional +1 to numMathFunctions because of internally used _event_floor
1236 4 numMathFunctions := numMathFunctions + 1;
1237
1238
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if Flags.isSet(Flags.RELIDX) then
1239 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + "\n");
1240 end if;
1241 4 then (eres, true, ((zeroCrossings, relations, samples, numMathFunctions), tp1, iters));
1242
1243 // rem is rewritten to div(x/y)*y - x
1244 case (DAE.CALL(path=Absyn.IDENT("rem"), expLst={e1, e2}, attr=attr as DAE.CALL_ATTR(ty=ty)), ((zeroCrossings, relations, samples, numMathFunctions), tp1 as (eq_count, _, _), iters), _)
1245 guard Flags.isSet(Flags.EVENTS)
1246 algorithm
1247 ✗ if Flags.isSet(Flags.RELIDX) then
1248 ✗ print("start collectZC: " + ExpressionBasics.printExpStr(inExp) + " numMathFunctions: " +intString(numMathFunctions) + "\n");
1249 end if;
1250
1251 ✗ e_1 := DAE.CALL(Absyn.IDENT("div"), {e1, e2, DAE.ICONST(numMathFunctions)}, attr);
1252
1253 ✗ zc := createZeroCrossing(e_1, {eq_count}, iters);
1254 ✗ (eres, zeroCrossings, numMathFunctions) := zcIndex(e_1, zeroCrossings, numMathFunctions, zc);
1255 ✗ e_2 := DAE.BINARY(e1, DAE.SUB(ty), DAE.BINARY(eres, DAE.MUL(ty), e2));
1256
1257 ✗ if Flags.isSet(Flags.RELIDX) then
1258 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + "\n");
1259 end if;
1260 ✗ then (e_2, true, ((zeroCrossings, relations, samples, numMathFunctions), tp1, iters));
1261
1262 else (inExp, true, inTpl);
1263 end match;
1264 end collectZC;
1265
1266 protected function collectZCAlgsFor
1267 "Collects zero crossings in for loops"
1268 input DAE.Exp inExp;
1269 input ForArgType inTpl;
1270 output DAE.Exp outExp;
1271 output Boolean cont;
1272 output ForArgType outTpl;
1273 algorithm
1274 (outExp,cont,outTpl) := match (inExp, inTpl)
1275 local
1276 DAE.Exp e1, e2, e_1, e_2, eres, iterator, range;
1277 list<DAE.Exp> inExpLst, explst;
1278 BackendDAE.Variables vars, globalKnownVars;
1279 BackendDAE.ZeroCrossingSet zeroCrossings, samples;
1280 BackendDAE.ZeroCrossingSet relations;
1281 list<BackendDAE.ZeroCrossing> zcLstNew, zc_lst;
1282 DAE.Operator op;
1283 Integer alg_indx, itmp, numMathFunctions, oldNumRelations;
1284 list<Integer> eqs;
1285 DAE.Exp startvalue, stepvalue;
1286 Option<DAE.Exp> stepvalueopt;
1287 Integer istart, istep;
1288 BackendDAE.ZeroCrossing zc;
1289 DAE.CallAttributes attr;
1290 DAE.Type ty;
1291 list<DAE.Exp> le;
1292 tuple<Integer, BackendDAE.Variables, BackendDAE.Variables> tp1;
1293 ForArgType tpl;
1294 tuple<BackendDAE.ZeroCrossingSet, BackendDAE.ZeroCrossingSet, BackendDAE.ZeroCrossingSet, Integer> tp2;
1295
1296 case (DAE.CALL(path=Absyn.IDENT(name="noEvent")), _)
1297 then (inExp, false, inTpl);
1298
1299 case (DAE.CALL(path=Absyn.IDENT(name="smooth")), _)
1300 then (inExp, false, inTpl);
1301
1302 case (DAE.CALL(path=Absyn.IDENT(name="sample")), (_, _, _, (_, _, samples, _), (alg_indx, _, _))) algorithm
1303 eqs := {alg_indx};
1304 21 zc := createZeroCrossing(inExp, eqs, NONE());
1305 21 ZeroCrossings.add(samples, zc);
1306
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
21 if Flags.isSet(Flags.RELIDX) then
1307 ✗ print("sample index algotihm: " + intString(alg_indx) + "\n");
1308 end if;
1309 then (inExp, true, inTpl);
1310
1311 case (DAE.LUNARY(exp=e1), (_, _, _, _, (_, vars, globalKnownVars)))
1312 guard not BackendDAEUtil.hasExpContinuousParts(e1, vars, globalKnownVars)
1313 then (inExp, true, inTpl);
1314
1315 // conditions that are zerocrossings.
1316 case (DAE.LUNARY(exp=e1, operator=op), (iterator, _, DAE.RANGE(), (zeroCrossings, relations, _, _), _))
1317 guard Expression.expContains(inExp, iterator)
1318 algorithm
1319
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if Flags.isSet(Flags.RELIDX) then
1320 ✗ print("continues LUNARY with Iterator: " + intString(ZeroCrossings.count(relations)) + "\n");
1321 end if;
1322 11 (e1, tpl as (iterator, inExpLst, _, (_, relations, _, _), (alg_indx, _, _))) := Expression.traverseExpTopDown(e1, collectZCAlgsFor, inTpl);
1323 11 e_1 := DAE.LUNARY(op, e1);
1324 11 (explst,_) := replaceIteratorWithStaticValues(e_1, iterator, inExpLst, ZeroCrossings.count(relations));
1325 11 zc_lst := createZeroCrossings(explst, {alg_indx});
1326 11 ZeroCrossings.add_list(zeroCrossings, zc_lst);
1327
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if Flags.isSet(Flags.RELIDX) then
1328 ✗ print("collectZCAlgsFor LUNARY with Iterator result zc: ");
1329 ✗ BackendDump.debugExpStr(e_1, "\n");
1330 end if;
1331 then (e_1, false, tpl);
1332
1333 // coditions that are zerocrossings.
1334 case (DAE.LUNARY(exp=e1, operator=op), (_, _, _, (zeroCrossings, relations, _, _), _)) algorithm
1335
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if Flags.isSet(Flags.RELIDX) then
1336 ✗ print("continues LUNARY: " + intString(ZeroCrossings.count(relations)) + "\n");
1337 end if;
1338 4 (e1, tpl as (_, _, _, _, (alg_indx, _, _))) := Expression.traverseExpTopDown(e1, collectZCAlgsFor, inTpl);
1339 4 e_1 := DAE.LUNARY(op, e1);
1340 4 zc := createZeroCrossing(e_1, {alg_indx}, NONE());
1341 4 ZeroCrossings.add(zeroCrossings, zc);
1342
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if Flags.isSet(Flags.RELIDX) then
1343 ✗ print("collectZCAlgsFor LUNARY result zc: ");
1344 ✗ BackendDump.debugExpStr(e_1, "\n");
1345 end if;
1346 then (e_1, false, tpl);
1347
1348 case (DAE.LBINARY(exp1=e1, exp2=e2), (_, _, _, _, (_, vars, globalKnownVars)))
1349 guard not (BackendDAEUtil.hasExpContinuousParts(e1, vars, globalKnownVars) or BackendDAEUtil.hasExpContinuousParts(e2, vars, globalKnownVars))
1350 then (inExp, true, inTpl);
1351
1352 case (DAE.LBINARY(exp1=e1, operator=op, exp2=e2), (iterator, inExpLst, range, (zeroCrossings, relations, samples, numMathFunctions), tp1))
1353 algorithm
1354
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 57 times.
57 if Flags.isSet(Flags.RELIDX) then
1355 ✗ print("continues LBINARY: " + intString(ZeroCrossings.count(relations)) + "\n");
1356 ✗ BackendDump.debugExpStr(inExp, "\n");
1357 end if;
1358 57 oldNumRelations := ZeroCrossings.count(relations);
1359 57 (e_1, (_, inExpLst, range, tp2, tp1)) := Expression.traverseExpTopDown(e1, collectZCAlgsFor, (iterator, inExpLst, range, (ZeroCrossings.new(), relations, samples, numMathFunctions), tp1));
1360 57 (e_2, (_, inExpLst, range, (_, relations, samples, numMathFunctions), tp1 as (alg_indx, _, _))) := Expression.traverseExpTopDown(e2, collectZCAlgsFor, (iterator, inExpLst, range, tp2, tp1));
1361
1/2
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
57 if intGt(ZeroCrossings.count(relations), oldNumRelations) then
1362 57 e_1 := DAE.LBINARY(e_1, op, e_2);
1363
3/4
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 40 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 17 times.
57 if Expression.expContains(e1, iterator) or Expression.expContains(e2, iterator) then
1364 40 (explst,_) := replaceIteratorWithStaticValues(e_1, iterator, inExpLst, ZeroCrossings.count(relations));
1365 40 zc_lst := createZeroCrossings(explst, {alg_indx});
1366 40 ZeroCrossings.add_list(zeroCrossings, zc_lst);
1367
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
40 if Flags.isSet(Flags.RELIDX) then
1368 ✗ BackendDump.dumpZeroCrossingList(ZeroCrossings.toList(zeroCrossings), "collectZCAlgsFor LBINARY1 result zc");
1369 end if;
1370 else
1371 17 zc := createZeroCrossing(e_1, {alg_indx}, NONE());
1372
1/2
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
17 if not ZeroCrossings.contains(zeroCrossings, zc) then
1373 17 ZeroCrossings.add(zeroCrossings, zc);
1374 end if;
1375
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
17 if Flags.isSet(Flags.RELIDX) then
1376 ✗ BackendDump.dumpZeroCrossingList(ZeroCrossings.toList(zeroCrossings), "collectZCAlgsFor LBINARY2 result zc");
1377 end if;
1378 end if;
1379 cont := false;
1380 57 tpl := (iterator, inExpLst, range, (zeroCrossings, relations, samples, numMathFunctions), tp1);
1381 else
1382 e_1 := inExp;
1383 cont := true;
1384 tpl := inTpl;
1385 end if;
1386 then (e_1, cont, tpl);
1387
1388 // function with discrete expressions generate no zerocrossing.
1389 case (DAE.RELATION(exp1=e1, exp2=e2), (_, _, _, _, (_, vars, globalKnownVars)))
1390 guard not (BackendDAEUtil.hasExpContinuousParts(e1, vars, globalKnownVars) or BackendDAEUtil.hasExpContinuousParts(e2, vars, globalKnownVars))
1391 then (inExp, true, inTpl);
1392
1393 // All other functions generate zerocrossing.
1394 case (DAE.RELATION(exp1=e1, operator=op, exp2=e2), (iterator, inExpLst, range as DAE.RANGE(start=startvalue, step=stepvalueopt), (zeroCrossings, relations, samples, numMathFunctions), tp1 as (alg_indx, _, globalKnownVars)))
1395 guard if Flags.isSet(Flags.EVENTS) then (if Expression.expContains(e1, iterator) then true else Expression.expContains(e2, iterator)) else false
1396 algorithm
1397
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 93 times.
93 if Flags.isSet(Flags.RELIDX) then
1398 ✗ print(" number of relations: " + intString(ZeroCrossings.count(relations)) + "\n");
1399 end if;
1400 93 stepvalue := Util.getOptionOrDefault(stepvalueopt, DAE.ICONST(1));
1401 93 istart := BackendDAEUtil.expInt(startvalue, globalKnownVars);
1402 93 istep := BackendDAEUtil.expInt(stepvalue, globalKnownVars);
1403 186 eres := DAE.RELATION(e1, op, e2, ZeroCrossings.count(relations), SOME((iterator, istart, istep)));
1404 93 (explst, itmp) := replaceIteratorWithStaticValues(inExp, iterator, inExpLst, ZeroCrossings.count(relations));
1405
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 93 times.
93 if Flags.isSet(Flags.RELIDX) then
1406 ✗ print(" number of new zc (1): " + intString(listLength(explst)) + "\n");
1407 end if;
1408 93 zcLstNew := createZeroCrossings(explst, {alg_indx});
1409 93 ZeroCrossings.push_list(relations, zcLstNew);
1410
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 93 times.
93 if Flags.isSet(Flags.RELIDX) then
1411 ✗ print(" number of new zc (2): " + intString(ZeroCrossings.count(relations)) + "\n");
1412 end if;
1413 93 itmp := listLength(zcLstNew);
1414
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 93 times.
93 if Flags.isSet(Flags.RELIDX) then
1415 ✗ print(" itmp: " + intString(itmp) + "\n");
1416 end if;
1417 93 ZeroCrossings.add_list(zeroCrossings, zcLstNew);
1418
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 93 times.
93 if Flags.isSet(Flags.RELIDX) then
1419 ✗ print("collectZCAlgsFor result zc: " + ExpressionBasics.printExpStr(eres)+ " index:" + intString(ZeroCrossings.count(relations)) + "\n");
1420 end if;
1421 93 then (eres, true, (iterator, inExpLst, range, (zeroCrossings, relations, samples, numMathFunctions), tp1));
1422
1423 // All other functions generate zerocrossing.
1424 case (DAE.RELATION(exp1=e1, operator=op, exp2=e2), (iterator, inExpLst, range, (zeroCrossings, relations, samples, numMathFunctions), tp1 as (alg_indx, _, _)))
1425 guard Flags.isSet(Flags.EVENTS) // and (not Expression.expContains(e1, iterator) or Expression.expContains(e2, iterator))
1426 algorithm
1427 133 eres := DAE.RELATION(e1, op, e2, ZeroCrossings.count(relations), NONE());
1428 133 zc := createZeroCrossing(eres, {alg_indx}, NONE());
1429 133 ZeroCrossings.push(relations, zc);
1430 133 ZeroCrossings.add(zeroCrossings, zc);
1431
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 133 times.
133 if Flags.isSet(Flags.RELIDX) then
1432 ✗ print("collectZCAlgsFor result zc: " + ExpressionBasics.printExpStr(eres)+ " index:" + intString(ZeroCrossings.count(relations)) + "\n");
1433 end if;
1434 133 then (eres, true, (iterator, inExpLst, range, (zeroCrossings, relations, samples, numMathFunctions), tp1));
1435
1436 // math function that triggering events
1437 case (DAE.CALL(path=Absyn.IDENT("integer"), expLst={e1}, attr=attr), (iterator, le, range, (zeroCrossings, relations, samples, numMathFunctions), tp1 as (alg_indx, _, _)))
1438 guard Flags.isSet(Flags.EVENTS)
1439 algorithm
1440 ✗ if Flags.isSet(Flags.RELIDX) then
1441 ✗ print("start collectZC: " + ExpressionBasics.printExpStr(inExp) + " numMathFunctions: " +intString(numMathFunctions) + "\n");
1442 end if;
1443
1444 ✗ e_1 := DAE.CALL(Absyn.IDENT("integer"), {e1, DAE.ICONST(numMathFunctions)}, attr);
1445
1446 ✗ zc := createZeroCrossing(e_1, {alg_indx}, NONE());
1447 ✗ (eres, zeroCrossings, numMathFunctions) := zcIndex(e_1, zeroCrossings, numMathFunctions, zc);
1448
1449 ✗ if Flags.isSet(Flags.RELIDX) then
1450 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + "\n");
1451 end if;
1452 ✗ then (eres, true, (iterator, le, range, (zeroCrossings, relations, samples, numMathFunctions), tp1));
1453
1454 case (DAE.CALL(path=Absyn.IDENT("floor"), expLst={e1}, attr=attr), (iterator, le, range, (zeroCrossings, relations, samples, numMathFunctions), tp1 as (alg_indx, _, _)))
1455 guard Flags.isSet(Flags.EVENTS)
1456 algorithm
1457 ✗ if Flags.isSet(Flags.RELIDX) then
1458 ✗ print("start collectZC: " + ExpressionBasics.printExpStr(inExp) + " numMathFunctions: " +intString(numMathFunctions) + "\n");
1459 end if;
1460
1461 ✗ e_1 := DAE.CALL(Absyn.IDENT("floor"), {e1, DAE.ICONST(numMathFunctions)}, attr);
1462
1463 ✗ zc := createZeroCrossing(e_1, {alg_indx}, NONE());
1464 ✗ (eres, zeroCrossings, numMathFunctions) := zcIndex(e_1, zeroCrossings, numMathFunctions, zc);
1465
1466 ✗ if Flags.isSet(Flags.RELIDX) then
1467 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + "\n");
1468 end if;
1469 ✗ then (eres, true, (iterator, le, range, (zeroCrossings, relations, samples, numMathFunctions), tp1));
1470
1471 case (DAE.CALL(path=Absyn.IDENT("ceil"), expLst={e1}, attr=attr), (iterator, le, range, (zeroCrossings, relations, samples, numMathFunctions), tp1 as (alg_indx, _, _)))
1472 guard Flags.isSet(Flags.EVENTS)
1473 algorithm
1474 ✗ if Flags.isSet(Flags.RELIDX) then
1475 ✗ print("start collectZC: " + ExpressionBasics.printExpStr(inExp) + " numMathFunctions: " +intString(numMathFunctions) + "\n");
1476 end if;
1477
1478 ✗ e_1 := DAE.CALL(Absyn.IDENT("ceil"), {e1, DAE.ICONST(numMathFunctions)}, attr);
1479
1480 ✗ zc := createZeroCrossing(e_1, {alg_indx}, NONE());
1481 ✗ (eres, zeroCrossings, numMathFunctions) := zcIndex(e_1, zeroCrossings, numMathFunctions, zc);
1482
1483 ✗ if Flags.isSet(Flags.RELIDX) then
1484 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + "\n");
1485 end if;
1486 ✗ then (eres, true, (iterator, le, range, (zeroCrossings, relations, samples, numMathFunctions), tp1));
1487
1488 case (DAE.CALL(path=Absyn.IDENT("div"), expLst={e1, e2}, attr=attr), (iterator, le, range, (zeroCrossings, relations, samples, numMathFunctions), tp1 as (alg_indx, _, _)))
1489 guard Flags.isSet(Flags.EVENTS)
1490 algorithm
1491 ✗ if Flags.isSet(Flags.RELIDX) then
1492 ✗ print("start collectZC: " + ExpressionBasics.printExpStr(inExp) + " numMathFunctions: " +intString(numMathFunctions) + "\n");
1493 end if;
1494
1495 ✗ e_1 := DAE.CALL(Absyn.IDENT("div"), {e1, e2, DAE.ICONST(numMathFunctions)}, attr);
1496
1497 ✗ zc := createZeroCrossing(e_1, {alg_indx}, NONE());
1498 ✗ (eres, zeroCrossings, numMathFunctions) := zcIndex(e_1, zeroCrossings, numMathFunctions, zc);
1499
1500 ✗ if Flags.isSet(Flags.RELIDX) then
1501 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + "\n");
1502 end if;
1503 ✗ then (eres, true, (iterator, le, range, (zeroCrossings, relations, samples, numMathFunctions), tp1));
1504
1505 case (DAE.CALL(path=Absyn.IDENT("mod"), expLst={e1, e2}, attr=attr as DAE.CALL_ATTR()), (iterator, le, range, (zeroCrossings, relations, samples, numMathFunctions), tp1 as (alg_indx, _, _)))
1506 guard Flags.isSet(Flags.EVENTS)
1507 algorithm
1508 ✗ if Flags.isSet(Flags.RELIDX) then
1509 ✗ print("start collectZC: " + ExpressionBasics.printExpStr(inExp) + " numMathFunctions: " +intString(numMathFunctions) + "\n");
1510 end if;
1511
1512 ✗ e_1 := DAE.CALL(Absyn.IDENT("mod"), {e1, e2, DAE.ICONST(numMathFunctions)}, attr);
1513
1514 ✗ zc := createZeroCrossing(e_1, {alg_indx}, NONE());
1515 ✗ (eres, zeroCrossings, numMathFunctions) := zcIndex(e_1, zeroCrossings, numMathFunctions, zc);
1516
1517 ✗ if Flags.isSet(Flags.RELIDX) then
1518 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + "\n");
1519 end if;
1520 ✗ then (eres, true, (iterator, le, range, (zeroCrossings, relations, samples, numMathFunctions), tp1));
1521
1522 // rem is rewritten to div(x/y)*y - x
1523 case (DAE.CALL(path=Absyn.IDENT("rem"), expLst={e1, e2}, attr=attr as DAE.CALL_ATTR(ty = ty)), (iterator, le, range, (zeroCrossings, relations, samples, numMathFunctions), tp1 as (alg_indx, _, _)))
1524 guard Flags.isSet(Flags.EVENTS)
1525 algorithm
1526 ✗ if Flags.isSet(Flags.RELIDX) then
1527 ✗ print("start collectZC: " + ExpressionBasics.printExpStr(inExp) + " numMathFunctions: " +intString(numMathFunctions) + "\n");
1528 end if;
1529
1530 ✗ e_1 := DAE.CALL(Absyn.IDENT("div"), {e1, e2, DAE.ICONST(numMathFunctions)}, attr);
1531
1532 ✗ zc := createZeroCrossing(e_1, {alg_indx}, NONE());
1533 ✗ (eres, zeroCrossings, numMathFunctions) := zcIndex(e_1, zeroCrossings, numMathFunctions, zc);
1534 ✗ e_2 := DAE.BINARY(e1, DAE.SUB(ty), DAE.BINARY(eres, DAE.MUL(ty), e2));
1535
1536 ✗ if Flags.isSet(Flags.RELIDX) then
1537 ✗ print("collectZC result zc: " + ExpressionBasics.printExpStr(eres) + "\n");
1538 end if;
1539 ✗ then (e_2, true, (iterator, le, range, (zeroCrossings, relations, samples, numMathFunctions), tp1));
1540
1541 else (inExp, true, inTpl);
1542 end match;
1543 end collectZCAlgsFor;
1544
1545 protected function replaceIteratorWithStaticValues
1546 input DAE.Exp inExp;
1547 input DAE.Exp inIterator;
1548 input list<DAE.Exp> inExpLst;
1549 input Integer inIndex;
1550 output list<DAE.Exp> outZeroCrossings;
1551 output Integer outIndex;
1552 algorithm
1553 (outZeroCrossings, outIndex) := match(inExp, inExpLst)
1554 local
1555 DAE.Exp e, e1, e2, res1, e_1;
1556 DAE.Operator op;
1557 list<DAE.Exp> rest, res2;
1558 Integer index;
1559
1560 case (_, {})
1561 then ({}, inIndex);
1562
1563 case (DAE.RELATION(exp1=e1, operator=op, exp2=e2), e::rest) algorithm
1564 158 e_1 := DAE.RELATION(e1, op, e2, inIndex, NONE());
1565 158 (res1, _) := Expression.replaceExpTpl(e_1, (inIterator, e));
1566 158 (res2, index) := replaceIteratorWithStaticValues(inExp, inIterator, rest, inIndex+1);
1567 res2 := res1::res2;
1568 158 then (res2, index);
1569
1570 case (DAE.LUNARY(exp=e1, operator=op), e::rest) algorithm
1571 12 e_1 := DAE.LUNARY(op, e1);
1572 12 (res1, _) := Expression.replaceExpTpl(e_1, (inIterator, e));
1573 12 (res2, index) := replaceIteratorWithStaticValues(inExp, inIterator, rest, inIndex+1);
1574 res2 := res1 :: res2;
1575 12 then (res2, index);
1576
1577 case (DAE.LBINARY(exp1=e1, operator=op, exp2=e2), e::rest) algorithm
1578 41 e_1 := DAE.LBINARY(e1, op, e2);
1579 41 (res1, _) := Expression.replaceExpTpl(e_1, (inIterator, e));
1580 41 (res2, index) := replaceIteratorWithStaticValues(inExp, inIterator, rest, inIndex+1);
1581 res2 := res1 :: res2;
1582 41 then (res2, index);
1583
1584 else algorithm
1585 ✗ Error.addInternalError(getInstanceName() + " failed.", sourceInfo());
1586 ✗ then fail();
1587 end match;
1588 end replaceIteratorWithStaticValues;
1589
1590 protected function zcIndex
1591 input output DAE.Exp relation;
1592 input output BackendDAE.ZeroCrossingSet zeroCrossings;
1593 input output Integer index;
1594 input BackendDAE.ZeroCrossing zc;
1595 algorithm
1596
2/2
✓ Branch 1 taken 994 times.
✓ Branch 2 taken 3402 times.
4396 if ZeroCrossings.contains(zeroCrossings, zc) then
1597 994 BackendDAE.ZERO_CROSSING(relation_=relation) := ZeroCrossings.get(zeroCrossings, zc);
1598 994 return;
1599 end if;
1600 (relation, index) := match relation
1601 local
1602
1603 case DAE.RELATION()
1604 algorithm
1605 3343 ZeroCrossings.add(zeroCrossings, zc);
1606 3343 then (relation, index+1);
1607
1608 // math function with one argument and index
1609 case DAE.CALL(expLst={_, _})
1610 algorithm
1611 50 ZeroCrossings.add(zeroCrossings, zc);
1612 50 then (relation, index+1);
1613
1614 // math function with two arguments and index
1615 case DAE.CALL(expLst={_, _, _})
1616 algorithm
1617 9 ZeroCrossings.add(zeroCrossings, zc);
1618 9 then (relation, index+2);
1619
1620 else algorithm
1621 ✗ Error.addInternalError(getInstanceName() + " failed for: " + ExpressionBasics.printExpStr(relation), sourceInfo());
1622 ✗ then fail();
1623 end match;
1624 end zcIndex;
1625
1626 protected function mergeZeroCrossings "
1627 Takes a list of zero crossings and if more than one have identical
1628 function expressions they are merged into one zerocrossing.
1629 In the resulting list all zerocrossing have uniq function expressions."
1630 input BackendDAE.ZeroCrossing newZc;
1631 input BackendDAE.ZeroCrossingSet zcs;
1632 protected
1633 algorithm
1634
1/2
✓ Branch 1 taken 130 times.
✗ Branch 2 not taken.
130 if not ZeroCrossings.contains(zcs, newZc) then
1635 130 ZeroCrossings.add(zcs, newZc);
1636 else
1637 ✗ DoubleEnded.mapNoCopy_1(zcs.zc, mergeZeroCrossingIfEqual, newZc);
1638 end if;
1639 end mergeZeroCrossings;
1640
1641 protected function mergeZeroCrossingIfEqual
1642 input BackendDAE.ZeroCrossing zc1;
1643 input BackendDAE.ZeroCrossing zc2;
1644 output BackendDAE.ZeroCrossing zc;
1645 algorithm
1646 ✗ zc := if ZeroCrossings.equals(zc1, zc2) then mergeZeroCrossing(zc1,zc2) else zc1;
1647 end mergeZeroCrossingIfEqual;
1648
1649 protected function mergeZeroCrossing "
1650 Merges two zero crossings into one by makeing the union of the lists of
1651 equations and when clauses they appear in."
1652 input BackendDAE.ZeroCrossing inZeroCrossing1;
1653 input BackendDAE.ZeroCrossing inZeroCrossing2;
1654 output BackendDAE.ZeroCrossing outZeroCrossing;
1655 protected
1656 list<Integer> eq, eq1, eq2;
1657 DAE.Exp e1, e2, res;
1658 algorithm
1659 ✗ BackendDAE.ZERO_CROSSING(relation_=e1, occurEquLst=eq1) := inZeroCrossing1;
1660 ✗ BackendDAE.ZERO_CROSSING(relation_=e2, occurEquLst=eq2) := inZeroCrossing2;
1661 ✗ res := getMinZeroCrossings(e1, e2);
1662 ✗ eq := List.union(eq1, eq2);
1663 ✗ outZeroCrossing := BackendDAE.ZERO_CROSSING(0, res, eq, NONE());
1664 end mergeZeroCrossing;
1665
1666 protected function getMinZeroCrossings "
1667 Return the expression with lower index in relation of zero-crossings."
1668 input DAE.Exp inZCexp1;
1669 input DAE.Exp inZCexp2;
1670 output DAE.Exp outMinZC;
1671 algorithm
1672 outMinZC := match (inZCexp1, inZCexp2)
1673 local
1674 DAE.Exp e1, e2, e3, e4, res, res2;
1675 DAE.Operator op;
1676 Integer index1, index2;
1677
1678 case (DAE.RELATION(index=index1), DAE.RELATION(index=index2)) algorithm
1679 ✗ res := if index1 < index2 then inZCexp1 else inZCexp2;
1680 then res;
1681
1682 case (DAE.LUNARY(operator=op, exp=e1), DAE.LUNARY(exp=e2)) algorithm
1683 ✗ res := getMinZeroCrossings(e1, e2);
1684 ✗ then DAE.LUNARY(op, res);
1685
1686 case (DAE.LBINARY(exp1=e1, operator=op, exp2=e2), DAE.LBINARY(exp1=e3, exp2=e4)) algorithm
1687 ✗ res := getMinZeroCrossings(e1, e2);
1688 ✗ res2 := getMinZeroCrossings(e3, e4);
1689 ✗ then DAE.LBINARY(res, op, res2);
1690
1691 case (DAE.CALL(path=Absyn.IDENT("sample"), expLst={_, _, _}), _)
1692 then inZCexp1;
1693
1694 case (_, DAE.CALL(path=Absyn.IDENT("sample"), expLst={_, _, _}))
1695 then inZCexp2;
1696
1697 else algorithm
1698 ✗ Error.addInternalError(getInstanceName() + " failed for {" + ExpressionBasics.printExpStr(inZCexp1) + "} and {" + ExpressionBasics.printExpStr(inZCexp2) + "}", sourceInfo());
1699 ✗ then fail();
1700 end match;
1701 end getMinZeroCrossings;
1702
1703 protected function traverseStmtsExps "Handles the traversing of list<DAE.Statement>.
1704 Works with the help of Expression.traverseExpTopDown to find
1705 ZeroCrossings in algorithm statements
1706 modified: 2011-01 by wbraun"
1707 input list<DAE.Statement> inStmts;
1708 input ForArgType inExtraArg;
1709 input BackendDAE.Variables inKnvars "this is needed to extend ranges" ;
1710 output list<DAE.Statement> slist = {};
1711 output ForArgType extraArg = inExtraArg;
1712 protected
1713 DAE.Exp e_1, e_2, e, e2, iteratorExp;
1714 list<DAE.Exp> expl1, expl2, iteratorexps;
1715 DAE.ComponentRef cr;
1716 list<DAE.Statement> stmts, stmts2;
1717 DAE.Type tp;
1718 DAE.Statement x, ew, ew_1;
1719 Boolean b1;
1720 String id1;
1721 DAE.ElementSource source;
1722 DAE.Else algElse;
1723 list<tuple<DAE.ComponentRef, SourceInfo>> loopPrlVars "list of parallel variables used/referenced in the parfor loop";
1724 list<DAE.ComponentRef> conditions;
1725 Boolean initialCall;
1726 list<tuple<DAE.ComponentRef, array<DAE.Exp>>> sub_iters;
1727 algorithm
1728
2/2
✓ Branch 0 taken 2449 times.
✓ Branch 1 taken 641 times.
3090 for stmt in inStmts loop
1729 (stmt, extraArg) := match stmt
1730 case DAE.STMT_ASSIGN(type_=tp, exp1=e2, exp=e, source=source) algorithm
1731 1941 (e_1, extraArg) := Expression.traverseExpTopDown(e, collectZCAlgsFor, extraArg);
1732 1941 (e_2, extraArg) := Expression.traverseExpTopDown(e2, collectZCAlgsFor, extraArg);
1733 1941 then (DAE.STMT_ASSIGN(tp, e_2, e_1, source), extraArg);
1734
1735 case DAE.STMT_TUPLE_ASSIGN(type_=tp, expExpLst=expl1, exp=e, source=source) algorithm
1736 1 (e_1, extraArg) := Expression.traverseExpTopDown(e, collectZCAlgsFor, extraArg);
1737 1 (expl2, extraArg) := Expression.traverseExpListTopDown(expl1, collectZCAlgsFor, extraArg);
1738 1 then (DAE.STMT_TUPLE_ASSIGN(tp, expl2, e_1, source), extraArg);
1739
1740 case DAE.STMT_ASSIGN_ARR(type_=tp, lhs=e2, exp=e, source=source) algorithm
1741 42 (e_1, extraArg) := Expression.traverseExpTopDown(e, collectZCAlgsFor, extraArg);
1742 42 (e_2, _, extraArg) := collectZCAlgsFor(e2, extraArg);
1743 42 then (DAE.STMT_ASSIGN_ARR(tp, e_2, e_1, source), extraArg);
1744
1745 case x as DAE.STMT_ASSIGN_ARR(type_=tp, lhs=e2, exp=e, source=source) algorithm
1746 ✗ (e_1, extraArg) := Expression.traverseExpTopDown(e, collectZCAlgsFor, extraArg);
1747 ✗ failure((e_2, _, _) := collectZCAlgsFor(e2, extraArg));
1748 ✗ true := Flags.isSet(Flags.FAILTRACE);
1749 ✗ print(DAEDump.ppStatementStr(x));
1750 ✗ print("Warning, not allowed to set the componentRef to a expression in FindZeroCrossings.traverseStmtsExps for ZeroCrosssing\n");
1751 ✗ then fail();
1752
1753 case DAE.STMT_IF(exp=e, statementLst=stmts, else_=algElse, source=source) algorithm
1754 169 (algElse, extraArg) := traverseStmtsElseExps(algElse, extraArg, inKnvars);
1755 169 (stmts2, extraArg) := traverseStmtsExps(stmts, extraArg, inKnvars);
1756 169 (e_1, extraArg) := Expression.traverseExpTopDown(e, collectZCAlgsFor, extraArg);
1757 169 then (DAE.STMT_IF(e_1, stmts2, algElse, source), extraArg);
1758
1759 case DAE.STMT_FOR(type_=tp, iterIsArray=b1, iter=id1, range=e, statementLst=stmts, source=source, sub_iters=sub_iters) algorithm
1760 95 cr := ComponentReferenceBasics.makeCrefIdent(id1, tp, {});
1761 95 iteratorExp := Expression.crefExp(cr);
1762 95 iteratorexps := BackendDAEUtil.extendRange(e, inKnvars);
1763 95 (stmts2, extraArg) := traverseStmtsForExps(iteratorExp, iteratorexps, e, stmts, inKnvars, extraArg);
1764
1/2
✓ Branch 0 taken 95 times.
✗ Branch 1 not taken.
190 then (DAE.STMT_FOR(tp, b1, id1, e, stmts2, source, sub_iters), extraArg);
1765
1766 case DAE.STMT_PARFOR(type_=tp, iterIsArray=b1, iter=id1, range=e, statementLst=stmts, loopPrlVars= loopPrlVars, source=source) algorithm
1767 ✗ cr := ComponentReferenceBasics.makeCrefIdent(id1, tp, {});
1768 ✗ iteratorExp := Expression.crefExp(cr);
1769 ✗ iteratorexps := BackendDAEUtil.extendRange(e, inKnvars);
1770 ✗ (stmts2, extraArg) := traverseStmtsForExps(iteratorExp, iteratorexps, e, stmts, inKnvars, extraArg);
1771 ✗ then (DAE.STMT_PARFOR(tp, b1, id1, e, stmts2, loopPrlVars, source), extraArg);
1772
1773 case DAE.STMT_WHILE(exp=e, statementLst=stmts, source=source) algorithm
1774 ✗ (stmts2, extraArg) := traverseStmtsExps(stmts, extraArg, inKnvars);
1775 ✗ (e_1, extraArg) := Expression.traverseExpTopDown(e, collectZCAlgsFor, extraArg);
1776 ✗ then (DAE.STMT_WHILE(e_1, stmts2, source), extraArg);
1777
1778 case DAE.STMT_WHEN(exp=e, conditions=conditions, initialCall=initialCall, statementLst=stmts, elseWhen=NONE(), source=source) algorithm
1779 // wbraun: statemenents inside when equations can't contain zero-crossings
1780 // (stmts2, extraArg) = traverseStmtsExps(stmts, extraArg, inKnvars);
1781 124 (e_1, extraArg) := Expression.traverseExpTopDown(e, collectZCAlgsFor, extraArg);
1782
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 7 times.
241 then (DAE.STMT_WHEN(e_1, conditions, initialCall, stmts, NONE(), source), extraArg);
1783
1784 case DAE.STMT_WHEN(exp=e, conditions=conditions, initialCall=initialCall, statementLst=stmts, elseWhen=SOME(ew), source=source) algorithm
1785
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 51 times.
51 ({ew_1}, extraArg) := traverseStmtsExps({ew}, extraArg, inKnvars);
1786 // wbraun: statemenents inside when equations can't contain zero-crossings
1787 // (stmts2, extraArg) = traverseStmtsExps(stmts, extraArg, inKnvars);
1788 51 (e_1, extraArg) := Expression.traverseExpTopDown(e, collectZCAlgsFor, extraArg);
1789
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 22 times.
80 then (DAE.STMT_WHEN(e_1, conditions, initialCall, stmts, SOME(ew_1), source), extraArg);
1790
1791 10 case DAE.STMT_ASSERT() then (stmt, extraArg);
1792 ✗ case DAE.STMT_TERMINATE() then (stmt, extraArg);
1793 ✗ case DAE.STMT_REINIT() then (stmt, extraArg);
1794
1795 case DAE.STMT_NORETCALL(exp=e, source=source) algorithm
1796 2 (e_1, extraArg) := Expression.traverseExpTopDown(e, collectZCAlgsFor, extraArg);
1797 2 then (DAE.STMT_NORETCALL(e_1, source), extraArg);
1798
1799 ✗ case DAE.STMT_RETURN() then (stmt, extraArg);
1800 14 case DAE.STMT_BREAK() then (stmt, extraArg);
1801
1802 // MetaModelica extension. KS
1803 case DAE.STMT_FAILURE(body=stmts, source=source) algorithm
1804 ✗ (stmts2, extraArg) := traverseStmtsExps(stmts, extraArg, inKnvars);
1805 ✗ then (DAE.STMT_FAILURE(stmts2, source), extraArg);
1806
1807 else algorithm
1808 ✗ Error.addInternalError(getInstanceName() + " failed: " + DAEDump.ppStatementStr(stmt), sourceInfo());
1809 ✗ then fail();
1810 end match;
1811
1812 slist := stmt :: slist;
1813 end for;
1814
1815 641 slist := listReverseInPlace(slist);
1816 end traverseStmtsExps;
1817
1818 protected function traverseStmtsElseExps "author: BZ, 2008-12
1819 modified: 2011-01 by wbraun
1820 Helper function for traverseStmtsExps to find ZeroCrosssings in algorithm
1821 else statements."
1822 input DAE.Else inElse;
1823 input ForArgType inExtraArg;
1824 input BackendDAE.Variables inKnvars;
1825 output DAE.Else outElse;
1826 output ForArgType outTplStmtTypeA;
1827 algorithm
1828 (outElse, outTplStmtTypeA) := match inElse
1829 local
1830 DAE.Exp e, e_1;
1831 list<DAE.Statement> st, st_1;
1832 DAE.Else el, el_1;
1833 ForArgType extraArg;
1834
1835 case DAE.NOELSE()
1836 then (DAE.NOELSE(), inExtraArg);
1837
1838 case DAE.ELSEIF(e, st, el) algorithm
1839 72 (el_1, extraArg) := traverseStmtsElseExps(el, inExtraArg, inKnvars);
1840 72 (st_1, extraArg) := traverseStmtsExps(st, extraArg, inKnvars);
1841 72 (e_1, extraArg) := Expression.traverseExpTopDown(e, collectZCAlgsFor, extraArg);
1842 72 then (DAE.ELSEIF(e_1, st_1, el_1), extraArg);
1843
1844 case DAE.ELSE(st) algorithm
1845 34 (st_1, extraArg) := traverseStmtsExps(st, inExtraArg, inKnvars);
1846 34 then (DAE.ELSE(st_1), extraArg);
1847 end match;
1848 end traverseStmtsElseExps;
1849
1850 protected function traverseStmtsForExps "modified: 2011-01 by wbraun
1851 Helper function for traverseStmtsExps to processed for loops to search
1852 zero crosssings."
1853 input DAE.Exp inIteratorExp;
1854 input list<DAE.Exp> inExplst;
1855 input DAE.Exp inRange;
1856 input list<DAE.Statement> inStmts;
1857 input BackendDAE.Variables inKnvars;
1858 input ForArgType inExtraArg;
1859 output list<DAE.Statement> outStatements;
1860 output ForArgType outTpl;
1861 algorithm
1862 (outStatements, outTpl) := match (inExplst, inExtraArg)
1863 local
1864 list<DAE.Statement> statementLst;
1865 tuple<BackendDAE.ZeroCrossingSet, BackendDAE.ZeroCrossingSet, BackendDAE.ZeroCrossingSet, Integer> tpl2;
1866 tuple<Integer, BackendDAE.Variables, BackendDAE.Variables> tpl3;
1867 ForArgType extraArg;
1868
1869 case ({}, _)
1870 6 then (inStmts, inExtraArg);
1871
1872 case (_, (_, _, _, tpl2, tpl3)) algorithm
1873 89 (statementLst, extraArg) := traverseStmtsExps(inStmts, (inIteratorExp, inExplst, inRange, tpl2, tpl3), inKnvars);
1874 then (statementLst, extraArg);
1875
1876 else algorithm
1877 ✗ Error.addInternalError(getInstanceName() + " failed.", sourceInfo());
1878 ✗ then fail();
1879 end match;
1880 end traverseStmtsForExps;
1881
1882 public function setOperatorZeroCrossingIndices
1883 "`delayZeroCrossing` and `spatialDistributionZeroCrossing` read `zeroCrossingsPre` at
1884 the index passed as their second argument, so it has to be the crossing's own index.
1885 `collectZC` cannot know it yet -- the call must exist before the crossing can be
1886 registered -- so it fills in the relation index; overwrite it once the list is final.
1887 A model has at least as many relations as crossings, so leaving it there reads
1888 another crossing's held value, or past the end of the array."
1889 input list<BackendDAE.ZeroCrossing> inZeroCrossings;
1890 output list<BackendDAE.ZeroCrossing> outZeroCrossings = {};
1891 protected
1892 DAE.Exp relation_;
1893 algorithm
1894
2/2
✓ Branch 0 taken 1713 times.
✓ Branch 1 taken 1069 times.
2782 for zc in inZeroCrossings loop
1895 1713 (relation_, _) := Expression.traverseExpBottomUp(zc.relation_, setOperatorIndex, zc.index);
1896 1713 zc.relation_ := relation_;
1897 outZeroCrossings := zc :: outZeroCrossings;
1898 end for;
1899 1069 outZeroCrossings := listReverse(outZeroCrossings);
1900 end setOperatorZeroCrossingIndices;
1901
1902 protected function setOperatorIndex
1903 input DAE.Exp inExp;
1904 input Integer inIndex;
1905 output DAE.Exp outExp;
1906 output Integer outIndex = inIndex;
1907 algorithm
1908 outExp := match inExp
1909 local
1910 DAE.Exp expr, delay, x, dir;
1911 DAE.CallAttributes attr;
1912 case DAE.CALL(path = Absyn.IDENT("delayZeroCrossing"), expLst = {expr, _, delay}, attr = attr)
1913 38 then DAE.CALL(Absyn.IDENT("delayZeroCrossing"), {expr, DAE.ICONST(inIndex), delay}, attr);
1914
1915 case DAE.CALL(path = Absyn.IDENT("spatialDistributionZeroCrossing"), expLst = {expr, _, x, dir}, attr = attr)
1916 16 then DAE.CALL(Absyn.IDENT("spatialDistributionZeroCrossing"), {expr, DAE.ICONST(inIndex), x, dir}, attr);
1917
1918 else inExp;
1919 end match;
1920 end setOperatorIndex;
1921
1922 protected function createZeroCrossings "
1923 Constructs a list of zero crossings from a list of relations. Each zero
1924 crossing gets the same equation indices and when clause indices."
1925 input list<DAE.Exp> inExpExpLst1;
1926 input list<Integer> inOccurEquLst;
1927 output list<BackendDAE.ZeroCrossing> outZeroCrossingLst;
1928 algorithm
1929 144 outZeroCrossingLst := List.map1(inExpExpLst1, function createZeroCrossing(iters = NONE()), inOccurEquLst);
1930 end createZeroCrossings;
1931
1932 protected function createZeroCrossing
1933 input DAE.Exp inRelation;
1934 input list<Integer> inOccurEquLst;
1935 input Option<list<BackendDAE.SimIterator>> iters;
1936 output BackendDAE.ZeroCrossing outZeroCrossing;
1937 algorithm
1938 outZeroCrossing := match inOccurEquLst
1939 case {-1}
1940 ✗ then BackendDAE.ZERO_CROSSING(0, inRelation, {}, iters);
1941
1942 5524 else BackendDAE.ZERO_CROSSING(0, inRelation, inOccurEquLst, iters);
1943 end match;
1944 end createZeroCrossing;
1945
1946 protected function createIterator
1947 input DAE.ReductionIterator red_iter;
1948 output BackendDAE.SimIterator iter;
1949 algorithm
1950 iter := match red_iter.exp
1951 local
1952 DAE.Exp exp, step, size;
1953 DAE.Type ty;
1954 Integer non_resizable_size;
1955
1956 case exp as DAE.RANGE() algorithm
1957 ✗ ty := Expression.typeof(exp.start);
1958 ✗ step := Util.getOptionOrDefault(exp.step, DAE.ICONST(1));
1959 // build the size expression (stop-start)/step+1
1960 ✗ size := DAE.BINARY(exp.stop, DAE.SUB(ty), exp.start);
1961 ✗ size := DAE.BINARY(size, DAE.DIV(ty), step);
1962 ✗ size := DAE.BINARY(size, DAE.ADD(ty), DAE.ICONST(1));
1963 ✗ size := ExpressionSimplify.simplify(size);
1964 try
1965 ✗ non_resizable_size := Expression.getEvaluatedConstInteger(size);
1966 else
1967 non_resizable_size := 0;
1968 end try;
1969 ✗ then BackendDAE.SIM_ITERATOR_RANGE(DAE.CREF_IDENT(red_iter.id, DAE.T_INTEGER_DEFAULT, {}), exp.start, step, exp.stop, size, non_resizable_size, {});
1970
1971 case exp as DAE.ARRAY() algorithm
1972 ✗ then BackendDAE.SIM_ITERATOR_LIST(DAE.CREF_IDENT(red_iter.id, DAE.T_INTEGER_DEFAULT, {}), list(DAEUtil.getInteger(e) for e in exp.array), listLength(exp.array), {});
1973
1974 else algorithm
1975 ✗ Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed for expression: " + ExpressionBasics.printExpStr(red_iter.exp) + ".\n"});
1976 ✗ then fail();
1977 end match;
1978 end createIterator;
1979
1980 annotation(__OpenModelica_Interface="backend");
1981 end FindZeroCrossings;
1982