Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 68.9% 1647 / 0 / 2391
Functions: -% 0 / 1 / 1
Branches: 60.0% 913 / 0 / 1522

OMCompiler/Compiler/BackEnd/BackendDAEUtil.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 BackendDAEUtil
37 " file: BackendDAEUtil.mo
38 package: BackendDAEUtil
39 description: BackendDAEUtil comprised functions for BackendDAE data types.
40
41 This module is a lowered form of a DAE including equations
42 and simple equations in
43 two separate lists. The variables are split into known variables
44 parameters and constants, and unknown variables,
45 states and algebraic variables.
46 The module includes the BLT sorting algorithm which sorts the
47 equations into blocks, and the index reduction algorithm using
48 dummy derivatives for solving higher index problems.
49 It also includes the tarjan algorithm to detect strong components
50 in the BLT sorting."
51
52 import Absyn;
53 import AvlSetInt;
54 import AvlSetPath;
55 import BackendDAE;
56 import BackendDAEFunc;
57 import BackendEquation;
58 import DAE;
59 import FCore;
60 import Util;
61
62 protected
63 import AdjacencyMatrix;
64 import Algorithm;
65 import Array;
66 import BackendDAEOptimize;
67 import BackendDAETransform;
68 import BackendDump;
69 import BackendDAEEXT;
70 import BackendInline;
71 import BackendVarTransform;
72 import BackendVariable;
73 import BaseHashTable;
74 import BinaryTree;
75 import Causalize;
76 import CheckModel;
77 import ClassInf;
78 import CommonSubExpression;
79 import ComponentReference;
80 import ComponentReferenceBasics;
81 import Config;
82 import DAEDump;
83 import DAEMode;
84 import DAEUtil;
85 import DataReconciliation;
86 import Debug;
87 import Differentiate;
88 import Dump;
89 import DumpGraphML;
90 import DynamicOptimization;
91 import ElementSource;
92 import Error;
93 import ErrorExt;
94 import EvaluateFunctions;
95 import EvaluateParameter;
96 import ExecStat.execStat;
97 import ExpandableArray;
98 import Ceval;
99 import Expression;
100 import ExpressionBasics;
101 import ExpressionDump;
102 import ExpressionSimplify;
103 import ExpressionSolve;
104 import FindZeroCrossings;
105 import Flags;
106 import FlagsUtil;
107 import Global;
108 import HpcOmEqSystems;
109 import HashSet;
110 import HashTableExpToExp;
111 import IndexReduction;
112 import Initialization;
113 import Inline;
114 import InlineArrayEquations;
115 import List;
116 import Matching;
117 import MetaModelica.Dangerous;
118 import OnRelaxation;
119 import RemoveSimpleEquations;
120 import ResolveLoops;
121 import SCode;
122 import SCodeUtil;
123 import Sorting;
124 import StackOverflow;
125 import SymbolicImplicitSolver;
126 import SymbolicJacobian;
127 import SynchronousFeatures;
128 import System;
129 import Tearing;
130 import Types;
131 import UnorderedSet;
132 import Values;
133 import XMLDump;
134 import ZeroCrossings;
135
136 public function isInitializationDAE
137 input BackendDAE.Shared inShared;
138 output Boolean res;
139 algorithm
140 res := match inShared
141 case BackendDAE.SHARED(backendDAEType=BackendDAE.INITIALSYSTEM()) then true;
142 else false;
143 end match;
144 end isInitializationDAE;
145
146 public function isSimulationDAE
147 input BackendDAE.Shared inShared;
148 output Boolean res;
149 algorithm
150 res := match inShared
151 case BackendDAE.SHARED(backendDAEType=BackendDAE.SIMULATION()) then true;
152 else false;
153 end match;
154 end isSimulationDAE;
155
156 public function isJacobianDAE
157 input BackendDAE.Shared inShared;
158 output Boolean res;
159 algorithm
160 res := match inShared
161 case BackendDAE.SHARED(backendDAEType=BackendDAE.JACOBIAN()) then true;
162 else false;
163 end match;
164 end isJacobianDAE;
165
166 /*************************************************
167 * checkBackendDAE and stuff
168 ************************************************/
169
170 public function checkBackendDAEWithErrorMsg "author: Frenkel TUD
171 run checkDEALow and prints all errors"
172 input BackendDAE.BackendDAE inBackendDAE;
173 protected
174 list<tuple<DAE.Exp, list<DAE.ComponentRef>>> expCrefs;
175 list<BackendDAE.Equation> wrongEqns;
176 algorithm
177
1/2
✓ Branch 1 taken 2170 times.
✗ Branch 2 not taken.
2170 if not Flags.isSet(Flags.CHECK_BACKEND_DAE) then return; end if;
178 () := matchcontinue inBackendDAE
179 local
180 Integer nVars, nEqns;
181 Boolean samesize;
182 BackendDAE.Variables vars;
183 BackendDAE.EquationArray orderedEqs;
184
185 case BackendDAE.DAE(eqs=(BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=orderedEqs))::{}, shared=BackendDAE.SHARED()) algorithm
186 //true = Flags.isSet(Flags.CHECK_BACKEND_DAE);
187 //Check for correct size
188 ✗ nVars := BackendVariable.varsSize(vars);
189 ✗ nEqns := BackendEquation.equationArraySize(orderedEqs);
190 samesize := nVars == nEqns;
191 ✗ if Flags.isSet(Flags.CHECK_BACKEND_DAE) then
192 ✗ print("No. of Equations: " + intString(nVars) + " No. of BackendDAE.Variables: " + intString(nEqns) + " Samesize: " + boolString(samesize) + "\n");
193 end if;
194 ✗ (expCrefs, wrongEqns) := checkBackendDAE(inBackendDAE);
195 ✗ printcheckBackendDAEWithErrorMsg(expCrefs, wrongEqns);
196 then ();
197
198 else algorithm
199 ✗ Error.addMessage(Error.INTERNAL_ERROR, {"./Compiler/BackEnd/BackendDAEUtil.mo: function checkBackendDAEWithErrorMsg failed"});
200 ✗ then fail();
201 end matchcontinue;
202 end checkBackendDAEWithErrorMsg;
203
204 public function printcheckBackendDAEWithErrorMsg"author: Frenkel TUD
205 helper for checkDEALowWithErrorMsg"
206 input list<tuple<DAE.Exp,list<DAE.ComponentRef>>> inExpCrefs;
207 input list<BackendDAE.Equation> inWrongEqns;
208 algorithm
209 () := match (inExpCrefs,inWrongEqns)
210 local
211 DAE.Exp e;
212 list<DAE.ComponentRef> crefs;
213 list<tuple<DAE.Exp,list<DAE.ComponentRef>>> res;
214 list<String> strcrefs;
215 String crefstring, expstr,scopestr;
216 BackendDAE.Equation eqn;
217 list<BackendDAE.Equation> wrongEqns;
218
219 case ({},{}) then ();
220
221 case ({},eqn::wrongEqns)
222 algorithm
223 ✗ printEqnSizeError(eqn);
224 ✗ printcheckBackendDAEWithErrorMsg({},wrongEqns);
225 then ();
226
227 case (((e,crefs))::res,wrongEqns)
228 algorithm
229 ✗ strcrefs := List.map(crefs,ComponentReference.crefStr);
230 ✗ crefstring := stringDelimitList(strcrefs,", ");
231 ✗ expstr := ExpressionBasics.printExpStr(e);
232 ✗ scopestr := stringAppendList({crefstring," from Expression: ",expstr});
233 ✗ Error.addMessage(Error.LOOKUP_VARIABLE_ERROR, {scopestr,"BackendDAE object"});
234 ✗ printcheckBackendDAEWithErrorMsg(res,wrongEqns);
235 then
236 ();
237 end match;
238 end printcheckBackendDAEWithErrorMsg;
239
240 protected function printEqnSizeError"author: Frenkel TUD 2010-12"
241 input BackendDAE.Equation inEqn;
242 algorithm
243 () := matchcontinue inEqn
244 local
245 BackendDAE.Equation eqn;
246 DAE.Exp e1, e2;
247 DAE.ComponentRef cr;
248 DAE.Type t1,t2;
249 String eqnstr, t1str, t2str, tstr;
250 DAE.ElementSource source;
251 case eqn as BackendDAE.EQUATION(exp=e1,scalar=e2,source=source)
252 algorithm
253 ✗ eqnstr := BackendDump.equationString(eqn);
254 ✗ t1 := Expression.typeof(e1);
255 ✗ t2 := Expression.typeof(e2);
256 ✗ t1str := TypesDump.unparseTypeNoAttr(t1);
257 ✗ t2str := TypesDump.unparseTypeNoAttr(t2);
258 ✗ tstr := stringAppendList({t1str," != ", t2str});
259 ✗ Error.addSourceMessage(Error.EQUATION_TYPE_MISMATCH_ERROR, {eqnstr,tstr}, ElementSource.getElementSourceFileInfo(source));
260 then ();
261 case eqn as BackendDAE.SOLVED_EQUATION(componentRef=cr,exp=e1,source=source)
262 algorithm
263 ✗ eqnstr := BackendDump.equationString(eqn);
264 ✗ t1 := Expression.typeof(e1);
265 ✗ t2 := ComponentReference.crefLastType(cr);
266 ✗ t1str := TypesDump.unparseTypeNoAttr(t1);
267 ✗ t2str := TypesDump.unparseTypeNoAttr(t2);
268 ✗ tstr := stringAppendList({t1str," != ", t2str});
269 ✗ Error.addSourceMessage(Error.EQUATION_TYPE_MISMATCH_ERROR, {eqnstr,tstr}, ElementSource.getElementSourceFileInfo(source));
270 then ();
271 //
272 else ();
273 end matchcontinue;
274 end printEqnSizeError;
275
276 public function checkBackendDAE "author: Frenkel TUD
277 This function checks the BackendDAE object if
278 - all component refercences used in the expressions are
279 part of the BackendDAE object.
280 - all variables that are reinit are states
281 Returns all component references which not part of the BackendDAE object."
282 input BackendDAE.BackendDAE inBackendDAE;
283 output list<tuple<DAE.Exp,list<DAE.ComponentRef>>> outExpCrefs;
284 output list<BackendDAE.Equation> outWrongEqns;
285 algorithm
286 (outExpCrefs,outWrongEqns) := matchcontinue inBackendDAE
287 local
288 BackendDAE.EqSystem syst;
289 BackendDAE.Shared shared;
290 BackendDAE.Variables allvars;
291 list<tuple<DAE.Exp,list<DAE.ComponentRef>>> expcrefs;
292 list<BackendDAE.Equation> wrongEqns;
293
294
295 case BackendDAE.DAE(syst::{}, shared)
296 algorithm
297 ✗ allvars := BackendVariable.mergeVariables(syst.orderedVars, shared.globalKnownVars);
298 ✗ (_, expcrefs) := traverseBackendDAEExpsVars(syst.orderedVars, checkBackendDAEExp, (allvars, {}));
299 ✗ (_, expcrefs) := traverseBackendDAEExpsEqns(shared.removedEqs, checkBackendDAEExp, (allvars, expcrefs));
300 ✗ (_, expcrefs) := traverseBackendDAEExpsVars(shared.globalKnownVars, checkBackendDAEExp, (allvars, expcrefs));
301 ✗ (_, expcrefs) := traverseBackendDAEExpsEqns(syst.orderedEqs, checkBackendDAEExp, (allvars, expcrefs));
302 ✗ (_, expcrefs) := traverseBackendDAEExpsEqns(syst.removedEqs, checkBackendDAEExp, (allvars, expcrefs));
303 ✗ (_, expcrefs) := traverseBackendDAEExpsEqns(shared.initialEqs, checkBackendDAEExp, (allvars, expcrefs));
304
305 ✗ wrongEqns := BackendEquation.traverseEquationArray(syst.orderedEqs, checkEquationSize, {});
306 ✗ wrongEqns := BackendEquation.traverseEquationArray(shared.removedEqs, checkEquationSize, wrongEqns);
307 ✗ wrongEqns := BackendEquation.traverseEquationArray(syst.removedEqs, checkEquationSize, wrongEqns);
308 ✗ wrongEqns := BackendEquation.traverseEquationArray(shared.initialEqs, checkEquationSize, wrongEqns);
309 then
310 (expcrefs, wrongEqns);
311
312 else
313 algorithm
314 ✗ true := Flags.isSet(Flags.FAILTRACE);
315 ✗ Debug.trace("- BackendDAEUtil.checkBackendDAE failed\n");
316 ✗ then
317 fail();
318 end matchcontinue;
319 end checkBackendDAE;
320
321 protected function checkBackendDAEExp
322 input DAE.Exp inExp;
323 input tuple<BackendDAE.Variables,list<tuple<DAE.Exp,list<DAE.ComponentRef>>>> inTpl;
324 output DAE.Exp outExp;
325 output tuple<BackendDAE.Variables,list<tuple<DAE.Exp,list<DAE.ComponentRef>>>> outTpl;
326 algorithm
327 (outExp,outTpl) := matchcontinue (inExp,inTpl)
328 local
329 DAE.Exp exp;
330 BackendDAE.Variables vars;
331 list<DAE.ComponentRef> crefs;
332 list<tuple<DAE.Exp,list<DAE.ComponentRef>>> lstExpCrefs;
333 case (exp,(vars,lstExpCrefs))
334 algorithm
335 ✗ (_,(_,crefs)) := Expression.traverseExpBottomUp(exp,traversecheckBackendDAEExp,(vars,{}));
336 ✗ then (exp, if not listEmpty(crefs) then (vars,(exp,crefs)::lstExpCrefs) else inTpl);
337 else (inExp,inTpl);
338 end matchcontinue;
339 end checkBackendDAEExp;
340
341 protected function traversecheckBackendDAEExp
342 input DAE.Exp inExp;
343 input tuple<BackendDAE.Variables,list<DAE.ComponentRef>> inTuple;
344 output DAE.Exp outExp;
345 output tuple<BackendDAE.Variables,list<DAE.ComponentRef>> outTuple;
346 algorithm
347 (outExp,outTuple) := matchcontinue (inExp,inTuple)
348 local
349 DAE.Exp e,e1;
350 BackendDAE.Variables vars;
351 DAE.ComponentRef cr;
352 list<DAE.ComponentRef> crefs;
353 list<DAE.Exp> expl;
354 list<DAE.Var> varLst;
355 list<BackendDAE.Var> backendVars;
356 DAE.ReductionIterators riters;
357 tuple<BackendDAE.Variables,list<DAE.ComponentRef>> tp;
358
359 // special case for time, it is never part of the equation system
360 case (e as DAE.CREF(componentRef = DAE.CREF_IDENT(ident="time")),_)
361 then (e, inTuple);
362
363 // Special Case for Records
364 case (e as DAE.CREF(componentRef = cr,ty= DAE.T_COMPLEX(varLst=varLst,complexClassType=ClassInf.RECORD(_))),_)
365 algorithm
366 ✗ expl := List.map1(varLst,Expression.generateCrefsExpFromExpVar,cr);
367 ✗ (_,tp) := Expression.traverseExpList(expl,traversecheckBackendDAEExp,inTuple);
368 ✗ then (e, tp);
369
370 // Special Case for Arrays
371 case (e as DAE.CREF(ty = DAE.T_ARRAY()),_)
372 algorithm
373 ✗ (e1,true) := Expression.extendArrExp(e,false);
374 ✗ (_,tp) := Expression.traverseExpBottomUp(e1,traversecheckBackendDAEExp,inTuple);
375 ✗ then (e, tp);
376
377 // case for Reductions
378 case (e as DAE.REDUCTION(iterators = riters),(vars,crefs))
379 algorithm
380 // add idents to vars
381 ✗ backendVars := List.map(riters,makeIterVariable);
382 ✗ vars := BackendVariable.addVars(backendVars,vars);
383 ✗ then (e, (vars,crefs));
384
385 // case for functionpointers
386 case (e as DAE.CREF(ty=DAE.T_FUNCTION_REFERENCE_FUNC()),_)
387 then (e, inTuple);
388
389 case (e as DAE.CREF(componentRef = cr),(vars,_))
390 algorithm
391 ✗ BackendVariable.getVar(cr, vars);
392 then (e, inTuple);
393
394 case (e as DAE.CREF(componentRef = cr),(vars,crefs))
395 //failed before, so no need to getVar() again
396 //failure((_,_) = BackendVariable.getVar(cr, vars));
397 ✗ then (e, (vars,cr::crefs));
398
399 else (inExp,inTuple);
400 end matchcontinue;
401 end traversecheckBackendDAEExp;
402
403 protected function makeIterVariable
404 input DAE.ReductionIterator iter;
405 output BackendDAE.Var backendVar;
406 protected
407 String name;
408 DAE.ComponentRef cr;
409 algorithm
410 ✗ name := Expression.reductionIterName(iter);
411 ✗ cr := ComponentReferenceBasics.makeCrefIdent(name,DAE.T_INTEGER_DEFAULT,{});
412 ✗ backendVar := BackendDAE.VAR(cr, BackendDAE.VARIABLE(), DAE.BIDIR(), DAE.NON_PARALLEL(), DAE.T_INTEGER_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), false, false, false);
413 end makeIterVariable;
414
415 protected function checkEquationSize"author: Frenkel TUD 2010-12
416 - check if the left hand side and the rigth hand side have equal types."
417 input BackendDAE.Equation inEq;
418 input list<BackendDAE.Equation> inEqs;
419 output BackendDAE.Equation outEq;
420 output list<BackendDAE.Equation> outEqs;
421 algorithm
422 (outEq,outEqs) := matchcontinue (inEq,inEqs)
423 local
424 BackendDAE.Equation e;
425 list<BackendDAE.Equation> wrongEqns,wrongEqns1;
426 DAE.Exp e1, e2;
427 DAE.ComponentRef cr;
428 DAE.Type t1,t2;
429 Boolean b;
430 case (e as BackendDAE.EQUATION(exp=e1,scalar=e2),wrongEqns)
431 algorithm
432 ✗ t1 := Expression.typeof(e1);
433 ✗ t2 := Expression.typeof(e2);
434 ✗ b := Expression.equalTypes(t1,t2);
435 ✗ wrongEqns1 := List.consOnTrue(not b,e,wrongEqns);
436 then (e,wrongEqns1);
437
438 case (e as BackendDAE.SOLVED_EQUATION(componentRef=cr,exp=e1),wrongEqns)
439 algorithm
440 ✗ t1 := Expression.typeof(e1);
441 ✗ t2 := ComponentReference.crefLastType(cr);
442 ✗ b := Expression.equalTypes(t1,t2);
443 ✗ wrongEqns1 := List.consOnTrue(not b,e,wrongEqns);
444 then (e,wrongEqns1);
445
446 //
447 else (inEq,inEqs);
448 end matchcontinue;
449 end checkEquationSize;
450
451 public function checkAssertCondition "Succeds if condition of assert is not constant false"
452 input DAE.Exp cond;
453 input DAE.Exp message;
454 input DAE.Exp level;
455 input SourceInfo info;
456 algorithm
457 // Don't check assertions when checking models
458
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32908 times.
32908 if Flags.getConfigBool(Flags.CHECK_MODEL) then return; end if;
459 () := matchcontinue info
460 local
461 String messageStr;
462 case _
463 guard
464 not Expression.isConstFalse(cond)
465 then ();
466 case _
467 algorithm
468
3/6
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 time.
1 failure(DAE.ENUM_LITERAL(index=2) := level);
469 then ();
470 case _
471 algorithm
472
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 true := Expression.isConstFalse(cond);
473 1 messageStr := ExpressionBasics.printExpStr(message);
474 1 Error.addSourceMessage(Error.ASSERT_CONSTANT_FALSE_ERROR,{messageStr},info);
475 1 then fail();
476 end matchcontinue;
477 end checkAssertCondition;
478
479 // =============================================================================
480 // Util function at Backend using for lowering and other stuff
481 //
482 // =============================================================================
483
484 public function copyBackendDAE "author: Frenkel TUD, wbraun
485 Copy the dae to avoid changes in vectors."
486 input BackendDAE.BackendDAE inDAE;
487 output BackendDAE.BackendDAE outDAE;
488 algorithm
489 3106 outDAE := mapEqSystem(inDAE, copyEqSystemTraverser);
490 3106 outDAE.shared := copyBackendDAEShared(outDAE.shared);
491 end copyBackendDAE;
492
493 public function copyEqSystemTraverser
494 input BackendDAE.EqSystem inSystem;
495 input BackendDAE.Shared inShared;
496 output BackendDAE.EqSystem outSystem;
497 output BackendDAE.Shared outShared;
498 algorithm
499 9259 outSystem := copyEqSystem(inSystem);
500 outShared := inShared;
501 end copyEqSystemTraverser;
502
503 public function copyEqSystem
504 input BackendDAE.EqSystem inSystem;
505 output BackendDAE.EqSystem outSystem;
506 protected
507 BackendDAE.Variables vars;
508 BackendDAE.EquationArray eqns, removedEqs;
509 Option<BackendDAE.AdjacencyMatrix> m, mt;
510 BackendDAE.Matching matching;
511 algorithm
512 29632 vars := BackendVariable.copyVariables(inSystem.orderedVars);
513 29632 eqns := BackendEquation.copyEquationArray(inSystem.orderedEqs);
514 29632 removedEqs := BackendEquation.copyEquationArray(inSystem.removedEqs);
515 29632 m := AdjacencyMatrix.copyAdjacencyMatrix(inSystem.m);
516 29632 mt := AdjacencyMatrix.copyAdjacencyMatrixT(inSystem.mT);
517 29632 matching := copyMatching(inSystem.matching);
518 29632 outSystem := BackendDAE.EQSYSTEM(vars, eqns, m, mt, inSystem.mapping, matching, inSystem.stateSets, inSystem.partitionKind, removedEqs);
519 end copyEqSystem;
520
521 public function copyEqSystems
522 input BackendDAE.EqSystems inSystems;
523 output BackendDAE.EqSystems outSystems = {};
524 algorithm
525
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 12 times.
30 for e in inSystems loop
526 18 outSystems := copyEqSystem(e) :: outSystems;
527 end for;
528 end copyEqSystems;
529
530 public function mergeEqSystems
531 input BackendDAE.EqSystem System1;
532 input output BackendDAE.EqSystem System2;
533 algorithm
534 77 System2.orderedEqs := BackendEquation.merge(System1.orderedEqs,System2.orderedEqs);
535 System2.orderedVars := BackendVariable.mergeVariables(System1.orderedVars,System2.orderedVars);
536 end mergeEqSystems;
537
538 public function copyBackendDAEShared
539 " author: Frenkel TUD, wbraun
540 Copy the shared part of an BackendDAE to avoid changes in
541 vectors."
542 input BackendDAE.Shared inShared;
543 output BackendDAE.Shared outShared;
544 algorithm
545 outShared:=
546 match inShared
547 local
548 BackendDAE.Shared shared;
549
550 case shared as BackendDAE.SHARED()
551 algorithm
552 3106 shared.globalKnownVars := BackendVariable.copyVariables(shared.globalKnownVars);
553 3106 shared.externalObjects := BackendVariable.copyVariables(shared.externalObjects);
554 3106 shared.initialEqs := BackendEquation.copyEquationArray(shared.initialEqs);
555 3106 shared.removedEqs := BackendEquation.copyEquationArray(shared.removedEqs);
556 then
557 shared;
558 end match;
559 end copyBackendDAEShared;
560
561 public function copyMatching
562 input BackendDAE.Matching inMatching;
563 output BackendDAE.Matching outMatching;
564 algorithm
565 outMatching := match inMatching
566 local
567 array<Integer> ass1, cass1, ass2, cass2;
568 BackendDAE.StrongComponents comps;
569 case BackendDAE.NO_MATCHING() then BackendDAE.NO_MATCHING();
570 case BackendDAE.MATCHING(ass1=ass1,ass2=ass2,comps=comps)
571 algorithm
572 9297 cass1 := arrayCopy(ass1);
573 9297 cass2 := arrayCopy(ass2);
574 9297 then BackendDAE.MATCHING(cass1,cass2,comps);
575 end match;
576 end copyMatching;
577
578 public function getCompsOfMatching "author: mwalther
579 Get all strong connected components of the given matching. If the matching
580 has the concrete type NO_MATCHING, the returned list is empty."
581 input BackendDAE.Matching inMatching;
582 output BackendDAE.StrongComponents outComps;
583 algorithm
584 outComps := match inMatching
585 local
586 BackendDAE.StrongComponents comps;
587 case BackendDAE.MATCHING(comps=comps)
588 then comps;
589 else
590 then {};
591 end match;
592 end getCompsOfMatching;
593
594 public function addVarsToEqSystem
595 input BackendDAE.EqSystem syst;
596 input list<BackendDAE.Var> varlst;
597 output BackendDAE.EqSystem osyst;
598 protected
599 BackendDAE.Variables vars;
600 algorithm
601 4718 BackendDAE.EQSYSTEM(orderedVars=vars) := syst;
602 4718 osyst := setEqSystVars(syst, BackendVariable.addVars(varlst, vars));
603 end addVarsToEqSystem;
604
605 public function numberOfZeroCrossings "author: lochel"
606 input BackendDAE.BackendDAE inBackendDAE;
607 output Integer outNumZeroCrossings "number of ordinary zero crossings" ;
608 output Integer outNumTimeEvents "number of zero crossings that are time events" ;
609 output Integer outNumRelations;
610 output Integer outNumMathEventFunctions;
611 protected
612 BackendDAE.EventInfo eventInfo = inBackendDAE.shared.eventInfo;
613 algorithm
614 1069 outNumZeroCrossings := ZeroCrossings.length(eventInfo.zeroCrossings);
615 1069 outNumTimeEvents := listLength(eventInfo.timeEvents);
616 1069 outNumRelations := ZeroCrossings.count(eventInfo.relations);
617
1/2
✓ Branch 0 taken 1069 times.
✗ Branch 1 not taken.
1069 outNumMathEventFunctions := eventInfo.numberMathEvents;
618 end numberOfZeroCrossings;
619
620 public function numberOfDiscreteVars "author: lochel"
621 input BackendDAE.BackendDAE inBackendDAE;
622 output Integer outNumDiscreteReal;
623 algorithm
624 ✗ outNumDiscreteReal := countDiscreteVars(inBackendDAE);
625 end numberOfDiscreteVars;
626
627 protected function countDiscreteVars "author: lochel"
628 input BackendDAE.BackendDAE inDAE;
629 output Integer outNumDiscreteVars;
630 protected
631 BackendDAE.Variables globalKnownVars, alias;
632 algorithm
633 ✗ BackendDAE.SHARED(globalKnownVars=globalKnownVars, aliasVars=alias) := inDAE.shared;
634 ✗ outNumDiscreteVars := countDiscreteVars1(inDAE.eqs);
635 ✗ outNumDiscreteVars := BackendVariable.traverseBackendDAEVars(globalKnownVars, countDiscreteVars3, outNumDiscreteVars);
636 ✗ outNumDiscreteVars := BackendVariable.traverseBackendDAEVars(alias, countDiscreteVars3, outNumDiscreteVars);
637 end countDiscreteVars;
638
639 protected function countDiscreteVars1 "author: lochel"
640 input BackendDAE.EqSystems inEqSystems;
641 output Integer outNumDiscreteVars;
642 algorithm
643 outNumDiscreteVars := 0;
644 ✗ outNumDiscreteVars := List.fold(inEqSystems, countDiscreteVars2, outNumDiscreteVars);
645 end countDiscreteVars1;
646
647 protected function countDiscreteVars2 "author: lochel"
648 input BackendDAE.EqSystem inEqSystem;
649 input Integer inNumDiscreteVars;
650 output Integer outNumDiscreteVars;
651 protected
652 BackendDAE.Variables vars;
653 algorithm
654 ✗ BackendDAE.EQSYSTEM(orderedVars=vars) := inEqSystem;
655 ✗ outNumDiscreteVars := BackendVariable.traverseBackendDAEVars(vars, countDiscreteVars3, inNumDiscreteVars);
656 end countDiscreteVars2;
657
658 protected function countDiscreteVars3 "author: lochel"
659 input BackendDAE.Var var;
660 input Integer nDiscreteVars;
661 output BackendDAE.Var outVar;
662 output Integer outCount;
663 algorithm
664 (outVar,outCount) := match var
665 // discrete
666 case BackendDAE.VAR(varKind=BackendDAE.DISCRETE(), varType=DAE.T_REAL())
667 ✗ then (var, nDiscreteVars+1);
668 else (var,nDiscreteVars);
669 end match;
670 end countDiscreteVars3;
671
672 public function replaceCrefsWithValues
673 input DAE.Exp inExp;
674 input tuple<BackendDAE.Variables, DAE.ComponentRef> inTuple;
675 output DAE.Exp outExp;
676 output tuple<BackendDAE.Variables, DAE.ComponentRef> outTuple;
677 algorithm
678 (outExp,outTuple) := matchcontinue (inExp,inTuple)
679 local
680 DAE.Exp e;
681 BackendDAE.Variables vars;
682 DAE.ComponentRef cr, cr_orign;
683 case (DAE.CREF(cr, _), (vars, cr_orign))
684 guard
685 not ComponentReferenceBasics.crefEqualNoStringCompare(cr, cr_orign)
686 algorithm
687
3/8
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 24 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
29 ({BackendDAE.VAR(bindExp = SOME(e))}, _) := BackendVariable.getVar(cr, vars);
688 ✗ (e, _) := Expression.traverseExpBottomUp(e, replaceCrefsWithValues, (vars, cr_orign));
689 ✗ then (e, (vars,cr_orign));
690 else (inExp,inTuple);
691 end matchcontinue;
692 end replaceCrefsWithValues;
693
694 public function makeExpType
695 "Transforms a BackendDAE.Type to DAE.Type"
696 input BackendDAE.Type inType;
697 output DAE.Type outType;
698 algorithm
699 outType := inType;
700 end makeExpType;
701
702 public function hasExpContinuousParts
703 "Returns true if expression has contiuous parts,
704 and false if the expression is completely discrete.
705 Used to detect if an expression is a ZeroCrossing."
706 input DAE.Exp inExp;
707 input BackendDAE.Variables inVariables;
708 input BackendDAE.Variables inKnvars;
709 output Boolean outBoolean;
710 algorithm
711 12790 (_,(_, _, outBoolean)) := Expression.traverseExpTopDown(inExp, traversingContinuousExpFinder, (inVariables, inKnvars, false));
712 end hasExpContinuousParts;
713
714 protected function traversingContinuousExpFinder "Helper for isDiscreteExp"
715 input DAE.Exp inExp;
716 input tuple<BackendDAE.Variables,BackendDAE.Variables,Boolean> inTpl;
717 output DAE.Exp outExp;
718 output Boolean cont;
719 output tuple<BackendDAE.Variables,BackendDAE.Variables,Boolean> outTpl;
720 algorithm
721 (outExp, cont, outTpl) := matchcontinue (inExp, inTpl)
722 local
723 BackendDAE.Variables vars, globalKnownVars;
724 DAE.ComponentRef cr;
725 BackendDAE.Var backendVar;
726 Absyn.Ident name;
727
728 case (DAE.CREF(componentRef=cr), (vars, globalKnownVars, _)) algorithm
729
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4569 times.
8221 ((backendVar::_), _) := BackendVariable.getVar(cr, vars);
730
2/2
✓ Branch 1 taken 2217 times.
✓ Branch 2 taken 2352 times.
4569 false := BackendVariable.isVarDiscrete(backendVar);
731 2352 then (inExp, false, (vars, globalKnownVars, true));
732
733 // builtin variable time is not discrete
734 case (DAE.CREF(componentRef=DAE.CREF_IDENT(ident="time")), (vars, globalKnownVars, _))
735 1356 then (inExp, false, (vars, globalKnownVars, true));
736
737 // Known variables that are input are continuous
738 case (DAE.CREF(componentRef=cr), (vars, globalKnownVars, _)) algorithm
739
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1979 times.
4513 (backendVar::_, _) := BackendVariable.getVar(cr, globalKnownVars);
740
1/2
✓ Branch 1 taken 1979 times.
✗ Branch 2 not taken.
1979 true := BackendVariable.isInput(backendVar);
741 ✗ then (inExp, false, (vars, globalKnownVars, true));
742
743 case (DAE.CALL(path=Absyn.IDENT(name=name)), _)
744 guard stringEq("pre", name) or
745 stringEq("change", name) or
746 stringEq("ceil", name) or
747 stringEq("floor", name)
748 then (inExp, false, inTpl);
749
750 case (DAE.CALL(path=Absyn.IDENT(name="noEvent")), (vars, globalKnownVars, _))
751 6850 then (inExp, false, (vars, globalKnownVars, false));
752
753 else (inExp, true, inTpl);
754 end matchcontinue;
755 end traversingContinuousExpFinder;
756
757 public function statesAndVarsExp
758 "This function investigates an expression and returns as subexpressions
759 that are variable names or derivatives of state names or states
760 inputs: (DAE.Exp, BackendDAE.Variables)
761 outputs: DAE.Exp list"
762 input DAE.Exp inExp;
763 input BackendDAE.Variables inVariables;
764 output list<DAE.Exp> exps;
765 algorithm
766 ✗ (_,(_,exps)) := Expression.traverseExpTopDown(inExp, traversingstatesAndVarsExpFinder, (inVariables,{}));
767 end statesAndVarsExp;
768
769 public function traversingstatesAndVarsExpFinder "
770 Author: Frenkel TUD 2010-10
771 Helper for statesAndVarsExp"
772 input DAE.Exp inExp;
773 input tuple<BackendDAE.Variables,list<DAE.Exp>> inTpl;
774 output DAE.Exp outExp;
775 output Boolean cont;
776 output tuple<BackendDAE.Variables,list<DAE.Exp>> outTpl;
777 algorithm
778 (outExp,cont,outTpl) := matchcontinue (inExp,inTpl)
779 local
780 DAE.ComponentRef cr;
781 list<DAE.Exp> expl,res,creexps;
782 DAE.Exp e,e1;
783 list<DAE.Var> varLst;
784 BackendDAE.Variables vars;
785 // Special Case for Records
786 case ((e as DAE.CREF(componentRef = cr,ty= DAE.T_COMPLEX(varLst=varLst,complexClassType=ClassInf.RECORD(_)))),(vars,_))
787 algorithm
788 ✗ creexps := List.map1(varLst,Expression.generateCrefsExpFromExpVar,cr);
789 ✗ (_,(_,res)) := Expression.traverseExpListTopDown(creexps, traversingstatesAndVarsExpFinder, inTpl);
790 ✗ then (e,true,(vars,res));
791 // Special Case for unextended arrays
792 case ((e as DAE.CREF(ty = DAE.T_ARRAY())),(vars,_))
793 algorithm
794 ✗ (e1,true) := Expression.extendArrExp(e,false);
795 ✗ (_,(_,res)) := Expression.traverseExpTopDown(e1, traversingstatesAndVarsExpFinder, inTpl);
796 ✗ then (e,true,(vars,res));
797 // Special Case for time variable
798 //case (((e as DAE.CREF(componentRef = DAE.CREF_IDENT(ident="time"))),(vars,expl)))
799 // then ((e,false,(vars,e::expl)));
800 case ((e as DAE.CREF(componentRef = cr)),(vars,expl))
801 algorithm
802 ✗ BackendVariable.getVar(cr, vars);
803 ✗ then (e,false,(vars,e::expl));
804 case ((e as DAE.CALL(path = Absyn.IDENT(name = "der"),expLst = {DAE.CREF(componentRef = cr)})),(vars,expl))
805 algorithm
806 ✗ ((BackendDAE.VAR(varKind = BackendDAE.STATE())::_),_) := BackendVariable.getVar(cr, vars);
807 ✗ then (e,false,(vars,e::expl));
808 // is this case right?
809 case (e as DAE.CALL(path = Absyn.IDENT(name = "der"),expLst = {DAE.CREF(componentRef = cr)}),(vars,_))
810 algorithm
811 ✗ BackendVariable.getVar(cr, vars);
812 then (e,false,inTpl);
813 else (inExp,true,inTpl);
814 end matchcontinue;
815 end traversingstatesAndVarsExpFinder;
816
817 public function isLoopDependent
818 "Checks if an expression is a variable that depends on a loop iterator,
819 ie. for i loop
820 V[i] = ... // V depends on i
821 end for;
822 Used by lowerStatementInputsOutputs in STMT_FOR case."
823 input DAE.Exp varExp;
824 input DAE.Exp iteratorExp;
825 output Boolean isDependent;
826 algorithm
827 isDependent := matchcontinue varExp
828 local
829 list<DAE.Exp> subscript_exprs;
830 list<DAE.Subscript> subscripts;
831 DAE.ComponentRef cr;
832 case DAE.CREF(componentRef = cr)
833 algorithm
834 ✗ subscripts := ComponentReferenceBasics.crefSubs(cr);
835 ✗ subscript_exprs := List.map(subscripts, ExpressionBasics.subscriptIndexExp);
836 ✗ true := isLoopDependentHelper(subscript_exprs, iteratorExp);
837 then true;
838 case DAE.ASUB(sub = subscripts)
839 algorithm
840 ✗ subscript_exprs := List.map(subscripts, Expression.getSubscriptExp);
841 ✗ then isLoopDependentHelper(subscript_exprs, iteratorExp);
842 else false;
843 end matchcontinue;
844 end isLoopDependent;
845
846 protected function isLoopDependentHelper
847 "Helper for isLoopDependent.
848 Checks if a list of subscripts contains a certain iterator expression."
849 input list<DAE.Exp> subscripts;
850 input DAE.Exp iteratorExp;
851 output Boolean isDependent = false;
852 algorithm
853 ✗ for subscript in subscripts loop
854 try
855 ✗ if Expression.expContains(subscript, iteratorExp) then
856 isDependent := true;
857 ✗ return;
858 end if;
859 else
860 // go on with iteration
861 end try;
862 end for;
863 end isLoopDependentHelper;
864
865 public function devectorizeArrayVar
866 input DAE.Exp arrayVar;
867 output DAE.Exp newArrayVar;
868 algorithm
869 newArrayVar := matchcontinue arrayVar
870 local
871 DAE.ComponentRef cr;
872 list<DAE.Subscript> subs;
873 DAE.Exp e;
874
875 case DAE.ASUB(exp = DAE.ARRAY(array = (DAE.CREF(componentRef = cr)::_)), sub = subs)
876 algorithm
877 ✗ cr := ComponentReferenceBasics.crefStripLastSubs(cr);
878 ✗ e := Expression.crefExp(cr);
879 ✗ then
880 // adrpo: TODO! FIXME! check if this is TYPE correct!
881 // shouldn't we change the type using the subs?
882 Expression.makeASUB(e, list(Expression.getSubscriptExp(s) for s in subs));
883
884 case DAE.ASUB(exp = DAE.MATRIX(matrix = (((DAE.CREF(componentRef = cr))::_)::_)), sub = subs)
885 algorithm
886 ✗ cr := ComponentReferenceBasics.crefStripLastSubs(cr);
887 ✗ e := Expression.crefExp(cr);
888 ✗ then
889 // adrpo: TODO! FIXME! check if this is TYPE correct!
890 // shouldn't we change the type using the subs?
891 Expression.makeASUB(e, list(Expression.getSubscriptExp(s) for s in subs));
892
893 case _ then arrayVar;
894 end matchcontinue;
895 end devectorizeArrayVar;
896
897 public function explodeArrayVars
898 "Explodes an array variable into its elements. Takes a variable that is a CREF
899 or ASUB, the name of the iterator variable and a range expression that the
900 iterator iterates over."
901 input DAE.Exp arrayVar;
902 input DAE.Exp iteratorExp;
903 input DAE.Exp rangeExpr;
904 input BackendDAE.Variables vars;
905 output list<DAE.Exp> arrayElements;
906 algorithm
907 arrayElements := matchcontinue arrayVar
908 local
909 list<DAE.Exp> clonedElements, newElements;
910 list<DAE.Exp> indices;
911 DAE.ComponentRef cref;
912 list<DAE.Exp> varExprs;
913 DAE.Exp daeExp;
914 list<BackendDAE.Var> bvars;
915
916 case DAE.CREF()
917 algorithm
918 ✗ indices := rangeExprs(rangeExpr);
919 ✗ clonedElements := List.fill(arrayVar, listLength(indices));
920 ✗ newElements := generateArrayElements(clonedElements, indices, iteratorExp);
921 then newElements;
922
923 case DAE.ASUB(exp = DAE.CREF())
924 algorithm
925 // If the range is constant, then we can use it to generate only those
926 // array elements that are actually used.
927 ✗ indices := rangeExprs(rangeExpr);
928 ✗ clonedElements := List.fill(arrayVar, listLength(indices));
929 ✗ newElements := generateArrayElements(clonedElements, indices, iteratorExp);
930 then newElements;
931
932 case DAE.CREF(componentRef = cref)
933 algorithm
934 ✗ (bvars, _) := BackendVariable.getVar(cref, vars);
935 ✗ varExprs := List.map(bvars, BackendVariable.varExp);
936 //varCrefs = List.map(bvars, BackendVariable.varCref);
937 //varExprs = List.map(varCrefs, Expression.crefExp);
938 then varExprs;
939
940 case DAE.ASUB(exp = DAE.CREF(componentRef = cref))
941 algorithm
942 // If the range is not constant, then we just extract all array elements
943 // of the array.
944 ✗ (bvars, _) := BackendVariable.getVar(cref, vars);
945 ✗ varExprs := List.map(bvars, BackendVariable.varExp);
946 //varCrefs = List.map(bvars, BackendVariable.varCref);
947 //varExprs = List.map(varCrefs, Expression.crefExp);
948 then varExprs;
949
950 case DAE.ASUB(exp = daeExp)
951 algorithm
952 ✗ varExprs := Expression.flattenArrayExpToList(daeExp);
953 then
954 varExprs;
955 end matchcontinue;
956 end explodeArrayVars;
957
958 protected function rangeExprs
959 "Tries to convert a range to a list of integer expressions. Returns a list of
960 integer expressions if possible, or fails. Used by explodeArrayVars."
961 input DAE.Exp inRange;
962 output list<DAE.Exp> outValues;
963 algorithm
964 outValues := match inRange
965 local
966 list<DAE.Exp> arrayElements;
967
968 case DAE.ARRAY(array = arrayElements) then arrayElements;
969 ✗ case DAE.RANGE() then Expression.expandRange(inRange);
970
971 end match;
972 end rangeExprs;
973
974 public function daeSize
975 "author: Frenkel TUD
976 Returns the size of the dae system, which correspondents to the number of variables."
977 input BackendDAE.BackendDAE inDAE;
978 output Integer sz;
979 algorithm
980
4/4
✓ Branch 0 taken 122787 times.
✓ Branch 1 taken 10487 times.
✓ Branch 2 taken 122787 times.
✓ Branch 3 taken 10487 times.
133274 sz := sum(systemSize(s) for s in inDAE.eqs);
981 end daeSize;
982
983 public function systemSize
984 "Returns the size of the dae system, the size of the equations in an BackendDAE.EquationArray,
985 which not corresponds to the number of equations in a system."
986 input BackendDAE.EqSystem inEqSystem;
987 output Integer outSize = BackendEquation.equationArraySize(inEqSystem.orderedEqs);
988 end systemSize;
989
990 public function maxSizeOfEqSystems
991 "Returns the maximum system size of given EqSystems"
992 input list<BackendDAE.EqSystem> inEqSystems;
993 output Integer outSize = 0;
994 protected
995 Integer i;
996 algorithm
997
2/2
✓ Branch 0 taken 3302 times.
✓ Branch 1 taken 2808 times.
6110 for eqSyst in inEqSystems loop
998 3302 i := systemSize(eqSyst);
999 if intGt(i, outSize) then
1000 outSize := i;
1001 end if;
1002 end for;
1003 end maxSizeOfEqSystems;
1004
1005 public function numOfComps "Returns the number of StrongComponents in the EqSystem
1006 author: waurich TUD"
1007 input BackendDAE.EqSystem inEqSystem;
1008 output Integer num;
1009 protected
1010 BackendDAE.StrongComponents comps;
1011 algorithm
1012 ✗ BackendDAE.MATCHING(comps=comps) := inEqSystem.matching;
1013 ✗ num := listLength(comps);
1014 end numOfComps;
1015
1016 public function equationArraySizeBDAE
1017 "author: Frenkel TUD
1018 Returns the size of the dae system, which correspondents to the number of variables."
1019 input BackendDAE.BackendDAE inDAE;
1020 output Integer outSize;
1021 algorithm
1022 3088 outSize := List.applyAndFold(inDAE.eqs, intAdd, equationArraySizeDAE, 0);
1023 end equationArraySizeBDAE;
1024
1025 public function equationArraySizeDAE
1026 "author: Frenkel TUD
1027 Returns the number of equations in a system."
1028 input BackendDAE.EqSystem inEqSystem;
1029 output Integer n = BackendEquation.getNumberOfEquations(inEqSystem.orderedEqs);
1030 end equationArraySizeDAE;
1031
1032 public function hasDAEMatching
1033 "Returns true if all system have already a matching, otherwise return false."
1034 input BackendDAE.BackendDAE inDAE;
1035 output Boolean b;
1036 algorithm
1037 3901 b := List.applyAndFold(inDAE.eqs, boolAnd, hasEqSystemMatching, true);
1038 end hasDAEMatching;
1039
1040 public function hasEqSystemMatching
1041 "Returns true if EqSystem has a matching."
1042 input BackendDAE.EqSystem dae;
1043 output Boolean b;
1044 algorithm
1045 b := match dae
1046 case BackendDAE.EQSYSTEM(matching=BackendDAE.MATCHING()) then true;
1047 case BackendDAE.EQSYSTEM(matching=BackendDAE.NO_MATCHING()) then false;
1048 end match;
1049 end hasEqSystemMatching;
1050
1051 protected function generateArrayElements
1052 "Takes a list of identical CREF or ASUB expressions, a list of ICONST indices
1053 and a loop iterator expression, and recursively replaces the loop iterator
1054 with a constant index. Ex:
1055 generateArrayElements(cref[i,j], {1,2,3}, j) =>
1056 {cref[i,1], cref[i,2], cref[i,3]}"
1057 input list<DAE.Exp> clones;
1058 input list<DAE.Exp> indices;
1059 input DAE.Exp iteratorExp;
1060 output list<DAE.Exp> newElements;
1061 algorithm
1062 newElements := match(clones, indices)
1063 local
1064 DAE.Exp clone, newElement, newElement2, index;
1065 list<DAE.Exp> restClones, restIndices, elements;
1066 case ({}, {}) then {};
1067 case (clone::restClones, index::restIndices)
1068 algorithm
1069 ✗ (newElement, _) := Expression.replaceExp(clone, iteratorExp, index);
1070 ✗ newElement2 := simplifySubscripts(newElement);
1071 ✗ elements := generateArrayElements(restClones, restIndices, iteratorExp);
1072 then (newElement2::elements);
1073 end match;
1074 end generateArrayElements;
1075
1076 protected function simplifySubscripts
1077 "Tries to simplify the subscripts of a CREF or ASUB. If an ASUB only contains
1078 constant subscripts, such as cref[1,4], then it also needs to be converted to
1079 a CREF."
1080 input DAE.Exp asub;
1081 output DAE.Exp maybeCref;
1082 algorithm
1083 maybeCref := matchcontinue asub
1084 local
1085 DAE.Ident varIdent;
1086 DAE.Type arrayType, varType;
1087 list<DAE.Exp> subExprs, subExprsSimplified;
1088 list<DAE.Subscript> subscripts;
1089 DAE.Exp newCrefExp;
1090 DAE.ComponentRef cref_;
1091
1092 // A CREF => just simplify the subscripts.
1093 case DAE.CREF(DAE.CREF_IDENT(varIdent, arrayType, subscripts), varType)
1094 algorithm
1095 ✗ subscripts := List.map(subscripts, simplifySubscript);
1096 ✗ cref_ := ComponentReferenceBasics.makeCrefIdent(varIdent, arrayType, subscripts);
1097 ✗ newCrefExp := Expression.makeCrefExp(cref_, varType);
1098 then
1099 newCrefExp;
1100
1101 // An ASUB => convert to CREF if only constant subscripts.
1102 case DAE.ASUB(DAE.CREF(DAE.CREF_IDENT(varIdent, arrayType, _), varType), subscripts)
1103 algorithm
1104 ✗ subExprs := List.map(subscripts, Expression.getSubscriptExp);
1105 ✗ {} := List.select(subExprs, Expression.isNotConst);
1106 // If a subscript is not a single constant value it needs to be
1107 // simplified, e.g. cref[3+4] => cref[7], otherwise some subscripts
1108 // might be counted twice, such as cref[3+4] and cref[2+5], even though
1109 // they reference the same element.
1110 ✗ subExprsSimplified := ExpressionSimplify.simplifyList(subExprs);
1111 ✗ subscripts := List.map(subExprsSimplified, Expression.makeIndexSubscript);
1112 ✗ cref_ := ComponentReferenceBasics.makeCrefIdent(varIdent, arrayType, subscripts);
1113 ✗ newCrefExp := Expression.makeCrefExp(cref_, varType);
1114 then
1115 newCrefExp;
1116
1117 else asub;
1118 end matchcontinue;
1119 end simplifySubscripts;
1120
1121 protected function simplifySubscript
1122 input DAE.Subscript sub;
1123 output DAE.Subscript simplifiedSub;
1124 algorithm
1125 simplifiedSub := matchcontinue sub
1126 local
1127 DAE.Exp e, e1;
1128
1129 case DAE.INDEX(exp = e)
1130 algorithm
1131 ✗ (e1,_) := ExpressionSimplify.simplify(e);
1132 ✗ then
1133 if referenceEq(e1,e) then sub else DAE.INDEX(e);
1134 else sub;
1135
1136 end matchcontinue;
1137 end simplifySubscript;
1138
1139 public function setTearingSelectAttribute
1140 "__OpenModelica_tearingSelect is an annotation and has to be extracted from the comment."
1141 input Option<SCode.Comment> optComment;
1142 output Option<BackendDAE.TearingSelect> tearingSelect = NONE();
1143 protected
1144 Option<SCode.Annotation> opt_anno;
1145 SCode.Annotation anno;
1146 SCode.Mod mod;
1147 Option<Absyn.Exp> opt_val;
1148 Absyn.Exp val;
1149 String name;
1150 SourceInfo info;
1151 algorithm
1152 207695 opt_anno := SCodeUtil.optCommentAnnotation(optComment);
1153
1154
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 207695 times.
✓ Branch 2 taken 139827 times.
✓ Branch 3 taken 67868 times.
207695 if isNone(opt_anno) then
1155 // No annotation.
1156 139827 return;
1157 end if;
1158
1159 67868 SOME(anno) := opt_anno;
1160 67868 mod := SCodeUtil.lookupAnnotation(anno, "__OpenModelica_tearingSelect");
1161
1162
2/2
✓ Branch 1 taken 67860 times.
✓ Branch 2 taken 8 times.
67868 if SCodeUtil.isEmptyMod(mod) then
1163 67860 mod := SCodeUtil.lookupAnnotation(anno, "tearingSelect");
1164
1165
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 67860 times.
67860 if not SCodeUtil.isEmptyMod(mod) then
1166 ✗ Error.addSourceMessage(Error.DEPRECATED_EXPRESSION,
1167 {"tearingSelect", "__OpenModelica_tearingSelect"}, SCodeUtil.getModifierInfo(mod));
1168 end if;
1169 end if;
1170
1171 67868 opt_val := SCodeUtil.getModifierBinding(mod);
1172
1173
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 67868 times.
✓ Branch 2 taken 67860 times.
✓ Branch 3 taken 8 times.
67868 if isNone(opt_val) then
1174 // Annotation exists but has no value.
1175 67860 return;
1176 end if;
1177
1178 8 SOME(val) := opt_val;
1179 8 info := SCodeUtil.getModifierInfo(mod);
1180 8 name := getTearingSelectName(val, info);
1181 8 tearingSelect := lookupTearingSelectMember(name);
1182
1183
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 if isNone(tearingSelect) then
1184 ✗ Error.addSourceMessage(Error.UNKNOWN_ANNOTATION_VALUE, {Dump.printExpStr(val), "__OpenModelica_tearingSelect"}, info);
1185 end if;
1186 end setTearingSelectAttribute;
1187
1188 protected function getTearingSelectName
1189 input Absyn.Exp exp;
1190 input SourceInfo info;
1191 output String name;
1192 algorithm
1193 name := match exp
1194 // TearingSelect.name
1195 case Absyn.Exp.CREF(componentRef =
1196 Absyn.ComponentRef.CREF_QUAL(name = "TearingSelect", subscripts = {}, componentRef =
1197 Absyn.ComponentRef.CREF_IDENT(name = name, subscripts = {})))
1198 then name;
1199
1200 // Single name without the TearingSelect prefix is deprecated and no longer accepted.
1201 case Absyn.Exp.CREF(componentRef = Absyn.ComponentRef.CREF_IDENT(name = name, subscripts = {}))
1202 algorithm
1203 ✗ Error.addSourceMessage(Error.DEPRECATED_EXPRESSION, {name, "TearingSelect." + name}, info);
1204 then
1205 "";
1206
1207 else "";
1208 end match;
1209 end getTearingSelectName;
1210
1211 protected function lookupTearingSelectMember
1212 input String name;
1213 output Option<BackendDAE.TearingSelect> tearingSelect;
1214 algorithm
1215 tearingSelect := match name
1216 case "never" then SOME(BackendDAE.TearingSelect.NEVER());
1217 case "avoid" then SOME(BackendDAE.TearingSelect.AVOID());
1218 case "default" then SOME(BackendDAE.TearingSelect.DEFAULT());
1219 case "prefer" then SOME(BackendDAE.TearingSelect.PREFER());
1220 case "always" then SOME(BackendDAE.TearingSelect.ALWAYS());
1221 else NONE();
1222 end match;
1223 end lookupTearingSelectMember;
1224
1225 public function setHideResultAttribute
1226 "Returns the expression of the hideResult annotation.
1227 See Modelica Spec 3.3, section 18.3"
1228 input Option<SCode.Comment> comment;
1229 input DAE.ComponentRef inCref;
1230 output Option<DAE.Exp> hideResult;
1231 protected
1232 DAE.Exp hr;
1233 SCode.Annotation ann;
1234 Absyn.Exp val;
1235 DAE.ComponentRef crefRoot;
1236 algorithm
1237 try
1238
6/8
✗ Branch 0 not taken.
✓ Branch 1 taken 349858 times.
✓ Branch 2 taken 317 times.
✓ Branch 3 taken 349541 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 349541 times.
✓ Branch 6 taken 245348 times.
✓ Branch 7 taken 104193 times.
349858 SOME(SCode.COMMENT(annotation_=SOME(ann))) := comment;
1239
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 104193 times.
✓ Branch 3 taken 99028 times.
✓ Branch 4 taken 5165 times.
104193 SOME(val) := SCodeUtil.lookupAnnotationBinding(ann, "HideResult");
1240 5165 hr := Expression.fromAbsynExp(val);
1241
1242 hideResult := match inCref
1243 case DAE.CREF_QUAL()
1244 algorithm
1245 5159 (crefRoot,_) := ComponentReference.splitCrefLast(inCref);
1246 5159 hr := Expression.traverseExpBottomUp(hr, ComponentReference.joinCrefsExp, crefRoot);
1247 then SOME(hr);
1248 else SOME(hr);
1249 end match;
1250
1251 else
1252 hideResult := NONE();
1253 end try;
1254 end setHideResultAttribute;
1255
1256
1257 /*******************************************
1258 Functions that deals with BackendDAE as input
1259 ********************************************/
1260
1261 public function blockIsDynamic "Return true if the block contains a variable that is marked"
1262 input list<Integer> lst;
1263 input array<Integer> arr;
1264 output Boolean outBoolean=true;
1265 algorithm
1266
2/2
✓ Branch 0 taken 512361 times.
✓ Branch 1 taken 387656 times.
900017 for x in lst loop
1267
2/2
✓ Branch 1 taken 43496 times.
✓ Branch 2 taken 468865 times.
512361 if arr[x]<>0 then
1268 43496 return;
1269 end if;
1270 end for;
1271 outBoolean := false;
1272 end blockIsDynamic;
1273
1274 public function markStateEquations "This function goes through all equations and marks the ones that
1275 calculates a state, or is needed in order to calculate a state,
1276 with a non-zero value in the array passed as argument.
1277 This is done by traversing the directed graph of nodes where
1278 a node is an equation/solved variable and following the edges in the
1279 backward direction.
1280 inputs: (daeLow: BackendDAE,
1281 marks: int array,
1282 adjacencyMatrix: AdjacencyMatrix,
1283 adjacencyMatrixT: AdjacencyMatrixT,
1284 assignments1: int vector,
1285 assignments2: int vector)
1286 outputs: marks: int array"
1287 input BackendDAE.EqSystem syst;
1288 input array<Integer> arr;
1289 input array<Integer> ass1;
1290 output array<Integer> outIntegerArray;
1291 protected
1292 list<Integer> statevarindx_lst,eqns;
1293 BackendDAE.AdjacencyMatrix m;
1294 BackendDAE.Variables v;
1295 algorithm
1296
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 51334 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51334 times.
51334 BackendDAE.EQSYSTEM(orderedVars = v,m=SOME(m)) := syst;
1297
2/2
✓ Branch 1 taken 54 times.
✓ Branch 2 taken 51280 times.
51334 if (Flags.getConfigEnum(Flags.SYM_SOLVER) > 0) then
1298 54 (_,statevarindx_lst) := BackendVariable.getAllVarIndicesFromVariables(v, BackendVariable.isAlgState);
1299 else
1300 51280 (_,statevarindx_lst) := BackendVariable.getAllVarIndicesFromVariables(v, BackendVariable.isStateVar);
1301 end if;
1302
5/6
✗ Branch 1 not taken.
✓ Branch 2 taken 4622 times.
✓ Branch 3 taken 4622 times.
✓ Branch 4 taken 51334 times.
✓ Branch 5 taken 4622 times.
✓ Branch 6 taken 51334 times.
55956 eqns := list(arrayGet(ass1,i) for i guard arrayGet(ass1,i)>0 in statevarindx_lst);
1303 51334 outIntegerArray := markStateEquationsWork(eqns,m,ass1,arr);
1304 end markStateEquations;
1305
1306 public function zeroCrossingVarIndices
1307 "For every equation system, the indices of its variables that occur in a zero
1308 crossing relation. All systems are resolved against one combined variable set
1309 in a single pass; looking each zero crossing up in every system is quadratic."
1310 input BackendDAE.EqSystems systs;
1311 input list<BackendDAE.ZeroCrossing> zeroCross;
1312 output array<AvlSetInt.Tree> trees;
1313 protected
1314 Integer nsys = listLength(systs), total = 0, gidx = 0, s = 0, n;
1315 BackendDAE.Variables allVars;
1316 array<Integer> sysOf, locOf "combined index -> system / index within that system";
1317 AvlSetInt.Tree tree;
1318 algorithm
1319 2185 trees := arrayCreate(intMax(nsys, 1), AvlSetInt.new());
1320
2/2
✓ Branch 0 taken 51286 times.
✓ Branch 1 taken 2185 times.
53471 for syst in systs loop
1321 51286 total := total + BackendVariable.varsSize(syst.orderedVars);
1322 end for;
1323
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 2061 times.
2185 if total == 0 then
1324 124 return;
1325 end if;
1326
1327 2061 allVars := BackendVariable.emptyVarsSized(total);
1328 2061 sysOf := arrayCreate(total, 0);
1329 2061 locOf := arrayCreate(total, 0);
1330
2/2
✓ Branch 0 taken 51178 times.
✓ Branch 1 taken 2061 times.
53239 for syst in systs loop
1331 51178 s := s + 1;
1332 51178 n := BackendVariable.varsSize(syst.orderedVars);
1333
1/2
✓ Branch 0 taken 51178 times.
✗ Branch 1 not taken.
249065 for i in 1:n loop
1334 197887 allVars := BackendVariable.addNewVar(BackendVariable.getVarAt(syst.orderedVars, i), allVars);
1335 197887 gidx := gidx + 1;
1336 197887 arrayUpdate(sysOf, gidx, s);
1337 197887 arrayUpdate(locOf, gidx, i);
1338 end for;
1339 end for;
1340
1341 2061 tree := AvlSetInt.new();
1342
2/2
✓ Branch 0 taken 1713 times.
✓ Branch 1 taken 2061 times.
3774 for zc in zeroCross loop
1343 1713 tree := BackendEquation.expressionVarsIndexes(zc.relation_, tree,
1344 function BackendEquation.checkEquationsVarsExpTopDown(vars=allVars));
1345 end for;
1346
1347
2/2
✓ Branch 1 taken 938 times.
✓ Branch 2 taken 2061 times.
2999 for gi in AvlSetInt.listKeys(tree) loop
1348 938 s := arrayGet(sysOf, gi);
1349 938 arrayUpdate(trees, s, AvlSetInt.add(arrayGet(trees, s), arrayGet(locOf, gi)));
1350 end for;
1351 end zeroCrossingVarIndices;
1352
1353 public function markZeroCrossingEquations
1354 "Marks the equations needed to evaluate this system's zero crossings by
1355 following the adjacency graph backwards from the variables they use."
1356 input BackendDAE.EqSystem syst;
1357 input AvlSetInt.Tree zcVars "this system's variables occurring in a zero crossing, see zeroCrossingVarIndices";
1358 input array<Integer> arr;
1359 input array<Integer> ass1;
1360 output array<Integer> outIntegerArray;
1361 protected
1362 list<Integer> eqns;
1363 BackendDAE.AdjacencyMatrix m;
1364 algorithm
1365
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 51286 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51286 times.
51286 BackendDAE.EQSYSTEM(m=SOME(m)) := syst;
1366
5/6
✗ Branch 2 not taken.
✓ Branch 3 taken 938 times.
✓ Branch 4 taken 938 times.
✓ Branch 5 taken 51286 times.
✓ Branch 6 taken 938 times.
✓ Branch 7 taken 51286 times.
52224 eqns := list(arrayGet(ass1,i) for i guard arrayGet(ass1,i)>0 in AvlSetInt.listKeys(zcVars));
1367 51286 outIntegerArray := markStateEquationsWork(eqns,m,ass1,arr);
1368 end markZeroCrossingEquations;
1369
1370 protected function markStateEquationsWork
1371 "Helper function to mark_state_equation
1372 Does the job by looking at variable indexes and adjacency matrix.
1373 inputs: (eqns: int list,
1374 marks: (int array BackendDAE.AdjacencyMatrix int vector int vector))
1375 outputs: ((marks: int array BackendDAE.AdjacencyMatrix
1376 int vector int vector))"
1377 input list<Integer> inEqns;
1378 input BackendDAE.AdjacencyMatrix m;
1379 input array<Integer> ass1;
1380 input array<Integer> iMark;
1381 output array<Integer> oMark = iMark;
1382 protected
1383 list<Integer> queue = inEqns;
1384 Integer j, eqn, len = arrayLength(ass1);
1385 Boolean positiveAndUnmarked;
1386 algorithm
1387
2/2
✓ Branch 0 taken 77788 times.
✓ Branch 1 taken 104468 times.
182256 while not listEmpty(queue) loop
1388 77788 eqn :: queue := queue;
1389
2/2
✓ Branch 1 taken 17457 times.
✓ Branch 2 taken 60331 times.
77788 if oMark[eqn] == 0 then // "Mark an unmarked node/equation"
1390 60331 arrayUpdate(oMark, eqn, 1);
1391
2/2
✓ Branch 1 taken 60331 times.
✓ Branch 2 taken 191480 times.
251811 for i in m[eqn] loop
1392
3/4
✓ Branch 0 taken 191465 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 191465 times.
✗ Branch 3 not taken.
191480 if i>0 and i <= len then
1393 // We already did bounds checking above
1394 191465 j := Dangerous.arrayGetNoBoundsChecking(ass1, i);
1395
3/4
✓ Branch 0 taken 191465 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 60647 times.
✓ Branch 4 taken 130818 times.
191465 positiveAndUnmarked := (if j>0 then arrayGet(oMark, j) == 0 else false);
1396 if positiveAndUnmarked then
1397 // Only add positive, unmarked variables to the queue
1398 queue := j::queue;
1399 end if;
1400 end if;
1401 end for;
1402 end if;
1403 end while;
1404 end markStateEquationsWork;
1405
1406 public function removeNegative
1407 "author: PA
1408 Removes all negative integers."
1409 input list<Integer> lst;
1410 output list<Integer> lst_1;
1411 algorithm
1412 52633 lst_1 := List.select(lst, Util.intPositive);
1413 end removeNegative;
1414
1415 public function eqnsForVarWithStates
1416 "author: PA
1417 This function returns all equations as a list of equation indices
1418 given a variable as a variable index, including the equations containing
1419 the state variable but not its derivative. This must be used to update
1420 equations when a state is changed to algebraic variable in index reduction
1421 using dummy derivatives.
1422 These equation indices are represented with negative index, thus all
1423 indices are mapped trough int_abs (absolute value).
1424 inputs: (AdjacencyMatrixT, int /* variable */)
1425 outputs: int list /* equations */"
1426 input BackendDAE.AdjacencyMatrixT inAdjacencyMatrixT;
1427 input Integer inInteger;
1428 output list<Integer> outIntegerLst;
1429 algorithm
1430 outIntegerLst := matchcontinue (inAdjacencyMatrixT,inInteger)
1431 local
1432 Integer n,indx;
1433 list<Integer> res,res_1;
1434 array<list<Integer>> mt;
1435 String s;
1436
1437 case (mt,n)
1438 algorithm
1439 ✗ res := mt[n];
1440 ✗ res_1 := List.map(res, intAbs);
1441 then
1442 res_1;
1443
1444 case (_,indx)
1445 algorithm
1446 ✗ print("- BackendDAEUtil.eqnsForVarWithStates failed, indx= ");
1447 ✗ s := intString(indx);
1448 ✗ print(s);
1449 ✗ print("\n");
1450 ✗ then
1451 fail();
1452 end matchcontinue;
1453 end eqnsForVarWithStates;
1454
1455 public function varsInEqn
1456 "author: PA
1457 This function returns all variable indices as a list for
1458 a given equation, given as an equation index. (1...n)
1459 Negative indexes are removed.
1460 See also: eqnsForVar and eqnsForVarWithStates
1461 inputs: (AdjacencyMatrix, int /* equation */)
1462 outputs: int list /* variables */"
1463 input BackendDAE.AdjacencyMatrix m;
1464 input Integer indx;
1465 output list<Integer> outIntegerLst;
1466 algorithm
1467 outIntegerLst := matchcontinue indx
1468 local String s;
1469 case _
1470 52633 then
1471 removeNegative(m[indx]);
1472 else
1473 algorithm
1474 ✗ s := "- BackendDAEUtil.varsInEqn failed, indx= " + intString(indx) + "array length: " + intString(arrayLength(m)) + "\n";
1475 ✗ Error.addMessage(Error.INTERNAL_ERROR,{s});
1476 ✗ then
1477 fail();
1478 end matchcontinue;
1479 end varsInEqn;
1480
1481 protected type TraverseIndicesTuple = tuple<list<Integer>, list<Integer>, list<Integer>>;
1482
1483 public function setEvaluationStage
1484 input BackendDAE.BackendDAE inBackendDAE;
1485 output BackendDAE.BackendDAE outBackendDAE;
1486 protected
1487 BackendDAE.Variables vars;
1488 BackendDAE.EquationArray eqns;
1489 BackendDAE.Matching matching;
1490 list<Integer> indicesDynamic, indicesDiscrete, indicesAlgebraic;
1491 TraverseIndicesTuple traverseArgs;
1492 array<Integer> assigndEqn, assigndVar, markedEqns;
1493 BackendDAE.EqSystems newEqs = {};
1494
1495 BackendDAE.AdjacencyMatrix adjMatrix, adjMatrixT;
1496
1497 list<BackendDAE.ZeroCrossing> zeroCrossings;
1498 array<AvlSetInt.Tree> zcVars;
1499 Integer sysIdx = 0;
1500
1501 constant Boolean debug = false;
1502 algorithm
1503
1504 // get zeroCrossings
1505 9 zeroCrossings := ZeroCrossings.toList(inBackendDAE.shared.eventInfo.zeroCrossings);
1506 9 zcVars := zeroCrossingVarIndices(inBackendDAE.eqs, zeroCrossings);
1507
1508 // walk once through all comps and get of dependends of dynamic, algebraic, zeroCrossings,
1509
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 9 times.
22 for eqSystem in inBackendDAE.eqs loop
1510 13 sysIdx := sysIdx + 1;
1511 if debug then
1512 BackendDump.printEqSystem(eqSystem);
1513 end if;
1514
1515 vars := eqSystem.orderedVars;
1516 13 eqns := eqSystem.orderedEqs;
1517
1518 try
1519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 matching as BackendDAE.MATCHING(ass2=assigndEqn,ass1=assigndVar) := eqSystem.matching;
1520 13 (eqSystem, adjMatrix, adjMatrixT) := getAdjacencyMatrixfromOption(eqSystem, BackendDAE.ABSOLUTE(), SOME(inBackendDAE.shared.functionTree), BackendDAEUtil.isInitializationDAE(inBackendDAE.shared));
1521
1522 // collect all dynamic, discrete, algebraic equations
1523 traverseArgs := ({}, {}, {});
1524 13 traverseArgs := BackendDAEUtil.traverseEqSystemStrongComponents(eqSystem, collectEqnsIndexByKind, traverseArgs);
1525 13 (indicesDynamic, indicesDiscrete, indicesAlgebraic) := traverseArgs;
1526
1527 if debug then
1528 print("Dynamic equation indicies:\n");
1529 print(stringDelimitList(list(intString(i) for i in indicesDynamic), ", "));
1530 print("\n");
1531 end if;
1532
1533 13 markedEqns := arrayCreate(BackendEquation.getNumberOfEquations(eqns), 0);
1534 13 markedEqns := markStateEquationsWork(indicesDynamic, adjMatrix, assigndVar, markedEqns);
1535 13 eqns := setMarkedEqnsEvalStage(eqns, markedEqns, BackendEquation.setEvalStageDynamic);
1536
1537 13 markedEqns := arrayCreate(BackendEquation.getNumberOfEquations(eqns), 0);
1538 13 markedEqns := markZeroCrossingEquations(eqSystem, arrayGet(zcVars, sysIdx), markedEqns, assigndVar);
1539 13 eqns := setMarkedEqnsEvalStage(eqns, markedEqns, BackendEquation.setEvalStageZeroCross);
1540
1541 13 markedEqns := arrayCreate(BackendEquation.getNumberOfEquations(eqns), 0);
1542 13 markedEqns := markStateEquationsWork(indicesAlgebraic, adjMatrix, assigndVar, markedEqns);
1543 13 eqns := setMarkedEqnsEvalStage(eqns, markedEqns, BackendEquation.setEvalStageAlgebraic);
1544
1545 13 markedEqns := arrayCreate(BackendEquation.getNumberOfEquations(eqSystem.removedEqs), 1);
1546 13 eqSystem.removedEqs := setMarkedEqnsEvalStage(eqSystem.removedEqs, markedEqns, BackendEquation.setEvalStageDiscrete);
1547
1548 /* For now avoid this and evaluate all the event update breaks right now
1549 quite a lot models.
1550 */
1551 13 markedEqns := arrayCreate(BackendEquation.getNumberOfEquations(eqns), 1);
1552 //markedEqns := markStateEquationsWork(indicesDiscrete, adjMatrix, assigndVar, markedEqns);
1553 //markedEqns := markStateEquationsWork(indicesDiscrete, adjMatrixT, assigndVar, markedEqns);
1554 13 eqns := setMarkedEqnsEvalStage(eqns, markedEqns, BackendEquation.setEvalStageDiscrete);
1555 else
1556 /* in case something goes wrong above mark all equation to be evaluated always */
1557 ✗ markedEqns := arrayCreate(BackendEquation.getNumberOfEquations(eqns), 1);
1558 ✗ eqns := setMarkedEqnsEvalStage(eqns, markedEqns, BackendEquation.setEvalStageAll);
1559 end try;
1560
1561 if debug then
1562 BackendDump.dumpEquationArray(eqns, "Updated equations");
1563 end if;
1564
1565 // update EvaluationState in EquationArray
1566 newEqs := eqSystem::newEqs;
1567 end for;
1568
1569 // update BackendDAE.DAE
1570 9 outBackendDAE := BackendDAE.DAE(newEqs, inBackendDAE.shared);
1571
1572 end setEvaluationStage;
1573
1574 protected function setMarkedEqnsEvalStage
1575 input output BackendDAE.EquationArray eqns;
1576 input array<Integer> markEqns;
1577 input setEvalStage func;
1578 partial function setEvalStage
1579 input output BackendDAE.EvaluationStages evalStage;
1580 end setEvalStage;
1581 protected
1582 BackendDAE.Equation eqn;
1583 algorithm
1584
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 59 times.
20863 for i in 1:arrayLength(markEqns) loop
1585
2/2
✓ Branch 1 taken 10649 times.
✓ Branch 2 taken 10149 times.
20798 if markEqns[i]>0 then
1586 10649 eqn := BackendEquation.get(eqns, i);
1587 10649 eqn := BackendEquation.setEquationEvalStage(eqn, func);
1588 10649 eqns := BackendEquation.setAtIndex(eqns, i, eqn);
1589 end if;
1590 end for;
1591 end setMarkedEqnsEvalStage;
1592
1593 protected function collectEqnsIndexByKind
1594 "This function collects equation indices by kind.
1595 "
1596 input list<BackendDAE.Equation> inEqns;
1597 input list<BackendDAE.Var> inVars;
1598 input list<Integer> varIdxs;
1599 input list<Integer> eqnIdxs;
1600 input output TraverseIndicesTuple traverserArgs;
1601 protected
1602 list<Integer> indicesDynamic, indicesDiscrete, indicesAlgebraic;
1603 algorithm
1604 5192 (indicesDynamic, indicesDiscrete, indicesAlgebraic) := traverserArgs;
1605
2/2
✓ Branch 0 taken 5366 times.
✓ Branch 1 taken 5192 times.
10558 for v in inVars loop
1606 // discrete equations are detected by the corresponding variables
1607
2/2
✓ Branch 1 taken 91 times.
✓ Branch 2 taken 5275 times.
5366 if BackendVariable.isVarDiscrete(v) then
1608 91 indicesDiscrete := listAppend(eqnIdxs, indicesDiscrete);
1609 end if;
1610 end for;
1611
1612
2/2
✓ Branch 0 taken 5192 times.
✓ Branch 1 taken 5192 times.
10384 for eq in inEqns loop
1613 // dynamic
1614
2/2
✓ Branch 1 taken 3800 times.
✓ Branch 2 taken 1392 times.
5192 if BackendEquation.isDynamicEquation(eq) then
1615 3800 indicesDynamic := listAppend(eqnIdxs, indicesDynamic);
1616 end if;
1617 // select also continuos equation
1618
2/2
✓ Branch 1 taken 1375 times.
✓ Branch 2 taken 3817 times.
5192 if BackendEquation.isAuxEquation(eq) then
1619 1375 indicesAlgebraic := listAppend(eqnIdxs, indicesAlgebraic);
1620 end if;
1621 end for;
1622
1623 5192 traverserArgs := (indicesDynamic, indicesDiscrete, indicesAlgebraic);
1624 end collectEqnsIndexByKind;
1625
1626 public function subscript2dCombinations
1627 "This function takes two lists of list of subscripts and combines them in
1628 all possible combinations. This is used when finding all indexes of a 2d
1629 array.
1630 For instance, subscript2dCombinations({{a},{b},{c}},{{x},{y},{z}})
1631 => {{a,x},{a,y},{a,z},{b,x},{b,y},{b,z},{c,x},{c,y},{c,z}}
1632 inputs: (DAE.Subscript list list /* dim1 subs */,
1633 DAE.Subscript list list /* dim2 subs */)
1634 outputs: (DAE.Subscript list list)"
1635 input list<list<DAE.Subscript>> inExpSubscriptLstLst1;
1636 input list<list<DAE.Subscript>> inExpSubscriptLstLst2;
1637 output list<list<DAE.Subscript>> outExpSubscriptLstLst;
1638 algorithm
1639 outExpSubscriptLstLst := match (inExpSubscriptLstLst1,inExpSubscriptLstLst2)
1640 local
1641 list<list<DAE.Subscript>> lst1,lst2,res,ss,ss2;
1642 list<DAE.Subscript> s1;
1643
1644 case ({},_) then {};
1645
1646 case ((s1::ss),ss2)
1647 algorithm
1648 ✗ lst1 := subscript2dCombinations2(s1, ss2);
1649 ✗ lst2 := subscript2dCombinations(ss, ss2);
1650 ✗ res := listAppend(lst1, lst2);
1651 then
1652 res;
1653 end match;
1654 end subscript2dCombinations;
1655
1656 protected function subscript2dCombinations2
1657 input list<DAE.Subscript> inExpSubscriptLst;
1658 input list<list<DAE.Subscript>> inExpSubscriptLstLst;
1659 output list<list<DAE.Subscript>> outExpSubscriptLstLst;
1660 algorithm
1661 outExpSubscriptLstLst := match (inExpSubscriptLst,inExpSubscriptLstLst)
1662 local
1663 list<list<DAE.Subscript>> lst1,ss2;
1664 list<DAE.Subscript> elt1,ss,s2;
1665
1666 case (_,{}) then {};
1667
1668 case (ss,(s2::ss2))
1669 algorithm
1670 ✗ lst1 := subscript2dCombinations2(ss, ss2);
1671 ✗ elt1 := listAppend(ss, s2);
1672 then
1673 (elt1::lst1);
1674 end match;
1675 end subscript2dCombinations2;
1676
1677 public function splitoutEquationAndVars
1678 " author: wbraun"
1679 input BackendDAE.StrongComponents inNeededBlocks;
1680 input BackendDAE.EquationArray inEqns;
1681 input BackendDAE.Variables inVars;
1682 input BackendDAE.EquationArray inEqnsNew;
1683 input BackendDAE.Variables inVarsNew;
1684 output BackendDAE.EquationArray outEqns;
1685 output BackendDAE.Variables outVars;
1686 algorithm
1687 (outEqns,outVars) := match(inNeededBlocks, inEqnsNew, inVarsNew)
1688 local
1689 BackendDAE.StrongComponent comp;
1690 BackendDAE.StrongComponents rest;
1691 list<BackendDAE.Equation> eqn_lst;
1692 list<BackendDAE.Var> var_lst;
1693 BackendDAE.EquationArray eqnsNew;
1694 BackendDAE.Variables varsNew;
1695 case ({}, eqnsNew, varsNew) then (eqnsNew,varsNew);
1696 case (comp::rest, eqnsNew, varsNew)
1697 algorithm
1698 ✗ (eqnsNew,varsNew) := splitoutEquationAndVars(rest,inEqns,inVars,eqnsNew,varsNew);
1699 ✗ (eqn_lst,var_lst,_) := BackendDAETransform.getEquationAndSolvedVar(comp, inEqns, inVars);
1700 ✗ eqnsNew := BackendEquation.addList(eqn_lst, eqnsNew);
1701 ✗ varsNew := BackendVariable.addVars(var_lst, varsNew);
1702 then (eqnsNew,varsNew);
1703 end match;
1704 end splitoutEquationAndVars;
1705
1706 public function getStrongComponents
1707 "author: Frenkel TUD 2011-11
1708 This function returns the strongComponents of a BackendDAE."
1709 input BackendDAE.EqSystem syst;
1710 output BackendDAE.StrongComponents outComps;
1711 algorithm
1712 outComps := match syst
1713 case BackendDAE.EQSYSTEM(matching=BackendDAE.MATCHING(comps=outComps)) then outComps;
1714 else {};
1715 end match;
1716 end getStrongComponents;
1717
1718 public function getFunctions
1719 "author: Frenkel TUD 2011-11
1720 This function returns the Functions of a BackendDAE."
1721 input BackendDAE.Shared shared;
1722 output AvlTreePathFunction.Tree functionTree;
1723 algorithm
1724 432417 BackendDAE.SHARED(functionTree=functionTree) := shared;
1725 end getFunctions;
1726
1727 public function getGlobalKnownVarsFromShared
1728 "function: getFunctions
1729 author: Frenkel TUD 2011-11
1730 This function returns known variable of a BackendDAE."
1731 input BackendDAE.Shared shared;
1732 output BackendDAE.Variables globalKnownVars;
1733 algorithm
1734 162834 BackendDAE.SHARED(globalKnownVars=globalKnownVars) := shared;
1735 end getGlobalKnownVarsFromShared;
1736
1737 public function getExtraInfo
1738 "function: getExtraInfo
1739 This function returns extra info of a BackendDAE."
1740 input BackendDAE.Shared shared;
1741 output BackendDAE.ExtraInfo einfo;
1742 algorithm
1743 2293 BackendDAE.SHARED(info=einfo) := shared;
1744 end getExtraInfo;
1745
1746
1747 public function reduceEqSystemsInDAE
1748 "Function reduces BackendDAE system by filtering
1749 the equation and select only the one that are needed
1750 to calculate the given varibales.
1751 "
1752 input BackendDAE.BackendDAE inDAE;
1753 input list<BackendDAE.Var> iVarlst;
1754 input Boolean makeMatching = true;
1755 input Boolean filterDiscretes = false;
1756 output BackendDAE.BackendDAE outDAE;
1757
1758 protected
1759 BackendDAE.Shared shared;
1760 list<BackendDAE.EqSystem> systs;
1761 algorithm
1762 1820 BackendDAE.DAE(systs, shared) := inDAE;
1763
4/4
✓ Branch 0 taken 1820 times.
✓ Branch 1 taken 1820 times.
✓ Branch 2 taken 1820 times.
✓ Branch 3 taken 1820 times.
3640 outDAE := BackendDAE.DAE(list(tryReduceEqSystem(syst, shared, iVarlst, filterDiscretes) for syst in systs), shared);
1764
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1820 times.
1820 if makeMatching then
1765 1820 outDAE := BackendDAEUtil.transformBackendDAE(outDAE,SOME((BackendDAE.NO_INDEX_REDUCTION(),BackendDAE.EXACT())),NONE(),NONE());
1766 end if;
1767 end reduceEqSystemsInDAE;
1768
1769 public function tryReduceEqSystem
1770 " Helpfunction to reduceEqSystemsInDAE.
1771 "
1772 input BackendDAE.EqSystem iSyst;
1773 input BackendDAE.Shared shared;
1774 input list<BackendDAE.Var> iVarlst;
1775 input Boolean filterDiscretes;
1776 output BackendDAE.EqSystem oSyst;
1777 algorithm
1778 try
1779 //BackendDump.dumpEqSystem(iSyst,"IN: tryReduceEqSystem");
1780 1822 oSyst := reduceEqSystem(iSyst, shared, iVarlst, filterDiscretes);
1781 //BackendDump.dumpEqSystem(oSyst,"OUT: tryReduceEqSystem");
1782 else
1783 oSyst := iSyst;
1784 end try;
1785 end tryReduceEqSystem;
1786
1787
1788 public function reduceEqSystem
1789 "Function reduces BackendDAE.EqSystem system by filtering
1790 the equation and select only the one that are needed
1791 to calculate the given varibales. Shared object is used
1792 only to get the functionsTree.
1793 "
1794 input BackendDAE.EqSystem iSyst;
1795 input BackendDAE.Shared shared;
1796 input list<BackendDAE.Var> iVarlst;
1797 input Boolean filterDiscretes;
1798 output BackendDAE.EqSystem oSyst;
1799
1800 protected
1801 array<Integer> ass1, ass2;
1802 BackendDAE.Variables vars;
1803 BackendDAE.EqSystem syst;
1804 BackendDAE.Variables iVars = BackendVariable.listVar(iVarlst);
1805 BackendDAE.EquationArray ordererdEqs, arrEqs;
1806 list<Integer> indx_lst_v, indx_lst_e, statevarindx_lst;
1807 array<Integer> indx_arr;
1808 list<BackendDAE.Equation> el;
1809 list<BackendDAE.Var> vl;
1810
1811 AvlTreePathFunction.Tree funcs;
1812 BackendDAE.AdjacencyMatrix m;
1813 algorithm
1814 oSyst := match iSyst
1815 case syst as BackendDAE.EQSYSTEM( orderedEqs=ordererdEqs, orderedVars=vars,
1816 matching=BackendDAE.MATCHING(ass1=ass1, ass2=ass2) )
1817 algorithm
1818
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 1814 times.
1822 if (Flags.getConfigEnum(Flags.SYM_SOLVER) > 0) then
1819 8 (_,statevarindx_lst) := BackendVariable.getAllVarIndicesFromVariables(vars, BackendVariable.isAlgState);
1820 else
1821 1814 (_,statevarindx_lst) := BackendVariable.getAllVarIndicesFromVariables(vars, BackendVariable.isStateVar);
1822 end if;
1823 1822 indx_lst_v := BackendVariable.getVarIndexFromVariables(iVars, vars);
1824
1825 1822 indx_lst_v := listAppend(indx_lst_v, statevarindx_lst) "overestimate" annotation(__OpenModelica_DisableListAppendWarning=true);
1826 1822 indx_lst_e := List.map1r(indx_lst_v, arrayGet, ass1);
1827
1828 1822 indx_arr := arrayCreate(equationArraySizeDAE(iSyst), 0);
1829 1822 funcs := getFunctions(shared);
1830 3644 (_, m, _) := getAdjacencyMatrix(iSyst, BackendDAE.SPARSE(), SOME(funcs), isInitializationDAE(shared));
1831
1832 1822 indx_arr := markStateEquationsWork(indx_lst_e, m, ass1, indx_arr);
1833
1834 1822 indx_lst_e := Array.foldIndex(indx_arr, translateArrayList, {});
1835
1836 1822 el := BackendEquation.getList(indx_lst_e, ordererdEqs);
1837
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1822 times.
1822 if filterDiscretes then
1838 ✗ el := list(e for e guard(not BackendEquation.isDiscreteEquation(e)) in el);
1839 end if;
1840
1841 1822 arrEqs := BackendEquation.listEquation(el);
1842 1822 vl := BackendEquation.equationsVars(arrEqs, vars);
1843
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1822 times.
1822 if filterDiscretes then
1844 ✗ vl := list(v for v guard(not BackendVariable.isVarDiscrete(v)) in vl);
1845 end if;
1846
1847 1822 syst.orderedVars := BackendVariable.listVar1(vl);
1848 1822 syst.orderedEqs := arrEqs;
1849 1822 syst.stateSets := {};
1850 1822 then clearEqSyst(syst);
1851 end match;
1852 end reduceEqSystem;
1853
1854 public function introduceOutputRealDerivatives
1855 "Find output variables of Real type and replace them with derivative equation
1856 (e.g) output Real y;
1857 $y_der = der(y)
1858 "
1859 input BackendDAE.BackendDAE inDAE;
1860 output BackendDAE.BackendDAE outDAE;
1861 protected
1862 BackendDAE.EqSystem currentSystem;
1863 DAE.ComponentRef newCref;
1864 DAE.Exp lhs, rhs;
1865 list<BackendDAE.Equation> newEqnlst;
1866 list<BackendDAE.Var> daeVarsLst;
1867 algorithm
1868
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
8 {currentSystem} := inDAE.eqs;
1869 daeVarsLst := {};
1870 newEqnlst := {};
1871
2/2
✓ Branch 1 taken 976 times.
✓ Branch 2 taken 8 times.
984 for var in BackendVariable.varList(currentSystem.orderedVars) loop
1872
3/4
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 974 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
976 if BackendVariable.isOutputVar(var) and BackendVariable.isRealVar(var) then
1873 2 newCref := ComponentReference.appendStringLastIdent("_der", var.varName); // append _der
1874 2 newCref := ComponentReference.prependStringCref("$", newCref); // prepend $
1875 2 daeVarsLst := BackendVariable.makeVar(newCref) :: daeVarsLst;
1876 2 lhs := Expression.crefExp(newCref);
1877 2 rhs := IndexReduction.makeder(BackendVariable.varExp(var));
1878 2 newEqnlst := BackendEquation.generateEquation(lhs, rhs, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_BINDING) :: newEqnlst;
1879 end if;
1880 end for;
1881 //BackendDump.dumpEquationList(newEqnlst, "first order derivative equation");
1882
1883 8 currentSystem := BackendVariable.addVarsDAE(daeVarsLst, currentSystem);
1884 8 currentSystem.orderedEqs := BackendEquation.merge(currentSystem.orderedEqs, BackendEquation.listEquation(newEqnlst));
1885
1886 8 outDAE := BackendDAE.DAE({currentSystem}, inDAE.shared);
1887
1888 //BackendDump.printBackendDAE(outDAE);
1889 end introduceOutputRealDerivatives;
1890
1891 public function introduceOutputAliases
1892 "Find top level output variables and replace them with alias variables."
1893 input output BackendDAE.BackendDAE dae;
1894 protected
1895 BackendDAE.EqSystems systems, returnSysts = {};
1896 BackendDAE.Variables vars, newVars;
1897 BackendDAE.EquationArray eqs, removedEqs;
1898 list<BackendDAE.Equation> newEqns, newRemovedEqs;
1899 DAE.ComponentRef newCref, cref;
1900 BackendDAE.Var newVar;
1901 BackendDAE.Equation newEqn;
1902 HashSet.HashSet topLevelOutputs = HashSet.emptyHashSet();
1903 algorithm
1904 83 systems := dae.eqs;
1905
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 83 times.
166 for system in systems loop
1906 83 eqs := system.orderedEqs;
1907 83 vars := system.orderedVars;
1908 83 removedEqs := system.removedEqs;
1909 83 newVars := BackendVariable.emptyVarsSized(realInt(intReal(BackendVariable.varsSize(vars)) * 1.4));
1910 newEqns := {};
1911 newRemovedEqs := {};
1912
1913 // Add alias variable and alias equation
1914
2/2
✓ Branch 1 taken 7299 times.
✓ Branch 2 taken 83 times.
7382 for v in BackendVariable.varList(vars) loop
1915
2/2
✓ Branch 1 taken 7183 times.
✓ Branch 2 taken 116 times.
7299 if not BackendVariable.isVarOnTopLevelAndOutput(v) then
1916 7183 newVars := BackendVariable.addVar(v, newVars);
1917 else
1918 116 cref := BackendVariable.varCref(v);
1919 116 topLevelOutputs := BaseHashSet.add(cref, topLevelOutputs);
1920
1921 // generate new internal alias var
1922 116 newCref := ComponentReference.prependStringCref(BackendDAE.outputAliasPrefix, cref);
1923 116 newVar := BackendVariable.copyVarNewName(newCref, v);
1924 116 newVar := BackendVariable.setVarDirection(newVar, DAE.BIDIR());
1925 /* A discrete output's alias stays discrete; as a continuous variable it
1926 * also gets "$PRE.alias = alias", which over-specifies the initial system.
1927 */
1928 newVar := match v.varKind
1929 case BackendDAE.DISCRETE() then newVar;
1930 69 else BackendVariable.setVarKind(newVar, BackendDAE.VARIABLE());
1931 end match;
1932 /* fix issue https://github.com/OpenModelica/OpenModelica/issues/15311
1933 * force StateSelect.never on the alias variable so that state selection never picks the alias
1934 * instead of original state variable, which would cause wrong code generation and simulation results.
1935 */
1936
2/2
✓ Branch 1 taken 109 times.
✓ Branch 2 taken 7 times.
116 if BackendVariable.isRealVar(v) then
1937 109 newVar := BackendVariable.setVarStateSelect(newVar, DAE.AVOID());
1938 end if;
1939 116 newVars := BackendVariable.addVar(newVar, newVars);
1940
1941 /*fix issue https://github.com/OpenModelica/OpenModelica/issues/13342
1942 *do not change the varkind of the output variable, except if var = BackendDAE.STATE()
1943 */
1944
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 if BackendVariable.isStateVar(v) then
1945 ✗ v := BackendVariable.setVarKind(v, BackendDAE.VARIABLE());
1946 end if;
1947 116 v := BackendVariable.removeFixedAttribute(v);
1948 116 v := BackendVariable.removeStartAttribute(v);
1949 116 newVars := BackendVariable.addVar(v, newVars);
1950
1951 // generate new equation and add it
1952 116 newEqn := BackendEquation.generateEquation(Expression.crefToExp(cref), Expression.crefToExp(newCref), DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_BINDING);
1953 newEqns := newEqn::newEqns;
1954 end if;
1955 end for;
1956
1957 // Replace variable with alias variable in all equations
1958 83 traverseBackendDAEExpsEqns(eqs, introduceOutputAliases_eqs, topLevelOutputs);
1959 83 eqs := BackendEquation.addList(newEqns, eqs);
1960 83 traverseBackendDAEExpsEqns(removedEqs, introduceOutputAliases_eqs, topLevelOutputs);
1961 83 removedEqs := BackendEquation.addList(newRemovedEqs, removedEqs);
1962
1963 // Update system
1964 83 system.orderedVars := newVars;
1965 system.orderedEqs := eqs;
1966 system.removedEqs := removedEqs;
1967 returnSysts := system::returnSysts;
1968 end for;
1969
1970 83 returnSysts := listReverse(returnSysts);
1971 83 dae.eqs := returnSysts;
1972 end introduceOutputAliases;
1973
1974 protected function introduceOutputAliases_eqs
1975 input DAE.Exp inExp;
1976 input HashSet.HashSet inStates;
1977 output DAE.Exp outExp;
1978 output HashSet.HashSet outStates;
1979 algorithm
1980 9251 (outExp, outStates) := Expression.traverseExpBottomUp(inExp, introduceOutputAliases_eqs2, inStates);
1981 end introduceOutputAliases_eqs;
1982
1983 protected function introduceOutputAliases_eqs2
1984 input DAE.Exp inExp;
1985 input HashSet.HashSet inStates;
1986 output DAE.Exp outExp;
1987 output HashSet.HashSet outStates = inStates;
1988 algorithm
1989 outExp := match inExp
1990 local
1991 DAE.Exp e1;
1992 DAE.ComponentRef cr, newCref;
1993
1994 // replace cr with <outputAliasPrefix>+cr
1995 case e1 as DAE.CREF(componentRef=cr) guard BaseHashSet.has(cr, inStates) algorithm
1996 75 newCref := ComponentReference.prependStringCref(BackendDAE.outputAliasPrefix, cr);
1997 75 e1.componentRef := newCref;
1998 then e1;
1999
2000 else inExp;
2001 end match;
2002 end introduceOutputAliases_eqs2;
2003
2004 protected function translateArrayList
2005 input Integer inElement;
2006 input Integer inIndex;
2007 input list<Integer> inFoldArg;
2008 output list<Integer> outFoldArg;
2009 algorithm
2010
2/2
✓ Branch 0 taken 18288 times.
✓ Branch 1 taken 655 times.
18943 outFoldArg := if intEq(inElement, 1) then inIndex::inFoldArg else inFoldArg;
2011 end translateArrayList;
2012
2013 public function removeDiscreteAssignments "
2014 Author: wbraun
2015 Function tarverse Statements and remove discrete one"
2016 input list<DAE.Statement> inStmts;
2017 input BackendDAE.Variables inVars;
2018 output list<DAE.Statement> outStmts;
2019 algorithm
2020 outStmts := matchcontinue(inStmts,inVars)
2021 local
2022 list<DAE.Statement> stmts,rest,xs;
2023 DAE.Else algElse;
2024 DAE.Statement stmt,ew;
2025 DAE.ComponentRef cref;
2026 BackendDAE.Var v;
2027 BackendDAE.Variables vars;
2028 DAE.Exp e;
2029 DAE.ElementSource source;
2030
2031 DAE.Type tp;
2032 Boolean b1;
2033 String id1;
2034
2035 list<DAE.ComponentRef> conditions;
2036 Boolean initialCall;
2037 list<tuple<DAE.ComponentRef, array<DAE.Exp>>> sub_iters;
2038
2039 case ({},_) then ({});
2040
2041 case ((DAE.STMT_ASSIGN(exp1 = e)::rest),vars)
2042 algorithm
2043 ✗ cref := Expression.expCref(e);
2044 ✗ ({v},_) := BackendVariable.getVar(cref,vars);
2045 ✗ true := BackendVariable.isVarDiscrete(v);
2046 ✗ xs := removeDiscreteAssignments(rest,vars);
2047 then xs;
2048
2049 /*case ((DAE.STMT_TUPLE_ASSIGN(expExpLst = expl1)::rest),vars)
2050 algorithm
2051 crefLst = List.map(expl1,Expression.expCref);
2052 (vlst,_) = List.map1_2(crefLst,BackendVariable.getVar,vars);
2053 //blst = List.map(vlst,BackendVariable.isVarDiscrete);
2054 //true = boolOrList(blst);
2055 xs = removeDiscreteAssignments(rest,vars);
2056 then xs;
2057 */
2058 case ((DAE.STMT_ASSIGN_ARR(lhs = e)::rest),vars)
2059 algorithm
2060 ✗ cref := Expression.expCref(e);
2061 ✗ ({v},_) := BackendVariable.getVar(cref,vars);
2062 ✗ true := BackendVariable.isVarDiscrete(v);
2063 ✗ xs := removeDiscreteAssignments(rest,vars);
2064 then xs;
2065
2066 case (((DAE.STMT_IF(exp=e,statementLst=stmts,else_ = algElse, source = source))::rest),vars)
2067 algorithm
2068 ✗ stmts := removeDiscreteAssignments(stmts,vars);
2069 ✗ algElse := removediscreteAssingmentsElse(algElse,vars);
2070 ✗ xs := removeDiscreteAssignments(rest,vars);
2071 ✗ then DAE.STMT_IF(e,stmts,algElse,source)::xs;
2072
2073 case (((DAE.STMT_FOR(type_=tp,iterIsArray=b1,iter=id1,range=e,statementLst=stmts, source = source, sub_iters=sub_iters))::rest),vars)
2074 algorithm
2075 ✗ stmts := removeDiscreteAssignments(stmts,vars);
2076 ✗ xs := removeDiscreteAssignments(rest,vars);
2077 ✗ then DAE.STMT_FOR(tp,b1,id1,e,stmts,source,sub_iters)::xs;
2078
2079 case (((DAE.STMT_WHILE(exp=e,statementLst=stmts, source = source))::rest),vars)
2080 algorithm
2081 ✗ stmts := removeDiscreteAssignments(stmts,vars);
2082 ✗ xs := removeDiscreteAssignments(rest,vars);
2083 ✗ then DAE.STMT_WHILE(e,stmts,source)::xs;
2084
2085 case (((DAE.STMT_WHEN(exp=e,conditions=conditions,initialCall=initialCall,statementLst=stmts,elseWhen=NONE(),source=source))::rest),vars)
2086 algorithm
2087 ✗ stmts := removeDiscreteAssignments(stmts,vars);
2088 ✗ xs := removeDiscreteAssignments(rest,vars);
2089 ✗ then DAE.STMT_WHEN(e,conditions,initialCall,stmts,NONE(),source)::xs;
2090
2091 case (((DAE.STMT_WHEN(exp=e,conditions=conditions,initialCall=initialCall,statementLst=stmts,elseWhen=SOME(ew),source=source))::rest),vars)
2092 algorithm
2093 ✗ stmts := removeDiscreteAssignments(stmts,vars);
2094 ✗ {ew} := removeDiscreteAssignments({ew},vars);
2095 ✗ xs := removeDiscreteAssignments(rest,vars);
2096 ✗ then DAE.STMT_WHEN(e,conditions,initialCall,stmts,SOME(ew),source)::xs;
2097
2098 case ((stmt::rest),vars)
2099 algorithm
2100 ✗ xs := removeDiscreteAssignments(rest,vars);
2101 then stmt::xs;
2102 end matchcontinue;
2103 end removeDiscreteAssignments;
2104
2105 protected function removediscreteAssingmentsElse "author: wbraun
2106 Helper function for traverseDAEEquationsELse"
2107 input DAE.Else inElse;
2108 input BackendDAE.Variables inVars;
2109 output DAE.Else outElse;
2110 algorithm
2111 outElse := match(inElse,inVars)
2112 local
2113 DAE.Exp e;
2114 list<DAE.Statement> st;
2115 DAE.Else el;
2116 BackendDAE.Variables vars;
2117 case(DAE.NOELSE(),_) then (DAE.NOELSE());
2118 case(DAE.ELSEIF(e,st,el),vars)
2119 algorithm
2120 ✗ el := removediscreteAssingmentsElse(el,vars);
2121 ✗ st := removeDiscreteAssignments(st,vars);
2122 ✗ then DAE.ELSEIF(e,st,el);
2123 case(DAE.ELSE(st),vars)
2124 algorithm
2125 ✗ st := removeDiscreteAssignments(st,vars);
2126 ✗ then DAE.ELSE(st);
2127 end match;
2128 end removediscreteAssingmentsElse;
2129
2130 public function collateAlgorithm "
2131 Author: Frenkel TUD 2010-07"
2132 input DAE.Algorithm inAlg;
2133 input Option<AvlTreePathFunction.Tree> infuncs;
2134 output DAE.Algorithm outAlg;
2135 algorithm
2136 outAlg := matchcontinue inAlg
2137 local list<DAE.Statement> statementLst;
2138 case DAE.ALGORITHM_STMTS(statementLst=statementLst)
2139 algorithm
2140 34466 (statementLst,_) := DAEUtil.traverseDAEStmts(statementLst, collateArrExpStmt, infuncs);
2141 34466 then
2142 DAE.ALGORITHM_STMTS(statementLst);
2143 else inAlg;
2144 end matchcontinue;
2145 end collateAlgorithm;
2146
2147 protected function collateArrExpStmt "author: Frenkel TUD 2010-07
2148 wbraun: added as workaround for when condition.
2149 As long as we don't support fully array helpVars,
2150 we can't collate the expression of a when condition."
2151 input DAE.Exp inExp;
2152 input DAE.Statement inStmt;
2153 input Option<AvlTreePathFunction.Tree> funcs;
2154 output DAE.Exp outExp = inExp;
2155 output Option<AvlTreePathFunction.Tree> oarg = funcs;
2156 algorithm
2157 try
2158 111497 outExp := Expression.traverseExpBottomUp(outExp, traversingcollateArrExpStmt, (inStmt, funcs));
2159 else
2160 end try;
2161 end collateArrExpStmt;
2162
2163 protected function traversingcollateArrExpStmt "wbraun: added as workaround for when condition.
2164 As long as we don't support fully array helpVars,
2165 we can't collate the expression of a when condition."
2166 input DAE.Exp inExp;
2167 input tuple<DAE.Statement, Option<AvlTreePathFunction.Tree>> inTpl;
2168 output DAE.Exp outExp;
2169 output tuple<DAE.Statement, Option<AvlTreePathFunction.Tree>> outTpl;
2170 algorithm
2171 (outExp,outTpl) := matchcontinue (inExp,inTpl)
2172 local
2173 DAE.Exp e,e1,e1_1,e1_2;
2174 // do nothing if try to collate when codition expression
2175 case (e as DAE.MATRIX(matrix=((DAE.CREF())::_)::_), (DAE.STMT_WHEN(), _))
2176 then (e,inTpl);
2177 case (e as DAE.MATRIX(matrix=(((DAE.UNARY(exp = DAE.CREF())))::_)::_), (DAE.STMT_WHEN(), _))
2178 then (e,inTpl);
2179 case (e as DAE.ARRAY(array=(DAE.CREF())::_), (DAE.STMT_WHEN(), _))
2180 then (e,inTpl);
2181 case (e as DAE.ARRAY(array=(DAE.UNARY(exp = DAE.CREF()))::_), (DAE.STMT_WHEN(), _))
2182 then (e,inTpl);
2183 // collate in other cases
2184 case (e as DAE.MATRIX(matrix=((e1 as DAE.CREF())::_)::_), _)
2185 algorithm
2186 4 e1_1 := Expression.expStripLastSubs(e1);
2187
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 (e1_2,true) := Expression.extendArrExp(e1_1,false);
2188
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 true := ExpressionBasics.expEqual(e,e1_2);
2189 then (e1_1,inTpl);
2190 case (e as DAE.MATRIX(matrix=(((e1 as DAE.UNARY(exp = DAE.CREF())))::_)::_), _)
2191 algorithm
2192 ✗ e1_1 := Expression.expStripLastSubs(e1);
2193 ✗ (e1_2,true) := Expression.extendArrExp(e1_1,false);
2194 ✗ true := ExpressionBasics.expEqual(e,e1_2);
2195 then (e1_1,inTpl);
2196 case (e as DAE.ARRAY(array=(e1 as DAE.CREF())::_), _)
2197 algorithm
2198 94 e1_1 := Expression.expStripLastSubs(e1);
2199
2/2
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 65 times.
98 (e1_2,true) := Expression.extendArrExp(e1_1,false);
2200
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 61 times.
65 true := ExpressionBasics.expEqual(e,e1_2);
2201 then (e1_1,inTpl);
2202 case (e as DAE.ARRAY(array=(e1 as DAE.UNARY(exp = DAE.CREF()))::_), _)
2203 algorithm
2204 ✗ e1_1 := Expression.expStripLastSubs(e1);
2205 ✗ (e1_2,true) := Expression.extendArrExp(e1_1,false);
2206 ✗ true := ExpressionBasics.expEqual(e,e1_2);
2207 then (e1_1,inTpl);
2208 else (inExp,inTpl);
2209 end matchcontinue;
2210 end traversingcollateArrExpStmt;
2211
2212 public function collateArrExpList
2213 " author Frenkel TUD:
2214 replace {a[1],a[2],a[3]} for Real a[3] with a"
2215 input list<DAE.Exp> iexpl;
2216 input Option<AvlTreePathFunction.Tree> optfunc;
2217 output list<DAE.Exp> outexpl;
2218 algorithm
2219 outexpl := match iexpl
2220 local
2221 DAE.Exp e,e1;
2222 list<DAE.Exp> expl1,expl;
2223
2224 case {} then {};
2225
2226 case e::expl algorithm
2227 ✗ (e1,_) := collateArrExp(e,optfunc);
2228 ✗ expl1 := collateArrExpList(expl,optfunc);
2229 then
2230 e1::expl1;
2231 end match;
2232 end collateArrExpList;
2233
2234 public function collateArrExp "
2235 Author: Frenkel TUD 2010-07"
2236 input DAE.Exp inExp;
2237 input Option<AvlTreePathFunction.Tree> inFuncs;
2238 output DAE.Exp outExp;
2239 output Option<AvlTreePathFunction.Tree> outFuncs;
2240 algorithm
2241 846 (outExp,outFuncs) := Expression.traverseExpBottomUp(inExp, traversingcollateArrExp, inFuncs);
2242 end collateArrExp;
2243
2244 protected function traversingcollateArrExp
2245 input DAE.Exp inExp;
2246 input Option<AvlTreePathFunction.Tree> inFuncs;
2247 output DAE.Exp outExp;
2248 output Option<AvlTreePathFunction.Tree> funcs;
2249 algorithm
2250 (outExp,funcs) := matchcontinue (inExp,inFuncs)
2251 local
2252 DAE.Exp e,e1,e1_1,e1_2;
2253 case (e as DAE.MATRIX(matrix=((e1 as DAE.CREF())::_)::_),funcs)
2254 algorithm
2255 4 e1_1 := Expression.expStripLastSubs(e1);
2256
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
6 (e1_2,true) := Expression.extendArrExp(e1_1,false);
2257
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 true := ExpressionBasics.expEqual(e,e1_2);
2258 then (e1_1,funcs);
2259
2260 case (e as DAE.MATRIX(matrix=(((e1 as DAE.UNARY(exp = DAE.CREF())))::_)::_),funcs)
2261 algorithm
2262 ✗ e1_1 := Expression.expStripLastSubs(e1);
2263 ✗ (e1_2,true) := Expression.extendArrExp(e1_1,false);
2264 ✗ true := ExpressionBasics.expEqual(e,e1_2);
2265 then (e1_1,funcs);
2266
2267 case (e as DAE.ARRAY(array=(e1 as DAE.CREF())::_),funcs)
2268 algorithm
2269 8 e1_1 := Expression.expStripLastSubs(e1);
2270
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 3 times.
11 (e1_2,true) := Expression.extendArrExp(e1_1,false);
2271
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 true := ExpressionBasics.expEqual(e,e1_2);
2272 then (e1_1,funcs);
2273
2274 case (e as DAE.ARRAY(array=(e1 as DAE.UNARY(exp = DAE.CREF()))::_),funcs)
2275 algorithm
2276 4 e1_1 := Expression.expStripLastSubs(e1);
2277
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 3 times.
7 (e1_2,true) := Expression.extendArrExp(e1_1,false);
2278
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 true := ExpressionBasics.expEqual(e,e1_2);
2279 then (e1_1,funcs);
2280
2281 else (inExp,inFuncs);
2282 end matchcontinue;
2283 end traversingcollateArrExp;
2284
2285 public function getEquationBlock"author: PA
2286
2287 Returns the block the equation belongs to.
2288 "
2289 input Integer inInteger;
2290 input BackendDAE.StrongComponents inComps;
2291 output BackendDAE.StrongComponent outComp;
2292 algorithm
2293 outComp:=
2294 matchcontinue (inInteger,inComps)
2295 local
2296 Integer i;
2297 list<Integer> elst;
2298 BackendDAE.StrongComponents comps;
2299 BackendDAE.StrongComponent comp;
2300 case (i,comp::_)
2301 algorithm
2302 ✗ (elst,_) := BackendDAETransform.getEquationAndSolvedVarIndxes(comp);
2303 ✗ true := listMember(i,elst);
2304 then
2305 comp;
2306 case (i,_::comps)
2307 algorithm
2308 ✗ comp := getEquationBlock(i,comps);
2309 then
2310 comp;
2311 end matchcontinue;
2312 end getEquationBlock;
2313
2314 /******************************************************************
2315 stuff to calculate adjacency matrix
2316
2317 wbraun: It should be renames to Adjacency matrix, because
2318 adjacency matrix descibes the relation between knots and edges.
2319 In the sense it is used here is the relation between knots and
2320 knots of a bigraph.
2321 ******************************************************************/
2322
2323 public function adjacencyMatrix
2324 "author: PA, adrpo
2325 Calculates the adjacency matrix, i.e. which variables are present in each equation.
2326 You can ask for absolute indexes or normal (negative for der) via the IndexType.
2327 wbraun: beware dim(AdjacencyMatrix) != dim(AdjacencyMatrixT) due to array equations. "
2328 input BackendDAE.EqSystem inEqSystem;
2329 input BackendDAE.IndexType inIndexType;
2330 input Option<AvlTreePathFunction.Tree> functionTree;
2331 input Boolean isInitial;
2332 output BackendDAE.AdjacencyMatrix outAdjacencyMatrix;
2333 output BackendDAE.AdjacencyMatrixT outAdjacencyMatrixT;
2334 protected
2335 BackendDAE.Variables vars;
2336 BackendDAE.EquationArray eqns;
2337 algorithm
2338 try
2339 103159 BackendDAE.EQSYSTEM(orderedVars = vars, orderedEqs = eqns) := inEqSystem;
2340 103159 (outAdjacencyMatrix, outAdjacencyMatrixT) :=
2341 adjacencyMatrixDispatch(vars, eqns, inIndexType, functionTree, isInitial);
2342 else
2343 ✗ Error.addMessage(Error.INTERNAL_ERROR, {"BackendDAEUtil.adjacencyMatrix failed."});
2344 ✗ fail();
2345 end try;
2346 end adjacencyMatrix;
2347
2348 public function adjacencyMatrixMasked
2349 input BackendDAE.EqSystem inEqSystem;
2350 input BackendDAE.IndexType inIndexType;
2351 input array<Boolean> inMask;
2352 input Option<AvlTreePathFunction.Tree> functionTree;
2353 input Boolean isInitial;
2354 output BackendDAE.AdjacencyMatrix outAdjacencyMatrix;
2355 output BackendDAE.AdjacencyMatrixT outAdjacencyMatrixT;
2356 protected
2357 BackendDAE.Variables vars;
2358 BackendDAE.EquationArray eqns;
2359 algorithm
2360 try
2361 46 BackendDAE.EQSYSTEM(orderedVars = vars, orderedEqs = eqns) := inEqSystem;
2362 46 (outAdjacencyMatrix, outAdjacencyMatrixT) :=
2363 adjacencyMatrixDispatchMasked(vars, eqns, inIndexType, inMask, functionTree, isInitial);
2364 else
2365 ✗ Error.addMessage(Error.INTERNAL_ERROR, {"BackendDAEUtil.adjacencyMatrix failed."});
2366 ✗ fail();
2367 end try;
2368 end adjacencyMatrixMasked;
2369
2370 public function adjacencyMatrixScalar
2371 "author: PA, adrpo
2372 Calculates the adjacency matrix, i.e. which variables are present in each equation.
2373 You can ask for absolute indexes or normal (negative for der) via the IndexType"
2374 input BackendDAE.EqSystem syst;
2375 input BackendDAE.IndexType inIndexType;
2376 input Option<AvlTreePathFunction.Tree> functionTree;
2377 input Boolean isInitial;
2378 output BackendDAE.AdjacencyMatrix outAdjacencyMatrix;
2379 output BackendDAE.AdjacencyMatrixT outAdjacencyMatrixT;
2380 output array<list<Integer>> outMapEqnIncRow;
2381 output array<Integer> outMapIncRowEqn;
2382 protected
2383 BackendDAE.Variables vars;
2384 BackendDAE.EquationArray eqns;
2385 algorithm
2386 try
2387 223221 BackendDAE.EQSYSTEM(orderedVars = vars, orderedEqs = eqns) := syst;
2388 223221 ExpandableArray.compress(eqns);
2389 223221 (outAdjacencyMatrix, outAdjacencyMatrixT, outMapEqnIncRow, outMapIncRowEqn) :=
2390 adjacencyMatrixDispatchScalar(vars, eqns, inIndexType, functionTree, isInitial);
2391 else
2392 ✗ Error.addMessage(Error.INTERNAL_ERROR, {"BackendDAEUtil.adjacencyMatrixScalar failed."});
2393 ✗ fail();
2394 end try;
2395 end adjacencyMatrixScalar;
2396
2397 public function uniqueRow
2398 "The row's variable indices without duplicates, in the descending order
2399 AvlSetInt.listKeys listed them in when the row was a set."
2400 input list<Integer> row;
2401 output list<Integer> outRow;
2402 algorithm
2403 3139682 outRow := List.sortedUnique(List.sort(row, intLt), intEq);
2404 end uniqueRow;
2405
2406 public function getIndexType
2407 "author kabdelhak FHB 10-2019
2408 Returns the index type of the current adjacency matrix and two Booleans:
2409 Boolean 1: true, if is scalar.
2410 Boolean 2: true, if analytical to structural singularity processing has already been done.
2411 Fails if none are present."
2412 input BackendDAE.EqSystem syst;
2413 output BackendDAE.IndexType indexType;
2414 output Boolean scalar;
2415 output Boolean processed;
2416 algorithm
2417
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 119015 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 119015 times.
✓ Branch 5 taken 119015 times.
✗ Branch 6 not taken.
119015 SOME((_, _, indexType, scalar, processed)) := syst.mapping;
2418 end getIndexType;
2419
2420 public function hasIndexTypeSolvableAndUnprocessedScalar
2421 "author kabdelhak FHB 10-2019
2422 Returns true if the equation system has an adjacency matrix that got
2423 computed by strict solvability rules and wasn't already analyzed
2424 by the analytical to structural conversion algorithm."
2425 input BackendDAE.EqSystem syst;
2426 output Boolean b = false;
2427 protected
2428 BackendDAE.IndexType indexType;
2429 Boolean scalar, processed;
2430 algorithm
2431 try
2432 119015 (indexType, scalar, processed) := getIndexType(syst);
2433 b := match (indexType, scalar, processed)
2434 case (BackendDAE.SOLVABLE(), true, false) then true;
2435 else false;
2436 end match;
2437 else
2438 /* no mapping available, return false */
2439 end try;
2440 end hasIndexTypeSolvableAndUnprocessedScalar;
2441
2442 public function hasScalarAdjacencyMatrix
2443 "author kabdelhak FHB 10-2019
2444 Returns true if the equation system has a scalar adjacency matrix."
2445 input BackendDAE.EqSystem syst;
2446 output Boolean b;
2447 algorithm
2448 ✗ (_, b, _) := getIndexType(syst);
2449 end hasScalarAdjacencyMatrix;
2450
2451 public function setAnalyticalToStructuralProcessed
2452 input output BackendDAE.EqSystem syst;
2453 input Boolean processed;
2454 protected
2455 array<list<Integer>> mapArrayToScalar;
2456 array<Integer> mapScalarToArray;
2457 BackendDAE.IndexType indexType;
2458 Boolean scalar;
2459 algorithm
2460
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1510 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1510 times.
1510 SOME((mapArrayToScalar, mapScalarToArray, indexType, scalar, _)) := syst.mapping;
2461
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1510 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1510 times.
3020 syst.mapping := SOME((mapArrayToScalar, mapScalarToArray, indexType, scalar, processed));
2462 end setAnalyticalToStructuralProcessed;
2463
2464 public function adjacencyMatrixDispatch
2465 "@author: adrpo
2466 Calculates the adjacency matrix as an array of list of integers"
2467 input BackendDAE.Variables inVars;
2468 input BackendDAE.EquationArray inEqns;
2469 input BackendDAE.IndexType inIndexType;
2470 input Option<AvlTreePathFunction.Tree> functionTree = NONE();
2471 input Boolean isInitial;
2472 output BackendDAE.AdjacencyMatrix outAdjacencyArray;
2473 output BackendDAE.AdjacencyMatrixT outAdjacencyArrayT;
2474 protected
2475 Integer num_eqs, num_vars;
2476 BackendDAE.Equation eq;
2477 list<Integer> row;
2478 list<Integer> rowLst;
2479 algorithm
2480 108254 num_eqs := BackendEquation.getNumberOfEquations(inEqns);
2481 108254 num_vars := BackendVariable.varsSize(inVars);
2482 108254 outAdjacencyArray := arrayCreate(num_eqs, {});
2483 108254 outAdjacencyArrayT := arrayCreate(num_vars, {});
2484
2485
2/2
✓ Branch 0 taken 6384 times.
✓ Branch 1 taken 101870 times.
1767501 for idx in 1:num_eqs loop
2486 // Get the equation.
2487 1659247 eq := BackendEquation.get(inEqns, idx);
2488 // Compute the row.
2489 1659247 rowLst := adjacencyRow(eq, inVars, inIndexType, functionTree, {}, isInitial);
2490 1659247 row := uniqueRow(rowLst);
2491 // Put it in the arrays.
2492 1659247 arrayUpdate(outAdjacencyArray, idx, row);
2493 1659247 outAdjacencyArrayT := filladjacencyMatrixT(row, {idx}, outAdjacencyArrayT);
2494 end for;
2495 end adjacencyMatrixDispatch;
2496
2497 public function adjacencyMatrixDispatchMasked
2498 input BackendDAE.Variables inVars;
2499 input BackendDAE.EquationArray inEqns;
2500 input BackendDAE.IndexType inIndexType;
2501 input array<Boolean> inMask;
2502 input Option<AvlTreePathFunction.Tree> functionTree = NONE();
2503 input Boolean isInitial;
2504 output BackendDAE.AdjacencyMatrix outAdjacencyArray;
2505 output BackendDAE.AdjacencyMatrixT outAdjacencyArrayT;
2506 protected
2507 Integer num_eqs, num_vars;
2508 BackendDAE.Equation eq;
2509 list<Integer> row;
2510 list<Integer> rowLst;
2511 algorithm
2512 46 num_eqs := BackendEquation.getNumberOfEquations(inEqns);
2513 46 num_vars := BackendVariable.varsSize(inVars);
2514 46 outAdjacencyArray := arrayCreate(num_eqs, {});
2515 46 outAdjacencyArrayT := arrayCreate(num_vars, {});
2516
2517
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
743 for idx in 1:num_eqs loop
2518
2/2
✓ Branch 1 taken 525 times.
✓ Branch 2 taken 172 times.
697 if inMask[idx] then
2519 // Get the equation.
2520 525 eq := BackendEquation.get(inEqns, idx);
2521 // Compute the row.
2522 525 rowLst := adjacencyRow(eq, inVars, inIndexType, functionTree, {}, isInitial);
2523 525 row := uniqueRow(rowLst);
2524 // Put it in the arrays.
2525 525 arrayUpdate(outAdjacencyArray, idx, row);
2526 525 outAdjacencyArrayT := filladjacencyMatrixT(row, {idx}, outAdjacencyArrayT);
2527 end if;
2528 end for;
2529 end adjacencyMatrixDispatchMasked;
2530
2531 protected function adjacencyMatrixDispatchScalar
2532 "@author: adrpo
2533 Calculates the adjacency matrix as an array of list of integers"
2534 input BackendDAE.Variables inVars;
2535 input BackendDAE.EquationArray inEqns;
2536 input BackendDAE.IndexType inIndexType;
2537 input Option<AvlTreePathFunction.Tree> functionTree;
2538 input Boolean isInitial;
2539 output BackendDAE.AdjacencyMatrix outAdjacencyArray;
2540 output BackendDAE.AdjacencyMatrixT outAdjacencyArrayT = outAdjacencyArrayT;
2541 output array<list<Integer>> omapEqnIncRow;
2542 output array<Integer> omapIncRowEqn;
2543 protected
2544 Integer num_eqs, num_vars, size, num_rows = 0;
2545 BackendDAE.Equation eq;
2546 list<Integer> rowLst;
2547 list<Integer> row, row_indices, imap = {};
2548 list<BackendDAE.AdjacencyMatrixElement> iarr = {};
2549 algorithm
2550 223221 num_eqs := BackendEquation.getNumberOfEquations(inEqns);
2551 223221 num_vars := BackendVariable.varsSize(inVars);
2552 223221 outAdjacencyArrayT := arrayCreate(num_vars, {});
2553 223221 omapEqnIncRow := arrayCreate(num_eqs, {});
2554
2555
2/2
✓ Branch 0 taken 174951 times.
✓ Branch 1 taken 48270 times.
1450306 for idx in 1:num_eqs loop
2556 // Get the equation.
2557 1227085 eq := BackendEquation.get(inEqns, idx);
2558
2559 // Compute the row.
2560 1227085 (rowLst, size) := adjacencyRow(eq, inVars, inIndexType, functionTree, {}, isInitial);
2561 1227085 row := uniqueRow(rowLst);
2562 1227085 row_indices := List.intRange2(num_rows + 1, num_rows + size);
2563 1227085 num_rows := num_rows + size;
2564 1227085 arrayUpdate(omapEqnIncRow, idx, row_indices);
2565 1227085 imap := List.consN(size, idx, imap);
2566
2567 // Put it in the arrays
2568 1227085 iarr := List.consN(size, row, iarr);
2569 1227085 outAdjacencyArrayT := filladjacencyMatrixT(row, row_indices, outAdjacencyArrayT);
2570 end for;
2571
2572 223221 outAdjacencyArray := List.listArrayReverse(iarr);
2573 223221 omapIncRowEqn := List.listArrayReverse(imap);
2574 end adjacencyMatrixDispatchScalar;
2575
2576 protected function filladjacencyMatrixT
2577 "@author: Frenkel TUD 2011-04
2578 inserts the equation numbers"
2579 input BackendDAE.AdjacencyMatrixElement eqns;
2580 input list<Integer> eqnsindxs;
2581 input BackendDAE.AdjacencyMatrixT inAdjacencyArrayT;
2582 output BackendDAE.AdjacencyMatrixT outAdjacencyArrayT = inAdjacencyArrayT;
2583 protected
2584 BackendDAE.AdjacencyMatrixElement row;
2585 list<Integer> ei, eqnsindxsNeg;
2586 algorithm
2587
4/4
✓ Branch 0 taken 3006360 times.
✓ Branch 1 taken 2886857 times.
✓ Branch 2 taken 3006360 times.
✓ Branch 3 taken 2886857 times.
5893217 eqnsindxsNeg := list(intNeg(e) for e in eqnsindxs);
2588
2/2
✓ Branch 0 taken 7909625 times.
✓ Branch 1 taken 2886857 times.
10796482 for v in eqns loop
2589
2/2
✓ Branch 0 taken 304405 times.
✓ Branch 1 taken 7605220 times.
7909625 if v < 0 then
2590 304405 v := intAbs(v);
2591 ei := eqnsindxsNeg;
2592 else
2593 ei := eqnsindxs;
2594 end if;
2595
2596 // Put it in the array.
2597 7909625 row := listAppend(ei, arrayGet(inAdjacencyArrayT, v));
2598 7909625 arrayUpdate(outAdjacencyArrayT, v, row);
2599 end for;
2600 end filladjacencyMatrixT;
2601
2602 public function adjacencyRow
2603 "author: PA
2604 Helper function to adjacencyMatrix. Calculates the indidence row
2605 in the matrix for one equation."
2606 input BackendDAE.Equation inEquation;
2607 input BackendDAE.Variables vars;
2608 input BackendDAE.IndexType inIndexType;
2609 input Option<AvlTreePathFunction.Tree> functionTree;
2610 input list<Integer> iRow;
2611 input Boolean isInitial;
2612 output list<Integer> outIntegerLst;
2613 output Integer rowSize;
2614 protected
2615 list<Integer> whenIntegerLst;
2616 BackendDAE.Equation inlinedEquation;
2617 algorithm
2618 whenIntegerLst := matchcontinue inIndexType
2619 local
2620 BackendDAE.EquationKind kind;
2621 DAE.ComponentRef cr;
2622 Integer i;
2623 list<Integer> varIxs;
2624 case BackendDAE.BASECLOCK_IDX()
2625 algorithm
2626 172462 BackendDAE.EQUATION_ATTRIBUTES(kind = kind) := BackendEquation.getEquationAttributes(inEquation);
2627
2/2
✓ Branch 0 taken 172395 times.
✓ Branch 1 taken 67 times.
172462 BackendDAE.CLOCKED_EQUATION(i) := kind;
2628 67 cr := DAE.CREF_IDENT(BackendDAE.WHENCLK_PRREFIX + intString(i), DAE.T_CLOCK_DEFAULT, {});
2629 67 (_, varIxs) := BackendVariable.getVar(cr, vars);
2630 67 then varIxs;
2631 case BackendDAE.SUBCLOCK_IDX()
2632 algorithm
2633 1230 BackendDAE.EQUATION_ATTRIBUTES(kind = kind) := BackendEquation.getEquationAttributes(inEquation);
2634
2/2
✓ Branch 0 taken 976 times.
✓ Branch 1 taken 254 times.
1230 BackendDAE.CLOCKED_EQUATION(i) := kind;
2635 254 cr := DAE.CREF_IDENT(BackendDAE.WHENCLK_PRREFIX + intString(i), DAE.T_CLOCK_DEFAULT, {});
2636 254 (_, varIxs) := BackendVariable.getVar(cr, vars);
2637 195 then varIxs;
2638 else {};
2639 end matchcontinue;
2640
2641 /* Fix for ticket #5170
2642 Functions with the annotation "InlineAfterIndexReduction" can contain dependencies which are only
2643 used for differentiation purposes and should not be part of the adjacency matrix. Therefore these
2644 are inlined before constructing the adjacency row.
2645 E.g. func(a,b) = a --d/dt--> func_der(a,b) = b
2646 */
2647 2918505 (inlinedEquation,_) := BackendInline.inlineEq(inEquation,(functionTree,{DAE.AFTER_INDEX_RED_INLINE()}));
2648
2649 (outIntegerLst,rowSize) := matchcontinue inlinedEquation
2650 local
2651 list<Integer> lst1,res;
2652 list<Integer> dimsize;
2653 DAE.Exp e1,e2,e,expCref;
2654 list<DAE.Exp> expl;
2655 DAE.ComponentRef cr;
2656 BackendDAE.WhenEquation we;
2657 Integer size;
2658 String eqnstr, str;
2659 list<DAE.Statement> statementLst;
2660 list<list<BackendDAE.Equation>> eqnslst;
2661 list<BackendDAE.Equation> eqns;
2662 BackendDAE.Equation eqn;
2663 list<DAE.ComponentRef> crefLst;
2664 list<BackendDAE.Var> varslst;
2665 list<Integer> p;
2666
2667 // EQUATION
2668 case BackendDAE.EQUATION(exp = e1,scalar = e2)
2669 algorithm
2670 2789316 lst1 := adjacencyRowExp(e1, vars, iRow, functionTree, inIndexType, isInitial);
2671 2789316 res := adjacencyRowExp(e2, vars, lst1, functionTree, inIndexType, isInitial);
2672 2789316 then
2673 (res,1);
2674
2675 // COMPLEX_EQUATION
2676 case BackendDAE.COMPLEX_EQUATION(size=size,left=e1,right=e2)
2677 algorithm
2678 19524 lst1 := adjacencyRowExp(e1, vars, iRow, functionTree, inIndexType, isInitial);
2679 19524 res := adjacencyRowExp(e2, vars, lst1, functionTree, inIndexType, isInitial);
2680 19524 then
2681 (res,size);
2682
2683 // ARRAY_EQUATION
2684 case BackendDAE.ARRAY_EQUATION(dimSize=dimsize,left=e1,right=e2)
2685 algorithm
2686
2/2
✓ Branch 1 taken 21335 times.
✓ Branch 2 taken 238 times.
21573 size := if Flags.isSet(Flags.NF_SCALARIZE) then List.reduce(dimsize, intMul) else 1;
2687 21573 lst1 := adjacencyRowExp(e1, vars, iRow, functionTree, inIndexType, isInitial);
2688 21573 res := adjacencyRowExp(e2, vars, lst1, functionTree, inIndexType, isInitial);
2689 21573 then
2690 (res,size);
2691
2692 // FOR_EQUATION
2693 case BackendDAE.FOR_EQUATION(body = eqn, iter = DAE.CREF(componentRef = DAE.CREF_IDENT(ident = str)))
2694 algorithm
2695 // assume one equation defining a whole array var (no NF_SCALARIZE)
2696 209 eqn := BackendEquation.traverseExpsOfEquation(eqn, function Expression.traverseExpTopDown(func = stripIterSub), str);
2697 209 then
2698 adjacencyRow(eqn, vars, inIndexType, functionTree, iRow, isInitial);
2699
2700 // SOLVED_EQUATION
2701 case BackendDAE.SOLVED_EQUATION(componentRef = cr,exp = e)
2702 algorithm
2703 71751 expCref := Expression.crefExp(cr);
2704 71751 lst1 := adjacencyRowExp(expCref, vars, iRow, functionTree, inIndexType, isInitial);
2705 71751 res := adjacencyRowExp(e, vars, lst1, functionTree, inIndexType, isInitial);
2706 71751 then
2707 (res,1);
2708
2709 // RESIDUAL_EQUATION
2710 case BackendDAE.RESIDUAL_EQUATION(exp = e)
2711 algorithm
2712 ✗ res := adjacencyRowExp(e, vars, iRow, functionTree, inIndexType, isInitial);
2713 ✗ then
2714 (res,1);
2715
2716 // WHEN_EQUATION
2717 case BackendDAE.WHEN_EQUATION(size=size,whenEquation = we)
2718 algorithm
2719 7416 res := adjacencyRowWhen(we, vars, inIndexType, functionTree, iRow, isInitial);
2720 7416 then
2721 (res,size);
2722
2723 // ALGORITHM
2724 case BackendDAE.ALGORITHM(size=size,alg=DAE.ALGORITHM_STMTS(statementLst = statementLst))
2725 algorithm
2726
2/2
✓ Branch 0 taken 5789 times.
✓ Branch 1 taken 2925 times.
14503 res := traverseStmts(statementLst, function adjacencyRowAlgorithm(inVariables = vars,
2727 functionTree = functionTree, inIndexType = inIndexType, isInitial = isInitial), iRow);
2728
2729 /*
2730 If looking for solvability add all discrete output variables, even if they don't occur in the algorithm.
2731 Discrete output variables that do not occur get computed by pre().
2732 Ticket #5659
2733 */
2734 8714 crefLst := CheckModel.algorithmStatementListOutputs(statementLst, DAE.EXPAND()); // expand as we're in an algorithm
2735
2/2
✓ Branch 0 taken 24820 times.
✓ Branch 1 taken 8714 times.
33534 for cr in crefLst loop
2736 try
2737 24820 (varslst, p) := BackendVariable.getVar(cr, vars);
2738 24251 res := adjacencyRowExp1DiscreteOrArray(varslst, p, res);
2739 else
2740 /* Nothing to do, BackendVariable.getVar fails for $START, $PRE, time etc. */
2741 end try;
2742
2/2
✓ Branch 0 taken 654 times.
✓ Branch 1 taken 24166 times.
24820 if vars.hasStartVars then
2743 try
2744 654 (varslst, p) := BackendVariable.getVar(ComponentReference.crefPrefixStart(cr), vars);
2745 ✗ res := adjacencyRowExp1DiscreteOrArray(varslst, p, res);
2746 else
2747 /* Nothing to do, BackendVariable.getVar fails for $START, $PRE, time etc. */
2748 end try;
2749 end if;
2750 end for;
2751 8714 then
2752 (res,size);
2753
2754 /*
2755 special case: initial()
2756 if initial() then ... else ... end if;
2757 only then branch needs to be checked for initialization and else branch otherwise
2758 */
2759 case BackendDAE.IF_EQUATION(conditions={DAE.CALL(path=Absyn.IDENT("initial"))},eqnstrue=eqnslst,eqnsfalse=eqns)
2760 algorithm
2761 ✗ if not isInitial then
2762 // only one condition, therefore the list of lists for "then" only contains one list
2763 ✗ {eqns} := eqnslst;
2764 end if;
2765 ✗ (res,size) := adjacencyRowLst(eqns, vars, inIndexType, functionTree, iRow, isInitial);
2766 then
2767 (res,size);
2768
2769 /*
2770 special case: NEGATED initial()
2771 if not initial() then ... else ... end if;
2772 only else branch needs to be checked for initialization and then branch otherwise
2773 */
2774 case BackendDAE.IF_EQUATION(conditions={DAE.LUNARY(DAE.NOT(), DAE.CALL(path=Absyn.IDENT("initial")))},eqnstrue=eqnslst,eqnsfalse=eqns)
2775 algorithm
2776 ✗ if isInitial then
2777 // only one condition, therefore the list of lists for "then" only contains one list
2778 ✗ {eqns} := eqnslst;
2779 end if;
2780 ✗ (res,size) := adjacencyRowLst(eqns, vars, inIndexType, functionTree, iRow, isInitial);
2781 then
2782 (res,size);
2783
2784 /*
2785 if Equation
2786 ToDo: More checks for stuff like initial()
2787 */
2788 case BackendDAE.IF_EQUATION(conditions=expl,eqnstrue=eqnslst,eqnsfalse=eqns)
2789 algorithm
2790
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 res := adjacencyRow1(expl, adjacencyRowExp, vars, iRow, functionTree, inIndexType, isInitial);
2791 2 res := adjacencyRowLstLst(eqnslst, vars, inIndexType, functionTree, res, isInitial);
2792 2 (res,size) := adjacencyRowLst(eqns, vars, inIndexType, functionTree, res, isInitial);
2793 then
2794 (res,size);
2795
2796 else
2797 algorithm
2798 ✗ eqnstr := BackendDump.equationString(inEquation);
2799 ✗ str := "- BackendDAEUtil.adjacencyRow failed for equation: " + eqnstr;
2800 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
2801 ✗ then
2802 fail();
2803 end matchcontinue;
2804 2918505 outIntegerLst := listAppend(whenIntegerLst, outIntegerLst);
2805 end adjacencyRow;
2806
2807 protected
2808 function stripIterSub
2809 "Strips the last subscript if it is equal to given inIter ident.
2810 This enables incicence analysis for array variables defined in for loops.
2811 author: rfranke"
2812 input DAE.Exp inExp;
2813 input DAE.Ident inIter;
2814 output DAE.Exp outExp;
2815 output Boolean cont;
2816 output DAE.Ident outIter = inIter;
2817 algorithm
2818 (outExp, cont) := match inExp
2819 local
2820 DAE.ComponentRef cr;
2821 DAE.Type ty;
2822 case DAE.CREF(componentRef = cr, ty = ty)
2823 526 then (DAE.CREF(ComponentReference.crefStripIterSub(cr, inIter), ty), false);
2824 else (inExp, true);
2825 end match;
2826 end stripIterSub;
2827
2828 protected function adjacencyRowLst
2829 "author: Frenkel TUD
2830 Helper function to adjacencyMatrix. Calculates the indidence row
2831 in the matrix for if equation."
2832 input list<BackendDAE.Equation> inEquation;
2833 input BackendDAE.Variables inVariables;
2834 input BackendDAE.IndexType inIndexType;
2835 input Option<AvlTreePathFunction.Tree> functionTree;
2836 input list<Integer> inIntegerLst;
2837 input Boolean isInitial;
2838 output list<Integer> outIntegerLst = inIntegerLst;
2839 output Integer rowSize = 0;
2840 protected
2841 Integer size;
2842 algorithm
2843
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 6 times.
13 for eq in inEquation loop
2844 7 (outIntegerLst, size) :=
2845 adjacencyRow(eq, inVariables, inIndexType, functionTree, outIntegerLst, isInitial);
2846 7 rowSize := rowSize + size;
2847 end for;
2848 end adjacencyRowLst;
2849
2850 protected function adjacencyRowLstLst
2851 "author: Frenkel TUD
2852 Helper function to adjacencyMatrix. Calculates the indidence row
2853 in the matrix for if equation."
2854 input list<list<BackendDAE.Equation>> inEquation;
2855 input BackendDAE.Variables inVariables;
2856 input BackendDAE.IndexType inIndexType;
2857 input Option<AvlTreePathFunction.Tree> functionTree;
2858 input list<Integer> inIntegerLst;
2859 input Boolean isInitial;
2860 output list<Integer> outIntegerLst = inIntegerLst;
2861 output Integer rowSize = 0;
2862 protected
2863 Integer size;
2864 algorithm
2865
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for eql in inEquation loop
2866 4 (outIntegerLst, size) := adjacencyRowLst(eql, inVariables, inIndexType,
2867 functionTree, outIntegerLst, isInitial);
2868 4 rowSize := rowSize + size;
2869 end for;
2870 end adjacencyRowLstLst;
2871
2872 protected function adjacencyRowWhen
2873 "Helper function to adjacencyMatrix. Calculates the indidence row
2874 in the matrix for a when equation."
2875 input BackendDAE.WhenEquation inEquation;
2876 input BackendDAE.Variables inVariables;
2877 input BackendDAE.IndexType inIndexType;
2878 input Option<AvlTreePathFunction.Tree> functionTree;
2879 input list<Integer> inRow;
2880 input Boolean isInitial;
2881 output list<Integer> outRow;
2882 algorithm
2883 outRow := match inEquation
2884 local
2885 DAE.Exp cond;
2886 BackendDAE.WhenEquation elsewe;
2887 Option<BackendDAE.WhenEquation> oelsewe;
2888 list<BackendDAE.WhenOperator> whenStmtLst;
2889
2890 case BackendDAE.WHEN_STMTS(condition = cond, whenStmtLst = whenStmtLst, elsewhenPart = oelsewe)
2891 algorithm
2892 7557 outRow := adjacencyRowExp(cond, inVariables, inRow, functionTree, inIndexType, isInitial);
2893 7557 outRow := adjacencyRowWhenOps(whenStmtLst, inVariables, inIndexType, functionTree, outRow, isInitial);
2894
2895
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7557 times.
✓ Branch 2 taken 141 times.
✓ Branch 3 taken 7416 times.
7557 if isSome(oelsewe) then
2896 141 SOME(elsewe) := oelsewe;
2897 outRow := adjacencyRowWhen(elsewe, inVariables, inIndexType, functionTree, outRow, isInitial);
2898 end if;
2899 then outRow;
2900 end match;
2901 end adjacencyRowWhen;
2902
2903 protected function adjacencyRowWhenOps
2904 "Helper function to adjacencyMatrix. Calculates the indidence row
2905 in the matrix for a when equation stmts."
2906 input list<BackendDAE.WhenOperator> inWhenOps;
2907 input BackendDAE.Variables inVariables;
2908 input BackendDAE.IndexType inIndexType;
2909 input Option<AvlTreePathFunction.Tree> functionTree;
2910 input list<Integer> inRow;
2911 input Boolean isInitial;
2912 output list<Integer> outRow;
2913 algorithm
2914 outRow := match inWhenOps
2915 local
2916 DAE.Exp e1, e2;
2917 DAE.ComponentRef cr;
2918 list<BackendDAE.WhenOperator> rest;
2919
2920 case {} then inRow;
2921 case BackendDAE.ASSIGN(left = DAE.CREF(componentRef = DAE.WILD()), right = e2)::rest
2922 algorithm
2923 ✗ outRow := adjacencyRowExp(e2, inVariables, inRow, functionTree, inIndexType, isInitial);
2924 ✗ outRow := adjacencyRowWhenOps(rest, inVariables, inIndexType, functionTree, outRow, isInitial);
2925 then outRow;
2926
2927 case BackendDAE.ASSIGN(left = e1, right = e2)::rest
2928 algorithm
2929 //e1 = Expression.crefExp(cr);
2930 7441 outRow := adjacencyRowExp(e1, inVariables, inRow, functionTree, inIndexType, isInitial);
2931 7441 outRow := adjacencyRowExp(e2, inVariables, outRow, functionTree, inIndexType, isInitial);
2932 7441 outRow := adjacencyRowWhenOps(rest, inVariables, inIndexType, functionTree, outRow, isInitial);
2933 then outRow;
2934
2935 case BackendDAE.REINIT(stateVar = cr, value = e2)::rest
2936 algorithm
2937 72 e1 := Expression.crefExp(cr);
2938 72 outRow := adjacencyRowExp(e1, inVariables, inRow, functionTree, inIndexType, isInitial);
2939 72 outRow := adjacencyRowExp(e2, inVariables, outRow, functionTree, inIndexType, isInitial);
2940 72 outRow := adjacencyRowWhenOps(rest, inVariables, inIndexType, functionTree, outRow, isInitial);
2941 then outRow;
2942 case BackendDAE.ASSERT(condition = e1, message = e2)::rest
2943 algorithm
2944 14 outRow := adjacencyRowExp(e1, inVariables, inRow, functionTree, inIndexType, isInitial);
2945 14 outRow := adjacencyRowExp(e2, inVariables, outRow, functionTree, inIndexType, isInitial);
2946 14 outRow := adjacencyRowWhenOps(rest, inVariables, inIndexType, functionTree, outRow, isInitial);
2947 then outRow;
2948 case BackendDAE.TERMINATE(message = e1)::rest
2949 algorithm
2950 14 outRow := adjacencyRowExp(e1, inVariables, inRow, functionTree, inIndexType, isInitial);
2951 14 outRow := adjacencyRowWhenOps(rest, inVariables, inIndexType, functionTree, outRow, isInitial);
2952 then outRow;
2953 case BackendDAE.NORETCALL(exp = e1)::rest
2954 algorithm
2955 16 outRow := adjacencyRowExp(e1, inVariables, inRow, functionTree, inIndexType, isInitial);
2956 16 outRow := adjacencyRowWhenOps(rest, inVariables, inIndexType, functionTree, outRow, isInitial);
2957 then outRow;
2958 end match;
2959 end adjacencyRowWhenOps;
2960
2961 protected function adjacencyRowAlgorithm
2962 input DAE.Exp exp;
2963 input output list<Integer> row;
2964 input BackendDAE.Variables inVariables;
2965 input Option<AvlTreePathFunction.Tree> functionTree;
2966 input BackendDAE.IndexType inIndexType;
2967 input Boolean isInitial;
2968 algorithm
2969 85572 row := adjacencyRowExp(exp, inVariables, row, functionTree, inIndexType, isInitial);
2970 end adjacencyRowAlgorithm;
2971
2972 public function adjacencyRow1
2973 "Tail recursive implementation."
2974 input list<Type_a> inList;
2975 input FuncType inFunc;
2976 input Type_b inArg;
2977 input Type_c inArg1;
2978 input Type_d inArg2;
2979 input Type_e inArg3;
2980 input Type_f inArg4;
2981 output Type_c outArg1;
2982
2983 replaceable type Type_a subtypeof Any;
2984 replaceable type Type_b subtypeof Any;
2985 replaceable type Type_c subtypeof Any;
2986 replaceable type Type_d subtypeof Any;
2987 replaceable type Type_e subtypeof Any;
2988 replaceable type Type_f subtypeof Any;
2989
2990 partial function FuncType
2991 input Type_a inElem;
2992 input Type_b inArg;
2993 input Type_c inArg1;
2994 input Type_d inArg2;
2995 input Type_e inArg3;
2996 input Type_f inArg4;
2997 output Type_c outArg1;
2998 end FuncType;
2999 algorithm
3000 outArg1 := match inList
3001 local
3002 Type_a e1;
3003 list<Type_a> rest_e1;
3004 Type_c res,res1;
3005 case {} then inArg1;
3006 case e1::rest_e1
3007 algorithm
3008
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 res := inFunc(e1, inArg, inArg1, inArg2, inArg3, inArg4);
3009 4 res1 := adjacencyRow1(rest_e1, inFunc, inArg, res, inArg2, inArg3, inArg4);
3010 then
3011 res1;
3012 end match;
3013 end adjacencyRow1;
3014
3015 public function adjacencyRowExp "author: PA
3016 Helper function to adjacencyRow, investigates expressions for variables,
3017 returning variable indexes."
3018 input DAE.Exp inExp;
3019 input BackendDAE.Variables inVariables;
3020 input list<Integer> inIntegerLst;
3021 input Option<AvlTreePathFunction.Tree> functionTree;
3022 input BackendDAE.IndexType inIndexType;
3023 input Boolean isInitial;
3024 output list<Integer> outIntegerLst;
3025 algorithm
3026 outIntegerLst := match inIndexType
3027 local
3028 list<Integer> vallst, outLst;
3029 Integer key;
3030
3031 case BackendDAE.SPARSE() algorithm
3032
2/2
✓ Branch 0 taken 251035 times.
✓ Branch 1 taken 14240 times.
516310 (_, (_, vallst, _)) := Expression.traverseExpTopDown(inExp, traversingadjacencyRowExpFinderwithInput, (inVariables, inIntegerLst, isInitial));
3033 then vallst;
3034
3035 case BackendDAE.SOLVABLE() algorithm
3036
2/2
✓ Branch 0 taken 809942 times.
✓ Branch 1 taken 655965 times.
2275849 (_, (vallst, _)) := Expression.traverseExpTopDown(inExp, function traversingadjacencyRowExpSolvableFinder(vars = inVariables, isInitial = isInitial, ofunctionTree = functionTree), (inIntegerLst, AvlSetPath.EMPTY()));
3037 then vallst;
3038
3039 case BackendDAE.BASECLOCK_IDX() algorithm
3040
1/2
✓ Branch 0 taken 349671 times.
✗ Branch 1 not taken.
699342 (_, (_, vallst, _)) := Expression.traverseExpTopDown(inExp, traversingAdjacencyRowExpFinderBaseClock, (inVariables, inIntegerLst, isInitial));
3041 then vallst;
3042
3043 case BackendDAE.SUBCLOCK_IDX() algorithm
3044
1/2
✓ Branch 0 taken 2444 times.
✗ Branch 1 not taken.
4888 (_, (_, vallst, _)) := Expression.traverseExpTopDown(inExp, traversingAdjacencyRowExpFinderSubClock, (inVariables, inIntegerLst, isInitial));
3045 then vallst;
3046
3047 // The row is absolute already; only what this expression adds needs intAbs.
3048 case BackendDAE.ABSOLUTE() algorithm
3049
2/2
✓ Branch 0 taken 544316 times.
✓ Branch 1 taken 303321 times.
1391953 (_, vallst) := Expression.traverseExpTopDown(inExp, function traversingadjacencyRowExpFinder(vars = inVariables, isInitial = isInitial), {});
3050 outLst := inIntegerLst;
3051
2/2
✓ Branch 1 taken 1503800 times.
✓ Branch 2 taken 847637 times.
2351437 for key in listReverse(vallst) loop
3052 1503800 outLst := intAbs(key) :: outLst;
3053 end for;
3054 then outLst;
3055
3056 else algorithm
3057
2/2
✓ Branch 0 taken 2254831 times.
✓ Branch 1 taken 816180 times.
5325842 (_, vallst) := Expression.traverseExpTopDown(inExp, function traversingadjacencyRowExpFinder(vars = inVariables, isInitial = isInitial), inIntegerLst);
3058 3071011 then vallst;
3059 end match;
3060 end adjacencyRowExp;
3061
3062 public function traversingadjacencyRowExpSolvableFinder "Helper for statesAndVarsExp.
3063 Bind vars, isInitial and ofunctionTree by partial application; only the row
3064 and the visited paths are threaded through the traversal."
3065 input DAE.Exp inExp;
3066 input tuple<list<Integer>, AvlSetPath.Tree> inTpl;
3067 input BackendDAE.Variables vars;
3068 input Boolean isInitial;
3069 input Option<AvlTreePathFunction.Tree> ofunctionTree;
3070 output DAE.Exp outExp;
3071 output Boolean cont;
3072 output tuple<list<Integer>, AvlSetPath.Tree> outTpl;
3073 algorithm
3074 (outExp, cont, outTpl) := match (inExp, inTpl)
3075 local
3076 list<Integer> p, p2;
3077 list<Integer> pa;
3078 DAE.ComponentRef cr;
3079 DAE.Exp e, e1, e2;
3080 list<BackendDAE.Var> varslst;
3081 Boolean b, b1, b2;
3082 list<DAE.Exp> explst;
3083 Integer i;
3084 list<DAE.ComponentRef> crlst;
3085 tuple<list<Integer>, AvlSetPath.Tree> tpl;
3086 Integer diffindx;
3087 list<DAE.Subscript> subs;
3088 AvlSetPath.Tree visitedPaths;
3089 String idn;
3090
3091 case (DAE.LBINARY(), tpl)
3092 4165 then (inExp, false, tpl);
3093
3094 case (DAE.RELATION(), tpl)
3095 3989 then (inExp, false, tpl);
3096
3097 case (DAE.IFEXP(), tpl)
3098 algorithm
3099 try
3100 61906 (e, b, tpl) := traversingadjacencyRowIfExpSolvableFinder(inExp, tpl, vars, isInitial, ofunctionTree);
3101 else
3102 ✗ (e, b, tpl) := (inExp, true, inTpl);
3103 end try;
3104 61906 then (e, b, tpl);
3105
3106 case (DAE.RANGE(), tpl)
3107 2116 then (inExp, false, tpl);
3108
3109 // a range subscript, else a constant index into the array expression
3110 case (DAE.ASUB(exp=e1, sub=subs), (pa, visitedPaths))
3111 algorithm
3112 try
3113
2/2
✓ Branch 0 taken 1725 times.
✓ Branch 1 taken 10 times.
1735 DAE.CREF(componentRef=cr) := e1;
3114 10 explst := List.map(subs, Expression.getSubscriptExp);
3115
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
10 {e2 as DAE.RANGE()} := ExpressionSimplify.simplifyList(explst);
3116 ✗ crlst := list(ComponentReference.subscriptCref(cr, {DAE.INDEX(e)}) for e in extendRange(e2, vars));
3117 ✗ (varslst, p) := BackendVariable.getVarLst(crlst, vars);
3118 ✗ pa := adjacencyRowExp1(varslst, p, pa, 0);
3119 ✗ tpl := (pa, visitedPaths);
3120 ✗ b := false;
3121 else
3122 try
3123
5/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1735 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1735 times.
✓ Branch 4 taken 1317 times.
✓ Branch 5 taken 418 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 418 times.
1735 {DAE.INDEX(DAE.ICONST(i))} := subs;
3124 418 e1 := Expression.nthArrayExp(e1, i);
3125
2/2
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 81 times.
755 (_, tpl) := Expression.traverseExpTopDown(e1, function traversingadjacencyRowExpSolvableFinder(vars = vars, isInitial = isInitial, ofunctionTree = ofunctionTree), inTpl);
3126 418 b := false;
3127 else
3128 1317 (b, tpl) := (true, inTpl);
3129 end try;
3130 end try;
3131 1735 then (inExp, b, tpl);
3132
3133 case (DAE.TSUB(exp=e1), tpl)
3134 algorithm
3135 try
3136
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 53 times.
171 (_, tpl) := Expression.traverseExpTopDown(e1, function traversingadjacencyRowExpSolvableFinder(vars = vars, isInitial = isInitial, ofunctionTree = ofunctionTree), tpl);
3137 112 b := false;
3138 else
3139 ✗ (b, tpl) := (true, inTpl);
3140 end try;
3141 112 then (inExp, b, tpl);
3142
3143 // cref and $START.cref
3144 case (DAE.CREF(componentRef=cr), (pa, visitedPaths))
3145 algorithm
3146 try
3147 3136978 pa := adjacencyRowCref(cr, vars, pa, 0);
3148
2/2
✓ Branch 0 taken 53304 times.
✓ Branch 1 taken 2405574 times.
2458878 if vars.hasStartVars then
3149 try
3150 53304 (varslst, _) := BackendVariable.getVar(cr, vars);
3151 53304 (_, p2) := BackendVariable.getVar(ComponentReference.crefPrefixStart(cr), vars);
3152 3246 pa := adjacencyRowExp1(varslst, p2, pa, 0);
3153 else
3154 end try;
3155 end if;
3156 2458878 tpl := (pa, visitedPaths);
3157 else
3158 678100 tpl := inTpl;
3159 end try;
3160 3136978 then (inExp, true, tpl);
3161
3162 // der(cr), and der(cr, n) for higher derivatives during index reduction
3163 case (DAE.CALL(path=Absyn.IDENT(name="der"), expLst=DAE.CREF(componentRef=cr)::explst), (pa, visitedPaths))
3164 algorithm
3165 try
3166 diffindx := match explst
3167 case {} then 1;
3168 case {DAE.ICONST(diffindx)} then diffindx;
3169 end match;
3170 79617 pa := adjacencyRowCref(cr, vars, pa, diffindx);
3171 72391 (e, b, tpl) := (inExp, false, (pa, visitedPaths));
3172 else
3173 7226 (e, b, tpl) := traversingadjacencyRowSolvableCall(inExp, inTpl, vars, isInitial, ofunctionTree);
3174 end try;
3175 79617 then (e, b, tpl);
3176
3177 /* pre(v) is considered a known variable */
3178 /* previous(v) is considered a known variable */
3179 case (DAE.CALL(path=Absyn.IDENT(name=idn)), tpl) guard idn=="pre" or idn=="previous"
3180 4108 then (inExp, false, tpl);
3181
3182 /* delay(...) can be used to break algebraic loops given some solver options */
3183 case (DAE.CALL(path=Absyn.IDENT(name="delay"), expLst = {_, _, e1, e2}), tpl)
3184 algorithm
3185 try
3186
2/4
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 55 times.
55 b := not (Flags.getConfigBool(Flags.DELAY_BREAK_LOOP) and ExpressionBasics.expEqual(e1, e2));
3187 e := inExp;
3188 else
3189 ✗ (e, b, tpl) := traversingadjacencyRowSolvableCall(inExp, inTpl, vars, isInitial, ofunctionTree);
3190 end try;
3191 55 then (e, b, tpl);
3192
3193 // homotopy operator for simulation system
3194 case (DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst = {e1, _}), _) guard not isInitial
3195 algorithm
3196 try
3197 1210 (e, b, tpl) := traversingadjacencyRowExpSolvableFinder(e1, inTpl, vars, isInitial, ofunctionTree);
3198 else
3199 ✗ (e, b, tpl) := traversingadjacencyRowSolvableCall(inExp, inTpl, vars, isInitial, ofunctionTree);
3200 end try;
3201 1210 then (e, b, tpl);
3202
3203 // homotopy operator for initialization system
3204 case (DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst = {e1, e2}), _) guard isInitial
3205 algorithm
3206 try
3207 880 (_, b1, tpl) := traversingadjacencyRowExpSolvableFinder(e1, inTpl, vars, isInitial, ofunctionTree);
3208 880 (_, b2, tpl) := traversingadjacencyRowExpSolvableFinder(e2, tpl, vars, isInitial, ofunctionTree);
3209
3/4
✓ Branch 0 taken 833 times.
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 833 times.
927 (e, b) := (inExp, b1 and b2);
3210 else
3211 ✗ (e, b, tpl) := traversingadjacencyRowSolvableCall(inExp, inTpl, vars, isInitial, ofunctionTree);
3212 end try;
3213 880 then (e, b, tpl);
3214
3215 // only traverse position and direction for spatialDistribution, not the inputs!
3216 case (DAE.CALL(path=Absyn.IDENT(name="spatialDistribution"), expLst = {_, _, _, e1, e2, _, _}), _)
3217 algorithm
3218 try
3219 45 (_, _, tpl) := traversingadjacencyRowExpSolvableFinder(e2, inTpl, vars, isInitial, ofunctionTree);
3220 45 (e, b, tpl) := traversingadjacencyRowExpSolvableFinder(e1, tpl, vars, isInitial, ofunctionTree);
3221 else
3222 ✗ (e, b, tpl) := traversingadjacencyRowSolvableCall(inExp, inTpl, vars, isInitial, ofunctionTree);
3223 end try;
3224 45 then (e, b, tpl);
3225
3226 case (DAE.CALL(path=Absyn.IDENT()), _)
3227 87013 then traversingadjacencyRowSolvableCall(inExp, inTpl, vars, isInitial, ofunctionTree);
3228
3229 6244912 else (inExp, true, inTpl);
3230 end match;
3231 end traversingadjacencyRowExpSolvableFinder;
3232
3233 protected function traversingadjacencyRowSolvableCall
3234 "Uses the inlined function to analyze the occurring variables of a call,
3235 else continues into its arguments."
3236 input DAE.Exp inExp;
3237 input tuple<list<Integer>, AvlSetPath.Tree> inTpl;
3238 input BackendDAE.Variables vars;
3239 input Boolean isInitial;
3240 input Option<AvlTreePathFunction.Tree> ofunctionTree;
3241 output DAE.Exp outExp = inExp;
3242 output Boolean cont;
3243 output tuple<list<Integer>, AvlSetPath.Tree> outTpl;
3244 protected
3245 list<Integer> pa;
3246 AvlSetPath.Tree visitedPaths;
3247 AvlTreePathFunction.Tree functionTree;
3248 Absyn.Path path;
3249 DAE.Exp e1;
3250 algorithm
3251 try
3252
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 94239 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 94239 times.
94239 DAE.CALL(path = path as Absyn.IDENT()) := inExp;
3253 94239 (pa, visitedPaths) := inTpl;
3254
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 94239 times.
✓ Branch 2 taken 1323 times.
✓ Branch 3 taken 92916 times.
94239 SOME(functionTree) := ofunctionTree;
3255
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 92916 times.
92916 false := AvlSetPath.hasKey(visitedPaths, path);
3256 92916 (e1,_) := Inline.forceInlineCall(inExp, {}, (SOME(functionTree), {DAE.NORM_INLINE(),DAE.DEFAULT_INLINE()}));
3257
2/2
✓ Branch 0 taken 92783 times.
✓ Branch 1 taken 133 times.
92916 false := referenceEq(inExp, e1);
3258
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 67 times.
199 (_, outTpl) := Expression.traverseExpTopDown(e1, function traversingadjacencyRowExpSolvableFinder(vars = vars, isInitial = isInitial, ofunctionTree = ofunctionTree), (pa, AvlSetPath.add(visitedPaths, path)));
3259 cont := false;
3260 else
3261 94106 (cont, outTpl) := (true, inTpl);
3262 end try;
3263 end traversingadjacencyRowSolvableCall;
3264
3265 protected function traversingadjacencyRowIfExpSolvableFinder
3266 "author: kabdelhak FHB 2020-01
3267 Checks if condition for special treatment, helper for only traversingadjacencyRowExpSolvableFinder.
3268 special treatment for inital() condition.
3269 Ticket: #5795
3270 ToDo: inside more complex expression? IF_EQUATION?"
3271 input output DAE.Exp e;
3272 output Boolean cont = false; // always false, just for convenience
3273 input output tuple<list<Integer>, AvlSetPath.Tree> tpl;
3274 input BackendDAE.Variables vars;
3275 input Boolean isInitial;
3276 input Option<AvlTreePathFunction.Tree> ofunctionTree;
3277 algorithm
3278 tpl := matchcontinue e
3279 local
3280 DAE.Exp expCond, expThen, expElse;
3281 Boolean conditionTrue;
3282 case DAE.IFEXP(expCond = expCond, expThen = expThen, expElse = expElse) guard(Expression.containsInitialCall(expCond))
3283 algorithm
3284 conditionTrue := match expCond
3285 case DAE.CALL(path=Absyn.IDENT("initial")) then isInitial;
3286 ✗ case DAE.LUNARY(operator = DAE.NOT(), exp = DAE.CALL(path=Absyn.IDENT("initial"))) then not isInitial;
3287 else fail(); // Lack of information, do not consider it as an initial call and traverse all branches
3288 end match;
3289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
68 if conditionTrue then
3290 ✗ (_, tpl) := Expression.traverseExpTopDown(expThen, function traversingadjacencyRowExpSolvableFinder(vars = vars, isInitial = isInitial, ofunctionTree = ofunctionTree), tpl);
3291 else
3292
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
136 (_, tpl) := Expression.traverseExpTopDown(expElse, function traversingadjacencyRowExpSolvableFinder(vars = vars, isInitial = isInitial, ofunctionTree = ofunctionTree), tpl);
3293 end if;
3294 68 then tpl;
3295 case DAE.IFEXP(expCond = expCond, expThen = expThen, expElse = expElse)
3296 algorithm
3297 /* check if condition can be simplified to true or false to make it more robust against non-simplified expressions */
3298 61838 expCond := simplifyIfCondCached(expCond);
3299 tpl := match expCond
3300 case DAE.BCONST(true) algorithm
3301
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 108 times.
164 (_,tpl) := Expression.traverseExpTopDown(expThen, function traversingadjacencyRowExpSolvableFinder(vars = vars, isInitial = isInitial, ofunctionTree = ofunctionTree), tpl);
3302 136 then tpl;
3303 case DAE.BCONST(false) algorithm
3304
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 45 times.
157 (_,tpl) := Expression.traverseExpTopDown(expElse, function traversingadjacencyRowExpSolvableFinder(vars = vars, isInitial = isInitial, ofunctionTree = ofunctionTree), tpl);
3305 101 then tpl;
3306 else algorithm
3307
2/2
✓ Branch 0 taken 38345 times.
✓ Branch 1 taken 23256 times.
99946 (_, tpl) := Expression.traverseExpTopDown(expThen, function traversingadjacencyRowExpSolvableFinder(vars = vars, isInitial = isInitial, ofunctionTree = ofunctionTree), tpl);
3308 61601 (_, tpl) := Expression.traverseExpTopDown(expElse, function traversingadjacencyRowExpSolvableFinder(vars = vars, isInitial = isInitial, ofunctionTree = ofunctionTree), tpl);
3309 61601 then tpl;
3310 end match;
3311 then tpl;
3312 else
3313 algorithm
3314 ✗ if Flags.isSet(Flags.FAILTRACE) then
3315 ✗ Error.addMessage(Error.GENERIC_ELAB_EXPRESSION, {"[BackendDAEUtil.traversingadjacencyRowIfExpSolvableFinder]: " + ExpressionDump.dumpExpStr(e, 0) + ": If-Expression could not be evaluated."});
3316 end if;
3317 ✗ then fail();
3318 end matchcontinue;
3319 end traversingadjacencyRowIfExpSolvableFinder;
3320
3321 protected function traversingadjacencyRowIfExp
3322 "author: kabdelhak FHB 2020-01
3323 Checks if condition for special treatment, helper for all traversingadjacencyRowExp
3324 functions except traversingadjacencyRowExpSolvableFinder.
3325 special treatment for inital() condition.
3326 Ticket: #5795
3327 ToDo: inside more complex expression? IF_EQUATION?"
3328 input output DAE.Exp e;
3329 output Boolean cont = false; // always false, just for convenience
3330 input output Acc acc;
3331 input Boolean isInitial;
3332 input traverserFunction traFunc;
3333 replaceable type Acc subtypeof Any;
3334 partial function traverserFunction
3335 input output DAE.Exp exp;
3336 output Boolean cont;
3337 input output Acc acc;
3338 end traverserFunction;
3339 algorithm
3340 acc := matchcontinue e
3341 local
3342 DAE.Exp expCond, expThen, expElse;
3343 Boolean conditionTrue;
3344 case DAE.IFEXP(expCond = expCond, expThen = expThen, expElse = expElse) guard(Expression.containsInitialCall(expCond))
3345 algorithm
3346 conditionTrue := match expCond
3347 case DAE.CALL(path=Absyn.IDENT("initial")) then isInitial;
3348 ✗ case DAE.LUNARY(operator = DAE.NOT(), exp = DAE.CALL(path=Absyn.IDENT("initial"))) then not isInitial;
3349 else fail(); // Lack of information, do not consider it as an initial call and traverse all branches
3350 end match;
3351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 120 times.
120 if conditionTrue then
3352 ✗ (_, acc) := Expression.traverseExpTopDown(expThen, traFunc, acc);
3353 else
3354 120 (_, acc) := Expression.traverseExpTopDown(expElse, traFunc, acc);
3355 end if;
3356 120 then acc;
3357 case DAE.IFEXP(expCond = expCond, expThen = expThen, expElse = expElse)
3358 algorithm
3359 /* check if condition can be simplified to true or false to make it more robust against non-simplified expressions */
3360 143999 expCond := simplifyIfCondCached(expCond);
3361 acc := match expCond
3362 case DAE.BCONST(true) algorithm
3363 613 (_,acc) := Expression.traverseExpTopDown(expThen, traFunc, acc);
3364 613 then acc;
3365 case DAE.BCONST(false) algorithm
3366 710 (_,acc) := Expression.traverseExpTopDown(expElse, traFunc, acc);
3367 710 then acc;
3368 else algorithm
3369 142676 (_, acc) := Expression.traverseExpTopDown(expCond, traFunc, acc);
3370 142676 (_, acc) := Expression.traverseExpTopDown(expThen, traFunc, acc);
3371 142676 (_, acc) := Expression.traverseExpTopDown(expElse, traFunc, acc);
3372 142676 then acc;
3373 end match;
3374 then acc;
3375 else
3376 algorithm
3377 ✗ if Flags.isSet(Flags.FAILTRACE) then
3378 ✗ Error.addMessage(Error.GENERIC_ELAB_EXPRESSION, {"[BackendDAEUtil.traversingadjacencyRowIfExp]: " + ExpressionDump.dumpExpStr(e, 0) + ": If-Expression could not be evaluated."});
3379 end if;
3380 ✗ then fail();
3381 end matchcontinue;
3382 end traversingadjacencyRowIfExp;
3383
3384 protected function simplifyIfCondCached
3385 "The same if-conditions are simplified in every adjacency row of every
3386 matrix build (thousands per translation); cleared in getSolvedSystem."
3387 input DAE.Exp cond;
3388 output DAE.Exp simplified;
3389 protected
3390 Option<HashTableExpToExp.HashTable> opt;
3391 HashTableExpToExp.HashTable ht;
3392 algorithm
3393 211416 opt := getGlobalRoot(Global.adjacencyIfCondCache);
3394 ht := match opt
3395 case SOME(ht) then ht;
3396 374 else HashTableExpToExp.emptyHashTableSized(1013);
3397 end match;
3398 try
3399 211416 simplified := BaseHashTable.get(cond, ht);
3400 else
3401 6480 simplified := ExpressionSimplify.simplify(cond);
3402 6480 ht := BaseHashTable.add((cond, simplified), ht);
3403 6480 setGlobalRoot(Global.adjacencyIfCondCache, SOME(ht));
3404 end try;
3405 end simplifyIfCondCached;
3406
3407 protected function traversingAdjacencyRowIfExpEnhanced
3408 "author: kabdelhak FHB 2020-01
3409 Checks if condition for special treatment, helper for traversingAdjacencyRowExpSolvableEnhancedFinder.
3410 special treatment for initial() condition.
3411 Ticket: #5795
3412 ToDo: inside more complex expression?"
3413 input output DAE.Exp e;
3414 output Boolean cont = false; // always false, just for convenience
3415 input output tuple<BackendDAE.Variables, Boolean, Boolean, Integer, array<Integer>, list<Integer>> tpl;
3416 input traverserFunction traFunc;
3417 partial function traverserFunction
3418 input output DAE.Exp exp;
3419 output Boolean cont;
3420 input output tuple<BackendDAE.Variables, Boolean, Boolean, Integer, array<Integer>, list<Integer>> tpl;
3421 end traverserFunction;
3422 algorithm
3423 tpl := matchcontinue e
3424 local
3425 DAE.Exp expCond, expThen, expElse;
3426 Boolean isInitial, conditionTrue, bs;
3427 BackendDAE.Variables vars;
3428 Integer it, mark;
3429 array<Integer> at, rowmark;
3430 list<Integer> pa;
3431 BinaryTree.BinTree bt;
3432 case DAE.IFEXP(expCond = expCond, expThen = expThen, expElse = expElse) guard(Expression.containsInitialCall(expCond))
3433 algorithm
3434 ✗ (_, _, isInitial, _, _, _) := tpl;
3435 conditionTrue := match expCond
3436 case DAE.CALL(path=Absyn.IDENT("initial")) then isInitial;
3437 ✗ case DAE.LUNARY(operator = DAE.NOT(), exp = DAE.CALL(path=Absyn.IDENT("initial"))) then not isInitial;
3438 else fail(); // Lack of information, do not consider it as an initial call and traverse all branches
3439 end match;
3440 ✗ if conditionTrue then
3441 ✗ (_, tpl) := Expression.traverseExpTopDown(expThen, traFunc, tpl);
3442 else
3443 ✗ (_, tpl) := Expression.traverseExpTopDown(expElse, traFunc, tpl);
3444 end if;
3445 ✗ then tpl;
3446 case DAE.IFEXP(expCond = expCond, expThen = expThen, expElse = expElse)
3447 algorithm
3448 /* check if condition can be simplified to true or false to make it more robust against non-simplified expressions */
3449 5579 expCond := simplifyIfCondCached(expCond);
3450 tpl := match expCond
3451 case DAE.BCONST(true) algorithm
3452 ✗ (_, tpl) := Expression.traverseExpTopDown(expThen, traFunc, tpl);
3453 ✗ then tpl;
3454 case DAE.BCONST(false) algorithm
3455 ✗ (_, tpl) := Expression.traverseExpTopDown(expElse, traFunc, tpl);
3456 ✗ then tpl;
3457 else algorithm
3458
2/2
✓ Branch 0 taken 1751 times.
✓ Branch 1 taken 3828 times.
5579 (vars, bs, isInitial, it, at, pa) := tpl;
3459 mark := it;
3460 rowmark := at;
3461
3/4
✓ Branch 0 taken 1751 times.
✓ Branch 1 taken 3828 times.
✓ Branch 2 taken 5579 times.
✗ Branch 3 not taken.
12909 (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(expThen, traFunc, (vars, bs, isInitial, it, at, pa));
3462 5579 (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(expElse, traFunc, (vars, bs, isInitial, it, at, pa));
3463 5579 (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(expCond, traFunc, (vars, true, isInitial, it, at, pa));
3464 // mark all vars which are not in all branches unsolvable
3465 5579 (_, bt) := Expression.traverseExpTopDown(e, getIfExpBranchVarOccurency, BinaryTree.emptyBinTree);
3466 5579 Expression.traverseExpTopDown(expThen, markBranchVars, (mark, rowmark, vars, bt));
3467 5579 Expression.traverseExpTopDown(expElse, markBranchVars, (mark, rowmark, vars, bt));
3468 5579 then (vars, bs, isInitial, it, at, pa);
3469 end match;
3470 then tpl;
3471 else
3472 algorithm
3473 ✗ if Flags.isSet(Flags.FAILTRACE) then
3474 ✗ Error.addMessage(Error.GENERIC_ELAB_EXPRESSION, {"[BackendDAEUtil.traversingAdjacencyRowIfExpEnhanced]: " + ExpressionDump.dumpExpStr(e, 0) + ": If-Expression could not be evaluated."});
3475 end if;
3476 ✗ then fail();
3477 end matchcontinue;
3478 end traversingAdjacencyRowIfExpEnhanced;
3479
3480 public function traversingAdjacencyRowExpFinderBaseClock "author: lochel
3481 This is used for base-clock partitioning."
3482 input DAE.Exp inExp;
3483 input tuple<BackendDAE.Variables, list<Integer>, Boolean> inTpl;
3484 output DAE.Exp outExp;
3485 output Boolean cont;
3486 output tuple<BackendDAE.Variables, list<Integer>, Boolean> outTpl;
3487 algorithm
3488 (outExp,cont,outTpl) := matchcontinue (inExp,inTpl)
3489 local
3490 list<Integer> p, p2;
3491 list<Integer> pa;
3492 DAE.ComponentRef cr;
3493 BackendDAE.Variables vars;
3494 DAE.Exp e;
3495 Boolean isInitial;
3496 tuple<BackendDAE.Variables,list<Integer>, Boolean> tpl;
3497
3498 case (DAE.CREF(componentRef=cr), (vars, pa, isInitial))
3499 algorithm
3500 552164 (_, p) := BackendVariable.getVar(cr, vars);
3501 497507 pa := listAppend(p, pa);
3502
3503
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 497507 times.
497507 if vars.hasStartVars then
3504 try
3505 ✗ (_, p2) := BackendVariable.getVar(ComponentReference.crefPrefixStart(cr), vars);
3506 ✗ pa := listAppend(p2, pa);
3507 else
3508 end try;
3509 end if;
3510
1/2
✓ Branch 0 taken 497507 times.
✗ Branch 1 not taken.
995014 then (inExp, true, (vars, pa, isInitial));
3511
3512 case (DAE.CALL(path=Absyn.IDENT(name="sample"), expLst={_, e}), _)
3513 algorithm
3514 89 (_, outTpl) := Expression.traverseExpTopDown(e, traversingAdjacencyRowExpFinderBaseClock, inTpl);
3515 89 then (inExp, false, outTpl);
3516
3517 case (DAE.CLKCONST(DAE.SOLVER_CLOCK(e)), _)
3518 algorithm
3519 2 (_, outTpl) := Expression.traverseExpTopDown(e, traversingAdjacencyRowExpFinderBaseClock, inTpl);
3520 2 then (inExp, true, outTpl);
3521
3522 case (DAE.CLKCONST(DAE.EVENT_CLOCK()), _)
3523 11 then (inExp, false, inTpl);
3524
3525 case (DAE.CALL(path=Absyn.IDENT(name="hold")), _)
3526 15 then (inExp, false, inTpl);
3527
3528 case (DAE.IFEXP(), tpl) algorithm
3529 6751 then traversingadjacencyRowIfExp(inExp, tpl, Util.tuple33(tpl), traversingAdjacencyRowExpFinderBaseClock);
3530
3531 1040994 else (inExp, true, inTpl);
3532 end matchcontinue;
3533 end traversingAdjacencyRowExpFinderBaseClock;
3534
3535 public function traversingAdjacencyRowExpFinderSubClock "author: lochel
3536 This is used for sub-clock partitioning.
3537 TODO: avoid code duplicates, cf. function traversingAdjacencyRowExpFinderBaseClock"
3538 input DAE.Exp inExp;
3539 input tuple<BackendDAE.Variables, list<Integer>, Boolean> inTpl;
3540 output DAE.Exp outExp;
3541 output Boolean cont;
3542 output tuple<BackendDAE.Variables, list<Integer>, Boolean> outTpl;
3543 algorithm
3544 (outExp,cont,outTpl) := matchcontinue (inExp,inTpl)
3545 local
3546 list<Integer> p, p2;
3547 list<Integer> pa, res;
3548 DAE.ComponentRef cr;
3549 BackendDAE.Variables vars;
3550 Boolean isInitial;
3551 tuple<BackendDAE.Variables,list<Integer>, Boolean> tpl;
3552
3553 case (DAE.CREF(componentRef=cr), (vars, pa, isInitial))
3554 algorithm
3555 3592 (_, p) := BackendVariable.getVar(cr, vars);
3556 3125 res := listAppend(p, pa);
3557
3558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3125 times.
3125 if vars.hasStartVars then
3559 try
3560 ✗ (_, p2) := BackendVariable.getVar(ComponentReference.crefPrefixStart(cr), vars);
3561 ✗ res := listAppend(p2, res);
3562 else
3563 end try;
3564 end if;
3565
1/2
✓ Branch 0 taken 3125 times.
✗ Branch 1 not taken.
6250 then (inExp, true, (vars, res, isInitial));
3566
3567 case (DAE.CALL(path=Absyn.IDENT(name="subSample")), _)
3568 6 then (inExp, false, inTpl);
3569
3570 case (DAE.CALL(path=Absyn.IDENT(name="superSample")), _)
3571 13 then (inExp, false, inTpl);
3572
3573 case (DAE.CALL(path=Absyn.IDENT(name="shiftSample")), _)
3574 5 then (inExp, false, inTpl);
3575
3576 case (DAE.CALL(path=Absyn.IDENT(name="backSample")), _)
3577 3 then (inExp, false, inTpl);
3578
3579 case (DAE.CALL(path=Absyn.IDENT(name="noClock")), _)
3580 ✗ then (inExp, false, inTpl);
3581
3582 case (DAE.IFEXP(), tpl) algorithm
3583 660 then traversingadjacencyRowIfExp(inExp, tpl, Util.tuple33(tpl), traversingAdjacencyRowExpFinderSubClock);
3584
3585 4129 else (inExp, true, inTpl);
3586 end matchcontinue;
3587 end traversingAdjacencyRowExpFinderSubClock;
3588
3589 public function traversingadjacencyRowExpFinder "
3590 author: Frenkel TUD 2010-11
3591 Helper for statesAndVarsExp. Bind vars and isInitial by partial application;
3592 only the row is threaded through the traversal."
3593 input DAE.Exp inExp;
3594 input list<Integer> inPa;
3595 input BackendDAE.Variables vars;
3596 input Boolean isInitial;
3597 output DAE.Exp outExp;
3598 output Boolean cont;
3599 output list<Integer> outPa;
3600 algorithm
3601 (outExp,cont,outPa) := match inExp
3602 local
3603 list<Integer> p2, pa;
3604 DAE.ComponentRef cr;
3605 DAE.Exp e,e1,e2;
3606 list<BackendDAE.Var> varslst;
3607 Boolean b, b1, b2;
3608 Integer i;
3609
3610 // cref and $START.cref
3611 case DAE.CREF(componentRef=cr)
3612 algorithm
3613 try
3614 7095555 pa := adjacencyRowCref(cr, vars, inPa, 0);
3615
2/2
✓ Branch 0 taken 164999 times.
✓ Branch 1 taken 5406310 times.
5571309 if vars.hasStartVars then
3616 try
3617 164999 (varslst, _) := BackendVariable.getVar(cr, vars);
3618 164999 (_, p2) := BackendVariable.getVar(ComponentReference.crefPrefixStart(cr), vars);
3619 4576 pa := adjacencyRowExp1(varslst, p2, pa, 0);
3620 else
3621 end try;
3622 end if;
3623 else
3624 1524246 pa := inPa;
3625 end try;
3626 7095555 then (inExp, true, pa);
3627
3628 case DAE.CALL(path = Absyn.IDENT(name = "der"),expLst = {DAE.CREF(componentRef = cr)})
3629 algorithm
3630 try
3631 119901 pa := traversingadjacencyRowDer(cr, vars, inPa, isInitial);
3632 104150 b := false;
3633 else
3634 try
3635 15751 pa := traversingadjacencyRowDer(ComponentReference.crefPrefixDer(cr), vars, inPa, isInitial);
3636 ✗ b := false;
3637 else
3638 15751 (b, pa) := (true, inPa);
3639 end try;
3640 end try;
3641 119901 then (inExp, b, pa);
3642
3643 /* pre(v) is considered a known variable */
3644 case DAE.CALL(path = Absyn.IDENT(name = "pre"),expLst = {DAE.CREF()}) then (inExp,false,inPa);
3645
3646 /* previous(v) is considered a known variable */
3647 case DAE.CALL(path = Absyn.IDENT(name = "previous"),expLst = {DAE.CREF()}) then (inExp,false,inPa);
3648
3649 /* delay(e) can be used to break algebraic loops given some solver options */
3650 case DAE.CALL(path = Absyn.IDENT(name = "delay"),expLst = {_,_,e1,e2})
3651 algorithm
3652 try
3653
2/4
✓ Branch 1 taken 270 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 270 times.
270 b := not (Flags.getConfigBool(Flags.DELAY_BREAK_LOOP) and ExpressionBasics.expEqual(e1,e2));
3654 else
3655 ✗ b := true;
3656 end try;
3657 270 then (inExp,b,inPa);
3658
3659 // homotopy operator for simulation system
3660 case DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst = {e1, _}) guard not isInitial
3661 algorithm
3662 try
3663 2191 (e, b, pa) := traversingadjacencyRowExpFinder(e1, inPa, vars, isInitial);
3664 else
3665 ✗ (e, b, pa) := (inExp, true, inPa);
3666 end try;
3667 2191 then (e, b, pa);
3668
3669 // homotopy operator for initialization system
3670 case DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst = {e1, e2}) guard isInitial
3671 algorithm
3672 try
3673 1678 (_, b1, pa) := traversingadjacencyRowExpFinder(e1, inPa, vars, isInitial);
3674 1678 (_, b2, pa) := traversingadjacencyRowExpFinder(e2, pa, vars, isInitial);
3675
3/4
✓ Branch 0 taken 1570 times.
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1570 times.
1786 b := b1 and b2;
3676 else
3677 ✗ (b, pa) := (true, inPa);
3678 end try;
3679 1678 then (inExp, b, pa);
3680
3681 // only traverse position and direction for spatialDistribution, not the inputs!
3682 case DAE.CALL(path=Absyn.IDENT(name="spatialDistribution"), expLst = {_, _, _, e1, e2, _, _})
3683 algorithm
3684 try
3685 116 (_, _, pa) := traversingadjacencyRowExpFinder(e2, inPa, vars, isInitial);
3686 116 (e, b, pa) := traversingadjacencyRowExpFinder(e1, pa, vars, isInitial);
3687 else
3688 ✗ (e, b, pa) := (inExp, true, inPa);
3689 end try;
3690 116 then (e, b, pa);
3691
3692 // a failing scalar lookup falls back to the element of the array expression
3693 case DAE.ASUB(exp = e1, sub={DAE.INDEX(DAE.ICONST(i))})
3694 algorithm
3695 try
3696 try
3697
2/2
✓ Branch 0 taken 10725 times.
✓ Branch 1 taken 22 times.
10747 DAE.CREF(componentRef=cr) := e1;
3698 22 cr := ComponentReference.subscriptCrefWithInt(cr, i);
3699 22 pa := adjacencyRowCref(cr, vars, inPa, 0);
3700 else
3701 10732 e1 := Expression.nthArrayExp(e1, i);
3702
2/2
✓ Branch 0 taken 10595 times.
✓ Branch 1 taken 137 times.
21327 (_, pa) := Expression.traverseExpTopDown(e1, function traversingadjacencyRowExpFinder(vars = vars, isInitial = isInitial), inPa);
3703 end try;
3704 10747 b := false;
3705 else
3706 ✗ (b, pa) := (true, inPa);
3707 end try;
3708 10747 then (inExp, b, pa);
3709
3710 case DAE.IFEXP()
3711 algorithm
3712 try
3713
2/2
✓ Branch 0 taken 85092 times.
✓ Branch 1 taken 38746 times.
208930 (e, b, pa) := traversingadjacencyRowIfExp(inExp, inPa, isInitial, function traversingadjacencyRowExpFinder(vars = vars, isInitial = isInitial));
3714 else
3715 ✗ (e, b, pa) := (inExp, true, inPa);
3716 end try;
3717 123838 then (e, b, pa);
3718
3719 else (inExp,true,inPa);
3720 end match;
3721 end traversingadjacencyRowExpFinder;
3722
3723 protected function traversingadjacencyRowDer
3724 "The der(cr) case of traversingadjacencyRowExpFinder, including the
3725 indices of cr."
3726 input DAE.ComponentRef cr;
3727 input BackendDAE.Variables vars;
3728 input list<Integer> inPa;
3729 input Boolean isInitial;
3730 output list<Integer> pa;
3731 algorithm
3732 135652 pa := adjacencyRowCref(cr, vars, inPa, 1);
3733
1/2
✓ Branch 0 taken 104150 times.
✗ Branch 1 not taken.
208300 (_, pa) := Expression.traverseExpTopDownCrefHelper(cr, function traversingadjacencyRowExpFinder(vars = vars, isInitial = isInitial), pa);
3734 end traversingadjacencyRowDer;
3735
3736 protected function adjacencyRowExp1
3737 "Adds an adjacency matrix entry for all variables in the inVarLst."
3738 input list<BackendDAE.Var> inVarLst;
3739 input list<Integer> inIntegerLst;
3740 input list<Integer> inVarIndxLst;
3741 input Integer diffindex;
3742 output list<Integer> outVarIndxLst;
3743 algorithm
3744 outVarIndxLst := match (inVarLst,inIntegerLst)
3745 local
3746 BackendDAE.Var v;
3747 list<BackendDAE.Var> rest;
3748 list<Integer> irest;
3749 Integer i;
3750 case ({},{}) then inVarIndxLst;
3751 case (v::rest,i::irest)
3752 476223 then adjacencyRowExp1(rest,irest,adjacencyRowVar(v,i,inVarIndxLst,diffindex),diffindex);
3753 end match;
3754 end adjacencyRowExp1;
3755
3756 protected function adjacencyRowVar
3757 "Adds the adjacency matrix entry of variable i: a state x enters as -i
3758 unless diffindex says der(x) is meant (used by index reduction)."
3759 input BackendDAE.Var var;
3760 input Integer i;
3761 input list<Integer> inRow;
3762 input Integer diffindex;
3763 output list<Integer> row;
3764 algorithm
3765 row := match var
3766 local
3767 Integer diffidx;
3768 case BackendDAE.VAR(varKind = BackendDAE.STATE(derName=SOME(_)))
3769
2/2
✓ Branch 0 taken 176771 times.
✓ Branch 1 taken 34399 times.
211170 then (if intGe(diffindex,1) then i else -i) :: inRow;
3770 case BackendDAE.VAR(varKind = BackendDAE.STATE(index=diffidx))
3771
2/2
✓ Branch 0 taken 603773 times.
✓ Branch 1 taken 139110 times.
742883 then (if intGe(diffindex,diffidx) then i else -i) :: inRow;
3772 else i :: inRow;
3773 end match;
3774 end adjacencyRowVar;
3775
3776 protected function adjacencyRowCref
3777 "adjacencyRowExp1 for the variables cr names, as BackendVariable.getVar
3778 finds them, without building lists for a single variable. Fails if cr
3779 names none."
3780 input DAE.ComponentRef cr;
3781 input BackendDAE.Variables vars;
3782 input list<Integer> inRow;
3783 input Integer diffindex;
3784 output list<Integer> row;
3785 protected
3786 Integer hash = ComponentReferenceBasics.hashComponentRef(cr);
3787 BackendDAE.Var v;
3788 Integer i;
3789 list<BackendDAE.Var> vl;
3790 list<Integer> il;
3791 algorithm
3792 try
3793 10447824 (v, i) := BackendVariable.getVarHashed(cr, hash, vars);
3794 8154854 row := adjacencyRowVar(v, i, inRow, diffindex);
3795 else
3796 2292970 (vl, il) := BackendVariable.getVarExpanded(cr, hash, vars);
3797 51889 row := adjacencyRowExp1(vl, il, inRow, diffindex);
3798 end try;
3799 end adjacencyRowCref;
3800
3801 protected function adjacencyRowExp1DiscreteOrArray
3802 "Adds an adjacency matrix entry for all variables in the inVarLst, if they are discrete."
3803 input list<BackendDAE.Var> inVarLst;
3804 input list<Integer> inIntegerLst;
3805 input list<Integer> inVarIndxLst;
3806 output list<Integer> outVarIndxLst;
3807 algorithm
3808 outVarIndxLst := match (inVarLst,inIntegerLst)
3809 local
3810 list<BackendDAE.Var> rest;
3811 list<Integer> irest;
3812 list<Integer> vars;
3813 Integer i;
3814 case ({}, {}) then inVarIndxLst;
3815 case (BackendDAE.VAR(varKind = BackendDAE.DISCRETE())::rest, i::irest)
3816 algorithm
3817 vars := i :: inVarIndxLst;
3818 20356 then adjacencyRowExp1DiscreteOrArray(rest,irest,vars);
3819 case (_::rest, _::irest)
3820 3895 then adjacencyRowExp1DiscreteOrArray(rest,irest,inVarIndxLst);
3821 end match;
3822 end adjacencyRowExp1DiscreteOrArray;
3823
3824 public function traversingadjacencyRowExpFinderwithInput "Helper for statesAndVarsExp"
3825 input DAE.Exp inExp;
3826 input tuple<BackendDAE.Variables,list<Integer>, Boolean> inTpl;
3827 output DAE.Exp outExp;
3828 output Boolean cont;
3829 output tuple<BackendDAE.Variables,list<Integer>, Boolean> outTpl;
3830 algorithm
3831 (outExp,cont,outTpl) := matchcontinue (inExp,inTpl)
3832 local
3833 list<Integer> p;
3834 list<Integer> pa, res;
3835 DAE.ComponentRef cr;
3836 BackendDAE.Variables vars;
3837 DAE.Exp e1, e2;
3838 list<BackendDAE.Var> varslst;
3839 tuple<BackendDAE.Variables,list<Integer>, Boolean> tpl;
3840 Boolean b1, b2, isInitial;
3841
3842 // inner variable
3843 case (DAE.CREF(componentRef = cr),(vars,pa,isInitial))
3844 algorithm
3845 697032 cr := ComponentReferenceBasics.makeCrefQual(BackendDAE.partialDerivativeNamePrefix, DAE.T_REAL_DEFAULT, {}, cr);
3846 697032 (varslst,p) := BackendVariable.getVar(cr, vars);
3847 105667 res := adjacencyRowExp1withInput(varslst,p,pa,0);
3848
2/2
✓ Branch 0 taken 100872 times.
✓ Branch 1 taken 4795 times.
206539 then (inExp,false,(vars,res,isInitial));
3849
3850 // iteration var, with its start value if it has one
3851 case (DAE.CREF(componentRef=cr), (vars, pa, isInitial))
3852 algorithm
3853 591365 (varslst, p) := BackendVariable.getVar(cr, vars);
3854 364113 res := adjacencyRowExp1withInput(varslst, p, pa, 0);
3855
3856
2/2
✓ Branch 0 taken 3065 times.
✓ Branch 1 taken 361048 times.
364113 if vars.hasStartVars then
3857 try
3858 3065 (varslst, p) := BackendVariable.getVar(ComponentReference.crefPrefixStart(cr), vars);
3859 33 res := adjacencyRowExp1withInput(varslst, p, res, 0);
3860 else
3861 end try;
3862 end if;
3863
2/2
✓ Branch 0 taken 356447 times.
✓ Branch 1 taken 7666 times.
720560 then (inExp, true, (vars, res, isInitial));
3864
3865 // state derivative (in backend)
3866 case (DAE.CALL(path = Absyn.IDENT(name = "der"),expLst = {DAE.CREF(componentRef = cr)}),(vars,pa,isInitial))
3867 algorithm
3868 10580 (varslst,p) := BackendVariable.getVar(cr, vars);
3869 7300 res := adjacencyRowExp1withInput(varslst,p,pa,1);
3870
1/2
✓ Branch 0 taken 7300 times.
✗ Branch 1 not taken.
14600 then (inExp,false,(vars,res,isInitial));
3871
3872 // state derivative (in simcode)
3873 case (DAE.CALL(path = Absyn.IDENT(name = "der"),expLst = {DAE.CREF(componentRef = cr)}),(vars,pa,isInitial))
3874 algorithm
3875 3280 cr := ComponentReference.crefPrefixDer(cr);
3876 3280 (varslst,p) := BackendVariable.getVar(cr, vars);
3877 ✗ res := adjacencyRowExp1withInput(varslst,p,pa,1);
3878 ✗ then (inExp,false,(vars,res,isInitial));
3879
3880 // CLOCKED state
3881 case (DAE.CALL(path = Absyn.IDENT(name = "previous"),expLst = {DAE.CREF(componentRef = cr)}),(vars,pa,isInitial))
3882 algorithm
3883 6 cr := ComponentReferenceBasics.makeCrefQual(DAE.previousNamePrefix, DAE.T_REAL_DEFAULT, {}, cr);
3884 6 (varslst,p) := BackendVariable.getVar(cr, vars);
3885 6 res := adjacencyRowExp1withInput(varslst,p,pa,1);
3886
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 then (inExp,false,(vars,res,isInitial));
3887
3888 // homotopy operator for simulation system
3889 case (DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst = {e1, _}), (_, _, false))
3890 286 then traversingadjacencyRowExpFinderwithInput(e1, inTpl);
3891
3892 // homotopy operator for initialization system
3893 case (DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst = {e1, e2}), (_, _, true))
3894 algorithm
3895 2 (_, b1, tpl) := traversingadjacencyRowExpFinderwithInput(e1, inTpl);
3896 2 (_, b2, tpl) := traversingadjacencyRowExpFinderwithInput(e2, tpl);
3897
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 then (inExp, b1 and b2, tpl);
3898
3899 // only traverse position and direction for spatialDistribution, not the inputs!
3900 case (DAE.CALL(path=Absyn.IDENT(name="spatialDistribution"), expLst = {_, _, _, e1, e2, _, _}), _)
3901 algorithm
3902 8 (_, _, tpl) := traversingadjacencyRowExpFinderwithInput(e2, inTpl);
3903 8 then traversingadjacencyRowExpFinderwithInput(e1, tpl);
3904
3905 /* pre(v) is considered a known variable */
3906 1535 case (DAE.CALL(path = Absyn.IDENT(name = "pre"),expLst = {DAE.CREF()}),_) then (inExp,false,inTpl);
3907
3908 case (DAE.IFEXP(), tpl) algorithm
3909 12870 then traversingadjacencyRowIfExp(inExp, tpl, Util.tuple33(tpl), traversingadjacencyRowExpFinderwithInput);
3910
3911 1472247 else (inExp,true,inTpl);
3912 end matchcontinue;
3913 end traversingadjacencyRowExpFinderwithInput;
3914
3915
3916 protected function adjacencyRowExp1withInput
3917 input list<BackendDAE.Var> inVarLst;
3918 input list<Integer> inIntegerLst;
3919 input list<Integer> vars;
3920 input Integer diffindex;
3921 output list<Integer> outIntegerLst;
3922 algorithm
3923 outIntegerLst := match (inVarLst, inIntegerLst)
3924 local
3925 list<BackendDAE.Var> rest;
3926 list<Integer> irest;
3927 Integer i;
3928 case ({}, {}) then vars;
3929 case (BackendDAE.VAR(varKind = BackendDAE.DAE_AUX_VAR())::rest, i::irest)
3930 155 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3931 case (BackendDAE.VAR(varKind = BackendDAE.DAE_RESIDUAL_VAR())::rest, i::irest)
3932 3800 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3933 case (BackendDAE.VAR(varKind = BackendDAE.JAC_TMP_VAR())::rest, i::irest)
3934 105679 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3935 case (BackendDAE.VAR(varKind = BackendDAE.STATE())::rest, i::irest)
3936 guard diffindex <> 0
3937 7298 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3938 case (BackendDAE.VAR(varKind = BackendDAE.STATE_DER())::rest, i::irest)
3939 771 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3940 case (BackendDAE.VAR(varKind = BackendDAE.CLOCKED_STATE())::rest, i::irest)
3941 22 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3942 case (BackendDAE.VAR(varKind = BackendDAE.VARIABLE())::rest, i::irest)
3943 254921 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3944 case (BackendDAE.VAR(varKind = BackendDAE.ALG_STATE())::rest, i::irest)
3945 816 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3946 case (BackendDAE.VAR(varKind = BackendDAE.DISCRETE())::rest, i::irest)
3947 7582 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3948 case (BackendDAE.VAR(varKind = BackendDAE.DUMMY_DER())::rest, i::irest)
3949 30357 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3950 case (BackendDAE.VAR(varKind = BackendDAE.DUMMY_STATE())::rest, i::irest)
3951 60420 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3952 case (BackendDAE.VAR(varKind = BackendDAE.OPT_CONSTR())::rest, i::irest)
3953 377 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3954 case (BackendDAE.VAR(varKind = BackendDAE.OPT_FCONSTR())::rest, i::irest)
3955 135 then adjacencyRowExp1(rest,irest,i::vars,diffindex);
3956 case (_ :: _, _::_)
3957 then vars;
3958 end match;
3959 end adjacencyRowExp1withInput;
3960
3961 public function updateAdjacencyMatrix
3962 "author: PA
3963 Takes a daelow and the adjacency matrix and its transposed
3964 represenation and a list of equation indexes that needs to be updated.
3965 First the BackendDAE.AdjacencyMatrix is updated, i.e. the mapping from equations
3966 to variables. Then, by collecting all variables in the list of equations
3967 to update, a list of changed variables are retrieved. This is used to
3968 update the BackendDAE.AdjacencyMatrixT (transpose) mapping from variables to
3969 equations. The function returns an updated adjacency matrix.
3970 inputs: (BackendDAE,
3971 AdjacencyMatrix,
3972 AdjacencyMatrixT,
3973 int list /* list of equations to update */)
3974 outputs: (AdjacencyMatrix, AdjacencyMatrixT)"
3975 input BackendDAE.EqSystem syst;
3976 input BackendDAE.IndexType inIndxType;
3977 input Option<AvlTreePathFunction.Tree> functionTree;
3978 input list<Integer> inIntegerLst;
3979 input Boolean isInitial;
3980 output BackendDAE.EqSystem osyst;
3981 algorithm
3982 osyst := matchcontinue syst
3983 local
3984 BackendDAE.AdjacencyMatrix m;
3985 BackendDAE.AdjacencyMatrixT mt;
3986 BackendDAE.Variables vars;
3987 BackendDAE.EquationArray daeeqns;
3988 BackendDAE.AdjacencyMatrixMapping mapping;
3989
3990 case BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=daeeqns, m=SOME(m), mT=SOME(mt), mapping=SOME(mapping))
3991 algorithm
3992 /* kabdelhak: throw warning for unequal index types - inIndexType - indexType? also scalar function check!*/
3993 20148 (m,mt) := updateAdjacencyMatrix1(vars, daeeqns, inIndxType, functionTree, m, mt, inIntegerLst, isInitial);
3994 40296 then BackendDAEUtil.setEqSystMatrices(syst, SOME(m), SOME(mt), SOME(mapping));
3995
3996 else
3997 algorithm
3998 ✗ Error.addMessage(Error.INTERNAL_ERROR,{"BackendDAEUtil.updateAdjacencyMatrix failed"});
3999 ✗ then fail();
4000
4001 end matchcontinue;
4002 end updateAdjacencyMatrix;
4003
4004 protected function updateAdjacencyMatrix1
4005 "Replaces the rows of the given equations, then rebuilds the transposed row of
4006 every variable an equation gained or lost once, with the result the one-by-one
4007 removals and prepends would give."
4008 input BackendDAE.Variables vars;
4009 input BackendDAE.EquationArray daeeqns;
4010 input BackendDAE.IndexType inIndxType;
4011 input Option<AvlTreePathFunction.Tree> functionTree;
4012 input output BackendDAE.AdjacencyMatrix m;
4013 input output BackendDAE.AdjacencyMatrixT mt;
4014 input list<Integer> inIntegerLst;
4015 input Boolean isInitial;
4016 protected
4017 Integer abse, size = 0;
4018 list<Integer> row, oldvars;
4019 AvlSetInt.Tree invars, outvars;
4020 list<tuple<Integer, Integer>> removed = {}, added = {} "(variable, signed equation)";
4021 array<list<Integer>> removedAt, addedAt;
4022 array<Integer> markPos, markNeg;
4023 algorithm
4024
2/2
✓ Branch 0 taken 2304 times.
✓ Branch 1 taken 20148 times.
22452 for e in inIntegerLst loop
4025 2304 abse := intAbs(e);
4026 2304 (row, _) := adjacencyRow(BackendEquation.get(daeeqns, abse), vars, inIndxType, functionTree, {}, isInitial);
4027 2304 row := uniqueRow(row);
4028 2304 oldvars := getOldVars(m, abse);
4029 2304 m := Array.replaceAtWithFill(abse, row, {}, m);
4030 2304 (_, outvars, invars) := AvlSetInt.intersection(AvlSetInt.addList(AvlSetInt.EMPTY(), oldvars), AvlSetInt.addList(AvlSetInt.EMPTY(), row));
4031
2/2
✓ Branch 1 taken 2946 times.
✓ Branch 2 taken 2304 times.
5250 for k in AvlSetInt.listKeys(outvars) loop
4032
2/2
✓ Branch 0 taken 243 times.
✓ Branch 1 taken 2703 times.
2946 removed := (intAbs(k), if k > 0 then abse else -abse) :: removed;
4033 end for;
4034
2/2
✓ Branch 1 taken 2228 times.
✓ Branch 2 taken 2304 times.
4532 for k in AvlSetInt.listKeys(invars) loop
4035
2/2
✓ Branch 0 taken 371 times.
✓ Branch 1 taken 1857 times.
2228 added := (intAbs(k), if k > 0 then abse else -abse) :: added;
4036 size := max(size, intAbs(k));
4037 end for;
4038 end for;
4039
4/4
✓ Branch 0 taken 19896 times.
✓ Branch 1 taken 252 times.
✓ Branch 2 taken 19891 times.
✓ Branch 3 taken 5 times.
20148 if listEmpty(removed) and listEmpty(added) then
4040 19891 return;
4041 end if;
4042
4043 257 mt := Array.expandToSize(size, mt, {});
4044 257 removedAt := arrayCreate(arrayLength(mt), {});
4045 257 addedAt := arrayCreate(arrayLength(mt), {});
4046
2/2
✓ Branch 0 taken 2946 times.
✓ Branch 1 taken 257 times.
3203 for r in removed loop
4047 5892 arrayUpdate(removedAt, Util.tuple21(r), Util.tuple22(r) :: removedAt[Util.tuple21(r)]);
4048 end for;
4049 // consed from the last addition back, so each list is in processing order
4050
2/2
✓ Branch 0 taken 2228 times.
✓ Branch 1 taken 257 times.
2485 for a in added loop
4051 4456 arrayUpdate(addedAt, Util.tuple21(a), Util.tuple22(a) :: addedAt[Util.tuple21(a)]);
4052 end for;
4053
4054 257 markPos := arrayCreate(arrayLength(m), 0);
4055 257 markNeg := arrayCreate(arrayLength(m), 0);
4056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 257 times.
79850 for k in 1:arrayLength(mt) loop
4057
4/4
✓ Branch 1 taken 77530 times.
✓ Branch 2 taken 2063 times.
✓ Branch 4 taken 1776 times.
✓ Branch 5 taken 75754 times.
79593 if not (listEmpty(removedAt[k]) and listEmpty(addedAt[k])) then
4058 3839 row := mt[k];
4059
2/2
✓ Branch 0 taken 2063 times.
✓ Branch 1 taken 1776 times.
3839 if not listEmpty(removedAt[k]) then
4060
2/2
✓ Branch 0 taken 2946 times.
✓ Branch 1 taken 2063 times.
5009 for v in removedAt[k] loop
4061 2946 setSignedMark(v, k, markPos, markNeg);
4062 end for;
4063
6/6
✓ Branch 1 taken 2946 times.
✓ Branch 2 taken 8054 times.
✓ Branch 3 taken 11000 times.
✓ Branch 4 taken 2063 times.
✓ Branch 5 taken 8054 times.
✓ Branch 6 taken 2063 times.
13063 row := list(v for v guard not hasSignedMark(v, k, markPos, markNeg) in row);
4064 end if;
4065
2/2
✓ Branch 1 taken 1779 times.
✓ Branch 2 taken 2060 times.
3839 if not listEmpty(addedAt[k]) then
4066
2/2
✓ Branch 0 taken 3747 times.
✓ Branch 1 taken 1779 times.
5526 for v in row loop
4067 3747 setSignedMark(v, -k, markPos, markNeg);
4068 end for;
4069
2/2
✓ Branch 1 taken 2228 times.
✓ Branch 2 taken 1779 times.
4007 for v in addedAt[k] loop
4070
1/2
✓ Branch 1 taken 2228 times.
✗ Branch 2 not taken.
2228 if not hasSignedMark(v, -k, markPos, markNeg) then
4071 row := v :: row;
4072 end if;
4073 end for;
4074 end if;
4075 3839 arrayUpdate(mt, k, row);
4076 end if;
4077 end for;
4078 end updateAdjacencyMatrix1;
4079
4080 protected function setSignedMark
4081 input Integer v;
4082 input Integer stamp;
4083 input array<Integer> markPos;
4084 input array<Integer> markNeg;
4085 algorithm
4086
3/4
✓ Branch 0 taken 6079 times.
✓ Branch 1 taken 614 times.
✓ Branch 2 taken 6079 times.
✗ Branch 3 not taken.
12772 if v > 0 and v <= arrayLength(markPos) then
4087 6079 arrayUpdate(markPos, v, stamp);
4088 elseif v < 0 and -v <= arrayLength(markNeg) then
4089 614 arrayUpdate(markNeg, -v, stamp);
4090 end if;
4091 end setSignedMark;
4092
4093 protected function hasSignedMark
4094 input Integer v;
4095 input Integer stamp;
4096 input array<Integer> markPos;
4097 input array<Integer> markNeg;
4098 output Boolean marked = false;
4099 algorithm
4100
2/2
✓ Branch 0 taken 11356 times.
✓ Branch 1 taken 1872 times.
13228 if v > 0 then
4101
1/2
✓ Branch 0 taken 11356 times.
✗ Branch 1 not taken.
11356 if v <= arrayLength(markPos) then
4102 11356 marked := markPos[v] == stamp;
4103 end if;
4104 elseif v < 0 then
4105
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1872 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1872 times.
3744 if -v <= arrayLength(markNeg) then
4106 1872 marked := markNeg[-v] == stamp;
4107 end if;
4108 end if;
4109 end hasSignedMark;
4110
4111 public function updateAdjacencyMatrixScalar
4112 "author: PA
4113 Takes a daelow and the adjacency matrix and its transposed
4114 represenation and a list of equation indexes that needs to be updated.
4115 First the BackendDAE.AdjacencyMatrix is updated, i.e. the mapping from equations
4116 to variables. Then, by collecting all variables in the list of equations
4117 to update, a list of changed variables are retrieved. This is used to
4118 update the BackendDAE.AdjacencyMatrixT (transpose) mapping from variables to
4119 equations. The function returns an updated adjacency matrix.
4120 inputs: (BackendDAE,
4121 AdjacencyMatrix,
4122 AdjacencyMatrixT,
4123 int list /* list of equations to update */)
4124 outputs: (AdjacencyMatrix, AdjacencyMatrixT)"
4125 input BackendDAE.EqSystem syst;
4126 input BackendDAE.IndexType inIndxType;
4127 input Option<AvlTreePathFunction.Tree> functionTree;
4128 input list<Integer> inIntegerLst "numbers of equations in BackendDAE.EquationArray";
4129 input array<list<Integer>> iMapEqnIncRow;
4130 input array<Integer> iMapIncRowEqn;
4131 input Boolean isInitial;
4132 output BackendDAE.EqSystem osyst;
4133 output array<list<Integer>> oMapEqnIncRow;
4134 output array<Integer> oMapIncRowEqn;
4135 algorithm
4136 (osyst, oMapEqnIncRow, oMapIncRowEqn) := matchcontinue syst
4137 local
4138 BackendDAE.AdjacencyMatrix m;
4139 BackendDAE.AdjacencyMatrixT mt;
4140 Integer oldsize, newsize, oldsize1, newsize1, deltasize;
4141 list<Integer> eqns;
4142 BackendDAE.Variables vars;
4143 BackendDAE.EquationArray daeeqns;
4144 array<list<Integer>> mapEqnIncRow;
4145 array<Integer> mapIncRowEqn;
4146 BackendDAE.IndexType indexType;
4147 Boolean scalar, processed;
4148
4149 case BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=daeeqns, m=SOME(m), mT=SOME(mt), mapping=SOME((_, _, indexType, scalar, processed)))
4150 algorithm
4151 // extend the mapping arrays
4152 oldsize := arrayLength(iMapEqnIncRow);
4153 2180 newsize := BackendEquation.getNumberOfEquations(daeeqns);
4154
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2180 times.
2180 mapEqnIncRow := Array.expand(newsize-oldsize, iMapEqnIncRow, {});
4155 oldsize1 := arrayLength(iMapIncRowEqn);
4156 2180 newsize1 := BackendEquation.equationArraySize(daeeqns);
4157 2180 deltasize := newsize1-oldsize1;
4158 2180 mapIncRowEqn := Array.expand(deltasize, iMapIncRowEqn, 0);
4159 // extend the adjacencyMatrix
4160 2180 m := Array.expand(deltasize, m, {});
4161 2180 mt := Array.expand(deltasize, mt, {});
4162 // fill the extended parts first
4163 2180 (m, mt, mapEqnIncRow, mapIncRowEqn) :=
4164 updateAdjacencyMatrixScalar2( oldsize+1, newsize, oldsize1, vars, daeeqns, m, mt, mapEqnIncRow,
4165 mapIncRowEqn, inIndxType, functionTree, isInitial);
4166 // update the old
4167 2180 eqns := List.removeOnTrue(oldsize, intLt, inIntegerLst);
4168 2180 (m,mt,mapEqnIncRow,mapIncRowEqn) :=
4169 updateAdjacencyMatrixScalar1( vars, daeeqns, m, mt, eqns, mapEqnIncRow,
4170 mapIncRowEqn, inIndxType, functionTree, isInitial);
4171
5/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2168 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2180 times.
✓ Branch 7 taken 2179 times.
✓ Branch 8 taken 1 time.
6552 then
4172 (BackendDAEUtil.setEqSystMatrices(syst, SOME(m), SOME(mt), SOME((mapEqnIncRow, mapIncRowEqn, indexType, scalar, processed))), mapEqnIncRow, mapIncRowEqn);
4173
4174 else
4175 algorithm
4176 ✗ Error.addMessage(Error.INTERNAL_ERROR,{"BackendDAEUtil.updateAdjacencyMatrixScalar failed"});
4177 ✗ then
4178 fail();
4179
4180 end matchcontinue;
4181 end updateAdjacencyMatrixScalar;
4182
4183 protected function updateAdjacencyMatrixScalar1
4184 "Helper"
4185 input BackendDAE.Variables vars;
4186 input BackendDAE.EquationArray daeeqns;
4187 input BackendDAE.AdjacencyMatrix m;
4188 input BackendDAE.AdjacencyMatrixT mt;
4189 input list<Integer> inIntegerLst;
4190 input array<list<Integer>> iMapEqnIncRow;
4191 input array<Integer> iMapIncRowEqn;
4192 input BackendDAE.IndexType inIndxType;
4193 input Option<AvlTreePathFunction.Tree> functionTree;
4194 input Boolean isInitial;
4195 output BackendDAE.AdjacencyMatrix outAdjacencyMatrix;
4196 output BackendDAE.AdjacencyMatrixT outAdjacencyMatrixT;
4197 output array<list<Integer>> oMapEqnIncRow;
4198 output array<Integer> oMapIncRowEqn;
4199 algorithm
4200 (outAdjacencyMatrix,outAdjacencyMatrixT,oMapEqnIncRow,oMapIncRowEqn):=
4201 match inIntegerLst
4202 local
4203 BackendDAE.AdjacencyMatrix m_1,m_2;
4204 BackendDAE.AdjacencyMatrixT mt_1,mt_2,mt_3;
4205 Integer e,abse;
4206 BackendDAE.Equation eqn;
4207 AvlSetInt.Tree invarsTree,outvarsTree;
4208 list<Integer> row,invars,outvars,eqns,oldvars,scalarindxs;
4209 array<list<Integer>> mapEqnIncRow;
4210 array<Integer> mapIncRowEqn;
4211
4212 case {} then (m,mt,iMapEqnIncRow,iMapIncRowEqn);
4213
4214 case e::eqns guard(BackendEquation.has(daeeqns, intAbs(e)))
4215 algorithm
4216 abse := intAbs(e);
4217 13156 eqn := BackendEquation.get(daeeqns, abse);
4218 13156 (row,_) := adjacencyRow(eqn,vars,inIndxType,functionTree,{},isInitial);
4219 13156 row := uniqueRow(row);
4220 13156 scalarindxs := iMapEqnIncRow[abse];
4221 13156 oldvars := getOldVars(m,listHead(scalarindxs));
4222 13156 (_,outvarsTree,invarsTree) := AvlSetInt.intersection(AvlSetInt.addList(AvlSetInt.EMPTY(), oldvars), AvlSetInt.addList(AvlSetInt.EMPTY(), row));
4223 13156 outvars := AvlSetInt.listKeys(outvarsTree);
4224 13156 invars := AvlSetInt.listKeys(invarsTree);
4225 // do the same for each scalar indxs
4226 13156 m_1 := List.fold1r(scalarindxs,arrayUpdate,row,m);
4227 13156 mt_1 := List.fold1(scalarindxs,removeValuefromMatrix,outvars,mt);
4228 13156 mt_2 := List.fold1(scalarindxs,addValuetoMatrix,invars,mt_1);
4229 13156 (m_2,mt_3,mapEqnIncRow,mapIncRowEqn) := updateAdjacencyMatrixScalar1(vars,daeeqns,m_1,mt_2,eqns,iMapEqnIncRow,iMapIncRowEqn,inIndxType,functionTree,isInitial);
4230 then (m_2,mt_3,mapEqnIncRow,mapIncRowEqn);
4231
4232 case e::eqns // Backup for non existent equations
4233 algorithm
4234 ✗ abse := intAbs(e);
4235 row := {};
4236 ✗ scalarindxs := iMapEqnIncRow[abse];
4237 ✗ oldvars := getOldVars(m,listHead(scalarindxs));
4238 ✗ (_,outvarsTree,invarsTree) := AvlSetInt.intersection(AvlSetInt.addList(AvlSetInt.EMPTY(), oldvars), AvlSetInt.EMPTY());
4239 ✗ outvars := AvlSetInt.listKeys(outvarsTree);
4240 ✗ invars := AvlSetInt.listKeys(invarsTree);
4241 // do the same for each scalar indxs
4242 ✗ m_1 := List.fold1r(scalarindxs,arrayUpdate,row,m);
4243 ✗ mt_1 := List.fold1(scalarindxs,removeValuefromMatrix,outvars,mt);
4244 ✗ mt_2 := List.fold1(scalarindxs,addValuetoMatrix,invars,mt_1);
4245 ✗ (m_2,mt_3,mapEqnIncRow,mapIncRowEqn) := updateAdjacencyMatrixScalar1(vars,daeeqns,m_1,mt_2,eqns,iMapEqnIncRow,iMapIncRowEqn,inIndxType,functionTree,isInitial);
4246 then (m_2,mt_3,mapEqnIncRow,mapIncRowEqn);
4247
4248 end match;
4249 end updateAdjacencyMatrixScalar1;
4250
4251 protected function updateAdjacencyMatrixScalar2
4252 "Helper"
4253 input Integer index;
4254 input Integer n;
4255 input Integer size;
4256 input BackendDAE.Variables vars;
4257 input BackendDAE.EquationArray daeeqns;
4258 input BackendDAE.AdjacencyMatrix m;
4259 input BackendDAE.AdjacencyMatrixT mt;
4260 input array<list<Integer>> iMapEqnIncRow;
4261 input array<Integer> iMapIncRowEqn;
4262 input BackendDAE.IndexType inIndxType;
4263 input Option<AvlTreePathFunction.Tree> functionTree;
4264 input Boolean isInitial;
4265 output BackendDAE.AdjacencyMatrix outAdjacencyMatrix;
4266 output BackendDAE.AdjacencyMatrixT outAdjacencyMatrixT;
4267 output array<list<Integer>> oMapEqnIncRow;
4268 output array<Integer> oMapIncRowEqn;
4269 algorithm
4270 (outAdjacencyMatrix,outAdjacencyMatrixT,oMapEqnIncRow,oMapIncRowEqn):=
4271 matchcontinue functionTree
4272 local
4273 BackendDAE.AdjacencyMatrix m1;
4274 BackendDAE.AdjacencyMatrixT mt1;
4275 Integer abse,rowsize,new_size;
4276 BackendDAE.Equation eqn;
4277 list<Integer> row;
4278 list<Integer> scalarindxs, row_lst;
4279 array<list<Integer>> mapEqnIncRow;
4280 array<Integer> mapIncRowEqn;
4281
4282 case _
4283 guard(not intGt(index,n) and BackendEquation.has(daeeqns, intAbs(index)))
4284 algorithm
4285 abse := intAbs(index);
4286 ✗ eqn := BackendEquation.get(daeeqns, abse);
4287 ✗ rowsize := BackendEquation.equationSize(eqn);
4288 ✗ (row,_) := adjacencyRow(eqn,vars,inIndxType,functionTree,{},isInitial);
4289 ✗ new_size := size+rowsize;
4290 ✗ scalarindxs := List.intRange2(size+1,new_size);
4291 ✗ mapEqnIncRow := arrayUpdate(iMapEqnIncRow,abse,scalarindxs);
4292 ✗ mapIncRowEqn := List.fold1r(scalarindxs,arrayUpdate,abse,iMapIncRowEqn);
4293 ✗ row_lst := uniqueRow(row);
4294 ✗ m1:= List.fold1r(scalarindxs,arrayUpdate,row_lst,m);
4295 ✗ mt1 := filladjacencyMatrixT(row_lst,scalarindxs,mt);
4296 ✗ (m1,mt1,mapEqnIncRow,mapIncRowEqn) := updateAdjacencyMatrixScalar2(index+1,n,new_size,vars,daeeqns,m1,mt1,mapEqnIncRow,mapIncRowEqn,inIndxType,functionTree,isInitial);
4297 then
4298 (m1,mt1,mapEqnIncRow,mapIncRowEqn);
4299 case _
4300 2180 then
4301 (m,mt,iMapEqnIncRow,iMapIncRowEqn);
4302
4303 else
4304 algorithm
4305 ✗ abse := intAbs(index);
4306 rowsize := 1;
4307 row := {};
4308 ✗ new_size := size+rowsize;
4309 ✗ scalarindxs := List.intRange2(size+1,new_size);
4310 ✗ mapEqnIncRow := arrayUpdate(iMapEqnIncRow,abse,scalarindxs);
4311 ✗ mapIncRowEqn := List.fold1r(scalarindxs,arrayUpdate,abse,iMapIncRowEqn);
4312 ✗ row_lst := uniqueRow(row);
4313 ✗ m1:= List.fold1r(scalarindxs,arrayUpdate,row_lst,m);
4314 ✗ mt1 := filladjacencyMatrixT(row_lst,scalarindxs,mt);
4315 ✗ (m1,mt1,mapEqnIncRow,mapIncRowEqn) := updateAdjacencyMatrixScalar2(index+1,n,new_size,vars,daeeqns,m1,mt1,mapEqnIncRow,mapIncRowEqn,inIndxType,functionTree,isInitial);
4316 then
4317 (m1,mt1,mapEqnIncRow,mapIncRowEqn);
4318 end matchcontinue;
4319 end updateAdjacencyMatrixScalar2;
4320
4321 protected function getOldVars
4322 input array<list<Integer>> m;
4323 input Integer pos;
4324 output list<Integer> oldvars;
4325 algorithm
4326
1/2
✓ Branch 0 taken 44726 times.
✗ Branch 1 not taken.
44726 oldvars := if pos <= arrayLength(m) then m[pos] else {};
4327 end getOldVars;
4328
4329 protected function removeValuefromMatrix
4330 "author: Frenkel TUD 2011-04"
4331 input Integer inValue;
4332 input list<Integer> inIntegerLst;
4333 input BackendDAE.AdjacencyMatrixT inAdjacencyMatrixT;
4334 output BackendDAE.AdjacencyMatrixT outAdjacencyMatrixT;
4335 algorithm
4336 outAdjacencyMatrixT:=
4337 matchcontinue (inValue,inIntegerLst,inAdjacencyMatrixT)
4338 local
4339 BackendDAE.AdjacencyMatrixT mt,mt_1,mt_2;
4340 BackendDAE.AdjacencyMatrixElement mlst,mlst1;
4341 list<Integer> keys;
4342 Integer k,kabs;
4343 Integer v,v_1;
4344 case (_,{},mt) then mt;
4345 case (v,k::keys,mt)
4346 algorithm
4347 15439 kabs := intAbs(k);
4348 15439 mlst := mt[kabs];
4349
2/2
✓ Branch 0 taken 4123 times.
✓ Branch 1 taken 11316 times.
15439 v_1 := if intGt(k,0) then v else -v;
4350 15439 mlst1 := List.removeOnTrue(v_1,intEq,mlst);
4351 15439 mt_1 := arrayUpdate(mt, kabs , mlst1);
4352 15439 mt_2 := removeValuefromMatrix(v,keys,mt_1);
4353 then
4354 mt_2;
4355 case (v,_::keys,mt)
4356 algorithm
4357 ✗ mt_2 := removeValuefromMatrix(v,keys,mt);
4358 then
4359 mt_2;
4360 case (_,_,_)
4361 algorithm
4362 ✗ print("- BackendDAE.removeValuefromMatrix failed\n");
4363 ✗ then
4364 fail();
4365 end matchcontinue;
4366 end removeValuefromMatrix;
4367
4368 protected function addValuetoMatrix
4369 "author: Frenkel TUD 2011-04"
4370 input Integer inValue;
4371 input list<Integer> inIntegerLst;
4372 input BackendDAE.AdjacencyMatrixT inAdjacencyMatrixT;
4373 output BackendDAE.AdjacencyMatrixT outAdjacencyMatrixT;
4374 algorithm
4375 outAdjacencyMatrixT:=
4376 matchcontinue (inValue,inIntegerLst,inAdjacencyMatrixT)
4377 local
4378 BackendDAE.AdjacencyMatrixT mt,mt_1,mt_2;
4379 BackendDAE.AdjacencyMatrixElement mlst;
4380 list<Integer> keys;
4381 Integer k,kabs;
4382 Integer v,v_1;
4383 case (_,{},mt) then mt;
4384 case (v,k::keys,mt)
4385 algorithm
4386 29266 kabs := intAbs(k);
4387 29266 mlst := getOldVars(mt,kabs);
4388
2/2
✓ Branch 0 taken 20135 times.
✓ Branch 1 taken 9131 times.
29266 v_1 := if intGt(k,0) then v else -v;
4389
2/2
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 29242 times.
29266 false := listMember(v_1, mlst);
4390 29242 mt_1 := Array.replaceAtWithFill(kabs,v_1::mlst,{},mt);
4391 29242 mt_2 := addValuetoMatrix(v,keys,mt_1);
4392 then
4393 mt_2;
4394 case (v,_::keys,mt)
4395 algorithm
4396 24 mt_2 := addValuetoMatrix(v,keys,mt);
4397 then
4398 mt_2;
4399 case (_,_,_)
4400 algorithm
4401 ✗ print("- BackendDAE.addValuetoMatrix failed\n");
4402 ✗ then
4403 fail();
4404 end matchcontinue;
4405 end addValuetoMatrix;
4406
4407 public function getAdjacencyMatrixfromOptionForMapEqSystem "function getAdjacencyMatrixfromOption"
4408 input BackendDAE.EqSystem syst;
4409 input BackendDAE.IndexType inIndxType;
4410 input BackendDAE.Shared shared;
4411 output BackendDAE.EqSystem osyst;
4412 output BackendDAE.Shared oshared;
4413 protected
4414 AvlTreePathFunction.Tree funcs;
4415 algorithm
4416 28 funcs := getFunctions(shared);
4417 56 (osyst,_,_) := getAdjacencyMatrixfromOption(syst, inIndxType,SOME(funcs), BackendDAEUtil.isInitializationDAE(shared));
4418 oshared := shared;
4419 end getAdjacencyMatrixfromOptionForMapEqSystem;
4420
4421 public function getAdjacencyMatrixfromOption
4422 input BackendDAE.EqSystem inSyst;
4423 input BackendDAE.IndexType inIndxType;
4424 input Option<AvlTreePathFunction.Tree> inFunctionTree;
4425 input Boolean isInitial;
4426 output BackendDAE.EqSystem outSyst;
4427 output BackendDAE.AdjacencyMatrix outM;
4428 output BackendDAE.AdjacencyMatrix outMT;
4429 algorithm
4430 (outSyst, outM, outMT) := match inSyst
4431 local
4432 BackendDAE.AdjacencyMatrix m, mT;
4433 BackendDAE.Variables v;
4434 BackendDAE.AdjacencyMatrixMapping mapping;
4435 case BackendDAE.EQSYSTEM(m=NONE()) algorithm
4436 73924 (m, mT) := adjacencyMatrix(inSyst, inIndxType, inFunctionTree, isInitial);
4437 73924 mapping := getArrayAdjacencyMatrixMapping(ExpandableArray.getNumberOfElements(inSyst.orderedEqs), inIndxType, false);
4438 147848 then (BackendDAEUtil.setEqSystMatrices(inSyst, SOME(m), SOME(mT), SOME(mapping)), m, mT);
4439
4440 case BackendDAE.EQSYSTEM(orderedVars=v, m=SOME(m), mT=NONE(), mapping=NONE()) algorithm
4441 ✗ mT := AdjacencyMatrix.transposeAdjacencyMatrix(m, BackendVariable.varsSize(v));
4442 ✗ then (BackendDAEUtil.setEqSystMatrices(inSyst, SOME(m), SOME(mT), NONE()), m, mT);
4443
4444 case BackendDAE.EQSYSTEM(orderedVars=v, m=SOME(m), mT=NONE(), mapping=SOME(mapping)) algorithm
4445 ✗ mT := AdjacencyMatrix.transposeAdjacencyMatrix(m, BackendVariable.varsSize(v));
4446 ✗ then (BackendDAEUtil.setEqSystMatrices(inSyst, SOME(m), SOME(mT), SOME(mapping)), m, mT);
4447
4448 case BackendDAE.EQSYSTEM(m=SOME(m), mT=SOME(mT))
4449 then (inSyst, m, mT);
4450 end match;
4451 end getAdjacencyMatrixfromOption;
4452
4453 public function getArrayAdjacencyMatrixMapping
4454 "author: kabdelhak FHB 10-2019
4455 Returns an identity mapping for array adjacency matrices."
4456 input Integer size;
4457 input BackendDAE.IndexType indexType;
4458 input Boolean scalar;
4459 output BackendDAE.AdjacencyMatrixMapping mapping;
4460 protected
4461 array<list<Integer>> mapEqnIncRow = arrayCreate(size, {-1});
4462 array<Integer> mapIncRowEqn = arrayCreate(size, -1);
4463 algorithm
4464
2/2
✓ Branch 0 taken 86413 times.
✓ Branch 1 taken 1983 times.
1000573 for i in 1:size loop
4465 912177 mapEqnIncRow[i] := {i};
4466 912177 mapIncRowEqn[i] := i;
4467 end for;
4468
1/2
✓ Branch 0 taken 88396 times.
✗ Branch 1 not taken.
176792 mapping := (mapEqnIncRow, mapIncRowEqn, indexType, scalar, false);
4469 end getArrayAdjacencyMatrixMapping;
4470
4471 public function getAdjacencyMatrix "this function returns the adjacency matrix,
4472 if the system contains multidimensional equations and the scalar one is needed use getAdjacencyMatrixScalar"
4473 input BackendDAE.EqSystem inEqSystem;
4474 input BackendDAE.IndexType inIndxType;
4475 input Option<AvlTreePathFunction.Tree> functionTree;
4476 input Boolean isInitial;
4477 output BackendDAE.EqSystem outEqSystem;
4478 output BackendDAE.AdjacencyMatrix outM;
4479 output BackendDAE.AdjacencyMatrix outMT;
4480 protected
4481 BackendDAE.AdjacencyMatrixMapping mapping;
4482 algorithm
4483 14472 (outM, outMT) := adjacencyMatrix(inEqSystem, inIndxType, functionTree, isInitial);
4484 14472 mapping := getArrayAdjacencyMatrixMapping(ExpandableArray.getNumberOfElements(inEqSystem.orderedEqs), inIndxType, false);
4485 28944 outEqSystem := BackendDAEUtil.setEqSystMatrices(inEqSystem, SOME(outM), SOME(outMT), SOME(mapping));
4486 end getAdjacencyMatrix;
4487
4488 public function getAdjacencyMatrixScalar "function getAdjacencyMatrixScalar"
4489 input BackendDAE.EqSystem syst;
4490 input BackendDAE.IndexType inIndxType;
4491 input Option<AvlTreePathFunction.Tree> functionTree;
4492 input Boolean isInitial;
4493 output BackendDAE.EqSystem osyst;
4494 output BackendDAE.AdjacencyMatrix outM;
4495 output BackendDAE.AdjacencyMatrix outMT;
4496 output array<list<Integer>> outMapEqnIncRow;
4497 output array<Integer> outMapIncRowEqn;
4498 algorithm
4499 223112 (outM, outMT, outMapEqnIncRow, outMapIncRowEqn) := adjacencyMatrixScalar(syst, inIndxType, functionTree, isInitial);
4500 669336 osyst := BackendDAEUtil.setEqSystMatrices(syst, SOME(outM), SOME(outMT), SOME((outMapEqnIncRow, outMapIncRowEqn, inIndxType, true, false)));
4501 end getAdjacencyMatrixScalar;
4502
4503 public function removedAdjacencyMatrix
4504 input BackendDAE.EqSystem inSyst;
4505 input BackendDAE.IndexType inIndxType;
4506 input Option<AvlTreePathFunction.Tree> inFunctionTree;
4507 input Boolean isInitial;
4508 output BackendDAE.AdjacencyMatrix outM;
4509 output BackendDAE.AdjacencyMatrix outMT;
4510 algorithm
4511 2454 (outM, outMT) := adjacencyMatrixDispatch(inSyst.orderedVars, inSyst.removedEqs, inIndxType, inFunctionTree, isInitial);
4512 end removedAdjacencyMatrix;
4513
4514 public function removedAdjacencyMatrixMasked
4515 input BackendDAE.EqSystem inSyst;
4516 input BackendDAE.IndexType inIndxType;
4517 input array<Boolean> inMask;
4518 input Option<AvlTreePathFunction.Tree> inFunctionTree;
4519 input Boolean isInitial;
4520 output BackendDAE.AdjacencyMatrix outM;
4521 output BackendDAE.AdjacencyMatrix outMT;
4522 algorithm
4523 ✗ (outM, outMT) := adjacencyMatrixDispatchMasked(inSyst.orderedVars, inSyst.removedEqs, inIndxType, inMask, inFunctionTree, isInitial);
4524 end removedAdjacencyMatrixMasked;
4525
4526 protected function traverseStmts<ArgT> "Author: Frenkel TUD 2012-06
4527 traverese DAE.Statement without change possibility."
4528 input list<DAE.Statement> inStmts;
4529 input FuncExpType func;
4530 input output ArgT extraArg;
4531
4532 partial function FuncExpType
4533 input DAE.Exp arg1;
4534 input output ArgT arg2;
4535 end FuncExpType;
4536
4537 protected
4538 DAE.Exp e,e2;
4539 list<DAE.Exp> expl1;
4540 DAE.ComponentRef cr;
4541 list<DAE.Statement> stmts;
4542 DAE.Type tp;
4543 DAE.Statement ew;
4544 String id1,str;
4545 DAE.Else algElse;
4546 algorithm
4547
2/2
✓ Branch 0 taken 47432 times.
✓ Branch 1 taken 22542 times.
69974 for stmt in inStmts loop
4548 extraArg := matchcontinue stmt
4549 case DAE.STMT_ASSIGN(exp1 = e2,exp = e)
4550 algorithm
4551 // kabdelhak: remove left hand side subscripts
4552 // (Modelica Specification v3.5 : 11.1.2)
4553 // solves ticket #7832
4554
1/2
✓ Branch 0 taken 30254 times.
✗ Branch 1 not taken.
30254 extraArg := func(e, extraArg);
4555
1/2
✓ Branch 0 taken 30254 times.
✗ Branch 1 not taken.
30254 extraArg := func(e2, extraArg);
4556 then
4557 extraArg;
4558
4559 case DAE.STMT_TUPLE_ASSIGN(expExpLst = expl1, exp = e)
4560 algorithm
4561 // kabdelhak: remove left hand side subscripts
4562 // (Modelica Specification v3.5 : 11.1.2)
4563 // solves ticket #7832
4564
1/2
✓ Branch 0 taken 279 times.
✗ Branch 1 not taken.
279 extraArg := func(e, extraArg);
4565 279 extraArg := List.fold(expl1,func,extraArg);
4566 then
4567 extraArg;
4568
4569 case DAE.STMT_ASSIGN_ARR(lhs = e2, exp = e)
4570 algorithm
4571 // kabdelhak: remove left hand side subscripts
4572 // (Modelica Specification v3.5 : 11.1.2)
4573 // solves ticket #7832
4574
1/2
✓ Branch 0 taken 1264 times.
✗ Branch 1 not taken.
1264 extraArg := func(e, extraArg);
4575
1/2
✓ Branch 0 taken 1264 times.
✗ Branch 1 not taken.
1264 extraArg := func(e2, extraArg);
4576 then
4577 extraArg;
4578
4579 case DAE.STMT_IF(exp=e,statementLst=stmts,else_ = algElse)
4580 algorithm
4581 5141 extraArg := traverseStmtsElse(algElse,func,extraArg);
4582 5141 extraArg := traverseStmts(stmts,func,extraArg);
4583
1/2
✓ Branch 0 taken 5141 times.
✗ Branch 1 not taken.
5141 extraArg := func(e, extraArg);
4584 then
4585 extraArg;
4586
4587 case DAE.STMT_FOR(type_=tp,iter=id1,range=e,statementLst=stmts)
4588 algorithm
4589
1/2
✓ Branch 0 taken 2776 times.
✗ Branch 1 not taken.
2776 extraArg := func(e, extraArg);
4590 2776 cr := ComponentReferenceBasics.makeCrefIdent(id1, tp, {});
4591 2776 (stmts,_) := DAEUtil.traverseDAEEquationsStmts(stmts,Expression.traverseSubexpressionsHelper,(Expression.replaceCref,(cr,e)));
4592 2776 extraArg := traverseStmts(stmts,func,extraArg);
4593 then
4594 extraArg;
4595
4596 case DAE.STMT_PARFOR(type_=tp,iter=id1,range=e,statementLst=stmts)
4597 algorithm
4598 ✗ extraArg := func(e, extraArg);
4599 ✗ cr := ComponentReferenceBasics.makeCrefIdent(id1, tp, {});
4600 ✗ (stmts,_) := DAEUtil.traverseDAEEquationsStmts(stmts,Expression.traverseSubexpressionsHelper,(Expression.replaceCref,(cr,e)));
4601 ✗ extraArg := traverseStmts(stmts,func,extraArg);
4602 then
4603 extraArg;
4604
4605 case DAE.STMT_WHILE(exp=e,statementLst=stmts)
4606 algorithm
4607 ✗ extraArg := traverseStmts(stmts,func,extraArg);
4608 ✗ extraArg := func(e, extraArg);
4609 then
4610 extraArg;
4611
4612 case DAE.STMT_WHEN(exp=e,statementLst=stmts,elseWhen=NONE())
4613 algorithm
4614 1914 extraArg := traverseStmts(stmts,func,extraArg);
4615
1/2
✓ Branch 0 taken 1914 times.
✗ Branch 1 not taken.
1914 extraArg := func(e, extraArg);
4616 then
4617 extraArg;
4618
4619 case DAE.STMT_WHEN(exp=e,statementLst=stmts,elseWhen=SOME(ew))
4620 algorithm
4621 775 extraArg := traverseStmts({ew},func,extraArg);
4622 775 extraArg := traverseStmts(stmts,func,extraArg);
4623
1/2
✓ Branch 0 taken 775 times.
✗ Branch 1 not taken.
775 extraArg := func(e, extraArg);
4624 then
4625 extraArg;
4626
4627 case DAE.STMT_ASSERT(cond = e, msg=e2)
4628 algorithm
4629
1/2
✓ Branch 0 taken 3903 times.
✗ Branch 1 not taken.
3903 extraArg := func(e, extraArg);
4630
1/2
✓ Branch 0 taken 3903 times.
✗ Branch 1 not taken.
3903 extraArg := func(e2, extraArg);
4631 then
4632 extraArg;
4633
4634
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 case DAE.STMT_TERMINATE(msg = e) then func(e, extraArg);
4635
4636 case DAE.STMT_REINIT(var = e,value=e2)
4637 algorithm
4638
1/2
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
364 extraArg := func(e, extraArg);
4639
1/2
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
364 extraArg := func(e2, extraArg);
4640 then
4641 extraArg;
4642
4643
1/2
✓ Branch 0 taken 450 times.
✗ Branch 1 not taken.
450 case DAE.STMT_NORETCALL(exp = e) then func(e, extraArg);
4644 ✗ case DAE.STMT_RETURN() then extraArg;
4645 308 case DAE.STMT_BREAK() then extraArg;
4646 ✗ case DAE.STMT_CONTINUE() then extraArg;
4647
4648 // MetaModelica extension. KS
4649 case DAE.STMT_FAILURE(body=stmts)
4650 ✗ then traverseStmts(stmts,func,extraArg);
4651
4652 else
4653 algorithm
4654 ✗ str := DAEDump.ppStatementStr(stmt);
4655 ✗ str := "BackenddAEUtil.traverseStmts not implemented correctly: " + str;
4656 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
4657 ✗ then fail();
4658 end matchcontinue;
4659 end for;
4660 end traverseStmts;
4661
4662 protected function traverseStmtsElse "
4663 Author: Frenkel TUD 2012-06
4664 Helper function for traverseStmts
4665 "
4666 input DAE.Else inElse;
4667 input FuncExpType func;
4668 input Type_a iextraArg;
4669 output Type_a oextraArg;
4670 partial function FuncExpType
4671 input DAE.Exp arg1;
4672 input output Type_a arg2;
4673 end FuncExpType;
4674 replaceable type Type_a subtypeof Any;
4675 algorithm
4676 oextraArg := match(inElse, iextraArg)
4677 local
4678 DAE.Exp e;
4679 list<DAE.Statement> st;
4680 DAE.Else el;
4681 Type_a extraArg;
4682 case (DAE.NOELSE(), extraArg) then extraArg;
4683 case (DAE.ELSEIF(e,st,el), extraArg)
4684 algorithm
4685 1622 extraArg := traverseStmtsElse(el,func,extraArg);
4686
1/2
✓ Branch 0 taken 1622 times.
✗ Branch 1 not taken.
1622 extraArg := func(e, extraArg);
4687 1622 then
4688 traverseStmts(st,func,extraArg);
4689 case(DAE.ELSE(st), extraArg)
4690 825 then
4691 traverseStmts(st,func,extraArg);
4692 end match;
4693 end traverseStmtsElse;
4694
4695 public function adjacencyMatrixToSparsePattern
4696 " Applies absolute value to all entries in the adjacency matrix and
4697 also sort and unique them."
4698 input BackendDAE.AdjacencyMatrix m;
4699 output BackendDAE.AdjacencyMatrix res;
4700 protected
4701 list<list<Integer>> lst,lst_1;
4702 algorithm
4703 ✗ lst := arrayList(m);
4704 ✗ lst_1 := List.mapList(lst, intAbs);
4705 ✗ lst_1 := List.map1(lst_1, List.sort, intGt);
4706 ✗ lst_1 := List.map1(lst_1, List.sortedUnique, intGe);
4707 ✗ res := listArray(lst_1);
4708 end adjacencyMatrixToSparsePattern;
4709
4710
4711 /******************************************************************
4712 stuff to calculate enhanced Adjacency matrix
4713
4714 The Adjacency matrix describes the relation between knots and
4715 knots of a bigraph. Additional information about the solvability
4716 of a variable are available.
4717 ******************************************************************/
4718
4719 public function getAdjacencyMatrixEnhancedScalar
4720 "author: Frenkel TUD 2012-05
4721 Calculates the Adjacency matrix, i.e. which variables are present in each equation
4722 and add some information how the variable occur in the equation(see BackendDAE.BackendDAE.Solvability)."
4723 input BackendDAE.EqSystem syst;
4724 input BackendDAE.Shared shared;
4725 input Boolean trytosolve "determine the solvability by solving for the variable instead of deriving, needed for 'Casual Tearing Set'";
4726 output BackendDAE.AdjacencyMatrixEnhanced outAdjacencyMatrix;
4727 output BackendDAE.AdjacencyMatrixTEnhanced outAdjacencyMatrixT;
4728 output array<list<Integer>> outMapEqnIncRow;
4729 output array<Integer> outMapIncRowEqn;
4730 protected
4731 list<tuple<Integer,list<Integer>>> varsSolvedInWhenEqnsTupleList;
4732 algorithm
4733 (outAdjacencyMatrix,outAdjacencyMatrixT,outMapEqnIncRow,outMapIncRowEqn) :=
4734 matchcontinue (syst, shared)
4735 local
4736 BackendDAE.AdjacencyMatrixEnhanced arr;
4737 BackendDAE.AdjacencyMatrixTEnhanced arrT;
4738 BackendDAE.Variables vars,globalKnownVars;
4739 BackendDAE.EquationArray eqns;
4740 Integer numberOfEqs,numberofVars;
4741 array<Integer> rowmark "array to mark if a variable is allready found in the equation, and to mark if it is unsolvable(marked negative) in the equation";
4742 array<list<Integer>> mapEqnIncRow;
4743 array<Integer> mapIncRowEqn;
4744
4745 case (BackendDAE.EQSYSTEM(orderedVars = vars,orderedEqs = eqns), BackendDAE.SHARED(globalKnownVars=globalKnownVars))
4746 algorithm
4747 // get the size
4748 2494 numberOfEqs := BackendEquation.getNumberOfEquations(eqns);
4749 2494 numberofVars := BackendVariable.varsSize(vars);
4750 // create the array to hold the Adjacency matrix
4751 2494 arrT := arrayCreate(numberofVars, {});
4752 // create the array to mark if a variable is allready found in the equation
4753 2494 rowmark := arrayCreate(numberofVars, 0);
4754 2494 (arr,arrT,mapEqnIncRow,mapIncRowEqn,varsSolvedInWhenEqnsTupleList) := adjacencyMatrixDispatchEnhancedScalar(vars, eqns,arrT, numberOfEqs, rowmark,globalKnownVars ,trytosolve, shared);
4755 2494 then
4756 (arr,arrT,mapEqnIncRow,mapIncRowEqn);
4757
4758 else
4759 algorithm
4760 ✗ Error.addMessage(Error.INTERNAL_ERROR,{"BackendDAEUtil.getAdjacencyMatrixEnhancedScalar failed"});
4761 ✗ then
4762 fail();
4763 end matchcontinue;
4764
4765 2494 makeWhenEqnVarsUnsolvable(outAdjacencyMatrix,outAdjacencyMatrixT,varsSolvedInWhenEqnsTupleList);
4766 end getAdjacencyMatrixEnhancedScalar;
4767
4768
4769 function makeWhenEqnVarsUnsolvable
4770 "Function to make variables solved in when-equations unsolvable in all other equations.
4771 author: ptaeuber FHB"
4772 input BackendDAE.AdjacencyMatrixEnhanced m;
4773 input BackendDAE.AdjacencyMatrixTEnhanced mt;
4774 input list<tuple<Integer,list<Integer>>> varsSolvedInWhenEqnsTupleList;
4775 protected
4776 Integer eqn;
4777 list<Integer> vars,eqns;
4778 BackendDAE.AdjacencyMatrixElementEnhanced adjacencyRow;
4779 BackendDAE.AdjacencyMatrixElementEnhanced adjacencyRowT;
4780 algorithm
4781
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2494 times.
2501 for tpl in varsSolvedInWhenEqnsTupleList loop
4782 7 (eqn,vars) := tpl;
4783
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 for var in vars loop
4784
4785 // update m
4786 7 adjacencyRowT := mt[var];
4787
4/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 7 times.
21 eqns := list(
4788 match adjacencyElemT
4789 local
4790 Integer i;
4791 case(i,_,_) then i;
4792 end match for adjacencyElemT in adjacencyRowT);
4793 7 eqns := List.deleteMemberOnTrue(eqn,eqns,intEq);
4794
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 for e in eqns loop
4795 7 adjacencyRow := m[e];
4796
4/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 7 times.
26 adjacencyRow := list(
4797 match adjacencyElem
4798 local
4799 Integer i;
4800 BackendDAE.Constraints c;
4801 7 case (i,_,c) guard intEq(i,var) then (i,BackendDAE.SOLVABILITY_UNSOLVABLE(),c);
4802 case (_,_,_) then (adjacencyElem);
4803 end match for adjacencyElem in adjacencyRow);
4804 7 arrayUpdate(m,e,adjacencyRow);
4805 end for;
4806
4807 // update mt
4808 7 adjacencyRowT := mt[var];
4809
4/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 7 times.
21 adjacencyRowT := list(
4810 match adjacencyElemT
4811 local
4812 Integer i;
4813 BackendDAE.Constraints c;
4814 7 case (i,_,c) guard not intEq(i,eqn) then (i,BackendDAE.SOLVABILITY_UNSOLVABLE(),c);
4815 case (_,_,_) then (adjacencyElemT);
4816 end match for adjacencyElemT in adjacencyRowT);
4817 7 arrayUpdate(mt,var,adjacencyRowT);
4818 end for;
4819 end for;
4820 end makeWhenEqnVarsUnsolvable;
4821
4822
4823 protected function adjacencyMatrixDispatchEnhancedScalar
4824 "@author: Frenkel TUD 2012-05
4825 Calculates the adjacency matrix and the transposed
4826 adjacency matrix."
4827 input BackendDAE.Variables vars;
4828 input BackendDAE.EquationArray eqArr;
4829 output BackendDAE.AdjacencyMatrixEnhanced outAdjacencyArray;
4830 input output BackendDAE.AdjacencyMatrixTEnhanced adjacencyArrayT;
4831 input Integer numberOfEqs;
4832 input array<Integer> rowmark;
4833 input BackendDAE.Variables globalKnownVars;
4834 input Boolean trytosolve;
4835 input BackendDAE.Shared shared;
4836 output array<list<Integer>> omapEqnIncRow;
4837 output array<Integer> omapIncRowEqn;
4838 output list<tuple<Integer,list<Integer>>> varsSolvedInWhenEqnsTupleListOut = {};
4839 protected
4840 list<BackendDAE.AdjacencyMatrixElementEnhanced> inAdjacencyArray = {};
4841 list<list<Integer>> mapEqnIncRow = {};
4842 list<Integer> imapIncRowEqn = {};
4843 BackendDAE.Equation e;
4844 BackendDAE.AdjacencyMatrixElementEnhanced row;
4845 Integer size, rowSize = 0;
4846 list<tuple<Integer,list<Integer>>> varsSolvedInWhenEqnsTuple;
4847 list<Integer> rowindxs;
4848 algorithm
4849
1/2
✓ Branch 0 taken 2494 times.
✗ Branch 1 not taken.
49994 for i1 in 1:numberOfEqs loop
4850 // get the equation
4851 47500 e := BackendEquation.get(eqArr, i1);
4852 // compute the row
4853 47500 (row,size,varsSolvedInWhenEqnsTuple) := adjacencyRowEnhanced(vars, e, i1, rowmark, globalKnownVars, trytosolve, shared);
4854 47500 rowindxs := List.intRange2(rowSize+1, rowSize+size);
4855 47500 rowSize := rowSize + size;
4856 47500 imapIncRowEqn := List.consN(size,i1,imapIncRowEqn);
4857 // put it in the arrays
4858 47500 inAdjacencyArray := List.consN(size,row,inAdjacencyArray);
4859 47500 adjacencyArrayT := fillincAdjacencyMatrixTEnhanced(row,rowindxs,adjacencyArrayT);
4860 47500 varsSolvedInWhenEqnsTupleListOut := listAppend(varsSolvedInWhenEqnsTuple, varsSolvedInWhenEqnsTupleListOut);
4861 mapEqnIncRow := rowindxs::mapEqnIncRow;
4862 end for;
4863 2494 outAdjacencyArray := List.listArrayReverse(inAdjacencyArray);
4864 2494 omapEqnIncRow := List.listArrayReverse(mapEqnIncRow);
4865 2494 omapIncRowEqn := List.listArrayReverse(imapIncRowEqn);
4866 end adjacencyMatrixDispatchEnhancedScalar;
4867
4868
4869 public function getAdjacencyMatrixEnhanced
4870 "author: Frenkel TUD 2012-05
4871 Calculates the Adjacency matrix, i.e. which variables are present in each equation
4872 and add some information how the variable occure in the equation(see BackendDAE.BackendDAE.Solvability)."
4873 input BackendDAE.EqSystem syst;
4874 input BackendDAE.Shared shared;
4875 input Boolean trytosolve;
4876 output BackendDAE.AdjacencyMatrixEnhanced outAdjacencyMatrix;
4877 output BackendDAE.AdjacencyMatrixTEnhanced outAdjacencyMatrixT;
4878 algorithm
4879 (outAdjacencyMatrix,outAdjacencyMatrixT) := matchcontinue (syst, shared)
4880 local
4881 BackendDAE.AdjacencyMatrixEnhanced arr;
4882 BackendDAE.AdjacencyMatrixTEnhanced arrT;
4883 BackendDAE.Variables vars,globalKnownVars;
4884 BackendDAE.EquationArray eqns;
4885 Integer numberOfEqs,numberofVars;
4886 array<Integer> rowmark "array to mark if a variable is allready found in the equation, and to mark if it is unsolvable(marked negative) in the equation";
4887
4888 case (BackendDAE.EQSYSTEM(orderedVars = vars,orderedEqs = eqns), BackendDAE.SHARED(globalKnownVars=globalKnownVars))
4889 algorithm
4890 // get the size
4891 34 numberOfEqs := BackendEquation.getNumberOfEquations(eqns);
4892 34 numberofVars := BackendVariable.varsSize(vars);
4893 // create the array to hold the Adjacency matrix
4894 34 arr := arrayCreate(BackendEquation.equationArraySize(eqns), {});
4895 34 arrT := arrayCreate(numberofVars, {});
4896 // create the array to mark if a variable is allready found in the equation
4897 34 rowmark := arrayCreate(numberofVars, 0);
4898 34 (arr,arrT) := adjacencyMatrixDispatchEnhanced(vars, eqns, arr,arrT, 0, numberOfEqs, intLt(0, numberOfEqs),rowmark,globalKnownVars,trytosolve,shared);
4899 then
4900 (arr,arrT);
4901
4902 else
4903 algorithm
4904 ✗ Error.addMessage(Error.INTERNAL_ERROR,{"BackendDAEUtil.getAdjacencyMatrixEnhanced failed"});
4905 ✗ then
4906 fail();
4907 end matchcontinue;
4908 end getAdjacencyMatrixEnhanced;
4909
4910 protected function adjacencyMatrixDispatchEnhanced
4911 "@author: Frenkel TUD 2012-05
4912 Calculates the adjacency matrix and the transposed
4913 adjacency matrix."
4914 input BackendDAE.Variables vars;
4915 input BackendDAE.EquationArray eqArr;
4916 input BackendDAE.AdjacencyMatrixEnhanced inAdjacencyArray;
4917 input BackendDAE.AdjacencyMatrixTEnhanced inAdjacencyArrayT;
4918 input Integer index;
4919 input Integer numberOfEqs;
4920 input Boolean stop;
4921 input array<Integer> rowmark;
4922 input BackendDAE.Variables globalKnownVars;
4923 input Boolean trytosolve;
4924 input BackendDAE.Shared shared;
4925 output BackendDAE.AdjacencyMatrixEnhanced outAdjacencyArray;
4926 output BackendDAE.AdjacencyMatrixTEnhanced outAdjacencyArrayT;
4927 algorithm
4928 (outAdjacencyArray,outAdjacencyArrayT) :=
4929 match stop
4930 local
4931 BackendDAE.AdjacencyMatrixElementEnhanced row;
4932 BackendDAE.Equation e;
4933 BackendDAE.AdjacencyMatrixEnhanced iArr;
4934 BackendDAE.AdjacencyMatrixTEnhanced iArrT;
4935 Integer i1;
4936
4937 // index = numberOfEqs (we reach the end)
4938 case false
4939 then (inAdjacencyArray, inAdjacencyArrayT);
4940
4941 // index < numberOfEqs
4942 case true
4943 algorithm
4944 2226 i1 := index+1;
4945
4946 // get the equation
4947 2226 e := BackendEquation.get(eqArr, i1);
4948 // compute the row
4949 2226 (row,_,_) := adjacencyRowEnhanced(vars, e, i1, rowmark, globalKnownVars, trytosolve,shared);
4950 // put it in the arrays
4951 2226 iArr := arrayUpdate(inAdjacencyArray, i1, row);
4952 2226 iArrT := fillincAdjacencyMatrixTEnhanced(row,{i1},inAdjacencyArrayT);
4953 2226 (iArr,iArrT) := adjacencyMatrixDispatchEnhanced(vars, eqArr, iArr, iArrT, i1, numberOfEqs, intLt(i1, numberOfEqs), rowmark, globalKnownVars, trytosolve, shared);
4954 then
4955 (iArr,iArrT);
4956 end match;
4957 end adjacencyMatrixDispatchEnhanced;
4958
4959 protected function fillincAdjacencyMatrixTEnhanced
4960 "@author: Frenkel TUD 2011-04
4961 helper for adjacencyMatrixDispatchEnhanced.
4962 Inserts the rows in the transposed adjacency matrix."
4963 input BackendDAE.AdjacencyMatrixElementEnhanced eqns;
4964 input list<Integer> eqnsindxs;
4965 input BackendDAE.AdjacencyMatrixTEnhanced inAdjacencyArrayT;
4966 output BackendDAE.AdjacencyMatrixTEnhanced outAdjacencyArrayT;
4967 algorithm
4968 outAdjacencyArrayT := matchcontinue eqns
4969 local
4970 BackendDAE.AdjacencyMatrixElementEnhanced row,rest,newrow;
4971 Integer v,vabs;
4972 BackendDAE.AdjacencyMatrixTEnhanced mT;
4973 BackendDAE.Solvability solva;
4974 BackendDAE.Constraints cons;
4975 list<Integer> eqnsindxs1;
4976
4977 case {} then inAdjacencyArrayT;
4978
4979 case (v,solva,cons)::rest
4980 guard
4981 intLt(0, v)
4982 algorithm
4983 119655 row := inAdjacencyArrayT[v];
4984 119655 newrow := List.map2(eqnsindxs,Util.make3Tuple,solva,cons);
4985 119655 row := listAppend(newrow,row);
4986 // put it in the array
4987 119655 mT := arrayUpdate(inAdjacencyArrayT, v, row);
4988 119655 then
4989 fillincAdjacencyMatrixTEnhanced(rest, eqnsindxs, mT);
4990
4991 case (v,solva,cons)::rest
4992 algorithm
4993 41404 vabs := intAbs(v);
4994 41404 row := inAdjacencyArrayT[vabs];
4995 41404 eqnsindxs1 := List.map(eqnsindxs,intNeg);
4996 41404 newrow := List.map2(eqnsindxs1,Util.make3Tuple,solva,cons);
4997 // put it in the array
4998 41404 row := listAppend(newrow,row);
4999 41404 mT := arrayUpdate(inAdjacencyArrayT, vabs, row);
5000 41404 then
5001 fillincAdjacencyMatrixTEnhanced(rest, eqnsindxs, mT);
5002
5003 case _
5004 algorithm
5005 ✗ Error.addMessage(Error.INTERNAL_ERROR,{"BackendDAEUtil.fillincAdjacencyMatrixTEnhanced failed"});
5006 ✗ then
5007 fail();
5008 end matchcontinue;
5009 end fillincAdjacencyMatrixTEnhanced;
5010
5011 public function adjacencyRowEnhanced
5012 "author: Frenkel TUD 2012-05
5013 Helper function to adjacencyMatrixDispatchEnhanced. Calculates the adjacency row
5014 in the matrix for one equation."
5015 input BackendDAE.Variables inVariables;
5016 input BackendDAE.Equation inEquation;
5017 input Integer mark;
5018 input array<Integer> rowmark;
5019 input BackendDAE.Variables globalKnownVars;
5020 input Boolean trytosolve;
5021 input BackendDAE.Shared shared;
5022 output BackendDAE.AdjacencyMatrixElementEnhanced outRow;
5023 output Integer size;
5024 output list<tuple<Integer,list<Integer>>> varsSolvedInWhenEqnsTuple={};
5025 protected
5026 Boolean isInitial;
5027 algorithm
5028 49769 isInitial := isInitializationDAE(shared);
5029 (outRow,size) := matchcontinue (inVariables, inEquation)
5030 local
5031 list<Integer> lst,ds, lstall, varsSolvedInWhenEqns;
5032 BackendDAE.Variables vars;
5033 DAE.Exp e1,e2,e,expCref;
5034 list<DAE.Exp> expl;
5035 DAE.ComponentRef cr;
5036 BackendDAE.WhenEquation elsewe;
5037 String eqnstr;
5038 DAE.Algorithm alg;
5039 BackendDAE.AdjacencyMatrixElementEnhanced row, row1;
5040 list<list<BackendDAE.Equation>> eqnslst;
5041 list<BackendDAE.Equation> eqns,eqnselse;
5042 list<DAE.ComponentRef> algoutCrefs;
5043 DAE.Expand crefExpand;
5044 DAE.ElementSource source;
5045
5046 // EQUATION
5047 case (vars, BackendDAE.EQUATION(exp = e1,scalar = e2))
5048 algorithm
5049 49340 lst := adjacencyRowExpEnhanced(e1, vars, mark, rowmark, isInitial, {});
5050 49340 lst := adjacencyRowExpEnhanced(e2, vars, mark, rowmark, isInitial, lst);
5051 49340 row := adjacencyRowEnhanced1(lst,e1,e2,vars,globalKnownVars,mark,rowmark,{},trytosolve,1,shared);
5052 then
5053 (row,1);
5054 // COMPLEX_EQUATION
5055 case (vars, BackendDAE.COMPLEX_EQUATION(size=size,left=e1,right=e2))
5056 algorithm
5057 357 lst := adjacencyRowExpEnhanced(e1, vars, mark, rowmark, isInitial, {});
5058 357 lst := adjacencyRowExpEnhanced(e2, vars, mark, rowmark, isInitial, lst);
5059 357 row := adjacencyRowEnhanced1(lst,e1,e2,vars,globalKnownVars,mark,rowmark,{},trytosolve,size,shared);
5060 357 then
5061 (row,size);
5062 // ARRAY_EQUATION
5063 case (vars, BackendDAE.ARRAY_EQUATION(dimSize=ds,left=e1,right=e2))
5064 algorithm
5065 23 lst := adjacencyRowExpEnhanced(e1, vars, mark, rowmark, isInitial, {});
5066 23 lst := adjacencyRowExpEnhanced(e2, vars, mark, rowmark, isInitial, lst);
5067 23 size := List.fold(ds,intMul,1);
5068 23 row := adjacencyRowEnhanced1(lst,e1,e2,vars,globalKnownVars,mark,rowmark,{},trytosolve,size,shared);
5069 23 then
5070 (row,size);
5071
5072 // SOLVED_EQUATION
5073 case (vars, BackendDAE.SOLVED_EQUATION(componentRef = cr,exp = e))
5074 algorithm
5075 ✗ expCref := Expression.crefExp(cr);
5076 ✗ lst := adjacencyRowExpEnhanced(expCref, vars, mark, rowmark, isInitial, {});
5077 ✗ lst := adjacencyRowExpEnhanced(e, vars, mark, rowmark, isInitial, lst);
5078 ✗ row := adjacencyRowEnhanced1(lst,expCref,e,vars,globalKnownVars,mark,rowmark,{},trytosolve,1,shared);
5079 then
5080 (row,1);
5081 // RESIDUAL_EQUATION
5082 case (vars, BackendDAE.RESIDUAL_EQUATION(exp = e))
5083 algorithm
5084 ✗ lst := adjacencyRowExpEnhanced(e, vars, mark, rowmark, isInitial, {});
5085 ✗ row := adjacencyRowEnhanced1(lst,e,DAE.RCONST(0.0),vars,globalKnownVars,mark,rowmark,{},trytosolve,1,shared);
5086 then
5087 (row,1);
5088
5089 // WHEN_EQUATION
5090 case (vars, BackendDAE.WHEN_EQUATION(size=size,whenEquation = elsewe))
5091 algorithm
5092 7 (row,varsSolvedInWhenEqns) := adjacencyRowWhenEnhanced(elsewe, mark, rowmark, vars, globalKnownVars, {}, {},shared);
5093 7 varsSolvedInWhenEqnsTuple := {(mark,varsSolvedInWhenEqns)};
5094 7 then
5095 (row,size);
5096
5097 // ALGORITHM For now assume that algorithm will be solvable for
5098 // output variables. Mark this as solved and input variables as unsolvable:
5099 case (vars, BackendDAE.ALGORITHM(size=size,alg=alg,source=source,expand=crefExpand))
5100 algorithm
5101 // get outputs
5102 42 algoutCrefs := CheckModel.checkAndGetAlgorithmOutputs(alg, source, crefExpand);
5103 // mark outputs as solved
5104 42 row := adjacencyRowAlgorithmOutputs(algoutCrefs,vars,mark,rowmark,{});
5105 // get inputs
5106 42 expl := Algorithm.getAllExps(alg);
5107 // mark inputs as unsolvable
5108 42 (_,(_,_,_,row)) := Expression.traverseExpList(expl, adjacencyRowAlgorithmInputs, (vars,mark,rowmark,row));
5109 42 then
5110 (row,size);
5111
5112 /*
5113 special case: initial()
5114 if initial() then ... else ... end if;
5115 only then branch needs to be checked for initialization and else branch otherwise
5116 */
5117 case(_, BackendDAE.IF_EQUATION(conditions={DAE.CALL(path=Absyn.IDENT("initial"))},eqnstrue={eqns}, eqnsfalse=eqnselse))
5118 algorithm
5119 ✗ if isInitializationDAE(shared) then
5120 ✗ (row,size) := adjacencyRowEnhancedEqnLst(eqns,inVariables,mark,rowmark,globalKnownVars,trytosolve,shared);
5121 else
5122 ✗ (row,size) := adjacencyRowEnhancedEqnLst(eqnselse,inVariables,mark,rowmark,globalKnownVars,trytosolve,shared);
5123 end if;
5124 ✗ then
5125 (row,size);
5126
5127 /*
5128 special case: NEGATED initial()
5129 if not initial() then ... else ... end if;
5130 only else branch needs to be checked for initialization and then branch otherwise
5131 */
5132 case(_, BackendDAE.IF_EQUATION(conditions={DAE.LUNARY(DAE.NOT(), DAE.CALL(path=Absyn.IDENT("initial")))},eqnstrue={eqns}, eqnsfalse=eqnselse))
5133 algorithm
5134 ✗ if isInitializationDAE(shared) then
5135 ✗ (row,size) := adjacencyRowEnhancedEqnLst(eqnselse,inVariables,mark,rowmark,globalKnownVars,trytosolve,shared);
5136 else
5137 ✗ (row,size) := adjacencyRowEnhancedEqnLst(eqns,inVariables,mark,rowmark,globalKnownVars,trytosolve,shared);
5138 end if;
5139 ✗ then
5140 (row,size);
5141
5142 // if Equation
5143 // TODO : how to handle this?
5144 // Proposal:
5145 // 1. mark all vars in conditions as unsolvable
5146 // 2. vars occur in all branches: check how they are occur
5147 // 3. vars occur not in all branches: mark as unsolvable
5148 case(vars, BackendDAE.IF_EQUATION(conditions=expl,eqnstrue=eqnslst,eqnsfalse=eqnselse))
5149 algorithm
5150 //print("Warning: BackendDAEUtil.adjacencyRowEnhanced does not handle if-equations propper!\n");
5151 // mark all negative because the when condition cannot used to solve a variable
5152 ✗ lst := List.fold4(expl, adjacencyRowExpEnhanced, vars, mark, rowmark, isInitial, {});
5153 ✗ List.fold1(lst,markNegativ,rowmark,mark);
5154 ✗ row1 := adjacencyRowEnhanced1(lst,DAE.RCONST(0.0),DAE.RCONST(0.0),vars,globalKnownVars,mark,rowmark,{},trytosolve,1,shared);
5155
5156 ✗ (row, size) := adjacencyRowEnhancedEqnLst(eqnselse, vars, mark, rowmark, globalKnownVars, trytosolve,shared);
5157 ✗ lst := List.map(row,Util.tuple31);
5158
5159 ✗ for eq in eqnslst loop
5160 ✗ (lst, row, _) := adjacencyRowEnhancedEqnLstIfBranches(eq, vars, mark, rowmark, globalKnownVars, trytosolve, shared, (lst, row, size));
5161 end for;
5162
5163 ✗ lstall := List.map(row, Util.tuple31);
5164 ✗ (_, lst, _) := List.intersection1OnTrue(lstall, lst, intEq);
5165 ✗ List.fold1(lst, markNegativ, rowmark, mark);
5166 ✗ row := listAppend(row1,row);
5167 ✗ then
5168 (row,size);
5169
5170 else
5171 algorithm
5172 ✗ eqnstr := BackendDump.equationString(inEquation);
5173 ✗ eqnstr := stringAppendList({"BackendDAE.adjacencyRowEnhanced failed for eqn:\n",eqnstr,"\n"});
5174 ✗ Error.addMessage(Error.INTERNAL_ERROR,{eqnstr});
5175 ✗ then
5176 fail();
5177 end matchcontinue;
5178 end adjacencyRowEnhanced;
5179
5180 protected function adjacencyRowEnhancedEqnLstIfBranches
5181 input list<BackendDAE.Equation> iEqns;
5182 input BackendDAE.Variables inVariables;
5183 input Integer mark;
5184 input array<Integer> rowmark;
5185 input BackendDAE.Variables globalKnownVars;
5186 input Boolean trytosolve;
5187 input BackendDAE.Shared shared;
5188 input tuple<list<Integer>,BackendDAE.AdjacencyMatrixElementEnhanced,Integer> intpl;
5189 output tuple<list<Integer>,BackendDAE.AdjacencyMatrixElementEnhanced,Integer> outtpl;
5190 protected
5191 BackendDAE.AdjacencyMatrixElementEnhanced row, iRow;
5192 list<Integer> lst, inLstAllBranch;
5193 Integer size, iSize;
5194 algorithm
5195 ✗ (inLstAllBranch,iRow,iSize) := intpl;
5196 ✗ for eqn in iEqns loop
5197 ✗ (row,size,_) := adjacencyRowEnhanced(inVariables, eqn, mark, rowmark, globalKnownVars, trytosolve,shared);
5198 ✗ lst := List.map(row,Util.tuple31);
5199 ✗ inLstAllBranch := List.intersectionOnTrue(lst, inLstAllBranch,intEq);
5200 ✗ iSize := iSize + size;
5201 ✗ iRow := listAppend(row,iRow);
5202 end for;
5203 ✗ outtpl := (inLstAllBranch,iRow,iSize);
5204 end adjacencyRowEnhancedEqnLstIfBranches;
5205
5206 protected function adjacencyRowEnhancedEqnLst
5207 input list<BackendDAE.Equation> iEqns;
5208 input BackendDAE.Variables inVariables;
5209 input Integer mark;
5210 input array<Integer> rowmark;
5211 input BackendDAE.Variables globalKnownVars;
5212 input Boolean trytosolve;
5213 input BackendDAE.Shared shared;
5214 output BackendDAE.AdjacencyMatrixElementEnhanced outRow = {};
5215 output Integer oSize = 0;
5216 protected
5217 BackendDAE.AdjacencyMatrixElementEnhanced row;
5218 Integer size;
5219 algorithm
5220 ✗ for eqn in iEqns loop
5221 ✗ (row,size,_) := adjacencyRowEnhanced(inVariables,eqn,mark,rowmark,globalKnownVars,trytosolve,shared);
5222 ✗ outRow := listAppend(row,outRow);
5223 ✗ oSize := oSize + size;
5224 end for;
5225 end adjacencyRowEnhancedEqnLst;
5226
5227 protected function adjacencyRowAlgorithmOutputs
5228 "author: Frenkel TUD 10-2012
5229 Helper function to adjacencyRowEnhanced. Mark all algorithm outputs
5230 as solved."
5231 input list<DAE.ComponentRef> algOutputs;
5232 input BackendDAE.Variables inVariables;
5233 input Integer mark;
5234 input array<Integer> rowmark;
5235 input BackendDAE.AdjacencyMatrixElementEnhanced iRow;
5236 output BackendDAE.AdjacencyMatrixElementEnhanced outRow;
5237 algorithm
5238 outRow := match algOutputs
5239 local
5240 DAE.ComponentRef cr;
5241 list<DAE.ComponentRef> rest;
5242 list<Integer> vindx;
5243 BackendDAE.AdjacencyMatrixElementEnhanced row;
5244 case {} then iRow;
5245 case cr::rest
5246 algorithm
5247 96 (_,vindx) := BackendVariable.getVar(cr,inVariables);
5248 96 row := adjacencyRowAlgorithmOutputs1(vindx,mark,rowmark,iRow);
5249 96 then
5250 adjacencyRowAlgorithmOutputs(rest,inVariables,mark,rowmark,row);
5251 end match;
5252 end adjacencyRowAlgorithmOutputs;
5253
5254 protected function adjacencyRowAlgorithmOutputs1
5255 "author: Frenkel TUD 10-2012
5256 Helper function to adjacencyRowEnhanced. Mark all algorithm outputs
5257 as solved."
5258 input list<Integer> vindx;
5259 input Integer mark;
5260 input array<Integer> rowmark;
5261 input BackendDAE.AdjacencyMatrixElementEnhanced iRow;
5262 output BackendDAE.AdjacencyMatrixElementEnhanced outRow;
5263 algorithm
5264 outRow := match vindx
5265 local
5266 Integer i;
5267 list<Integer> rest;
5268 case {} then iRow;
5269 case i::rest
5270 algorithm
5271 96 arrayUpdate(rowmark,i,mark);
5272 192 then
5273 adjacencyRowAlgorithmOutputs1(rest,mark,rowmark,(i,BackendDAE.SOLVABILITY_SOLVED(),{})::iRow);
5274 end match;
5275 end adjacencyRowAlgorithmOutputs1;
5276
5277 protected function adjacencyRowAlgorithmInputs
5278 "author: Frenkel TUD 10-2012
5279 Helper function to adjacencyRowEnhanced. Mark all algorithm inputs
5280 as unsolvable."
5281 input DAE.Exp inExp;
5282 input tuple<BackendDAE.Variables,Integer,array<Integer>,BackendDAE.AdjacencyMatrixElementEnhanced> iTpl;
5283 output DAE.Exp outExp;
5284 output tuple<BackendDAE.Variables,Integer,array<Integer>,BackendDAE.AdjacencyMatrixElementEnhanced> oTpl;
5285 algorithm
5286 (outExp,oTpl) := matchcontinue (inExp,iTpl)
5287 local
5288 DAE.Exp e;
5289 DAE.ComponentRef cr;
5290 BackendDAE.Variables vars;
5291 Integer mark;
5292 array<Integer>rowmark;
5293 BackendDAE.AdjacencyMatrixElementEnhanced row;
5294 list<Integer> vindx;
5295 case (e as DAE.CREF(componentRef=cr),(vars,mark,rowmark,row))
5296 algorithm
5297 1510 (_,vindx) := BackendVariable.getVar(cr,vars);
5298 548 row := adjacencyRowAlgorithmInputs1(vindx,mark,rowmark,row);
5299 548 then (e,(vars,mark,rowmark,row));
5300 else (inExp,iTpl);
5301 end matchcontinue;
5302 end adjacencyRowAlgorithmInputs;
5303
5304 protected function adjacencyRowAlgorithmInputs1
5305 "author: Frenkel TUD 10-2012
5306 Helper function to adjacencyRowEnhanced. Mark all algorithm inputs
5307 as unsolvable."
5308 input list<Integer> vindx;
5309 input Integer mark;
5310 input array<Integer> rowmark;
5311 input BackendDAE.AdjacencyMatrixElementEnhanced iRow;
5312 output BackendDAE.AdjacencyMatrixElementEnhanced outRow;
5313 algorithm
5314 outRow := match vindx
5315 local
5316 Integer i;
5317 list<Integer> rest;
5318 case {} then iRow;
5319 case i::rest
5320 guard
5321 // not already handled
5322 not intEq(intAbs(rowmark[i]),mark)
5323 algorithm
5324 104 arrayUpdate(rowmark,i,-mark);
5325 208 then
5326 adjacencyRowAlgorithmInputs1(rest,mark,rowmark,(i,BackendDAE.SOLVABILITY_UNSOLVABLE(),{})::iRow);
5327 case _::rest
5328 609 then
5329 adjacencyRowAlgorithmInputs1(rest,mark,rowmark,iRow);
5330 end match;
5331 end adjacencyRowAlgorithmInputs1;
5332
5333 protected function adjacencyRowWhenEnhanced
5334 "author: Frenkel TUD
5335 Helper function to adjacencyMatrixDispatchEnhanced. Calculates the adjacency row
5336 in the matrix for one equation."
5337 input BackendDAE.WhenEquation inEquation;
5338 input Integer mark;
5339 input array<Integer> rowmark;
5340 input BackendDAE.Variables vars;
5341 input BackendDAE.Variables globalKnownVars;
5342 input list<Integer> iLst;
5343 input BackendDAE.AdjacencyMatrixElementEnhanced iRow;
5344 input BackendDAE.Shared shared;
5345 output BackendDAE.AdjacencyMatrixElementEnhanced outRow = iRow;
5346 output list<Integer> varsSolvedInWhenEqns={};
5347 protected
5348 DAE.Exp condition;
5349 list<BackendDAE.WhenOperator> whenStmtLst;
5350 Option<BackendDAE.WhenEquation> oelsepart;
5351 list<Integer> lst;
5352 BackendDAE.WhenEquation elsepart;
5353 Boolean isInitial;
5354 algorithm
5355 7 isInitial := isInitializationDAE(shared);
5356 7 BackendDAE.WHEN_STMTS(condition = condition, whenStmtLst = whenStmtLst, elsewhenPart = oelsepart) := inEquation;
5357 7 lst := adjacencyRowExpEnhanced(condition, vars, mark, rowmark, isInitial, iLst);
5358
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 for rs in whenStmtLst loop
5359 () := match rs
5360 local
5361 Integer varIndx;
5362 list<Integer> varIdcs;
5363 DAE.ComponentRef left;
5364 list<DAE.ComponentRef> crefs;
5365 DAE.Exp right, leftexp;
5366
5367 case BackendDAE.ASSIGN(left = leftexp as DAE.CREF(componentRef = left), right=right)
5368 algorithm
5369
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
7 (_,{varIndx}) := BackendVariable.getVar(left, vars);
5370 varsSolvedInWhenEqns := varIndx :: varsSolvedInWhenEqns;
5371 7 lst := adjacencyRowExpEnhanced(right, vars, mark, rowmark, isInitial, lst);
5372 // mark all negative because the when condition cannot used to solve a variable
5373 7 List.fold1(lst,markNegativ,rowmark,mark);
5374 //leftexp = Expression.crefExp(left);
5375 7 lst := adjacencyRowExpEnhanced(leftexp, vars, mark, rowmark, isInitial, lst);
5376 7 outRow := adjacencyRowEnhanced1(lst,leftexp,right,vars,globalKnownVars,mark,rowmark,outRow,false,1,shared);
5377 then ();
5378
5379 case BackendDAE.ASSIGN(leftexp, right) algorithm
5380 ✗ crefs := Expression.getAllCrefs(leftexp);
5381 ✗ (_,varIdcs) := BackendVariable.getVarLst(crefs, vars);
5382 ✗ varsSolvedInWhenEqns := listAppend(varIdcs, varsSolvedInWhenEqns);
5383 ✗ lst := adjacencyRowExpEnhanced(right, vars, mark, rowmark, isInitial, lst);
5384 // mark all negative because the when condition cannot used to solve a variable
5385 ✗ List.fold1(lst,markNegativ,rowmark,mark);
5386 ✗ lst := adjacencyRowExpEnhanced(leftexp, vars, mark, rowmark, isInitial, lst);
5387 ✗ outRow := adjacencyRowEnhanced1(lst,leftexp,right,vars,globalKnownVars,mark,rowmark,outRow,false,1,shared);
5388 then ();
5389
5390 else ();
5391 end match;
5392
5393 end for;
5394
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 if isSome(oelsepart) then
5395 ✗ SOME(elsepart) := oelsepart;
5396 ✗ outRow := adjacencyRowWhenEnhanced(elsepart, mark, rowmark, vars, globalKnownVars, lst, outRow, shared);
5397 end if;
5398 end adjacencyRowWhenEnhanced;
5399
5400 protected function markNegativ
5401 "author: Frenkel TUD 2012-05
5402 Helper function to adjacencyRowEnhanced. Update the array
5403 with a negative entry in indx."
5404 input Integer indx;
5405 input array<Integer> rowmark;
5406 input Integer mark;
5407 output Integer oMark;
5408 algorithm
5409 15 arrayUpdate(rowmark,indx,-mark);
5410 oMark := mark;
5411 end markNegativ;
5412
5413 protected function adjacencyRowEnhanced1
5414 "author: Frenkel TUD 2012-05
5415 Helper function to adjacencyRowEnhanced. Calculates the
5416 solvability of the variables."
5417 input list<Integer> lst;
5418 input DAE.Exp e1;
5419 input DAE.Exp e2;
5420 input BackendDAE.Variables vars;
5421 input BackendDAE.Variables globalKnownVars;
5422 input Integer mark;
5423 input array<Integer> rowmark;
5424 input BackendDAE.AdjacencyMatrixElementEnhanced inRow;
5425 input Boolean trytosolve;
5426 input Integer size;
5427 input BackendDAE.Shared shared;
5428 output BackendDAE.AdjacencyMatrixElementEnhanced outRow;
5429 algorithm
5430 outRow := matchcontinue(lst, e1, e2)
5431 local
5432 Integer r,rabs;
5433 list<Integer> rest;
5434 DAE.Exp de,e, e_derAlias;
5435 DAE.ComponentRef cr,cr1,crarr;
5436 BackendDAE.Solvability solvab;
5437 list<DAE.ComponentRef> crlst;
5438 Absyn.Path path,path1;
5439 list<DAE.Exp> explst,crexplst;
5440 Boolean solved,derived;
5441 BackendDAE.Constraints cons;
5442 case({}, _, _) then inRow;
5443 /* case(r::rest,_,_,_,_,_,_,_)
5444 algorithm
5445 // if r negativ then unsolvable
5446 true = intLt(r,0);
5447 then
5448 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_UNSOLVABLE())::inRow,trytosolve);
5449 */
5450 case(r::rest, DAE.CALL(path= Absyn.IDENT("der"),expLst={DAE.CREF(componentRef = cr)}), _)
5451 guard
5452 intGt(r,0)
5453 algorithm
5454 // if not negatet rowmark then
5455
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 426 times.
426 false := intEq(rowmark[r],-mark);
5456 // solved?
5457
2/2
✓ Branch 1 taken 261 times.
✓ Branch 2 taken 165 times.
426 BackendDAE.VAR(varName=cr1,varKind=BackendDAE.STATE()) := BackendVariable.getVarAt(vars, r);
5458
2/2
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 148 times.
165 true := ComponentReferenceBasics.crefEqualNoStringCompare(cr, cr1);
5459
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 148 times.
148 false := Expression.expHasDerCref(e2,cr);
5460 296 then
5461 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5462 case(r::rest, _, DAE.CALL(path= Absyn.IDENT("der"),expLst={DAE.CREF(componentRef = cr)}))
5463 algorithm
5464 96 rabs := intAbs(r);
5465 // if not negatet rowmark then
5466
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 96 times.
96 false := intEq(rowmark[rabs],-mark);
5467 // solved?
5468
2/2
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 48 times.
96 BackendDAE.VAR(varName=cr1,varKind=BackendDAE.STATE()) := BackendVariable.getVarAt(vars, rabs);
5469
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 true := ComponentReferenceBasics.crefEqualNoStringCompare(cr, cr1);
5470
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 false := Expression.expHasDerCref(e1,cr);
5471 96 then
5472 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5473 case(r::rest, DAE.CREF(componentRef=cr), _)
5474 algorithm
5475 122522 rabs := intAbs(r);
5476 // if not negatet rowmark then
5477
2/2
✓ Branch 1 taken 6474 times.
✓ Branch 2 taken 116048 times.
122522 false := intEq(rowmark[rabs],-mark);
5478 // solved?
5479 116048 BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5480
2/2
✓ Branch 1 taken 79860 times.
✓ Branch 2 taken 36188 times.
116048 true := ComponentReferenceBasics.crefEqualNoStringCompare(cr, cr1);
5481
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 36168 times.
36188 false := Expression.expHasCrefNoPreorDer(e2,cr);
5482 72336 then
5483 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5484 case(r::rest, DAE.CREF(componentRef=cr), _)
5485 algorithm
5486 86354 rabs := intAbs(r);
5487 // if not negatet rowmark then
5488
2/2
✓ Branch 1 taken 6474 times.
✓ Branch 2 taken 79880 times.
86354 false := intEq(rowmark[rabs],-mark);
5489 // solved?
5490 79880 BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5491 79880 crarr := ComponentReferenceBasics.crefStripLastSubs(cr1);
5492
2/2
✓ Branch 1 taken 79860 times.
✓ Branch 2 taken 20 times.
79880 true := ComponentReferenceBasics.crefEqualNoStringCompare(cr, crarr);
5493
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 false := Expression.expHasCrefNoPreorDer(e2,cr);
5494 ✗ then
5495 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5496 case(r::rest, DAE.LUNARY(operator=DAE.NOT(_),exp=DAE.CREF(componentRef=cr)), _)
5497 algorithm
5498 ✗ rabs := intAbs(r);
5499 // if not negatet rowmark then
5500 ✗ false := intEq(rowmark[rabs],-mark);
5501 // solved?
5502 ✗ BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5503 ✗ true := ComponentReferenceBasics.crefEqualNoStringCompare(cr, cr1);
5504 ✗ false := Expression.expHasCrefNoPreorDer(e2,cr);
5505 ✗ then
5506 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5507 case(r::rest, DAE.UNARY(operator=DAE.UMINUS(_),exp=DAE.CREF(componentRef=cr)), _)
5508 algorithm
5509 7086 rabs := intAbs(r);
5510 // if not negatet rowmark then
5511
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 7084 times.
7086 false := intEq(rowmark[rabs],-mark);
5512 // solved?
5513 7084 BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5514
2/2
✓ Branch 1 taken 4977 times.
✓ Branch 2 taken 2107 times.
7084 true := ComponentReferenceBasics.crefEqualNoStringCompare(cr, cr1);
5515
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2107 times.
2107 false := Expression.expHasCrefNoPreorDer(e2,cr);
5516 4214 then
5517 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5518 case(r::rest, DAE.UNARY(operator=DAE.UMINUS_ARR(_),exp=DAE.CREF(componentRef=cr)), _)
5519 algorithm
5520 ✗ rabs := intAbs(r);
5521 // if not negatet rowmark then
5522 ✗ false := intEq(rowmark[rabs],-mark);
5523 // solved?
5524 ✗ BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5525 ✗ crarr := ComponentReferenceBasics.crefStripLastSubs(cr1);
5526 ✗ true := ComponentReferenceBasics.crefEqualNoStringCompare(cr, crarr);
5527 ✗ false := Expression.expHasCrefNoPreorDer(e2,cr);
5528 ✗ then
5529 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5530 case(r::rest, _, DAE.CREF(componentRef=cr))
5531 algorithm
5532 5324 rabs := intAbs(r);
5533 // if not negatet rowmark then
5534
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5324 times.
5324 false := intEq(rowmark[rabs],-mark);
5535 // solved?
5536 5324 BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5537
2/2
✓ Branch 1 taken 3085 times.
✓ Branch 2 taken 2239 times.
5324 true := ComponentReferenceBasics.crefEqualNoStringCompare(cr, cr1);
5538
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2239 times.
2239 false := Expression.expHasCrefNoPreorDer(e1,cr);
5539 4478 then
5540 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5541 case(r::rest, _, DAE.CREF(componentRef=cr))
5542 algorithm
5543 3085 rabs := intAbs(r);
5544 // if not negatet rowmark then
5545
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3085 times.
3085 false := intEq(rowmark[rabs],-mark);
5546 // solved?
5547 3085 BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5548 3085 crarr := ComponentReferenceBasics.crefStripLastSubs(cr1);
5549
1/2
✓ Branch 1 taken 3085 times.
✗ Branch 2 not taken.
3085 true := ComponentReferenceBasics.crefEqualNoStringCompare(cr, crarr);
5550 ✗ false := Expression.expHasCrefNoPreorDer(e1,cr);
5551 ✗ then
5552 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5553 case(r::rest, _, DAE.LUNARY(operator=DAE.NOT(_),exp=DAE.CREF(componentRef=cr)))
5554 algorithm
5555 ✗ rabs := intAbs(r);
5556 // if not negatet rowmark then
5557 ✗ false := intEq(rowmark[rabs],-mark);
5558 // solved?
5559 ✗ BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5560 ✗ true := ComponentReferenceBasics.crefEqualNoStringCompare(cr, cr1);
5561 ✗ false := Expression.expHasCrefNoPreorDer(e1,cr);
5562 ✗ then
5563 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5564 case(r::rest, _, DAE.UNARY(operator=DAE.UMINUS(_),exp=DAE.CREF(componentRef=cr)))
5565 algorithm
5566 69 rabs := intAbs(r);
5567 // if not negatet rowmark then
5568
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 69 times.
69 false := intEq(rowmark[rabs],-mark);
5569 // solved?
5570 69 BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5571
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 51 times.
69 true := ComponentReferenceBasics.crefEqualNoStringCompare(cr, cr1);
5572
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 49 times.
51 false := Expression.expHasCrefNoPreorDer(e1,cr);
5573 98 then
5574 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5575 case(r::rest, _, DAE.UNARY(operator=DAE.UMINUS_ARR(_),exp=DAE.CREF(componentRef=cr)))
5576 algorithm
5577 ✗ rabs := intAbs(r);
5578 // if not negatet rowmark then
5579 ✗ false := intEq(rowmark[rabs],-mark);
5580 // solved?
5581 ✗ BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5582 ✗ crarr := ComponentReferenceBasics.crefStripLastSubs(cr1);
5583 ✗ true := ComponentReferenceBasics.crefEqualNoStringCompare(cr, crarr);
5584 ✗ false := Expression.expHasCrefNoPreorDer(e1,cr);
5585 ✗ then
5586 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5587 case(r::rest, DAE.CREF(componentRef=cr), _)
5588 algorithm
5589 85086 rabs := intAbs(r);
5590 // if not negatet rowmark then
5591
2/2
✓ Branch 1 taken 6474 times.
✓ Branch 2 taken 78612 times.
85086 false := intEq(rowmark[rabs],-mark);
5592 // solved?
5593 78612 BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5594
2/2
✓ Branch 1 taken 77698 times.
✓ Branch 2 taken 914 times.
78612 true := ComponentReferenceBasics.crefPrefixOf(cr, cr1);
5595
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 894 times.
914 false := Expression.expHasCrefNoPreorDer(e2,cr);
5596 1788 then
5597 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5598 case(r::rest, _, DAE.CREF(componentRef=cr))
5599 algorithm
5600 3085 rabs := intAbs(r);
5601 // if not negatet rowmark then
5602
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3085 times.
3085 false := intEq(rowmark[rabs],-mark);
5603 // solved?
5604 3085 BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5605
1/2
✓ Branch 1 taken 3085 times.
✗ Branch 2 not taken.
3085 true := ComponentReferenceBasics.crefPrefixOf(cr, cr1);
5606 ✗ false := Expression.expHasCrefNoPreorDer(e1,cr);
5607 ✗ then
5608 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5609 case(r::rest, DAE.CALL(path=path,expLst=explst,attr=DAE.CALL_ATTR(ty= DAE.T_COMPLEX(complexClassType=ClassInf.RECORD(path1)))), _)
5610 algorithm
5611 ✗ true := AbsynUtil.pathEqual(path,path1);
5612 ✗ rabs := intAbs(r);
5613 // if not negated rowmark then
5614 ✗ false := intEq(rowmark[rabs],-mark);
5615 // solved?
5616 ✗ BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5617 ✗ true := expCrefLstHasCref(explst,cr1);
5618 ✗ false := Expression.expHasCrefNoPreorDer(e2,cr1);
5619 ✗ then
5620 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5621 case(r::rest, _, DAE.CALL(path=path,expLst=explst,attr=DAE.CALL_ATTR(ty= DAE.T_COMPLEX(complexClassType=ClassInf.RECORD(path1)))))
5622 algorithm
5623
1/2
✓ Branch 1 taken 1356 times.
✗ Branch 2 not taken.
1356 true := AbsynUtil.pathEqual(path,path1);
5624 ✗ rabs := intAbs(r);
5625 // if not negated rowmark then
5626 ✗ false := intEq(rowmark[rabs],-mark);
5627 // solved?
5628 ✗ BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5629 ✗ true := expCrefLstHasCref(explst,cr1);
5630 ✗ false := Expression.expHasCrefNoPreorDer(e1,cr1);
5631 ✗ then
5632 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5633 case(r::rest, DAE.RECORD(exps=explst), _)
5634 algorithm
5635 1238 rabs := intAbs(r);
5636 // if not negated rowmark then
5637
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1238 times.
1238 false := intEq(rowmark[rabs],-mark);
5638 // solved?
5639 1238 BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5640
2/2
✓ Branch 1 taken 193 times.
✓ Branch 2 taken 1045 times.
1238 true := expCrefLstHasCref(explst,cr1);
5641
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1045 times.
1045 false := Expression.expHasCrefNoPreorDer(e2,cr1);
5642 2090 then
5643 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5644 case(r::rest, _, DAE.RECORD(exps=explst))
5645 algorithm
5646 ✗ rabs := intAbs(r);
5647 // if not negated rowmark then
5648 ✗ false := intEq(rowmark[rabs],-mark);
5649 // solved?
5650 ✗ BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5651 ✗ true := expCrefLstHasCref(explst,cr1);
5652 ✗ false := Expression.expHasCrefNoPreorDer(e1,cr1);
5653 ✗ then
5654 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5655 case(r::rest, DAE.TUPLE(PR=explst), DAE.CALL())
5656 algorithm
5657 1626 rabs := intAbs(r);
5658 // if not negated rowmark then
5659
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1626 times.
1626 false := intEq(rowmark[rabs],-mark);
5660 // solved?
5661 1626 BackendDAE.VAR(varName=cr1) := BackendVariable.getVarAt(vars, rabs);
5662 1626 explst := List.flatten(List.map1(explst, Expression.generateCrefsExpLstFromExp, NONE()));
5663 1626 crlst := List.map(explst, Expression.expCref);
5664 1626 crlst := List.flatten(List.map1(crlst, ComponentReference.expandCref, true));
5665 1626 crexplst := List.map(crlst, Expression.crefExp);
5666
2/2
✓ Branch 1 taken 525 times.
✓ Branch 2 taken 1101 times.
1626 true := expCrefLstHasCref(crexplst,cr1);
5667
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1101 times.
1101 false := Expression.expHasCrefNoPreorDer(e2,cr1);
5668 2202 then
5669 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_SOLVED(),{})::inRow,trytosolve,size,shared);
5670 case(r::rest, _, _)
5671 // case: state derivative
5672 algorithm
5673 // ticket #6806, only allow inverting of function if the sizes match
5674
2/2
✓ Branch 0 taken 852 times.
✓ Branch 1 taken 116275 times.
117127 1 := size;
5675 // if not negated rowmark then linear or nonlinear
5676
2/2
✓ Branch 0 taken 27782 times.
✓ Branch 1 taken 88493 times.
116275 true := intGt(r,0);
5677
2/2
✓ Branch 1 taken 6780 times.
✓ Branch 2 taken 81713 times.
88493 false := intEq(rowmark[r],-mark);
5678 // de/dvar
5679
2/2
✓ Branch 1 taken 80122 times.
✓ Branch 2 taken 1591 times.
81713 BackendDAE.VAR(varName=cr,varKind=BackendDAE.STATE()) := BackendVariable.getVarAt(vars, r);
5680 1591 cr1 := ComponentReference.crefPrefixDer(cr);
5681 1591 e := Expression.crefExp(cr);
5682 1591 (e,_) := Expression.replaceExp(Expression.expSub(e1,e2), DAE.CALL(Absyn.IDENT("der"),{e},DAE.callAttrBuiltinReal), Expression.crefExp(cr1));
5683 1591 e_derAlias := Expression.traverseExpDummy(e, replaceDerCall);
5684 1591 (de,solved,derived,cons) := tryToSolveOrDerive(e_derAlias, cr1, vars, SOME(shared.functionTree),trytosolve);
5685
1/2
✓ Branch 0 taken 1391 times.
✗ Branch 1 not taken.
1391 if not solved then
5686 1391 (de,_) := ExpressionSimplify.simplify(de);
5687 1391 (_,crlst) := Expression.traverseExpBottomUp(de, Expression.traversingComponentRefFinder, {});
5688 1391 solvab := adjacencyRowEnhanced2(cr1,de,crlst,vars,globalKnownVars);
5689 else
5690 ✗ if derived then
5691 ✗ (de,_) := ExpressionSimplify.simplify(de);
5692 ✗ (_,crlst) := Expression.traverseExpBottomUp(de, Expression.traversingComponentRefFinder, {});
5693 ✗ solvab := adjacencyRowEnhanced2(cr1,de,crlst,vars,globalKnownVars);
5694 ✗ solvab := transformSolvabilityForCasualTearingSet(solvab);
5695 else
5696 solvab := BackendDAE.SOLVABILITY_SOLVABLE();
5697 end if;
5698 end if;
5699 2782 then
5700 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,solvab,cons)::inRow,trytosolve,size,shared);
5701 case(r::rest, _, _)
5702 algorithm
5703 // ticket #6806, only allow inverting of function if the sizes match
5704
2/2
✓ Branch 0 taken 852 times.
✓ Branch 1 taken 114884 times.
115736 1 := size;
5705 114884 rabs := intAbs(r);
5706 // if not negated rowmark then linear or nonlinear
5707
2/2
✓ Branch 1 taken 7271 times.
✓ Branch 2 taken 107613 times.
114884 false := intEq(rowmark[rabs],-mark);
5708 // de/dvar
5709 107613 BackendDAE.VAR(varName=cr) := BackendVariable.getVarAt(vars, rabs);
5710
2/2
✓ Branch 1 taken 523 times.
✓ Branch 2 taken 107090 times.
107613 if CommonSubExpression.isCSECref(cr) then
5711 solvab := BackendDAE.SOLVABILITY_UNSOLVABLE();
5712 523 cons := {};
5713 else
5714 107090 e := Expression.expSub(e1,e2);
5715 107089 e_derAlias := Expression.traverseExpDummy(e, replaceDerCall);
5716 107089 (de,solved,derived,cons) := tryToSolveOrDerive(e_derAlias, cr, vars, SOME(shared.functionTree),trytosolve);
5717
2/2
✓ Branch 0 taken 95150 times.
✓ Branch 1 taken 3023 times.
98173 if not solved then
5718 95150 (de,_) := ExpressionSimplify.simplify(de);
5719 95150 (_,crlst) := Expression.traverseExpTopDown(de, Expression.traversingComponentRefFinderNoPreDer, {});
5720 95150 solvab := adjacencyRowEnhanced2(cr,de,crlst,vars,globalKnownVars);
5721 else
5722
1/2
✓ Branch 0 taken 3023 times.
✗ Branch 1 not taken.
3023 if derived then
5723 3023 (de,_) := ExpressionSimplify.simplify(de);
5724 3023 (_,crlst) := Expression.traverseExpTopDown(de, Expression.traversingComponentRefFinderNoPreDer, {});
5725 3023 solvab := adjacencyRowEnhanced2(cr,de,crlst,vars,globalKnownVars);
5726 3023 solvab := transformSolvabilityForCasualTearingSet(solvab);
5727 else
5728 solvab := BackendDAE.SOLVABILITY_SOLVABLE();
5729 end if;
5730 end if;
5731 end if;
5732 197392 then
5733 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,solvab,cons)::inRow,trytosolve,size,shared);
5734 case(r::rest, _, _)
5735 34080 then
5736 adjacencyRowEnhanced1(rest,e1,e2,vars,globalKnownVars,mark,rowmark,(r,BackendDAE.SOLVABILITY_UNSOLVABLE(),{})::inRow,trytosolve,size,shared);
5737 end matchcontinue;
5738 end adjacencyRowEnhanced1;
5739
5740
5741 protected function replaceDerCall "
5742 replaces der-calls in expression with alias-variable"
5743 input DAE.Exp inExp;
5744 output DAE.Exp outExp;
5745 algorithm
5746 outExp := matchcontinue inExp
5747 local
5748 DAE.ComponentRef cr;
5749 DAE.Type ty;
5750 BackendDAE.Var v;
5751
5752 case DAE.CALL(path=Absyn.IDENT(name="der"), expLst={DAE.CREF(componentRef=cr, ty=ty)})
5753 algorithm
5754 5247 v := BackendVariable.createAliasDerVar(cr);
5755 5247 cr := BackendVariable.varCref(v);
5756 5247 outExp := DAE.CREF(cr,ty);
5757 then (outExp);
5758
5759 case DAE.CALL(path=Absyn.IDENT(name="der"))
5760 algorithm
5761 ✗ Error.addMessage(Error.INTERNAL_ERROR, {getInstanceName() + " failed for: " + ExpressionBasics.printExpStr(inExp) + "\n"});
5762 ✗ then fail();
5763
5764 else (inExp);
5765 end matchcontinue;
5766 end replaceDerCall;
5767
5768
5769 protected function tryToSolveOrDerive
5770 input DAE.Exp e;
5771 input DAE.ComponentRef cr "x";
5772 input BackendDAE.Variables vars;
5773 input Option<AvlTreePathFunction.Tree> functions;
5774 input Boolean trytosolve1 "if true, try to solve the expression for the variable, even if flag 'allowImpossibleAssignments' is not set";
5775 output DAE.Exp f;
5776 output Boolean solved=false "true if equation is solved for the variable with ExpressionSolve.solve2, false if equation is differentiated";
5777 output Boolean derived=false;
5778 output BackendDAE.Constraints outCons={};
5779 protected
5780 DAE.Type tp = Expression.typeof(e);
5781 Boolean trytosolve2 = stringEqual(Flags.getConfigString(Flags.TEARING_STRICTNESS), "casual");
5782 Boolean localCon;
5783 DAE.Exp one, tmpEqn, solvedExp, con;
5784 list<BackendDAE.Equation> eqnForNewVars;
5785 list<DAE.ComponentRef> newVarsCrefs;
5786 DAE.ComponentRef tmpVar;
5787 DAE.Constraint constraint;
5788 BackendDAE.Constraints constraints;
5789 constant Boolean debug = false;
5790 algorithm
5791
2/2
✓ Branch 0 taken 3136 times.
✓ Branch 1 taken 105544 times.
108680 if trytosolve1 or trytosolve2 then
5792 try // try to solve for x (1*x = f(y))
5793 3136 (solvedExp,_,eqnForNewVars,newVarsCrefs) := ExpressionSolve.solve2(e, Expression.makeConstZero(tp),Expression.crefExp(cr), functions, SOME(1));
5794
5795 if debug then
5796 print("Solve expression:\n" + ExpressionBasics.printExpStr(e) + "\n");
5797 print("for variable: " + ExpressionBasics.printExpStr(Expression.crefExp(cr)) + "\n");
5798 print("Solved expression:\n" + ExpressionBasics.printExpStr(solvedExp) + "\n");
5799 ComponentReference.printComponentRefList(newVarsCrefs);
5800 BackendDump.dumpEquationList(eqnForNewVars, "eqnForNewVars");
5801 ExpressionDump.dumpExp(solvedExp);
5802 print("listLength(eqnForNewVars): " + intString(listLength(eqnForNewVars)) + "\n\n");
5803 end if;
5804
5805
2/2
✓ Branch 0 taken 2960 times.
✓ Branch 1 taken 64 times.
3024 if trytosolve1 then
5806 2960 (_,(constraints,_)) := Expression.traverseExpTopDown(solvedExp, getConstraints, ({},vars));
5807
5808
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2959 times.
2980 for eqn in eqnForNewVars loop
5809
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 20 times.
21 BackendDAE.SOLVED_EQUATION(componentRef=tmpVar, exp=tmpEqn) := eqn;
5810 20 (_,(constraints,_)) := Expression.traverseExpTopDown(tmpEqn, getConstraints, (constraints,vars));
5811 end for;
5812
5813
5814
2/2
✓ Branch 1 taken 1676 times.
✓ Branch 2 taken 1283 times.
4635 for i in listLength(constraints):-1:1 loop
5815 1676 constraint := listGet(constraints, i);
5816
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1676 times.
1676 DAE.CONSTRAINT_DT(constraint = con, localCon=localCon) := constraint;
5817
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1676 times.
1696 for eqn in eqnForNewVars loop
5818
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 BackendDAE.SOLVED_EQUATION(componentRef=tmpVar, exp=tmpEqn) := eqn;
5819 20 con := Expression.replaceCrefBottomUp(con, tmpVar, tmpEqn);
5820 end for;
5821
2/2
✓ Branch 0 taken 1640 times.
✓ Branch 1 taken 36 times.
3316 outCons := DAE.CONSTRAINT_DT(con, localCon)::outCons;
5822 end for;
5823
5824 if debug then
5825 print("Constraints before substitution: " + ExpressionDump.constraintDTlistToString(constraints, "\n") + "\n\n");
5826 print("Substituted expression:\n" + ExpressionBasics.printExpStr(solvedExp) + "\n");
5827 print("Constraints:" + ExpressionDump.constraintDTlistToString(outCons, "\n") + "\n\n");
5828 end if;
5829 end if;
5830
5831 solved := true;
5832 else end try;
5833 end if;
5834 try
5835 108680 f := Differentiate.differentiateExpSolve(e, cr, functions);
5836 f := match f
5837 /* der(f(x)) = c/y => c*x = y*lhs */
5838 case DAE.BINARY(one,DAE.DIV(), DAE.CREF()) /*Note: 1/x => ln(x) => Expression.solve will solve it */
5839 guard Expression.isConst(one) and not Expression.isZero(one)
5840 then one;
5841 else f;
5842 end match;
5843 derived := true;
5844 else
5845 6877 f := Expression.makeConstOne(tp);
5846 end try;
5847
2/2
✓ Branch 1 taken 2239 times.
✓ Branch 2 taken 106441 times.
108680 if Expression.isZero(f) then
5848 // see https://trac.openmodelica.org/OpenModelica/ticket/3742#comment:12
5849 // ExpressionSolve will fail for f == 0 --> internal loops inside tearing
5850 2239 fail();
5851 end if;
5852
2/2
✓ Branch 0 taken 6877 times.
✓ Branch 1 taken 99564 times.
106441 true := solved or derived;
5853 if debug then
5854 if solved then
5855 print("[SOLVED] ");
5856 elseif derived then
5857 print("[DERIVED] ");
5858 else
5859 print("[?BROKEN?] ");
5860 end if;
5861 print("tryToSolveOrDerive " + ExpressionBasics.printExpStr(e) + " -> " + ExpressionBasics.printExpStr(f) + " == " + ExpressionBasics.printExpStr(Expression.crefExp(cr)) + "\n");
5862 end if;
5863 end tryToSolveOrDerive;
5864
5865 public function isSolvable
5866 input BackendDAE.Solvability solvability;
5867 input Boolean strict = false;
5868 output Boolean solvable;
5869 algorithm
5870 solvable := match solvability
5871 local
5872 Boolean b;
5873 case BackendDAE.SOLVABILITY_NONLINEAR() then false;
5874 case BackendDAE.SOLVABILITY_UNSOLVABLE() then false;
5875 case BackendDAE.SOLVABILITY_CONST(b=b) then b;
5876 case BackendDAE.SOLVABILITY_PARAMETER(b=b) then b;
5877 ✗ case BackendDAE.SOLVABILITY_LINEAR(b=b) then (b and not strict);
5878 else true;
5879 end match;
5880 end isSolvable;
5881
5882 protected function getConstraints "
5883 author: ptaeuber
5884 Function to find the constraints for Dynamic Tearing."
5885 input DAE.Exp inExp;
5886 input tuple<BackendDAE.Constraints,BackendDAE.Variables> inTpl;
5887 output DAE.Exp outExp;
5888 output Boolean cont=true;
5889 output tuple<BackendDAE.Constraints,BackendDAE.Variables> outTpl;
5890 protected
5891 BackendDAE.Constraints inCons;
5892 BackendDAE.Variables vars;
5893 algorithm
5894 78996 (inCons,vars) := inTpl;
5895 (outExp,outTpl) := match inExp
5896 local
5897 DAE.Exp e;
5898 DAE.Exp rel;
5899 DAE.Constraint con;
5900 list<DAE.ComponentRef> crlst;
5901 Boolean localCon;
5902 case DAE.BINARY(operator=DAE.DIV(), exp2=e)
5903 algorithm
5904 1654 rel := DAE.RELATION(DAE.CALL(Absyn.IDENT("abs"), {e}, DAE.callAttrBuiltinOther), DAE.GREATER(DAE.T_REAL_DEFAULT), DAE.RCONST(1e-12), -1, NONE());
5905 1654 (_,crlst) := Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
5906 1654 localCon := containAnyVarWithoutStates(crlst,vars);
5907
2/2
✓ Branch 0 taken 1640 times.
✓ Branch 1 taken 14 times.
3294 con := DAE.CONSTRAINT_DT(rel,localCon);
5908 1654 then (inExp,(con::inCons,vars));
5909
5910 case DAE.CALL(path = Absyn.IDENT(name = "sqrt"), expLst = {e})
5911 algorithm
5912 ✗ rel := DAE.RELATION(e, DAE.GREATEREQ(DAE.T_REAL_DEFAULT), DAE.RCONST(0.0), -1, NONE());
5913 ✗ (_,crlst) := Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
5914 ✗ localCon := containAnyVarWithoutStates(crlst,vars);
5915 ✗ con := DAE.CONSTRAINT_DT(rel,localCon);
5916 ✗ then (inExp,(con::inCons,vars));
5917
5918 case DAE.BINARY(exp1=e, operator=DAE.POW(), exp2=DAE.RCONST(0.5))
5919 algorithm
5920 20 rel := DAE.RELATION(e, DAE.GREATEREQ(DAE.T_REAL_DEFAULT), DAE.RCONST(0.0), -1, NONE());
5921 20 (_,crlst) := Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
5922 20 localCon := containAnyVarWithoutStates(crlst,vars);
5923
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 con := DAE.CONSTRAINT_DT(rel,localCon);
5924 20 then (inExp,(con::inCons,vars));
5925
5926 case DAE.CALL(path = Absyn.IDENT(name = "log"), expLst = {e})
5927 algorithm
5928 2 rel := DAE.RELATION(e, DAE.GREATER(DAE.T_REAL_DEFAULT), DAE.RCONST(1e-12), -1, NONE());
5929 2 (_,crlst) := Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
5930 2 localCon := containAnyVarWithoutStates(crlst,vars);
5931
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 con := DAE.CONSTRAINT_DT(rel,localCon);
5932 2 then (inExp,(con::inCons,vars));
5933
5934 case DAE.CALL(path = Absyn.IDENT(name = "log10"), expLst = {e})
5935 algorithm
5936 ✗ rel := DAE.RELATION(e, DAE.GREATER(DAE.T_REAL_DEFAULT), DAE.RCONST(1e-12), -1, NONE());
5937 ✗ (_,crlst) := Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
5938 ✗ localCon := containAnyVarWithoutStates(crlst,vars);
5939 ✗ con := DAE.CONSTRAINT_DT(rel,localCon);
5940 ✗ then (inExp,(con::inCons,vars));
5941
5942 case DAE.CALL(path = Absyn.IDENT(name = "asin"), expLst = {e})
5943 algorithm
5944 ✗ rel := DAE.RELATION(DAE.CALL(Absyn.IDENT("abs"), {e}, DAE.callAttrBuiltinOther), DAE.LESSEQ(DAE.T_REAL_DEFAULT), DAE.RCONST(1.0), -1, NONE());
5945 ✗ (_,crlst) := Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
5946 ✗ localCon := containAnyVarWithoutStates(crlst,vars);
5947 ✗ con := DAE.CONSTRAINT_DT(rel,localCon);
5948 ✗ then (inExp,(con::inCons,vars));
5949
5950 case DAE.CALL(path = Absyn.IDENT(name = "acos"), expLst = {e})
5951 algorithm
5952 ✗ rel := DAE.RELATION(DAE.CALL(Absyn.IDENT("abs"), {e}, DAE.callAttrBuiltinOther), DAE.LESSEQ(DAE.T_REAL_DEFAULT), DAE.RCONST(1.0), -1, NONE());
5953 ✗ (_,crlst) := Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
5954 ✗ localCon := containAnyVarWithoutStates(crlst,vars);
5955 ✗ con := DAE.CONSTRAINT_DT(rel,localCon);
5956 ✗ then (inExp,(con::inCons,vars));
5957
5958 case DAE.CALL(path = Absyn.IDENT(name = "tan"), expLst = {e})
5959 algorithm
5960 ✗ rel := DAE.RELATION(DAE.BINARY(exp1=DAE.CALL(Absyn.IDENT("abs"), {DAE.BINARY(exp1=DAE.BINARY(exp1=e, operator=DAE.DIV(ty=DAE.T_REAL_DEFAULT), exp2=DAE.RCONST(3.14159265358979)), operator=DAE.MUL(ty=DAE.T_REAL_DEFAULT), exp2=DAE.RCONST(2.0))}, DAE.callAttrBuiltinOther), operator=DAE.SUB(ty=DAE.T_REAL_DEFAULT), exp2=DAE.CALL(Absyn.IDENT("floor"), {DAE.CALL(Absyn.IDENT("abs"), {DAE.BINARY(exp1=DAE.BINARY(exp1=e, operator=DAE.DIV(ty=DAE.T_REAL_DEFAULT), exp2=DAE.RCONST(3.14159265358979)), operator=DAE.MUL(ty=DAE.T_REAL_DEFAULT), exp2=DAE.RCONST(2.0))}, DAE.callAttrBuiltinOther)}, DAE.callAttrBuiltinOther)), DAE.GREATER(DAE.T_REAL_DEFAULT), DAE.RCONST(1e-12), -1, NONE());
5961 ✗ (_,crlst) := Expression.traverseExpTopDown(rel, Expression.traversingComponentRefFinderNoPreDer, {});
5962 ✗ localCon := containAnyVarWithoutStates(crlst,vars);
5963 ✗ con := DAE.CONSTRAINT_DT(rel,localCon);
5964 ✗ then (inExp,(con::inCons,vars));
5965
5966 else
5967 then (inExp,inTpl);
5968 end match;
5969 end getConstraints;
5970
5971
5972 public function getEqnAndVarsFromInnerEquation
5973 "author: ptaeuber
5974 Returns the equation and the variables from BackendDAE record INNEREQUATION
5975 or the equation, variables and constraints from INNEREQUATIONCONSTRAINTS."
5976 input BackendDAE.InnerEquation innerEquation;
5977 output Integer outEqn;
5978 output list<Integer> outVars;
5979 output BackendDAE.Constraints outCons;
5980 algorithm
5981 (outEqn,outVars,outCons) := match innerEquation
5982 local
5983 Integer eqn;
5984 list<Integer> vars;
5985 BackendDAE.Constraints cons;
5986 case BackendDAE.INNEREQUATION(eqn=eqn, vars=vars) then (eqn,vars,{});
5987 case BackendDAE.INNEREQUATIONCONSTRAINTS(eqn=eqn, vars=vars, cons=cons) then (eqn,vars,cons);
5988 end match;
5989 end getEqnAndVarsFromInnerEquation;
5990
5991 public function getEqnAndVarsFromInnerEquationLst
5992 input BackendDAE.InnerEquations innerEquations;
5993 output list<Integer> eqns = {};
5994 output list<list<Integer>> allVars = {};
5995 output list<BackendDAE.Constraints> allConstraints = {};
5996 protected
5997 Integer eqn;
5998 list<Integer> vars;
5999 BackendDAE.Constraints constraints;
6000 algorithm
6001 ✗ for innerEq in innerEquations loop
6002 ✗ (eqn,vars,constraints) := getEqnAndVarsFromInnerEquation(innerEq);
6003 eqns := eqn::eqns;
6004 ✗ if isPresent(allVars) then allVars := vars::allVars; end if;
6005 ✗ if isPresent(allConstraints) then allConstraints := constraints::allConstraints; end if;
6006 end for;
6007 end getEqnAndVarsFromInnerEquationLst;
6008
6009 protected function transformSolvabilityForCasualTearingSet
6010 input BackendDAE.Solvability inSolvab;
6011 output BackendDAE.Solvability outSolvab;
6012 algorithm
6013 outSolvab := match inSolvab
6014 case BackendDAE.SOLVABILITY_CONST(b=false) then BackendDAE.SOLVABILITY_CONST(false);
6015 case BackendDAE.SOLVABILITY_PARAMETER(b=false) then BackendDAE.SOLVABILITY_PARAMETER(false);
6016 case BackendDAE.SOLVABILITY_LINEAR(b=false) then BackendDAE.SOLVABILITY_LINEAR(false);
6017 else BackendDAE.SOLVABILITY_SOLVABLE();
6018 end match;
6019 end transformSolvabilityForCasualTearingSet;
6020
6021
6022 protected function expCrefLstHasCref
6023 input list<DAE.Exp> iExpLst;
6024 input DAE.ComponentRef inCr;
6025 output Boolean outB;
6026 algorithm
6027 outB := matchcontinue iExpLst
6028 local
6029 DAE.ComponentRef cr;
6030 list<DAE.Exp> rest;
6031 Boolean b;
6032 case {} then false;
6033 case DAE.CREF(componentRef=cr)::rest
6034 algorithm
6035 15713 b := ComponentReferenceBasics.crefEqualNoStringCompare(cr,inCr);
6036
2/2
✓ Branch 0 taken 13567 times.
✓ Branch 1 taken 2146 times.
15713 b := if not b then expCrefLstHasCref(rest, inCr) else b;
6037 then
6038 b;
6039 else
6040 then
6041 false;
6042 end matchcontinue;
6043 end expCrefLstHasCref;
6044
6045 protected function adjacencyRowEnhanced2
6046 "author: Frenkel TUD 2012-05
6047 Helper function to adjacencyRowEnhanced. Calculates the
6048 solvability of the variables."
6049 input DAE.ComponentRef cr;
6050 input DAE.Exp e;
6051 input list<DAE.ComponentRef> crlst;
6052 input BackendDAE.Variables vars;
6053 input BackendDAE.Variables globalKnownVars;
6054 output BackendDAE.Solvability oSolvab;
6055 algorithm
6056 oSolvab := match crlst
6057 local
6058 Boolean b1,b2;
6059 case {}
6060 algorithm
6061 38950 b1 := Expression.isZeroOrAlmostZero(e);
6062
4/4
✓ Branch 1 taken 23945 times.
✓ Branch 2 taken 15005 times.
✓ Branch 4 taken 6352 times.
✓ Branch 5 taken 17593 times.
38950 b2 := Expression.isConstOne(e) or Expression.isConstMinusOne(e);
6063
2/2
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 6115 times.
6589 then
6064 if b2 then BackendDAE.SOLVABILITY_CONSTONE() else BackendDAE.SOLVABILITY_CONST(not b1);
6065 case _ guard List.isMemberOnTrue(cr,crlst,ComponentReferenceBasics.crefEqualNoStringCompare)
6066 then
6067 BackendDAE.SOLVABILITY_NONLINEAR();
6068 case _
6069 algorithm
6070 49360 b1 := containAnyVar(crlst,globalKnownVars);
6071 49360 b2 := containAnyVar(crlst,vars);
6072 49360 then
6073 adjacencyRowEnhanced3(b1,b2,cr,e,crlst,vars,globalKnownVars);
6074 end match;
6075 end adjacencyRowEnhanced2;
6076
6077 protected function adjacencyRowEnhanced3
6078 "author: Frenkel TUD 2012-05
6079 Helper function to adjacencyRowEnhanced. Calculates the
6080 solvability of the variables."
6081 input Boolean b1;
6082 input Boolean b2;
6083 input DAE.ComponentRef cr;
6084 input DAE.Exp e;
6085 input list<DAE.ComponentRef> crlst;
6086 input BackendDAE.Variables vars;
6087 input BackendDAE.Variables globalKnownVars;
6088 output BackendDAE.Solvability oSolvab;
6089 algorithm
6090 oSolvab := match(b1, b2)
6091 local
6092 Boolean b,b_1;
6093 DAE.Exp e1, nominal;
6094 case(true, true)
6095 algorithm
6096 3324 (e1,_) := Expression.traverseExpBottomUp(e, replaceVarWithValue, globalKnownVars);
6097 3324 (e1,_) := ExpressionSimplify.simplify(e1);
6098 3324 b := not Expression.isZeroOrAlmostZero(e1);
6099
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3312 times.
3336 then
6100 BackendDAE.SOLVABILITY_LINEAR(b);
6101 case(false, _)
6102 algorithm
6103 31534 b := not Expression.isZeroOrAlmostZero(e);
6104
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 31493 times.
31575 then
6105 BackendDAE.SOLVABILITY_LINEAR(b);
6106 case(true, _)
6107 algorithm
6108 14502 (nominal,_) := Expression.traverseExpBottomUp(e, replaceVarWithNominal, globalKnownVars);
6109 14502 (nominal,_) := ExpressionSimplify.simplify(nominal);
6110 14502 (e1,_) := Expression.traverseExpBottomUp(e, replaceVarWithValue, globalKnownVars);
6111 14502 (e1,_) := ExpressionSimplify.simplify(e1);
6112 14502 b := not Expression.isZeroOrAlmostZero(e1, nominal);
6113
4/4
✓ Branch 1 taken 4542 times.
✓ Branch 2 taken 9960 times.
✓ Branch 4 taken 244 times.
✓ Branch 5 taken 4298 times.
14502 b_1 := Expression.isConst(e1) or BackendVariable.isKnownAndParam(e1,globalKnownVars);
6114
3/4
✓ Branch 0 taken 2512 times.
✓ Branch 1 taken 7692 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4298 times.
17014 then
6115 if b_1 then BackendDAE.SOLVABILITY_PARAMETER(b) else BackendDAE.SOLVABILITY_LINEAR(b);
6116 case(_, _)
6117 algorithm
6118 ✗ b := not Expression.isZeroOrAlmostZero(e);
6119 ✗ then
6120 BackendDAE.SOLVABILITY_LINEAR(b);
6121 end match;
6122 end adjacencyRowEnhanced3;
6123
6124 public function replaceVarWithValue
6125 "Helper function to adjacencyRowEnhanced3. Traverser to replace variables(parameters) with their bind expression."
6126 input DAE.Exp inExp;
6127 input BackendDAE.Variables inVars;
6128 output DAE.Exp outExp;
6129 output BackendDAE.Variables outVars;
6130 algorithm
6131 (outExp,outVars) := matchcontinue (inExp,inVars)
6132 local
6133 DAE.ComponentRef cr;
6134 BackendDAE.Variables vars;
6135 BackendDAE.Var v;
6136 DAE.Exp e;
6137
6138 case (DAE.CREF(componentRef=cr),vars)
6139 algorithm
6140
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 98569 times.
110773 (v::_,_) := BackendVariable.getVar(cr,vars);
6141 98569 e := BackendVariable.varBindExp(v);
6142 97741 (e,_) := Expression.traverseExpBottomUp(e, replaceVarWithValue, vars);
6143 then (e, vars);
6144
6145 case (DAE.CREF(componentRef=cr),vars)
6146 algorithm
6147
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 828 times.
13032 (v::_,_) := BackendVariable.getVar(cr,vars);
6148
2/2
✓ Branch 1 taken 710 times.
✓ Branch 2 taken 118 times.
828 true := BackendVariable.varFixed(v);
6149 118 e := BackendVariable.varBindExpStartValue(v);
6150 118 (e,_) := Expression.traverseExpBottomUp(e, replaceVarWithValue, vars);
6151 then (e, vars);
6152
6153 else (inExp,inVars);
6154
6155 end matchcontinue;
6156 end replaceVarWithValue;
6157
6158 protected function replaceVarWithNominal
6159 "Helper function to adjacencyRowEnhanced3. Traverser to replace variables(parameters) with their nominal values."
6160 input DAE.Exp inExp;
6161 input BackendDAE.Variables inVars;
6162 output DAE.Exp outExp;
6163 output BackendDAE.Variables outVars;
6164 algorithm
6165 (outExp,outVars) := matchcontinue (inExp,inVars)
6166 local
6167 DAE.ComponentRef cr;
6168 BackendDAE.Variables vars;
6169 BackendDAE.Var v;
6170 DAE.Exp nom;
6171
6172 case (DAE.CREF(componentRef=cr),vars)
6173 algorithm
6174
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 20452 times.
25885 (v::_,_) := BackendVariable.getVar(cr,vars);
6175 20452 nom := BackendVariable.getVarNominalValue(v);
6176 20452 (nom,_) := Expression.traverseExpBottomUp(nom, replaceVarWithNominal, vars);
6177 then (nom, vars);
6178
6179 else (inExp,inVars);
6180
6181 end matchcontinue;
6182 end replaceVarWithNominal;
6183
6184 protected function adjacencyRowExpEnhanced
6185 "author: Frenkel TUD 2012-05
6186 Helper function to adjacencyRowEnhanced, investigates expressions for
6187 variables, returning variable indexes, and mark the solvability."
6188 input DAE.Exp inExp;
6189 input BackendDAE.Variables inVariables;
6190 input Integer mark;
6191 input array<Integer> rowmark;
6192 input Boolean isInitial;
6193 input list<Integer> inRow;
6194 output list<Integer> outRow;
6195 algorithm
6196
2/2
✓ Branch 0 taken 51787 times.
✓ Branch 1 taken 47674 times.
151248 (_,(_,_,_,_,_,outRow)) := Expression.traverseExpTopDown(inExp, traversingAdjacencyRowExpSolvableEnhancedFinder, (inVariables,false,isInitial,mark,rowmark,inRow));
6197 end adjacencyRowExpEnhanced;
6198
6199 protected function traversingAdjacencyRowExpSolvableEnhancedFinder "Helper for adjacencyRowExpEnhanced"
6200 input DAE.Exp inExp;
6201 input tuple<BackendDAE.Variables, Boolean, Boolean, Integer, array<Integer>, list<Integer>> inTpl "(exp, (variables, unsolvable, mark, rowmark, row))";
6202 output DAE.Exp outExp;
6203 output Boolean cont;
6204 output tuple<BackendDAE.Variables, Boolean, Boolean, Integer, array<Integer>, list<Integer>> outTpl;
6205 algorithm
6206 (outExp, cont, outTpl) := matchcontinue (inExp, inTpl)
6207 local
6208 list<Integer> p, pa, res;
6209 DAE.ComponentRef cr;
6210 BackendDAE.Variables vars;
6211 DAE.Exp e1, e2, e3;
6212 list<BackendDAE.Var> varslst;
6213 Boolean b, b1, b2, bs, isInitial;
6214 Integer mark, i;
6215 array<Integer> rowmark;
6216 Integer it;
6217 array<Integer> at;
6218 tuple<BackendDAE.Variables, Boolean, Boolean, Integer, array<Integer>, list<Integer>> tpl;
6219
6220 case (DAE.LUNARY(exp=e1), (vars, bs, isInitial, it, at, pa)) algorithm
6221
4/4
✓ Branch 0 taken 248 times.
✓ Branch 1 taken 292 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 512 times.
816 (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(e1, traversingAdjacencyRowExpSolvableEnhancedFinder, (vars, bs, isInitial, it, at, pa));
6222 540 then (inExp, false, (vars, bs, isInitial, it, at, pa));
6223
6224 case (DAE.LBINARY(exp1=e1, exp2=e2), (vars, bs, isInitial, it, at, pa)) algorithm
6225
2/2
✓ Branch 0 taken 722 times.
✓ Branch 1 taken 4027 times.
5471 (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(e1, traversingAdjacencyRowExpSolvableEnhancedFinder, (vars, true, isInitial, it, at, pa));
6226 4749 (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(e2, traversingAdjacencyRowExpSolvableEnhancedFinder, (vars, true, isInitial, it, at, pa));
6227
2/2
✓ Branch 0 taken 179 times.
✓ Branch 1 taken 4570 times.
4928 then (inExp, false, (vars, bs, isInitial, it, at, pa));
6228
6229 case (DAE.RELATION(exp1=e1, exp2=e2), (vars, bs, isInitial, it, at, pa)) algorithm
6230
2/2
✓ Branch 0 taken 1655 times.
✓ Branch 1 taken 6968 times.
10278 (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(e1, traversingAdjacencyRowExpSolvableEnhancedFinder, (vars, true, isInitial, it, at, pa));
6231 8623 (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(e2, traversingAdjacencyRowExpSolvableEnhancedFinder, (vars, true, isInitial, it, at, pa));
6232
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 8565 times.
8681 then (inExp, false, (vars, bs, isInitial, it, at, pa));
6233
6234 case (DAE.IFEXP(), (vars, bs, isInitial, it, at, pa))
6235
3/4
✓ Branch 0 taken 1751 times.
✓ Branch 1 taken 3828 times.
✓ Branch 2 taken 5579 times.
✗ Branch 3 not taken.
12909 then traversingAdjacencyRowIfExpEnhanced(inExp, (vars, bs, isInitial, it, at, pa), traversingAdjacencyRowExpSolvableEnhancedFinder);
6236 case (DAE.RANGE(start=e1, step=NONE(), stop=e2), (vars, bs, isInitial, it, at, pa)) algorithm
6237
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
15 (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(e1, traversingAdjacencyRowExpSolvableEnhancedFinder, (vars, true, isInitial, it, at, pa));
6238 10 (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(e2, traversingAdjacencyRowExpSolvableEnhancedFinder, (vars, true, isInitial, it, at, pa));
6239
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
20 then (inExp, false, (vars, bs, isInitial, it, at, pa));
6240
6241 case (DAE.RANGE(start=e1, step=SOME(e3), stop=e2), (vars, bs, isInitial, it, at, pa)) algorithm
6242 ✗ (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(e1, traversingAdjacencyRowExpSolvableEnhancedFinder, (vars, true, isInitial, it, at, pa));
6243 ✗ (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(e2, traversingAdjacencyRowExpSolvableEnhancedFinder, (vars, true, isInitial, it, at, pa));
6244 ✗ (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(e3, traversingAdjacencyRowExpSolvableEnhancedFinder, (vars, true, isInitial, it, at, pa));
6245 ✗ then (inExp, false, (vars, bs, isInitial, it, at, pa));
6246
6247 case (DAE.ASUB(exp=e1, sub={DAE.INDEX(DAE.ICONST(i))}), (vars, bs, isInitial, it, at, pa)) algorithm
6248 31 e1 := Expression.nthArrayExp(e1, i);
6249
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
78 (_, (vars, _, _, _, _, pa)) := Expression.traverseExpTopDown(e1, traversingAdjacencyRowExpSolvableEnhancedFinder, (vars, bs, isInitial, it, at, pa));
6250 31 then (inExp, false, (vars, bs, isInitial, it, at, pa));
6251
6252 case (DAE.ASUB(), _)
6253 then fail();
6254
6255 case (DAE.CREF(componentRef=cr), (vars, bs, isInitial, it, at, pa)) algorithm
6256 mark := it;
6257 rowmark := at;
6258 296848 (varslst, p) := BackendVariable.getVar(cr, vars);
6259 192104 res := adjacencyRowExpEnhanced1(varslst, p, pa, true, mark, rowmark, bs);
6260
4/4
✓ Branch 0 taken 79045 times.
✓ Branch 1 taken 113059 times.
✓ Branch 2 taken 178522 times.
✓ Branch 3 taken 13582 times.
449671 then (inExp, false, (vars, bs, isInitial, it, at, res));
6261
6262 case (DAE.CALL(path=Absyn.IDENT(name="der"), expLst={DAE.CREF(componentRef=cr)}), (vars, bs, isInitial, it, at, pa)) algorithm
6263 mark := it;
6264 rowmark := at;
6265 2384 (varslst, p) := BackendVariable.getVar(cr, vars);
6266 2043 res := adjacencyRowExpEnhanced1(varslst, p, pa, false, mark, rowmark, bs);
6267
2/4
✓ Branch 0 taken 2043 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2043 times.
✗ Branch 3 not taken.
6129 then (inExp, false, (vars, bs, isInitial, it, at, res));
6268
6269 case (DAE.CALL(path=Absyn.IDENT(name="der"), expLst={DAE.CREF(componentRef=cr), DAE.ICONST(_)}), (vars, bs, isInitial, it, at, pa)) algorithm
6270 mark := it;
6271 rowmark := at;
6272 ✗ (varslst, p) := BackendVariable.getVar(cr, vars);
6273 ✗ res := adjacencyRowExpEnhanced1(varslst, p, pa, false, mark, rowmark, bs);
6274 ✗ then (inExp, false, (vars, bs, isInitial, it, at, res));
6275
6276 // pre(v) is considered a known variable
6277 case (DAE.CALL(path=Absyn.IDENT(name="pre"), expLst={DAE.CREF()}), _)
6278 226 then (inExp, false, inTpl);
6279
6280 // previous(v) is considered a known variable
6281 case (DAE.CALL(path=Absyn.IDENT(name="previous"), expLst={DAE.CREF()}), _)
6282 ✗ then (inExp, false, inTpl);
6283
6284 // delay(e) can be used to break algebraic loops given some solver options
6285 case (DAE.CALL(path=Absyn.IDENT(name="delay"), expLst={_, _, e1, e2}), _) algorithm
6286 ✗ b := Flags.getConfigBool(Flags.DELAY_BREAK_LOOP) and ExpressionBasics.expEqual(e1, e2);
6287 ✗ then (inExp, not b, inTpl);
6288
6289 // homotopy operator for simulation system
6290 case (DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst = {e1, _}), (_, _, false, _, _, _))
6291 ✗ then traversingAdjacencyRowExpSolvableEnhancedFinder(e1, inTpl);
6292
6293 // homotopy operator for initialization system
6294 case (DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst = {e1, e2}), (_, _, true, _, _, _))
6295 algorithm
6296 259 (_, b1, tpl) := traversingAdjacencyRowExpSolvableEnhancedFinder(e1, inTpl);
6297 259 (_, b2, tpl) := traversingAdjacencyRowExpSolvableEnhancedFinder(e2, tpl);
6298
4/4
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 235 times.
283 then (inExp, b1 and b2, tpl);
6299
6300 // only traverse position and direction for spatialDistribution, not the inputs!
6301 case (DAE.CALL(path=Absyn.IDENT(name="spatialDistribution"), expLst = {_, _, _, e1, e2, _, _}), _)
6302 algorithm
6303 ✗ (_, _, tpl) := traversingAdjacencyRowExpSolvableEnhancedFinder(e2, inTpl);
6304 ✗ then traversingAdjacencyRowExpSolvableEnhancedFinder(e1, tpl);
6305
6306 539941 else (inExp, true, inTpl);
6307 end matchcontinue;
6308 end traversingAdjacencyRowExpSolvableEnhancedFinder;
6309
6310 protected function markBranchVars "mark all vars of a if expression which are not in all branches as unsolvable"
6311 input DAE.Exp inExp;
6312 input tuple<Integer,array<Integer>,BackendDAE.Variables,BinaryTree.BinTree> inTuple;
6313 output DAE.Exp outExp;
6314 output Boolean cont=true;
6315 output tuple<Integer,array<Integer>,BackendDAE.Variables,BinaryTree.BinTree> outTuple;
6316 algorithm
6317 (outExp, cont, outTuple) := matchcontinue (inExp,inTuple)
6318 local
6319 BackendDAE.Variables vars;
6320 DAE.ComponentRef cr;
6321 BinaryTree.BinTree bt;
6322 list<Integer> ilst;
6323 Integer mark;
6324 array<Integer> rowmark;
6325 list<BackendDAE.Var> backendVars;
6326
6327 // special case for time, it is never part of the equation system
6328 case (DAE.CREF(componentRef = DAE.CREF_IDENT(ident="time")),_)
6329 then (inExp, false, inTuple);
6330
6331 // case for functionpointers
6332 case (DAE.CREF(ty=DAE.T_FUNCTION_REFERENCE_FUNC()),_)
6333 then (inExp, false, inTuple);
6334
6335 case (DAE.CALL(path = Absyn.IDENT(name = "pre"),expLst = {DAE.CREF()}),_)
6336 then (inExp, false, inTuple);
6337
6338 case (DAE.CALL(path = Absyn.IDENT(name = "previous"),expLst = {DAE.CREF()}),_)
6339 then (inExp, false, inTuple);
6340
6341 // mark if not in bt
6342 case (DAE.CREF(componentRef = cr),(mark,rowmark,vars,bt))
6343 algorithm
6344 117220 (backendVars,ilst) := BackendVariable.getVar(cr, vars);
6345 97647 markBranchVars1(backendVars,ilst,mark,rowmark,bt);
6346 then (inExp, true, inTuple);
6347
6348 else (inExp, true, inTuple);
6349 end matchcontinue;
6350 end markBranchVars;
6351
6352 protected function markBranchVars1
6353 "Author: Frenkel TUD 2012-09
6354 Helper for markBranchVars"
6355 input list<BackendDAE.Var> varlst;
6356 input list<Integer> iIlst;
6357 input Integer mark;
6358 input array<Integer> rowmark;
6359 input BinaryTree.BinTree bt;
6360 algorithm
6361 () := matchcontinue(varlst, iIlst)
6362 local
6363 DAE.ComponentRef cr;
6364 list<BackendDAE.Var> vlst;
6365 Integer i;
6366 list<Integer> ilst;
6367 case({}, _) then ();
6368 case(BackendDAE.VAR(varName=cr)::vlst, _::ilst)
6369 algorithm
6370 97647 BinaryTree.treeGet(bt,cr);
6371 44755 markBranchVars1(vlst,ilst,mark,rowmark,bt);
6372 then
6373 ();
6374 case(_::vlst, i::ilst)
6375 algorithm
6376 52892 arrayUpdate(rowmark,i,-mark);
6377 52892 markBranchVars1(vlst,ilst,mark,rowmark,bt);
6378 then
6379 ();
6380 end matchcontinue;
6381 end markBranchVars1;
6382
6383 protected function getIfExpBranchVarOccurency "Helper for getIfExpBranchVarOccurency"
6384 input DAE.Exp inExp;
6385 input BinaryTree.BinTree inBt;
6386 output DAE.Exp outExp;
6387 output Boolean cont;
6388 output BinaryTree.BinTree bt;
6389 algorithm
6390 (outExp,cont,bt) := match (inExp,inBt)
6391 local
6392 DAE.ComponentRef cr;
6393 DAE.Exp e,e1,e2;
6394 BinaryTree.BinTree bt_then,bt_else;
6395 Boolean b;
6396 case (e as DAE.IFEXP(expThen = e1,expElse = e2),bt)
6397 algorithm
6398 11145 (_,bt_then) := Expression.traverseExpTopDown(e1,getIfExpBranchVarOccurency,BinaryTree.emptyBinTree);
6399 11145 (_,bt_else) := Expression.traverseExpTopDown(e2,getIfExpBranchVarOccurency,BinaryTree.emptyBinTree);
6400 11145 bt := BinaryTree.binTreeintersection(bt_then,bt_else,bt);
6401 then (e,false,bt);
6402 // skip relations,ranges,asubs
6403 case (e as DAE.LUNARY(),bt)
6404 then (e,false,bt);
6405 case (e as DAE.LBINARY(),bt)
6406 then (e,false,bt);
6407 case (e as DAE.RELATION(),bt)
6408 then (e,false,bt);
6409 case (e as DAE.RANGE(),bt)
6410 then (e,false,bt);
6411 case (e as DAE.RANGE(),bt)
6412 then (e,false,bt);
6413 case (e as DAE.ASUB(exp = e1),bt)
6414 algorithm
6415 ✗ (_,bt) := Expression.traverseExpTopDown(e1, getIfExpBranchVarOccurency, bt);
6416 ✗ then (e,false,bt);
6417 // add crefs
6418 case (e as DAE.CREF(componentRef = cr),bt)
6419 algorithm
6420 92639 bt := BinaryTree.treeAdd(bt,cr,0);
6421 then (e,false,bt);
6422 case (e as DAE.CALL(path = Absyn.IDENT(name = "der"),expLst = {DAE.CREF(componentRef = cr)}),bt)
6423 algorithm
6424 426 bt := BinaryTree.treeAdd(bt,cr,0);
6425 then (e,false,bt);
6426 case (e as DAE.CALL(path = Absyn.IDENT(name = "der"),expLst = {DAE.CREF(componentRef = cr)}),bt)
6427 algorithm
6428 ✗ bt := BinaryTree.treeAdd(bt,cr,0);
6429 then (e,false,bt);
6430 // pre(v) is considered a known variable
6431 case (e as DAE.CALL(path = Absyn.IDENT(name = "pre"),expLst = {DAE.CREF()}),bt)
6432 then (e,false,bt);
6433 // previous(v) is considered a known variable
6434 case (e as DAE.CALL(path = Absyn.IDENT(name = "previous"),expLst = {DAE.CREF()}),bt)
6435 then (e,false,bt);
6436 // delay(e) can be used to break algebraic loops given some solver options
6437 case (e as DAE.CALL(path = Absyn.IDENT(name = "delay"),expLst = {_,_,e1,e2}),bt)
6438 algorithm
6439 ✗ b := Flags.getConfigBool(Flags.DELAY_BREAK_LOOP) and ExpressionBasics.expEqual(e1,e2);
6440 ✗ then (e,not b,bt);
6441
6442 case (DAE.CALL(path=Absyn.IDENT(name="homotopy"), expLst = {e1, _}), _) algorithm
6443 // phi: what about e2?
6444 ✗ then getIfExpBranchVarOccurency(e1, inBt);
6445
6446 else (inExp,true,inBt);
6447 end match;
6448 end getIfExpBranchVarOccurency;
6449
6450 protected function adjacencyRowExpEnhanced1
6451 "author: Frenkel TUD 2012-05
6452 Helper function to traversingAdjacencyRowExpSolvableEnhancedFinder, fill the variable indexes
6453 in the list and update the array to mark the variables."
6454 input list<BackendDAE.Var> inVarLst;
6455 input list<Integer> inIntegerLst;
6456 input list<Integer> vars;
6457 input Boolean notinder;
6458 input Integer mark;
6459 input array<Integer> rowmark;
6460 input Boolean unsolvable;
6461 output list<Integer> outIntegerLst;
6462 algorithm
6463 outIntegerLst := matchcontinue (inVarLst, inIntegerLst, notinder, unsolvable)
6464 local
6465 list<BackendDAE.Var> rest;
6466 list<Integer> irest,res;
6467 Integer i,i1;
6468 Boolean b,b1;
6469 case ({}, {}, _, _) then vars;
6470 /*If variable x is a state, der(x) is a variable in adjacency matrix,
6471 x is inserted as negative value, since it is needed by debugging and
6472 index reduction using dummy derivatives */
6473 case (BackendDAE.VAR(varKind = BackendDAE.STATE())::rest, i::irest, false, _)
6474 guard
6475 not intEq(intAbs(rowmark[i]),mark)
6476 algorithm
6477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2031 times.
2031 arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6478 2031 res := adjacencyRowExpEnhanced1(rest,irest,i::vars,notinder,mark,rowmark,unsolvable);
6479 then res;
6480 case (BackendDAE.VAR(varKind = BackendDAE.STATE())::rest, i::irest, true, _)
6481 algorithm
6482 42399 i1 := -i;
6483
2/2
✓ Branch 0 taken 42399 times.
✓ Branch 1 taken 41404 times.
83803 failure(List.getMemberOnTrue(i1, vars, intEq));
6484 41404 res := adjacencyRowExpEnhanced1(rest,irest,i1::vars,notinder,mark,rowmark,unsolvable);
6485 then res;
6486 case (BackendDAE.VAR(varKind = BackendDAE.STATE_DER())::rest, i::irest, _, _)
6487 guard
6488 not intEq(intAbs(rowmark[i]),mark)
6489 algorithm
6490
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6491 8 res := adjacencyRowExpEnhanced1(rest,irest,i::vars,notinder,mark,rowmark,unsolvable);
6492 then res;
6493 case (BackendDAE.VAR(varKind = BackendDAE.STATE_DER())::rest, i::irest, _, true)
6494 algorithm
6495 ✗ b := intEq(rowmark[i],mark);
6496 ✗ b1 := intEq(rowmark[i],-mark);
6497 b := b or b1;
6498 ✗ arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6499 ✗ res := List.consOnTrue(not b, i, vars);
6500 ✗ res := adjacencyRowExpEnhanced1(rest,irest,res,notinder,mark,rowmark,unsolvable);
6501 then res;
6502 case (BackendDAE.VAR(varKind = BackendDAE.VARIABLE())::rest, i::irest, _, _)
6503 guard
6504 not intEq(intAbs(rowmark[i]),mark)
6505 algorithm
6506
2/2
✓ Branch 0 taken 1285 times.
✓ Branch 1 taken 92330 times.
93615 arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6507 93615 res := adjacencyRowExpEnhanced1(rest,irest,i::vars,notinder,mark,rowmark,unsolvable);
6508 then res;
6509 case (BackendDAE.VAR(varKind = BackendDAE.VARIABLE())::rest, i::irest, _, true)
6510 algorithm
6511 10748 b := intEq(rowmark[i],mark);
6512 10748 b1 := intEq(rowmark[i],-mark);
6513 b := b or b1;
6514
1/2
✓ Branch 0 taken 10748 times.
✗ Branch 1 not taken.
21496 arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6515 10748 res := List.consOnTrue(not b, i, vars);
6516 10748 res := adjacencyRowExpEnhanced1(rest,irest,res,notinder,mark,rowmark,unsolvable);
6517 then res;
6518 case (BackendDAE.VAR(varKind = BackendDAE.ALG_STATE())::rest, i::irest, _, _)
6519 guard
6520 not intEq(intAbs(rowmark[i]),mark)
6521 algorithm
6522
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 486 times.
490 arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6523 490 res := adjacencyRowExpEnhanced1(rest,irest,i::vars,notinder,mark,rowmark,unsolvable);
6524 then res;
6525 case (BackendDAE.VAR(varKind = BackendDAE.ALG_STATE())::rest, i::irest, _, true)
6526 algorithm
6527 ✗ b := intEq(rowmark[i],mark);
6528 ✗ b1 := intEq(rowmark[i],-mark);
6529 b := b or b1;
6530 ✗ arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6531 ✗ res := List.consOnTrue(not b, i, vars);
6532 ✗ res := adjacencyRowExpEnhanced1(rest,irest,res,notinder,mark,rowmark,unsolvable);
6533 then res;
6534 case (BackendDAE.VAR(varKind = BackendDAE.DISCRETE())::rest, i::irest, _, _)
6535 guard
6536 not intEq(intAbs(rowmark[i]),mark)
6537 algorithm
6538
2/2
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 467 times.
989 arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6539 989 res := adjacencyRowExpEnhanced1(rest,irest,i::vars,notinder,mark,rowmark,unsolvable);
6540 then res;
6541 case (BackendDAE.VAR(varKind = BackendDAE.DISCRETE())::rest, i::irest, _, true)
6542 algorithm
6543 11 b := intEq(rowmark[i],mark);
6544 11 b1 := intEq(rowmark[i],-mark);
6545 b := b or b1;
6546
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
22 arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6547 11 res := List.consOnTrue(not b, i, vars);
6548 11 res := adjacencyRowExpEnhanced1(rest,irest,res,notinder,mark,rowmark,unsolvable);
6549 then res;
6550 case (BackendDAE.VAR(varKind = BackendDAE.DUMMY_DER())::rest, i::irest, _, _)
6551 guard
6552 not intEq(intAbs(rowmark[i]),mark)
6553 algorithm
6554
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11620 times.
11620 arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6555 11620 res := adjacencyRowExpEnhanced1(rest,irest,i::vars,notinder,mark,rowmark,unsolvable);
6556 then res;
6557 case (BackendDAE.VAR(varKind = BackendDAE.DUMMY_DER())::rest, i::irest, _, true)
6558 algorithm
6559 ✗ b := intEq(rowmark[i],mark);
6560 ✗ b1 := intEq(rowmark[i],-mark);
6561 b := b or b1;
6562 ✗ arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6563 ✗ res := List.consOnTrue(not b, i, vars);
6564 ✗ res := adjacencyRowExpEnhanced1(rest,irest,res,notinder,mark,rowmark,unsolvable);
6565 then res;
6566 case (BackendDAE.VAR(varKind = BackendDAE.DUMMY_STATE())::rest, i::irest, _, _)
6567 guard
6568 not intEq(intAbs(rowmark[i]),mark)
6569 algorithm
6570
2/2
✓ Branch 0 taken 170 times.
✓ Branch 1 taken 10599 times.
10769 arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6571 10769 res := adjacencyRowExpEnhanced1(rest,irest,i::vars,notinder,mark,rowmark,unsolvable);
6572 then res;
6573 case (BackendDAE.VAR(varKind = BackendDAE.DUMMY_STATE())::rest, i::irest, _, true)
6574 algorithm
6575 642 b := intEq(rowmark[i],mark);
6576 642 b1 := intEq(rowmark[i],-mark);
6577 b := b or b1;
6578
1/2
✓ Branch 0 taken 642 times.
✗ Branch 1 not taken.
1284 arrayUpdate(rowmark,i,if unsolvable then -mark else mark);
6579 642 res := List.consOnTrue(not b, i, vars);
6580 642 res := adjacencyRowExpEnhanced1(rest,irest,res,notinder,mark,rowmark,unsolvable);
6581 then res;
6582 case (_::rest, _::irest, _, _)
6583 algorithm
6584 22787 res := adjacencyRowExpEnhanced1(rest,irest,vars,notinder,mark,rowmark,unsolvable);
6585 then res;
6586 end matchcontinue;
6587 end adjacencyRowExpEnhanced1;
6588
6589 public function solvabilityWights
6590 "author: Frenkel TUD 2012-05,
6591 return a integer for the solvability, this function is used
6592 to calculade wights for variables "
6593 input BackendDAE.Solvability solva;
6594 output Integer i;
6595 algorithm
6596 i := match solva
6597 case BackendDAE.SOLVABILITY_SOLVED() then 1;
6598 case BackendDAE.SOLVABILITY_CONSTONE() then 2;
6599 case BackendDAE.SOLVABILITY_CONST() then 5;
6600 case BackendDAE.SOLVABILITY_PARAMETER(b=false) then 0;
6601 case BackendDAE.SOLVABILITY_PARAMETER(b=true) then 50;
6602 case BackendDAE.SOLVABILITY_LINEAR(b=false) then 0;
6603 case BackendDAE.SOLVABILITY_LINEAR(b=true) then 100;
6604 case BackendDAE.SOLVABILITY_NONLINEAR() then 500;
6605 case BackendDAE.SOLVABILITY_UNSOLVABLE() then 1000;
6606 end match;
6607 end solvabilityWights;
6608
6609 public function solvabilityCMP
6610 "author: Frenkel TUD 2012-05,
6611 function to compare solvabilities in the way solvabilityA < solvabilityB with
6612 solved < constone < const < parameter < linear < nonlinear < unsolvable."
6613 input BackendDAE.Solvability sa;
6614 input BackendDAE.Solvability sb;
6615 output Boolean b;
6616 algorithm
6617 b := match(sa,sb)
6618 case (BackendDAE.SOLVABILITY_SOLVED(),BackendDAE.SOLVABILITY_SOLVED()) then false;
6619 case (_,BackendDAE.SOLVABILITY_SOLVED()) then true;
6620 case (BackendDAE.SOLVABILITY_SOLVED(),BackendDAE.SOLVABILITY_CONSTONE()) then false;
6621 case (BackendDAE.SOLVABILITY_CONSTONE(),BackendDAE.SOLVABILITY_CONSTONE()) then false;
6622 case (_,BackendDAE.SOLVABILITY_CONSTONE()) then true;
6623 case (BackendDAE.SOLVABILITY_SOLVED(),BackendDAE.SOLVABILITY_CONST()) then false;
6624 case (BackendDAE.SOLVABILITY_CONSTONE(),BackendDAE.SOLVABILITY_CONST()) then false;
6625 case (BackendDAE.SOLVABILITY_CONST(),BackendDAE.SOLVABILITY_CONST()) then false;
6626 case (_,BackendDAE.SOLVABILITY_CONST()) then true;
6627 case (BackendDAE.SOLVABILITY_SOLVED(),BackendDAE.SOLVABILITY_PARAMETER()) then false;
6628 case (BackendDAE.SOLVABILITY_CONSTONE(),BackendDAE.SOLVABILITY_PARAMETER()) then false;
6629 case (BackendDAE.SOLVABILITY_CONST(),BackendDAE.SOLVABILITY_PARAMETER()) then false;
6630 case (BackendDAE.SOLVABILITY_PARAMETER(),BackendDAE.SOLVABILITY_PARAMETER()) then false;
6631 case (_,BackendDAE.SOLVABILITY_PARAMETER()) then true;
6632 case (BackendDAE.SOLVABILITY_SOLVED(),BackendDAE.SOLVABILITY_LINEAR()) then false;
6633 case (BackendDAE.SOLVABILITY_CONSTONE(),BackendDAE.SOLVABILITY_LINEAR()) then false;
6634 case (BackendDAE.SOLVABILITY_CONST(),BackendDAE.SOLVABILITY_LINEAR()) then false;
6635 case (BackendDAE.SOLVABILITY_PARAMETER(),BackendDAE.SOLVABILITY_LINEAR()) then false;
6636 case (BackendDAE.SOLVABILITY_LINEAR(),BackendDAE.SOLVABILITY_LINEAR()) then false;
6637 case (_,BackendDAE.SOLVABILITY_LINEAR()) then true;
6638 case (BackendDAE.SOLVABILITY_SOLVED(),BackendDAE.SOLVABILITY_NONLINEAR()) then false;
6639 case (BackendDAE.SOLVABILITY_CONSTONE(),BackendDAE.SOLVABILITY_NONLINEAR()) then false;
6640 case (BackendDAE.SOLVABILITY_CONST(),BackendDAE.SOLVABILITY_NONLINEAR()) then false;
6641 case (BackendDAE.SOLVABILITY_PARAMETER(),BackendDAE.SOLVABILITY_NONLINEAR()) then false;
6642 case (BackendDAE.SOLVABILITY_LINEAR(),BackendDAE.SOLVABILITY_NONLINEAR()) then false;
6643 case (BackendDAE.SOLVABILITY_NONLINEAR(),BackendDAE.SOLVABILITY_NONLINEAR()) then false;
6644 case (_,BackendDAE.SOLVABILITY_NONLINEAR()) then true;
6645 case (BackendDAE.SOLVABILITY_UNSOLVABLE(),BackendDAE.SOLVABILITY_UNSOLVABLE()) then false;
6646 case (BackendDAE.SOLVABILITY_UNSOLVABLE(),_) then true;
6647 end match;
6648 end solvabilityCMP;
6649
6650 public function getArrayEquationSub"author: Frenkel TUD
6651 helper for calculateJacobianRow"
6652 input Integer Index;
6653 input list<Option<Integer>> inAD;
6654 input list<tuple<Integer,list<list<DAE.Subscript>>>> inList;
6655 output list<DAE.Subscript> outSubs;
6656 output list<tuple<Integer,list<list<DAE.Subscript>>>> outList;
6657 algorithm
6658 (outSubs,outList) :=
6659 matchcontinue (Index,inAD,inList)
6660 local
6661 Integer i,ie;
6662 list<Option<Integer>> ad;
6663 list<DAE.Subscript> subs,subs1;
6664 list<list<DAE.Subscript>> subslst,subslst1;
6665 list<tuple<Integer,list<list<DAE.Subscript>>>> rest,entrylst;
6666 tuple<Integer,list<list<DAE.Subscript>>> entry;
6667 // new entry
6668 case (i,ad,{})
6669 algorithm
6670 ✗ subslst := Expression.dimensionSizesSubcriptsOpt(ad);
6671 ✗ subs::subslst1 := Expression.rangesToSubscripts(subslst);
6672 ✗ then
6673 (subs,{(i,subslst1)});
6674 // found last entry
6675 case (i,_,((ie,{subs}))::rest)
6676 guard
6677 intEq(i,ie)
6678 then
6679 (subs,rest);
6680 // found entry
6681 case (i,_,((ie,subs::subslst))::rest)
6682 guard
6683 intEq(i,ie)
6684 ✗ then
6685 (subs,(ie,subslst)::rest);
6686 // next entry
6687 case (i,ad,(entry as (ie,_))::rest)
6688 guard
6689 not intEq(i,ie)
6690 algorithm
6691 ✗ (subs1,entrylst) := getArrayEquationSub(i,ad,rest);
6692 ✗ then
6693 (subs1,entry::entrylst);
6694 case (_,_,_)
6695 algorithm
6696 ✗ true := Flags.isSet(Flags.FAILTRACE);
6697 ✗ Debug.trace("- BackendDAE.getArrayEquationSub failed\n");
6698 ✗ then
6699 fail();
6700 end matchcontinue;
6701 end getArrayEquationSub;
6702
6703 public function containAnyVar "author: PA
6704 Returns true if any of the variables given
6705 as ComponentRef list is among the BackendDAE.Variables."
6706 input list<DAE.ComponentRef> inExpComponentRefLst;
6707 input BackendDAE.Variables inVariables;
6708 output Boolean outBoolean;
6709 algorithm
6710 outBoolean := matchcontinue (inExpComponentRefLst,inVariables)
6711 local
6712 DAE.ComponentRef cr;
6713 list<DAE.ComponentRef> crefs;
6714 BackendDAE.Variables vars;
6715 case ({},_) then false;
6716 case ((cr::_),vars)
6717 algorithm
6718 125111 BackendVariable.getVar(cr, vars);
6719 then
6720 true;
6721 case ((_::crefs),vars)
6722 84913 then
6723 containAnyVar(crefs, vars);
6724 end matchcontinue;
6725 end containAnyVar;
6726
6727 protected function containAnyVarWithoutStates
6728 "Like containAnyVar but if var is state it is not counted."
6729 input list<DAE.ComponentRef> inExpComponentRefLst;
6730 input BackendDAE.Variables inVariables;
6731 output Boolean outBoolean;
6732 algorithm
6733 outBoolean := matchcontinue (inExpComponentRefLst,inVariables)
6734 local
6735 DAE.ComponentRef cr;
6736 list<DAE.ComponentRef> crefs;
6737 BackendDAE.Variables vars;
6738 BackendDAE.Var v;
6739 case ({},_) then false;
6740 case ((cr::_),vars)
6741 algorithm
6742
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
1868 (v::_,_) := BackendVariable.getVar(cr, vars);
6743
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
36 false := BackendVariable.isStateVar(v);
6744 then
6745 true;
6746 case ((_::crefs),vars)
6747 1832 then
6748 containAnyVarWithoutStates(crefs, vars);
6749 end matchcontinue;
6750 end containAnyVarWithoutStates;
6751
6752 public function getEqnSysRhs "author: Frenkel TUD 2013-02
6753
6754 Retrieve the right hand side of an equation system, given a set of variables.
6755 Uses A1*x + b1= A2*x + b2 -> 0 = (A1 - A2)*x+(b1-b2) -> x=0 -> rhs= A*0+b=b.
6756 Does not work for nonlinear Equations.
6757
6758 inputs: (DAE.Exp, BackendDAE.Variables /* variables of the eqn sys. */)
6759 outputs: DAE.Exp =
6760 "
6761 input BackendDAE.EquationArray inEqns;
6762 input BackendDAE.Variables inVariables;
6763 input Option<AvlTreePathFunction.Tree> funcs;
6764 output list<DAE.Exp> outRhsExps;
6765 output list<DAE.ElementSource> outSources;
6766 protected
6767 BackendVarTransform.VariableReplacements repl;
6768 algorithm
6769 213 repl := makeZeroReplacements(inVariables);
6770
2/2
✓ Branch 2 taken 151 times.
✓ Branch 3 taken 62 times.
213 (_, outRhsExps, outSources, _, _) := BackendEquation.traverseEquationArray(inEqns, equationToExp, (inVariables, {}, {}, funcs, repl));
6771 end getEqnSysRhs;
6772
6773 protected function equationToExp
6774 input BackendDAE.Equation inEq;
6775 input tuple<BackendDAE.Variables,list<DAE.Exp>,list<DAE.ElementSource>,Option<AvlTreePathFunction.Tree>,BackendVarTransform.VariableReplacements> inTpl;
6776 output BackendDAE.Equation outEq;
6777 output tuple<BackendDAE.Variables,list<DAE.Exp>,list<DAE.ElementSource>,Option<AvlTreePathFunction.Tree>,BackendVarTransform.VariableReplacements> outTpl;
6778 algorithm
6779 (outEq,outTpl) := matchcontinue (inEq,inTpl)
6780 local
6781 DAE.Exp e;
6782 DAE.Exp e1,e2,new_exp,rhs_exp,rhs_exp_1,rhs_exp_2;
6783 list<Integer> ds;
6784 BackendDAE.Equation eqn;
6785 BackendDAE.Variables v;
6786 list<DAE.Exp> explst,explst1;
6787 list<DAE.ElementSource> sources;
6788 DAE.ElementSource source;
6789 String str;
6790 list<list<DAE.Subscript>> subslst;
6791 Option<AvlTreePathFunction.Tree> funcs;
6792 BackendVarTransform.VariableReplacements repl;
6793 DAE.ComponentRef componentRef;
6794
6795 case (eqn as BackendDAE.RESIDUAL_EQUATION(exp=e,source=source),(v,explst,sources,funcs,repl))
6796 algorithm
6797 ✗ rhs_exp := getEqnsysRhsExp(e, v, funcs, SOME(repl));
6798 ✗ then (eqn,(v,rhs_exp::explst,source::sources,funcs,repl));
6799
6800 case (eqn as BackendDAE.EQUATION(exp=e1, scalar=e2,source=source),(v,explst,sources,funcs,repl))
6801 algorithm
6802 3438 new_exp := Expression.expSub(e1,e2);
6803 3438 rhs_exp := getEqnsysRhsExp(new_exp, v, funcs, SOME(repl));
6804 3438 rhs_exp_1 := Expression.negate(rhs_exp);
6805 3438 (rhs_exp_2,_) := ExpressionSimplify.simplify(rhs_exp_1);
6806 3438 then (eqn,(v,rhs_exp_2::explst,source::sources,funcs,repl));
6807
6808 case (eqn as BackendDAE.ARRAY_EQUATION(dimSize=ds, left=e1, right=e2, source=source), (v,explst,sources,funcs,repl))
6809 algorithm
6810 ✗ new_exp := Expression.expSub(e1,e2);
6811 ✗ subslst := Expression.dimensionSizesSubscripts(ds);
6812 ✗ subslst := Expression.rangesToSubscripts(subslst);
6813 ✗ explst1 := List.map1r(subslst,Expression.applyExpSubscripts,new_exp);
6814 ✗ explst1 := List.map3(explst1,getEqnsysRhsExp,v,funcs,SOME(repl));
6815 ✗ explst1 := List.map(explst1,Expression.negate);
6816 ✗ explst1 := ExpressionSimplify.simplifyList(explst1);
6817 ✗ explst := List.append_reverse(explst1,explst);
6818 ✗ sources := List.consN(BackendEquation.equationSize(eqn), source, sources);
6819 ✗ then (eqn,(v,explst,sources,funcs,repl));
6820
6821 case (eqn as BackendDAE.SOLVED_EQUATION(componentRef=componentRef, exp=e2, source=source),(v,explst,sources,funcs,repl))
6822 algorithm
6823 ✗ e1 := Expression.crefExp(componentRef);
6824 ✗ new_exp := Expression.expSub(e1,e2);
6825 ✗ rhs_exp := getEqnsysRhsExp(new_exp, v, funcs, SOME(repl));
6826 ✗ rhs_exp_1 := Expression.negate(rhs_exp);
6827 ✗ (rhs_exp_2,_) := ExpressionSimplify.simplify(rhs_exp_1);
6828 ✗ then (eqn,(v,rhs_exp_2::explst,source::sources,funcs,repl));
6829
6830 case (eqn as BackendDAE.COMPLEX_EQUATION(),_)
6831 algorithm
6832 ✗ str := BackendDump.equationString(eqn);
6833 ✗ str := "BackendDAEUtil.equationToExp failed for complex equation: " + str;
6834 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR,{str},BackendEquation.equationInfo(eqn));
6835 ✗ then fail();
6836
6837 case (eqn,_)
6838 algorithm
6839 ✗ str := BackendDump.equationString(eqn);
6840 ✗ str := "BackendDAEUtil.equationToExp failed: " + str;
6841 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR,{str},BackendEquation.equationInfo(eqn));
6842 ✗ then
6843 fail();
6844 end matchcontinue;
6845 end equationToExp;
6846
6847 public function getEqnsysRhsExp "author: PA
6848
6849 Retrieve the right hand side expression of an equation
6850 in an equation system, given a set of variables.
6851 Uses A1*x + b1= A2*x + b2 -> 0 = (A1 - A2)*x+(b1-b2) -> x=0 -> rhs= A*0+b=b.
6852 Does not work for nonlinear Equations.
6853
6854 inputs: (DAE.Exp, BackendDAE.Variables /* variables of the eqn sys. */)
6855 outputs: DAE.Exp =
6856 "
6857 input DAE.Exp inExp;
6858 input BackendDAE.Variables inVariables;
6859 input Option<AvlTreePathFunction.Tree> funcs;
6860 input Option<BackendVarTransform.VariableReplacements> oRepl;
6861 output DAE.Exp outExp;
6862 algorithm
6863 outExp := match oRepl
6864 local
6865 BackendVarTransform.VariableReplacements repl;
6866 case SOME(repl)
6867 algorithm
6868
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 3777 times.
3777 (outExp,(_,_,_,true)) := Expression.traverseExpTopDown(inExp, getEqnsysRhsExp1, (repl,inVariables,funcs,true));
6869 3777 (outExp,_) := ExpressionSimplify.simplify(outExp);
6870 then
6871 outExp;
6872 else
6873 algorithm
6874 ✗ repl := makeZeroReplacements(inVariables);
6875 ✗ (outExp,(_,_,_,true)) := Expression.traverseExpTopDown(inExp, getEqnsysRhsExp1, (repl,inVariables,funcs,true));
6876 ✗ (outExp,_) := ExpressionSimplify.simplify(outExp);
6877 then
6878 outExp;
6879 end match;
6880 end getEqnsysRhsExp;
6881
6882 protected function getEqnsysRhsExp1
6883 input DAE.Exp inExp;
6884 input tuple<BackendVarTransform.VariableReplacements,BackendDAE.Variables,Option<AvlTreePathFunction.Tree>,Boolean> inTpl;
6885 output DAE.Exp outExp;
6886 output Boolean cont;
6887 output tuple<BackendVarTransform.VariableReplacements,BackendDAE.Variables,Option<AvlTreePathFunction.Tree>,Boolean> outTpl;
6888 algorithm
6889 (outExp,cont,outTpl) := match (inExp,inTpl)
6890 local
6891 DAE.Exp cond,t,f,e, e1, e2, zero,exp;
6892 DAE.Type tp;
6893 BackendVarTransform.VariableReplacements repl;
6894 BackendDAE.Variables vars;
6895 Boolean b,b1;
6896 Absyn.Path path;
6897 list<DAE.Exp> expLst;
6898 Option<AvlTreePathFunction.Tree> funcs;
6899 tuple<BackendVarTransform.VariableReplacements,BackendDAE.Variables,Option<AvlTreePathFunction.Tree>,Boolean> tpl;
6900 case (e as DAE.CREF(),(repl,_,_,_))
6901 algorithm
6902 26257 (e1,b1) := BackendVarTransform.replaceExp(e, repl, NONE());
6903
2/2
✓ Branch 0 taken 13511 times.
✓ Branch 1 taken 12746 times.
26257 e1 := if b1 then e1 else e;
6904 then (e1,false,inTpl);
6905
6906 case (DAE.IFEXP(cond,t,f),(repl,vars,funcs,b))
6907 algorithm
6908 // check if vars not in condition
6909
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 176 times.
176 (_,(_,b)) := Expression.traverseExpTopDown(cond, getEqnsysRhsExp2, (vars,b));
6910
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 176 times.
176 (t,tpl) := Expression.traverseExpTopDown(t, getEqnsysRhsExp1, (repl,vars,funcs,b));
6911 176 (f,tpl) := Expression.traverseExpTopDown(f, getEqnsysRhsExp1, tpl);
6912 176 then
6913 (DAE.IFEXP(cond,t,f),false,tpl);
6914
6915 case (e as DAE.CALL(path=Absyn.IDENT(name = "der")),_)
6916 then (e,true,inTpl);
6917
6918 case (e as DAE.CALL(path = Absyn.IDENT(name = "pre")),_)
6919 then (e,false,inTpl);
6920
6921 case (e as DAE.CALL(path = Absyn.IDENT(name = "previous")),_)
6922 then (e,false,inTpl);
6923
6924 case (e as DAE.CALL(path = Absyn.IDENT(name = "semiLinear"), expLst={cond,t,f}),_)
6925 algorithm
6926 ✗ tp := Expression.typeof(e);
6927 ✗ (zero, _) := Expression.makeZeroExpression(Expression.arrayDimension(tp));
6928 ✗ e1 := Expression.expMul(cond,t);
6929 ✗ e2 := Expression.expMul(cond,f);
6930 ✗ exp := DAE.IFEXP(DAE.RELATION(cond, DAE.GREATEREQ(tp), zero, -1, NONE()), e1, e2);
6931 ✗ (exp, tpl) := Expression.traverseExpTopDown(exp, getEqnsysRhsExp1, inTpl);
6932 ✗ then (exp,false,tpl);
6933
6934 case (e as DAE.CALL(expLst=expLst),(repl,vars,funcs,b))
6935 algorithm
6936 // check if vars not in expList
6937
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 (_,(_,b)) := Expression.traverseExpListTopDown(expLst, getEqnsysRhsExp2, (vars,b));
6938 9 (e,b) := getEqnsysRhsExp3(b,e,(repl,vars,funcs,true));
6939
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 then (e,false,(repl,vars,funcs,b));
6940
6941 case (e,(_,_,_,b)) then (e,b,inTpl);
6942 end match;
6943 end getEqnsysRhsExp1;
6944
6945 protected function getEqnsysRhsExp3
6946 input Boolean b;
6947 input DAE.Exp inExp;
6948 input tuple<BackendVarTransform.VariableReplacements,BackendDAE.Variables,Option<AvlTreePathFunction.Tree>,Boolean> iTpl;
6949 output DAE.Exp oExp;
6950 output Boolean notfound;
6951 algorithm
6952 (oExp,notfound) := matchcontinue(b, iTpl)
6953 local
6954 Option<AvlTreePathFunction.Tree> funcs;
6955 DAE.Exp e;
6956 case (false, (_,_,funcs,_))
6957 algorithm
6958 // try to inline
6959 ✗ (e,_,true) := Inline.forceInlineExp(inExp,(funcs,{DAE.NORM_INLINE(),DAE.DEFAULT_INLINE()}),DAE.emptyElementSource,Ceval.cevalSimpleWithFunctionTreeReturnExp);
6960 ✗ (e,(_,_,_,notfound)) := Expression.traverseExpTopDown(e, getEqnsysRhsExp1, iTpl);
6961 then
6962 (e,notfound);
6963 else (inExp,b);
6964 end matchcontinue;
6965 end getEqnsysRhsExp3;
6966
6967 public function getEqnsysRhsExp2
6968 input DAE.Exp inExp;
6969 input tuple<BackendDAE.Variables,Boolean> inTpl;
6970 output DAE.Exp outExp;
6971 output Boolean cont;
6972 output tuple<BackendDAE.Variables,Boolean> outTpl;
6973 algorithm
6974 (outExp,cont,outTpl) := matchcontinue (inExp,inTpl)
6975 local
6976 BackendDAE.Variables vars;
6977 DAE.ComponentRef cr;
6978 Boolean b;
6979 // special case for time, it is never part of the equation system
6980 case (DAE.CREF(componentRef = DAE.CREF_IDENT(ident="time")),_)
6981 then (inExp, false, inTpl);
6982
6983 // case for functionpointers
6984 case (DAE.CREF(ty=DAE.T_FUNCTION_REFERENCE_FUNC()),_)
6985 then (inExp, false, inTpl);
6986
6987 case (DAE.CALL(path = Absyn.IDENT(name = "pre")),_)
6988 then (inExp,false,inTpl);
6989
6990 case (DAE.CALL(path = Absyn.IDENT(name = "previous")),_)
6991 then (inExp,false,inTpl);
6992
6993 // found ?
6994 case (DAE.CREF(componentRef = cr),(vars,_))
6995 algorithm
6996
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
3374 (_::_,_) := BackendVariable.getVar(cr, vars);
6997 21 then (inExp, false,(vars,false));
6998
6999 case (_,(_,b)) then (inExp,b,inTpl);
7000 end matchcontinue;
7001 end getEqnsysRhsExp2;
7002
7003 public function makeZeroReplacements "
7004 Help function to ifBranchesFreeFromVar, creates replacement rules
7005 v -> 0, for all variables"
7006 input BackendDAE.Variables vars;
7007 output BackendVarTransform.VariableReplacements repl;
7008 algorithm
7009 475 repl := BackendVariable.traverseBackendDAEVars(vars,makeZeroReplacement,BackendVarTransform.emptyReplacements());
7010 end makeZeroReplacements;
7011
7012 protected function makeZeroReplacement "helper function to makeZeroReplacements.
7013 Creates replacement BackendDAE.Var -> 0"
7014 input BackendDAE.Var inVar;
7015 input BackendVarTransform.VariableReplacements inRepl;
7016 output BackendDAE.Var var;
7017 output BackendVarTransform.VariableReplacements repl;
7018 algorithm
7019 (var,repl) := matchcontinue (inVar,inRepl)
7020 local
7021 DAE.ComponentRef cr;
7022 case (var,repl)
7023 algorithm
7024 4516 cr := BackendVariable.varCref(var);
7025 4516 repl := BackendVarTransform.addReplacement(repl,cr,Expression.makeConstZero(ComponentReference.crefLastType(cr)),NONE());
7026 then (var,repl);
7027 else (inVar,inRepl);
7028 end matchcontinue;
7029 end makeZeroReplacement;
7030
7031 /*************************************************
7032 * traverseBackendDAE and stuff
7033 ************************************************/
7034 public function traverseBackendDAEExps "author: Frenkel TUD
7035
7036 This function goes through the BackendDAE structure and finds all the
7037 expressions and performs the function on them in a list
7038 an extra argument passed through the function.
7039 "
7040 replaceable type Type_a subtypeof Any;
7041 input BackendDAE.BackendDAE inBackendDAE;
7042 input FuncExpType func;
7043 input Type_a inTypeA;
7044 output Type_a outTypeA;
7045 partial function FuncExpType
7046 input DAE.Exp inExp;
7047 input Type_a inTypeA;
7048 output DAE.Exp outExp;
7049 output Type_a outA;
7050 end FuncExpType;
7051 algorithm
7052 outTypeA := matchcontinue inBackendDAE
7053 local
7054 BackendDAE.Shared shared;
7055 list<BackendDAE.EqSystem> systs;
7056 String name;
7057
7058 case BackendDAE.DAE(systs, shared)
7059 algorithm
7060 7547 outTypeA := List.fold1(systs, traverseBackendDAEExpsEqSystem, func, inTypeA);
7061 7547 outTypeA := traverseBackendDAEExpsVars(shared.globalKnownVars, func, outTypeA);
7062 7547 outTypeA := traverseBackendDAEExpsEqns(shared.initialEqs, func, outTypeA);
7063 7547 outTypeA := traverseBackendDAEExpsEqns(shared.removedEqs, func, outTypeA);
7064 then
7065 outTypeA;
7066
7067 else algorithm
7068 ✗ (_, _, name) := System.dladdr(func);
7069 ✗ Error.addInternalError("traverseBackendDAEExps failed for " + name, sourceInfo());
7070 ✗ then fail();
7071 end matchcontinue;
7072 end traverseBackendDAEExps;
7073
7074 public function traverseBackendDAEExpsEqSystemJacobians "author: wbraun
7075
7076 This function goes through the all jacobians and stateSets and finds all the
7077 expressions and performs the function on them in a list
7078 an extra argument passed through the function.
7079 "
7080 replaceable type Type_a subtypeof Any;
7081 input BackendDAE.EqSystem syst;
7082 input FuncExpType func;
7083 input Type_a inTypeA;
7084 output Type_a outTypeA;
7085 partial function FuncExpType
7086 input DAE.Exp inExp;
7087 input Type_a inTypeA;
7088 output DAE.Exp outExp;
7089 output Type_a outA;
7090 end FuncExpType;
7091 algorithm
7092 outTypeA :=
7093 matchcontinue syst
7094 local
7095 BackendDAE.StrongComponents comps;
7096 BackendDAE.StateSets stateSets;
7097 Type_a arg;
7098 case BackendDAE.EQSYSTEM(stateSets = stateSets)
7099 algorithm
7100 50745 comps := getStrongComponents(syst);
7101 50745 arg := traverseStrongComponentsJacobiansExp(comps, func, inTypeA);
7102 50745 arg := traverseStateSetsJacobiansExp(stateSets, func, arg);
7103 then arg;
7104 else inTypeA;
7105 end matchcontinue;
7106 end traverseBackendDAEExpsEqSystemJacobians;
7107
7108 public function traverseStrongComponentsJacobiansExp
7109 "author: wbraun"
7110 replaceable type Type_a subtypeof Any;
7111 input BackendDAE.StrongComponents inComps;
7112 input FuncExpType inFunc;
7113 input output Type_a arg;
7114 partial function FuncExpType
7115 input DAE.Exp inExp;
7116 input Type_a inTypeA;
7117 output DAE.Exp outExp;
7118 output Type_a outA;
7119 end FuncExpType;
7120 algorithm
7121
2/2
✓ Branch 0 taken 134977 times.
✓ Branch 1 taken 50745 times.
185722 for comp in inComps loop
7122 arg := match comp
7123 local
7124 list<tuple<Integer, Integer, BackendDAE.Equation>> jac;
7125 BackendDAE.BackendDAE bdae;
7126 case BackendDAE.EQUATIONSYSTEM(jac=BackendDAE.FULL_JACOBIAN(SOME(jac)))
7127 143 then traverseBackendDAEExpsJacobianEqn(jac, inFunc, arg);
7128 case BackendDAE.EQUATIONSYSTEM(jac=BackendDAE.GENERIC_JACOBIAN(jacobian = SOME((bdae,_,_,_,_,_))))
7129 255 then traverseBackendDAEExps(bdae, inFunc, arg);
7130 case BackendDAE.TORNSYSTEM(BackendDAE.TEARINGSET(jac=BackendDAE.GENERIC_JACOBIAN(jacobian = SOME((bdae,_,_,_,_,_)))))
7131 1176 then traverseBackendDAEExps(bdae, inFunc, arg);
7132 else arg;
7133 end match;
7134 end for;
7135 end traverseStrongComponentsJacobiansExp;
7136
7137 protected function traverseBackendDAEExpsJacobianEqn "Helper for traverseExpsOfEquation."
7138 replaceable type Type_a subtypeof Any;
7139 input list<tuple<Integer, Integer, BackendDAE.Equation>> inJacEntry;
7140 input FuncExpType func;
7141 input Type_a inTypeA;
7142 output Type_a outTypeA;
7143 partial function FuncExpType
7144 input DAE.Exp inExp;
7145 input Type_a inTypeA;
7146 output DAE.Exp outExp;
7147 output Type_a outA;
7148 end FuncExpType;
7149 algorithm
7150 outTypeA :=
7151 match inJacEntry
7152 local
7153 BackendDAE.Equation eqn;
7154 Type_a typeA;
7155 case {} then inTypeA;
7156 case (_,_,eqn)::_
7157 algorithm
7158 143 typeA := traverseBackendDAEExpsOptEqn(SOME(eqn),func,inTypeA);
7159 then typeA;
7160 end match;
7161 end traverseBackendDAEExpsJacobianEqn;
7162
7163 public function traverseStateSetsJacobiansExp
7164 replaceable type Type_a subtypeof Any;
7165 input BackendDAE.StateSets inStateSets;
7166 input FuncExpType inFunc;
7167 input Type_a inTypeA;
7168 output Type_a outTypeA;
7169 partial function FuncExpType
7170 input DAE.Exp inExp;
7171 input Type_a inTypeA;
7172 output DAE.Exp outExp;
7173 output Type_a outA;
7174 end FuncExpType;
7175 algorithm
7176 outTypeA :=
7177 match inStateSets
7178 local
7179 BackendDAE.StateSets rest;
7180 BackendDAE.BackendDAE bdae;
7181 Type_a arg;
7182 case {} then inTypeA;
7183 case BackendDAE.STATESET(jacobian = BackendDAE.GENERIC_JACOBIAN(jacobian = SOME((bdae,_,_,_,_,_))))::rest
7184 algorithm
7185 21 arg := traverseBackendDAEExps(bdae, inFunc, inTypeA);
7186 21 then
7187 traverseStateSetsJacobiansExp(rest, inFunc, arg);
7188 end match;
7189 end traverseStateSetsJacobiansExp;
7190
7191 public function traverseBackendDAEExpsNoCopyWithUpdate<A>
7192 "This function goes through the BackendDAE structure and finds all the
7193 expressions and performs the function on them in a list
7194 an extra argument passed through the function."
7195 input BackendDAE.BackendDAE inBackendDAE;
7196 input FuncExpType func;
7197 input A inTypeA;
7198 output A outTypeA;
7199 partial function FuncExpType
7200 input DAE.Exp inExp;
7201 input A inTypeA;
7202 output DAE.Exp outExp;
7203 output A outA;
7204 end FuncExpType;
7205 protected
7206 list<BackendDAE.EqSystem> systs;
7207 BackendDAE.Shared shared;
7208 String name;
7209 algorithm
7210 try
7211 2378 BackendDAE.DAE(systs, shared) := inBackendDAE;
7212 2378 outTypeA := List.fold1(systs, traverseBackendDAEExpsEqSystemWithUpdate, func, inTypeA);
7213 2378 outTypeA := traverseBackendDAEExpsVarsWithUpdate(shared.globalKnownVars, func, outTypeA);
7214 2378 outTypeA := traverseBackendDAEExpsEqns(shared.initialEqs, func, outTypeA);
7215 2378 outTypeA := traverseBackendDAEExpsEqns(shared.removedEqs, func, outTypeA);
7216 else
7217 ✗ (_, _, name) := System.dladdr(func);
7218 ✗ Error.addInternalError("traverseBackendDAEExpsNoCopyWithUpdate failed for " + name, sourceInfo());
7219 ✗ fail();
7220 end try;
7221 end traverseBackendDAEExpsNoCopyWithUpdate;
7222
7223 public function traverseBackendDAEExpsEqSystem "This function goes through the BackendDAE structure and finds all the
7224 expressions and performs the function on them in a list
7225 an extra argument passed through the function.
7226 "
7227 replaceable type Type_a subtypeof Any;
7228 input BackendDAE.EqSystem syst;
7229 input FuncExpType func;
7230 input Type_a inTypeA;
7231 output Type_a outTypeA;
7232 partial function FuncExpType
7233 input DAE.Exp inExp;
7234 input Type_a inTypeA;
7235 output DAE.Exp outExp;
7236 output Type_a outA;
7237 end FuncExpType;
7238 algorithm
7239 81907 outTypeA := traverseBackendDAEExpsVars(syst.orderedVars, func, inTypeA);
7240 81907 outTypeA := traverseBackendDAEExpsEqns(syst.orderedEqs, func, outTypeA);
7241 81907 outTypeA := traverseBackendDAEExpsEqns(syst.removedEqs, func, outTypeA);
7242 end traverseBackendDAEExpsEqSystem;
7243
7244 public function traverseBackendDAEExpsEqSystemWithUpdate "This function goes through the BackendDAE structure and finds all the
7245 expressions and performs the function on them in a list
7246 an extra argument passed through the function."
7247 replaceable type Type_a subtypeof Any;
7248 input BackendDAE.EqSystem syst;
7249 input FuncExpType func;
7250 input Type_a inTypeA;
7251 output Type_a outTypeA;
7252 partial function FuncExpType
7253 input DAE.Exp inExp;
7254 input Type_a inTypeA;
7255 output DAE.Exp outExp;
7256 output Type_a outA;
7257 end FuncExpType;
7258 algorithm
7259 55022 outTypeA := traverseBackendDAEExpsVarsWithUpdate(syst.orderedVars, func, inTypeA);
7260 55022 outTypeA := traverseBackendDAEExpsEqns(syst.orderedEqs, func, outTypeA);
7261 55022 outTypeA := traverseBackendDAEExpsEqns(syst.removedEqs, func, outTypeA);
7262 end traverseBackendDAEExpsEqSystemWithUpdate;
7263
7264 public function traverseBackendDAEExpsVars "Helper for traverseBackendDAEExps"
7265 replaceable type Type_a subtypeof Any;
7266 input BackendDAE.Variables inVariables;
7267 input FuncExpType func;
7268 input Type_a inTypeA;
7269 output Type_a outTypeA;
7270 partial function FuncExpType
7271 input DAE.Exp inExp;
7272 input Type_a inTypeA;
7273 output DAE.Exp outExp;
7274 output Type_a outA;
7275 end FuncExpType;
7276 algorithm
7277 outTypeA:=
7278 matchcontinue inVariables
7279 local
7280 array<Option<BackendDAE.Var>> varOptArr;
7281 Type_a ext_arg_1;
7282 String name;
7283 case BackendDAE.VARIABLES(varArr = BackendDAE.VARIABLE_ARRAY(varOptArr=varOptArr))
7284 algorithm
7285 96961 ext_arg_1 := traverseArrayNoCopy(varOptArr,func,traverseBackendDAEExpsVar,inTypeA);
7286 then
7287 ext_arg_1;
7288
7289 else algorithm
7290 ✗ true := Flags.isSet(Flags.FAILTRACE);
7291 ✗ (_, _, name) := System.dladdr(func);
7292 ✗ Debug.trace("- BackendDAE.traverseBackendDAEExpsVars failed for " + name + "\n");
7293 ✗ then fail();
7294 end matchcontinue;
7295 end traverseBackendDAEExpsVars;
7296
7297 public function traverseBackendDAEExpsVarsWithUpdate "Helper for traverseBackendDAEExps"
7298 replaceable type Type_a subtypeof Any;
7299 input BackendDAE.Variables inVariables;
7300 input FuncExpType func;
7301 input Type_a inTypeA;
7302 output Type_a outTypeA;
7303 partial function FuncExpType
7304 input DAE.Exp inExp;
7305 input Type_a inTypeA;
7306 output DAE.Exp outExp;
7307 output Type_a outA;
7308 end FuncExpType;
7309 algorithm
7310 outTypeA:=
7311 matchcontinue inVariables
7312 local
7313 array<Option<BackendDAE.Var>> varOptArr;
7314 Type_a ext_arg_1;
7315 String name;
7316 case BackendDAE.VARIABLES(varArr = BackendDAE.VARIABLE_ARRAY(varOptArr=varOptArr))
7317 algorithm
7318 60224 (_,ext_arg_1) := traverseArrayNoCopyWithUpdate(varOptArr,func,traverseBackendDAEExpsVarWithUpdate,inTypeA);
7319 60224 then
7320 ext_arg_1;
7321
7322 else algorithm
7323 ✗ (_, _, name) := System.dladdr(func);
7324 ✗ Error.addInternalError("traverseBackendDAEExpsVarsWithUpdate failed for " + name, sourceInfo());
7325 ✗ then fail();
7326 end matchcontinue;
7327 end traverseBackendDAEExpsVarsWithUpdate;
7328
7329 public function traverseArrayNoCopy<ArrT, ElemT, ArgT>
7330 input array<ArrT> inArray;
7331 input ElemFuncType inElemFunc;
7332 input ArrayFuncType inArrayFunc;
7333 input ArgT inArg;
7334 input Integer inLength = arrayLength(inArray);
7335 output ArgT outArg = inArg;
7336
7337 partial function ElemFuncType
7338 input ElemT inElement;
7339 input ArgT inArg;
7340 output ElemT outElement;
7341 output ArgT outArg;
7342 end ElemFuncType;
7343
7344 partial function ArrayFuncType
7345 input ArrT inElement;
7346 input ElemFuncType inFunc;
7347 input ArgT inArg;
7348 output ArgT outArg;
7349 end ArrayFuncType;
7350 algorithm
7351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 426472 times.
426472 true := inLength <= arrayLength(inArray);
7352
7353
2/2
✓ Branch 0 taken 25094 times.
✓ Branch 1 taken 401378 times.
61150450 for i in 1:inLength loop
7354
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60723978 times.
60723978 outArg := inArrayFunc(inArray[i], inElemFunc, outArg);
7355 end for;
7356 end traverseArrayNoCopy;
7357
7358 public function traverseArrayNoCopyWithStop<ArrT, ElemT, ArgT>
7359 "Same as traverseArrayNoCopy, but with an additional parameter to
7360 stop the traversal."
7361 input array<ArrT> inArray;
7362 input ElemFuncType inElemFunc;
7363 input ArrayFuncType inArrayFunc;
7364 input ArgT inArg;
7365 input Integer inLength = arrayLength(inArray);
7366 output ArgT outArg = inArg;
7367
7368 partial function ElemFuncType
7369 input ElemT inElement;
7370 input ArgT inArg;
7371 output ElemT outElement;
7372 output Boolean outContinue;
7373 output ArgT outArg;
7374 end ElemFuncType;
7375
7376 partial function ArrayFuncType
7377 input ArrT inElement;
7378 input ElemFuncType inFunc;
7379 input ArgT inArg;
7380 output Boolean outContinue;
7381 output ArgT outArg;
7382 end ArrayFuncType;
7383 protected
7384 Boolean cont;
7385 algorithm
7386 ✗ true := inLength <= arrayLength(inArray);
7387
7388 ✗ for i in 1:inLength loop
7389 ✗ (cont, outArg) := inArrayFunc(inArray[i], inElemFunc, outArg);
7390 ✗ if not cont then break; end if;
7391 end for;
7392 end traverseArrayNoCopyWithStop;
7393
7394 public function traverseArrayNoCopyWithUpdate<ArrT, ElemT, ArgT>
7395 input array<ArrT> inArray;
7396 input ElemFuncType inElemFunc;
7397 input ArrayFuncType inArrayFunc;
7398 input ArgT inArg;
7399 input Integer inLength = arrayLength(inArray);
7400 output array<ArrT> outArray = inArray;
7401 output ArgT outArg = inArg;
7402
7403 partial function ElemFuncType
7404 input ElemT inElement;
7405 input ArgT inArg;
7406 output ElemT outElement;
7407 output ArgT outArg;
7408 end ElemFuncType;
7409
7410 partial function ArrayFuncType
7411 input ArrT inElement;
7412 input ElemFuncType inFunc;
7413 input ArgT inArg;
7414 output ArrT outElement;
7415 output ArgT outArg;
7416 end ArrayFuncType;
7417 protected
7418 ArrT e, new_e;
7419 algorithm
7420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98543 times.
98543 true := inLength <= arrayLength(inArray);
7421
7422
2/2
✓ Branch 0 taken 7073 times.
✓ Branch 1 taken 91470 times.
22553673 for i in 1:inLength loop
7423 22455130 e := inArray[i];
7424
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22455130 times.
22455130 (new_e, outArg) := inArrayFunc(e, inElemFunc, outArg);
7425
2/2
✓ Branch 0 taken 18336607 times.
✓ Branch 1 taken 4118523 times.
22455130 if not referenceEq(e, new_e) then
7426 18336607 arrayUpdate(outArray, i, new_e);
7427 end if;
7428 end for;
7429 end traverseArrayNoCopyWithUpdate;
7430
7431 protected function traverseBackendDAEExpsVar "author: Frenkel TUD
7432 Helper traverseBackendDAEExpsVar. Get all exps from a BackendDAE.Var.
7433 DAE.T_UNKNOWN_DEFAULT is used as type for componentref. Not important here.
7434 We only use the exp list for finding function calls"
7435 replaceable type Type_a subtypeof Any;
7436 input Option<BackendDAE.Var> inVar;
7437 input FuncExpType func;
7438 input Type_a inTypeA;
7439 output Type_a outTypeA;
7440 partial function FuncExpType
7441 input DAE.Exp inExp;
7442 input Type_a inTypeA;
7443 output DAE.Exp outExp;
7444 output Type_a outA;
7445 end FuncExpType;
7446 algorithm
7447 55832953 (_,outTypeA):=traverseBackendDAEExpsVarWithUpdate(inVar,func,inTypeA);
7448 end traverseBackendDAEExpsVar;
7449
7450 protected function traverseBackendDAEExpsVarWithUpdate "author: Frenkel TUD
7451 Helper traverseBackendDAEExpsVar. Get all exps from a BackendDAE.Var.
7452 DAE.T_UNKNOWN_DEFAULT is used as type for componentref. Not important here.
7453 We only use the exp list for finding function calls"
7454 replaceable type Type_a subtypeof Any;
7455 input Option<BackendDAE.Var> inVar;
7456 input FuncExpType func;
7457 input Type_a inTypeA;
7458 output Option<BackendDAE.Var> ovar;
7459 output Type_a outTypeA;
7460 partial function FuncExpType
7461 input DAE.Exp inExp;
7462 input Type_a inTypeA;
7463 output DAE.Exp outExp;
7464 output Type_a outA;
7465 end FuncExpType;
7466 algorithm
7467 (ovar, outTypeA) := matchcontinue inVar
7468 local
7469 DAE.Exp e1, e1_;
7470 DAE.ComponentRef cref;
7471 list<DAE.Dimension> instdims;
7472 Option<DAE.VariableAttributes> attr, attr_;
7473 Option<BackendDAE.TearingSelect> ts;
7474 Option<DAE.Exp> hideResult;
7475 Type_a ext_arg_1, ext_arg_2;
7476 BackendDAE.VarKind varKind;
7477 DAE.VarDirection varDirection;
7478 DAE.VarParallelism varParallelism;
7479 BackendDAE.Type varType;
7480 DAE.ElementSource source;
7481 Option<SCode.Comment> comment;
7482 DAE.ConnectorType ct;
7483 DAE.VarInnerOuter io;
7484 Boolean unreplaceable, initNonlinear, encrypted;
7485 String name;
7486 Option<BackendDAE.Var> v;
7487 Option<DAE.Exp> tplExp;
7488
7489 case NONE()
7490 then (NONE(), inTypeA);
7491
7492 case SOME(BackendDAE.VAR(cref, varKind, varDirection, varParallelism, varType, SOME(e1), tplExp, instdims, source, attr, ts, hideResult, comment, ct, io, unreplaceable, initNonlinear, encrypted)) algorithm
7493
2/2
✓ Branch 0 taken 369973 times.
✓ Branch 1 taken 1437076 times.
1807049 (e1_, ext_arg_1) := func(e1, inTypeA);
7494 1807049 (attr_, ext_arg_2) := traverseBackendDAEVarAttr(attr, func, ext_arg_1);
7495
2/2
✓ Branch 0 taken 65418 times.
✓ Branch 1 taken 1741631 times.
1807049 if referenceEq(e1,e1_) and referenceEq(attr,attr_) then
7496 v := inVar;
7497 else
7498
4/6
✓ Branch 0 taken 65418 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 65418 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 62186 times.
✓ Branch 5 taken 3232 times.
261672 v := SOME(BackendDAE.VAR(cref, varKind, varDirection, varParallelism, varType, SOME(e1_), tplExp, instdims, source, attr_, ts, hideResult, comment, ct, io, unreplaceable, initNonlinear, encrypted));
7499 end if;
7500 1807049 then (v, ext_arg_2);
7501
7502 case SOME(BackendDAE.VAR(cref, varKind, varDirection, varParallelism, varType, NONE(), tplExp, instdims, source, attr, ts, hideResult, comment, ct, io, unreplaceable, initNonlinear, encrypted)) algorithm
7503 838541 (attr_, ext_arg_2) := traverseBackendDAEVarAttr(attr, func, inTypeA);
7504
2/2
✓ Branch 0 taken 316886 times.
✓ Branch 1 taken 521655 times.
838541 if referenceEq(attr,attr_) then
7505 v := inVar;
7506 else
7507
4/6
✓ Branch 0 taken 316886 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 316886 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 297130 times.
✓ Branch 5 taken 19756 times.
1247788 v := SOME(BackendDAE.VAR(cref, varKind, varDirection, varParallelism, varType, NONE(), tplExp, instdims, source, attr_, ts, hideResult, comment, ct, io, unreplaceable, initNonlinear, encrypted));
7508 end if;
7509 838541 then (v, ext_arg_2);
7510
7511 else algorithm
7512 ✗ true := Flags.isSet(Flags.FAILTRACE);
7513 ✗ (_, _, name) := System.dladdr(func);
7514 ✗ Debug.trace("- BackendDAE.traverseBackendDAEExpsVar failed for " + name + "\n");
7515 ✗ then fail();
7516 end matchcontinue;
7517 end traverseBackendDAEExpsVarWithUpdate;
7518
7519 public function traverseBackendDAEVarAttr
7520 "help function to traverseBackendDAEExpsVarWithUpdate
7521 author: Peter Aronsson (paronsson@wolfram.com)
7522 "
7523 input Option<DAE.VariableAttributes> attr;
7524 input FuncExpType func;
7525 input ExtraArgType extraArg;
7526 replaceable type ExtraArgType subtypeof Any;
7527 partial function FuncExpType
7528 input DAE.Exp inExp;
7529 input ExtraArgType inTypeA;
7530 output DAE.Exp outExp;
7531 output ExtraArgType outA;
7532 end FuncExpType;
7533 output Option<DAE.VariableAttributes> outAttr;
7534 output ExtraArgType outExtraArg;
7535 algorithm
7536 (outAttr,outExtraArg) := match attr
7537 local
7538 Option<DAE.Exp> q,u,du,min,max,i,f,n,eqbound;
7539 Option<DAE.StartOrigin> startOrigin;
7540 Option<DAE.Exp> q_,u_,du_,min_,max_,i_,f_,n_,eqbound_;
7541 Option<DAE.StateSelect> ss;
7542 Option<DAE.Uncertainty> unc;
7543 Option<DAE.Distribution> dist, dist_;
7544 Option<Boolean> p,fin;
7545 Option<DAE.VariableAttributes> a;
7546 case NONE() then (NONE(),extraArg);
7547 case SOME(DAE.VAR_ATTR_REAL(q,u,du,min,max,i,f,n,ss,unc,dist,eqbound,p,fin,startOrigin)) algorithm
7548 3217341 (q_,outExtraArg) := Expression.traverseExpOpt(q,func,extraArg);
7549 3217341 (u_,outExtraArg) := Expression.traverseExpOpt(u,func,outExtraArg);
7550 3217341 (du_,outExtraArg) := Expression.traverseExpOpt(du,func,outExtraArg);
7551 3217341 (min_,outExtraArg) := Expression.traverseExpOpt(min,func,outExtraArg);
7552 3217341 (max_,outExtraArg) := Expression.traverseExpOpt(max,func,outExtraArg);
7553 3217341 (i_,outExtraArg) := Expression.traverseExpOpt(i,func,outExtraArg);
7554 3217341 (f_,outExtraArg) := Expression.traverseExpOpt(f,func,outExtraArg);
7555 3217341 (n_,outExtraArg) := Expression.traverseExpOpt(n,func,outExtraArg);
7556 3217341 (eqbound_,outExtraArg) := Expression.traverseExpOpt(eqbound,func,outExtraArg);
7557 3217341 (dist_,outExtraArg) := traverseBackendDAEAttrDistribution(dist,func,outExtraArg);
7558
9/10
✓ Branch 0 taken 3217281 times.
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 3217183 times.
✓ Branch 3 taken 98 times.
✓ Branch 4 taken 3213587 times.
✓ Branch 5 taken 3596 times.
✓ Branch 6 taken 3213587 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 846670 times.
✓ Branch 9 taken 2366917 times.
3217341 if referenceEq(q,q_) and referenceEq(u,u_) and referenceEq(du,du_) and referenceEq(min,min_) and referenceEq(max,max_) and referenceEq(i,i_) and referenceEq(f,f_) and referenceEq(n,n_)
7559 and referenceEq(eqbound,eqbound_) and referenceEq(dist,dist_) then
7560 a := attr;
7561 else
7562 850424 a := SOME(DAE.VAR_ATTR_REAL(q_,u_,du_,min_,max_,i_,f_,n_,ss,unc,dist_,eqbound_,p,fin,startOrigin));
7563 end if;
7564 3217341 then (a,outExtraArg);
7565
7566 case SOME(DAE.VAR_ATTR_INT(q,min,max,i,f,unc,dist,eqbound,p,fin,startOrigin)) algorithm
7567 139110 (q_,outExtraArg) := Expression.traverseExpOpt(q,func,extraArg);
7568 139110 (min_,outExtraArg) := Expression.traverseExpOpt(min,func,outExtraArg);
7569 139110 (max_,outExtraArg) := Expression.traverseExpOpt(max,func,outExtraArg);
7570 139110 (i_,outExtraArg) := Expression.traverseExpOpt(i,func,outExtraArg);
7571 139110 (f_,outExtraArg) := Expression.traverseExpOpt(f,func,outExtraArg);
7572 139110 (eqbound_,outExtraArg) := Expression.traverseExpOpt(eqbound,func,outExtraArg);
7573 139110 (dist_,outExtraArg) := traverseBackendDAEAttrDistribution(dist,func,outExtraArg);
7574
5/8
✓ Branch 0 taken 139110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 139110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 139110 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 28140 times.
✓ Branch 7 taken 110970 times.
139110 if referenceEq(q,q_) and referenceEq(min,min_) and referenceEq(max,max_) and referenceEq(i,i_) and referenceEq(f,f_)
7575 and referenceEq(eqbound,eqbound_) and referenceEq(dist,dist_) then
7576 a := attr;
7577 else
7578 28140 a := SOME(DAE.VAR_ATTR_INT(q_,min_,max_,i_,f_,unc,dist_,eqbound_,p,fin,startOrigin));
7579 end if;
7580 139110 then (a,outExtraArg);
7581
7582 case SOME(DAE.VAR_ATTR_BOOL(q,i,f,eqbound,p,fin,startOrigin)) algorithm
7583 147932 (q_,outExtraArg) := Expression.traverseExpOpt(q,func,extraArg);
7584 147932 (i_,outExtraArg) := Expression.traverseExpOpt(i,func,outExtraArg);
7585 147932 (f_,outExtraArg) := Expression.traverseExpOpt(f,func,outExtraArg);
7586 147932 (eqbound_,outExtraArg) := Expression.traverseExpOpt(eqbound,func,outExtraArg);
7587
2/4
✓ Branch 0 taken 147932 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 147932 times.
147932 if referenceEq(q,q_) and referenceEq(i,i_) and referenceEq(f,f_) and referenceEq(eqbound,eqbound_) then
7588 a := attr;
7589 else
7590 ✗ a := SOME(DAE.VAR_ATTR_BOOL(q_,i_,f_,eqbound_,p,fin,startOrigin));
7591 end if;
7592 147932 then (a,outExtraArg);
7593
7594 case SOME(DAE.VAR_ATTR_STRING(q,i,f,eqbound,p,fin,startOrigin)) algorithm
7595 15430 (q_,outExtraArg) := Expression.traverseExpOpt(q,func,extraArg);
7596 15430 (i_,outExtraArg) := Expression.traverseExpOpt(i,func,outExtraArg);
7597 15430 (f_,outExtraArg) := Expression.traverseExpOpt(f,func,outExtraArg);
7598 15430 (eqbound_,outExtraArg) := Expression.traverseExpOpt(eqbound,func,outExtraArg);
7599
2/4
✓ Branch 0 taken 15430 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15430 times.
15430 if referenceEq(q,q_) and referenceEq(i,i_) and referenceEq(f,f_) and referenceEq(eqbound,eqbound_) then
7600 a := attr;
7601 else
7602 ✗ a := SOME(DAE.VAR_ATTR_STRING(q_,i_,f_,eqbound_,p,fin,startOrigin));
7603 end if;
7604 15430 then (a,outExtraArg);
7605
7606 case SOME(DAE.VAR_ATTR_ENUMERATION(q,min,max,i,f,eqbound,p,fin,startOrigin)) algorithm
7607 24068 (q_,outExtraArg) := Expression.traverseExpOpt(q,func,extraArg);
7608 24068 (min_,outExtraArg) := Expression.traverseExpOpt(min,func,outExtraArg);
7609 24068 (max_,outExtraArg) := Expression.traverseExpOpt(max,func,outExtraArg);
7610 24068 (i_,outExtraArg) := Expression.traverseExpOpt(i,func,outExtraArg);
7611 24068 (f_,outExtraArg) := Expression.traverseExpOpt(f,func,outExtraArg);
7612 24068 (eqbound_,outExtraArg) := Expression.traverseExpOpt(eqbound,func,outExtraArg);
7613
3/6
✓ Branch 0 taken 24068 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24068 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 24068 times.
24068 if referenceEq(q,q_) and referenceEq(min,min_) and referenceEq(max,max_) and referenceEq(i,i_) and referenceEq(f,f_) and referenceEq(eqbound,eqbound_) then
7614 a := attr;
7615 else
7616 ✗ a := SOME(DAE.VAR_ATTR_ENUMERATION(q_,min_,max_,i_,f_,eqbound_,p,fin,startOrigin));
7617 end if;
7618 24068 then (a,outExtraArg);
7619 case SOME(DAE.VAR_ATTR_CLOCK(_, _))
7620 then (attr,extraArg);
7621
7622 end match;
7623 end traverseBackendDAEVarAttr;
7624
7625 protected function traverseBackendDAEAttrDistribution
7626 "help function to traverseBackendDAEVarAttr
7627 author: Peter Aronsson (paronsson@wolfram.com)
7628 "
7629 input Option<DAE.Distribution> distOpt;
7630 input FuncExpType func;
7631 input Type_a extraArg;
7632 replaceable type Type_a subtypeof Any;
7633 partial function FuncExpType
7634 input DAE.Exp inExp;
7635 input Type_a inTypeA;
7636 output DAE.Exp outExp;
7637 output Type_a outA;
7638 end FuncExpType;
7639 output Option<DAE.Distribution> outDistOpt;
7640 output Type_a outExtraArg;
7641 algorithm
7642 (outDistOpt,outExtraArg) := match(distOpt, extraArg)
7643 local
7644 DAE.Exp name,arr,sarr;
7645 DAE.Exp name_,arr_,sarr_;
7646 Option<DAE.Distribution> d;
7647
7648 case(NONE(), outExtraArg) then (NONE(),outExtraArg);
7649
7650 case(SOME(DAE.DISTRIBUTION(name,arr,sarr)), _) algorithm
7651 ✗ (arr_,_) := Expression.extendArrExp(arr,false);
7652 ✗ (sarr_,_) := Expression.extendArrExp(sarr,false);
7653 ✗ (name_,outExtraArg) := Expression.traverseExpBottomUp(name,func,extraArg);
7654 ✗ (arr_,outExtraArg) := Expression.traverseExpBottomUp(arr_,func,outExtraArg);
7655 ✗ (sarr_,outExtraArg) := Expression.traverseExpBottomUp(sarr_,func,outExtraArg);
7656 ✗ if referenceEq(name, name_) and referenceEq(arr, arr_) and referenceEq(sarr, sarr_) then
7657 d := distOpt;
7658 else
7659 ✗ d := SOME(DAE.DISTRIBUTION(name_,arr_,sarr_));
7660 end if;
7661 ✗ then (d,outExtraArg);
7662 end match;
7663 end traverseBackendDAEAttrDistribution;
7664
7665 public function traverseBackendDAEExpsEqns<T> "author: lochel
7666 Traverse all expressions of an equation array and apply modifications to them."
7667 input BackendDAE.EquationArray equationArray;
7668 input FuncExpType func;
7669 input output T extraArg;
7670
7671 partial function FuncExpType
7672 input output DAE.Exp exp;
7673 input output T extraArg;
7674 end FuncExpType;
7675 protected
7676 String name;
7677 BackendDAE.Equation eqn, eqn_new;
7678 algorithm
7679 try
7680
2/2
✓ Branch 1 taken 192057 times.
✓ Branch 2 taken 201526 times.
2057314 for i in 1:ExpandableArray.getLastUsedIndex(equationArray) loop
7681
1/2
✓ Branch 1 taken 1663731 times.
✗ Branch 2 not taken.
1663731 if ExpandableArray.occupied(i, equationArray) then
7682 1663731 eqn := ExpandableArray.get(i, equationArray);
7683 1663731 (eqn_new, extraArg) := BackendEquation.traverseExpsOfEquation(eqn, func, extraArg);
7684
1/2
✓ Branch 0 taken 1663731 times.
✗ Branch 1 not taken.
1663731 if not referenceEq(eqn, eqn_new) then
7685 1663731 ExpandableArray.update(i, eqn_new, equationArray);
7686 end if;
7687 end if;
7688 end for;
7689 else
7690 ✗ if Flags.isSet(Flags.FAILTRACE) then
7691 ✗ (_, _, name) := System.dladdr(func);
7692 ✗ Debug.trace("- BackendDAE.traverseBackendDAEExpsEqns failed for " + name + "\n");
7693 end if;
7694 ✗ fail();
7695 end try;
7696 end traverseBackendDAEExpsEqns;
7697
7698 public function traverseBackendDAEExpsEqnsWithStop<T> "author: lochel"
7699 input BackendDAE.EquationArray equationArray;
7700 input FuncExpType func;
7701 input output T extraArg;
7702
7703 partial function FuncExpType
7704 input DAE.Exp inExp;
7705 input T inTypeA;
7706 output DAE.Exp outExp;
7707 output Boolean cont;
7708 output T outA;
7709 end FuncExpType;
7710 protected
7711 String name;
7712 BackendDAE.Equation e;
7713 Boolean continue_;
7714 algorithm
7715 try
7716
1/2
✓ Branch 1 taken 2949 times.
✗ Branch 2 not taken.
41639 for i in 1:ExpandableArray.getLastUsedIndex(equationArray) loop
7717
1/2
✓ Branch 1 taken 38874 times.
✗ Branch 2 not taken.
38874 if ExpandableArray.occupied(i, equationArray) then
7718 38874 e := ExpandableArray.get(i, equationArray);
7719 38874 (continue_, extraArg) := BackendEquation.traverseExpsOfEquation_WithStop(e, func, extraArg);
7720
2/2
✓ Branch 0 taken 38690 times.
✓ Branch 1 taken 184 times.
38874 if not continue_ then
7721 break;
7722 end if;
7723 end if;
7724 end for;
7725 else
7726 ✗ if Flags.isSet(Flags.FAILTRACE) then
7727 ✗ (_, _, name) := System.dladdr(func);
7728 ✗ Error.addInternalError("BackendDAEUtil.traverseBackendDAEExpsEqnsWithStop failed for " + name, sourceInfo());
7729 end if;
7730 ✗ fail();
7731 end try;
7732 end traverseBackendDAEExpsEqnsWithStop;
7733
7734 public function traverseBackendDAEExpsOptEqn "author: Frenkel TUD 2010-11
7735 Helper for traverseExpsOfEquation."
7736 replaceable type Type_a subtypeof Any;
7737 input Option<BackendDAE.Equation> inEquation;
7738 input FuncExpType func;
7739 input Type_a inTypeA;
7740 output Type_a outTypeA;
7741 partial function FuncExpType
7742 input DAE.Exp inExp;
7743 input Type_a inTypeA;
7744 output DAE.Exp outExp;
7745 output Type_a outA;
7746 end FuncExpType;
7747 algorithm
7748 143 (_,outTypeA) := traverseBackendDAEExpsOptEqnWithUpdate(inEquation,func,inTypeA);
7749 end traverseBackendDAEExpsOptEqn;
7750
7751 protected function traverseBackendDAEExpsOptEqnWithUpdate "author: Frenkel TUD 2010-11
7752 Helper for traverseExpsOfEquation."
7753 replaceable type Type_a subtypeof Any;
7754 input Option<BackendDAE.Equation> inEquation;
7755 input FuncExpType func;
7756 input Type_a inTypeA;
7757 output Option<BackendDAE.Equation> outEquation;
7758 output Type_a outTypeA;
7759 partial function FuncExpType
7760 input DAE.Exp inExp;
7761 input Type_a inTypeA;
7762 output DAE.Exp outExp;
7763 output Type_a outA;
7764 end FuncExpType;
7765 algorithm
7766 (outEquation,outTypeA) := match inEquation
7767 local
7768 BackendDAE.Equation eqn1,eqn2;
7769 Type_a ext_arg_1;
7770 case SOME(eqn1)
7771 algorithm
7772 143 (eqn2,ext_arg_1) := BackendEquation.traverseExpsOfEquation(eqn1,func,inTypeA);
7773
1/2
✓ Branch 0 taken 143 times.
✗ Branch 1 not taken.
286 then
7774 (if referenceEq(eqn1,eqn2) then inEquation else SOME(eqn2),ext_arg_1);
7775 else (NONE(),inTypeA);
7776 end match;
7777 end traverseBackendDAEExpsOptEqnWithUpdate;
7778
7779 public function traverseAlgorithmExpsWithUpdate "
7780 This function goes through the Algorithm structure and finds all the
7781 expressions and performs the function on them
7782 "
7783 replaceable type Type_a subtypeof Any;
7784 input DAE.Algorithm inAlgorithm;
7785 input FuncExpType func;
7786 input Type_a inTypeA;
7787 output DAE.Algorithm outAlgorithm;
7788 output Type_a outTypeA;
7789 partial function FuncExpType
7790 input DAE.Exp inExp;
7791 input Type_a inTypeA;
7792 output DAE.Exp outExp;
7793 output Type_a outA;
7794 end FuncExpType;
7795 algorithm
7796 (outAlgorithm,outTypeA) := match inAlgorithm
7797 local
7798 list<DAE.Statement> stmts,stmts1;
7799 Type_a ext_arg_1;
7800 DAE.Algorithm alg;
7801 case DAE.ALGORITHM_STMTS(statementLst = stmts)
7802 algorithm
7803 ✗ (stmts1,ext_arg_1) := DAEUtil.traverseDAEEquationsStmts(stmts,func,inTypeA);
7804 ✗ alg := if referenceEq(stmts,stmts1) then inAlgorithm else DAE.ALGORITHM_STMTS(stmts1);
7805 ✗ then
7806 (alg,ext_arg_1);
7807 end match;
7808 end traverseAlgorithmExpsWithUpdate;
7809
7810 protected function traverseZeroCrossingExps
7811 replaceable type Type_a subtypeof Any;
7812 input list<BackendDAE.ZeroCrossing> iZeroCrossing;
7813 input FuncExpType func;
7814 input Type_a inTypeA;
7815 input list<BackendDAE.ZeroCrossing> iAcc={};
7816 output list<BackendDAE.ZeroCrossing> oZeroCrossing;
7817 output Type_a outTypeA;
7818 partial function FuncExpType
7819 input DAE.Exp inExp;
7820 input Type_a inTypeA;
7821 output DAE.Exp outExp;
7822 output Type_a outA;
7823 end FuncExpType;
7824 algorithm
7825 (oZeroCrossing,outTypeA) := match iZeroCrossing
7826 local
7827 list<BackendDAE.ZeroCrossing> zeroCrossing;
7828 DAE.Exp relation1;
7829 Type_a arg;
7830 BackendDAE.ZeroCrossing zc;
7831 ✗ case {} then (listReverse(iAcc),inTypeA);
7832 case (zc as BackendDAE.ZERO_CROSSING())::zeroCrossing
7833 algorithm
7834 ✗ (relation1,arg) := Expression.traverseExpBottomUp(zc.relation_,func,inTypeA);
7835 ✗ (zeroCrossing,arg) := traverseZeroCrossingExps(zeroCrossing,func,arg,(if referenceEq(relation1,zc.relation_) then zc else BackendDAE.ZERO_CROSSING(zc.index,relation1,zc.occurEquLst,zc.iter))::iAcc);
7836 then
7837 (zeroCrossing,arg);
7838 end match;
7839 end traverseZeroCrossingExps;
7840
7841 /*************************************************
7842 * Equation System Pipeline
7843 ************************************************/
7844
7845 public function getSolvedSystem "Run the equation system pipeline."
7846 input BackendDAE.BackendDAE inDAE;
7847 input String fileNamePrefix;
7848 input Option<list<String>> strPreOptModules = NONE();
7849 input Option<String> strmatchingAlgorithm = NONE();
7850 input Option<String> strdaeHandler = NONE();
7851 input Option<list<String>> strPostOptModules = NONE();
7852 output BackendDAE.BackendDAE outSimDAE;
7853 output BackendDAE.BackendDAE outInitDAE;
7854 output Option<BackendDAE.BackendDAE> outInitDAE_lambda0_option;
7855 output Option<BackendDAE.InlineData > outInlineData;
7856 output list<BackendDAE.Equation> outRemovedInitialEquationLst;
7857 protected
7858 BackendDAE.BackendDAE dae, simDAE, outInitDAE_lambda0;
7859 list<tuple<BackendDAEFunc.optimizationModule, String>> preOptModules;
7860 list<tuple<BackendDAEFunc.optimizationModule, String>> postOptModules;
7861 tuple<BackendDAEFunc.StructurallySingularSystemHandlerFunc, String, BackendDAEFunc.stateDeselectionFunc, String> daeHandler;
7862 tuple<BackendDAEFunc.matchingAlgorithmFunc, String> matchingAlgorithm;
7863 BackendDAE.Variables globalKnownVars;
7864 Integer numCheckpoints, oldSize;
7865 AvlTreePathFunction.Tree funcTree;
7866 algorithm
7867 1080 numCheckpoints:=ErrorExt.getNumCheckpoints();
7868 try
7869 1080 StackOverflow.clearStacktraceMessages();
7870 1080 setGlobalRoot(Global.adjacencyIfCondCache, NONE());
7871 1080 preOptModules := getPreOptModules(strPreOptModules);
7872 1080 postOptModules := getPostOptModules(strPostOptModules);
7873 1080 matchingAlgorithm := getMatchingAlgorithm(strmatchingAlgorithm);
7874 1080 daeHandler := getIndexReductionMethod(strdaeHandler);
7875
7876
4/4
✓ Branch 1 taken 1079 times.
✓ Branch 2 taken 1 time.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 1077 times.
1080 if Flags.isSet(Flags.DUMP_DAE_LOW) or Flags.isSet(Flags.OPT_DAE_DUMP) then
7877 3 BackendDump.dumpBackendDAE(inDAE, "dumpdaelow (before pre-optimization)");
7878
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if Flags.isSet(Flags.ADDITIONAL_GRAPHVIZ_DUMP) then
7879 ✗ BackendDump.graphvizAdjacencyMatrix(inDAE, "dumpdaelow");
7880 end if;
7881 end if;
7882
7883 // pre-optimization phase
7884 1080 dae := preOptimizeDAE(inDAE, preOptModules);
7885
7886 1078 execStat("pre-optimization done (n="+String(daeSize(dae))+")");
7887 // transformation phase (matching and sorting using index reduction method)
7888 1078 Error.checkCancel();
7889 1078 dae := causalizeDAE(dae, NONE(), matchingAlgorithm, daeHandler, true);
7890 1077 execStat("matching and sorting (n="+String(daeSize(dae))+")");
7891
7892 // synchronous features post-phase
7893 1077 dae := SynchronousFeatures.synchronousFeatures(dae);
7894
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1075 times.
1077 if Flags.isSet(Flags.OPT_DAE_DUMP) then
7895 2 BackendDump.dumpBackendDAE(dae, "synchronousFeatures");
7896 end if;
7897
7898
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1077 times.
1077 if Flags.isSet(Flags.GRAPHML) then
7899 ✗ BackendDump.dumpBipartiteGraphDAE(dae, fileNamePrefix);
7900 end if;
7901
7902
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1076 times.
1077 if Flags.isSet(Flags.EVAL_OUTPUT_ONLY) then
7903 1 oldSize := daeSize(dae);
7904 1 dae := BackendDAEOptimize.evaluateOutputsOnly(dae);
7905 1 execStat("evaluateOutputsOnly (n=" + intString(oldSize) + " -> n=" + intString(daeSize(dae)) + ")");
7906 end if;
7907
7908 //generate Jacobian for StateSets for initial state selection
7909 1077 Error.checkCancel();
7910 1077 dae := SymbolicJacobian.calculateStateSetsJacobians(dae);
7911
7912 // generate system for initialization
7913 1077 Error.checkCancel();
7914 1077 (outInitDAE, outInitDAE_lambda0_option, outRemovedInitialEquationLst, globalKnownVars, dae) := Initialization.solveInitialSystem(dae);
7915
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1076 times.
1076 if Flags.isSet(Flags.WARN_NO_NOMINAL) then
7916 ✗ warnAboutIterationVariablesWithNoNominal(outInitDAE);
7917 end if;
7918
7919 // use function tree from initDAE further for simDAE
7920 1076 simDAE := BackendDAEUtil.setFunctionTree(dae, BackendDAEUtil.getFunctions(outInitDAE.shared));
7921
7922 // Set updated globalKnownVars
7923 1076 simDAE := setDAEGlobalKnownVars(simDAE, globalKnownVars);
7924
7925 // add initial assignmnents to all algorithms
7926 1076 simDAE := BackendDAEOptimize.addInitialStmtsToAlgorithms(simDAE, false);
7927
7928 // remove homotopy and initial calls
7929 1076 simDAE := Initialization.removeInitializationStuff(simDAE);
7930
7931 // generate inline solver
7932 1076 outInlineData := SymbolicImplicitSolver.symSolver(simDAE);
7933
7934 // post-optimization phase
7935 1076 simDAE := postOptimizeDAE(simDAE, postOptModules, matchingAlgorithm, daeHandler);
7936
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1076 times.
1076 if Flags.isSet(Flags.WARN_NO_NOMINAL) then
7937 ✗ warnAboutIterationVariablesWithNoNominal(simDAE);
7938 end if;
7939
7940 // sort the globalKnownVars
7941 1076 simDAE := sortGlobalKnownVarsInDAE(simDAE);
7942 1076 execStat("sort global known variables");
7943
7944 // remove unused functions
7945 1076 funcTree := BackendDAEOptimize.copyRecordConstructorAndExternalObjConstructorDestructor(BackendDAEUtil.getFunctions(simDAE.shared));
7946 1076 funcTree := BackendDAEOptimize.removeUnusedFunctions(outInitDAE.eqs, outInitDAE.shared, outRemovedInitialEquationLst, BackendDAEUtil.getFunctions(simDAE.shared), funcTree);
7947
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1076 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 1043 times.
1076 if isSome(outInitDAE_lambda0_option) then
7948 33 SOME(outInitDAE_lambda0) := outInitDAE_lambda0_option;
7949 33 funcTree := BackendDAEOptimize.removeUnusedFunctions(outInitDAE_lambda0.eqs, simDAE.shared, {}, BackendDAEUtil.getFunctions(simDAE.shared), funcTree);
7950 end if;
7951 1076 funcTree := BackendDAEOptimize.removeUnusedFunctions(simDAE.eqs, simDAE.shared, {}, BackendDAEUtil.getFunctions(simDAE.shared), funcTree);
7952 1075 outSimDAE := BackendDAEUtil.setFunctionTree(simDAE, funcTree);
7953
7954 1075 execStat("remove unused functions");
7955
7956
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1069 times.
1075 if Flags.isSet(Flags.DUMP_INDX_DAE) then
7957 6 BackendDump.dumpBackendDAE(outSimDAE, "dumpindxdae");
7958
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if Flags.isSet(Flags.ADDITIONAL_GRAPHVIZ_DUMP) then
7959 ✗ BackendDump.graphvizBackendDAE(outSimDAE, "dumpindxdae");
7960 end if;
7961 end if;
7962
4/6
✓ Branch 1 taken 1016 times.
✓ Branch 2 taken 59 times.
✓ Branch 4 taken 1016 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1016 times.
1075 if Flags.isSet(Flags.DUMP_BACKENDDAE_INFO) or Flags.isSet(Flags.DUMP_STATESELECTION_INFO) or Flags.isSet(Flags.DUMP_DISCRETEVARS_INFO) then
7963 59 BackendDump.dumpCompShort(outSimDAE);
7964 end if;
7965
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1074 times.
1075 if Flags.isSet(Flags.DUMP_EQNINORDER) then
7966 1 BackendDump.dumpEqnsSolved(outSimDAE, "indxdae: eqns in order");
7967 end if;
7968
3/4
✓ Branch 1 taken 1073 times.
✓ Branch 2 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1073 times.
1075 if Flags.isSet(Flags.DUMP_LOOPS) or Flags.isSet(Flags.DUMP_LOOPS_VERBOSE) then
7969 2 print("\n" + BackendDump.BORDER + "\n\n Algbraic Loops (Simulation): \n\n" + BackendDump.BORDER + "\n");
7970 2 BackendDump.dumpLoops(outSimDAE);
7971 2 print("\n" + BackendDump.BORDER + "\n\n Algbraic Loops (Initialization): \n\n" + BackendDump.BORDER + "\n");
7972 2 BackendDump.dumpLoops(outInitDAE);
7973
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if isSome(outInitDAE_lambda0_option) then
7974 ✗ print("\n" + BackendDump.BORDER + "\n\n Algbraic Loops (Initialization Lambda=0 (Homotopy)): \n\n" + BackendDump.BORDER + "\n");
7975 ✗ BackendDump.dumpLoops(Util.getOption(outInitDAE_lambda0_option));
7976 end if;
7977 end if;
7978 1075 checkBackendDAEWithErrorMsg(outSimDAE);
7979
2/2
✓ Branch 0 taken 1061 times.
✓ Branch 1 taken 14 times.
1075 return;
7980 else
7981 ✗ setGlobalRoot(Global.stackoverFlowIndex, NONE());
7982 ✗ ErrorExt.rollbackNumCheckpoints(ErrorExt.getNumCheckpoints()-numCheckpoints);
7983 // A user cancel unwinds through this checkpoint like a failure; report it as
7984 // such (after the rollback, so the message survives) rather than as overflow.
7985 ✗ Error.checkCancel();
7986 ✗ Error.addInternalError(StackOverflow.errorPrefix() + " in "+getInstanceName()+"...\n"+stringDelimitList(StackOverflow.readableStacktraceMessages(), "\n"), sourceInfo());
7987 /* Do not fail or we can loop too much */
7988 ✗ StackOverflow.clearStacktraceMessages();
7989 end try annotation(__OpenModelica_stackOverflowCheckpoint=true);
7990 ✗ fail();
7991 end getSolvedSystem;
7992
7993 public function preOptimizeBackendDAE "
7994 This function runs the pre-optimization modules."
7995 input BackendDAE.BackendDAE inDAE;
7996 input Option<list<String>> strPreOptModules;
7997 output BackendDAE.BackendDAE outDAE;
7998 protected
7999 list<tuple<BackendDAEFunc.optimizationModule, String>> preOptModules;
8000 algorithm
8001 2 preOptModules := getPreOptModules(strPreOptModules);
8002 2 outDAE := preOptimizeDAE(inDAE, preOptModules);
8003 end preOptimizeBackendDAE;
8004
8005 public function preOptimizeDAE "
8006 This function runs the pre-optimization modules."
8007 input BackendDAE.BackendDAE inDAE;
8008 input list<tuple<BackendDAEFunc.optimizationModule, String>> inPreOptModules;
8009 output BackendDAE.BackendDAE outDAE = inDAE;
8010 protected
8011 BackendDAEFunc.optimizationModule optModule;
8012 String moduleStr;
8013 BackendDAE.EqSystems systs;
8014 BackendDAE.Shared shared;
8015 algorithm
8016 2845 execStat("prepare preOptimizeDAE");
8017
2/2
✓ Branch 0 taken 20544 times.
✓ Branch 1 taken 2843 times.
23387 for preOptModule in inPreOptModules loop
8018 20544 Error.checkCancel();
8019 20544 (optModule, moduleStr) := preOptModule;
8020 20544 moduleStr := moduleStr + " (" + BackendDump.printBackendDAEType2String(inDAE.shared.backendDAEType) + ")";
8021 try
8022
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20544 times.
20544 BackendDAE.DAE(systs, shared) := optModule(outDAE);
8023 20542 (systs, shared) := filterEmptySystems(systs, shared);
8024 20542 outDAE := BackendDAE.DAE(systs, shared);
8025 20542 execStat("preOpt " + moduleStr);
8026
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 20527 times.
20542 if Flags.isSet(Flags.OPT_DAE_DUMP) then
8027 15 BackendDump.dumpBackendDAE(outDAE, "pre-optimization module " + moduleStr);
8028 end if;
8029 else
8030 2 execStat("preOpt " + moduleStr + " <failed>");
8031 2 Error.addCompilerError("pre-optimization module " + moduleStr + " failed.");
8032 2 fail();
8033 end try;
8034 end for;
8035
8036
2/2
✓ Branch 1 taken 2841 times.
✓ Branch 2 taken 2 times.
2843 if Flags.isSet(Flags.OPT_DAE_DUMP) then
8037 2 print("pre-optimization done.\n");
8038 end if;
8039 end preOptimizeDAE;
8040
8041 public function transformBackendDAE "
8042 Run the matching and index reduction algorithm"
8043 input BackendDAE.BackendDAE inDAE;
8044 input Option<BackendDAE.MatchingOptions> inMatchingOptions;
8045 input Option<String> strmatchingAlgorithm;
8046 input Option<String> strindexReductionMethod;
8047 output BackendDAE.BackendDAE outDAE;
8048 protected
8049 tuple<BackendDAEFunc.matchingAlgorithmFunc,String> matchingAlgorithm;
8050 tuple<BackendDAEFunc.StructurallySingularSystemHandlerFunc,String,BackendDAEFunc.stateDeselectionFunc,String> indexReductionMethod;
8051 algorithm
8052 6438 matchingAlgorithm := getMatchingAlgorithm(strmatchingAlgorithm);
8053 6438 indexReductionMethod := getIndexReductionMethod(strindexReductionMethod);
8054 6438 outDAE := causalizeDAE(inDAE,inMatchingOptions,matchingAlgorithm,indexReductionMethod,true);
8055 end transformBackendDAE;
8056
8057 public function causalizeDAE "
8058 Run the matching Algorithm.
8059 In case of a DAE a DAE handler is used to reduce the index of the DAE."
8060 input BackendDAE.BackendDAE inDAE;
8061 input Option<BackendDAE.MatchingOptions> inMatchingOptions;
8062 input tuple<BackendDAEFunc.matchingAlgorithmFunc,String> matchingAlgorithm;
8063 input tuple<BackendDAEFunc.StructurallySingularSystemHandlerFunc,String,BackendDAEFunc.stateDeselectionFunc,String> stateDeselection;
8064 input Boolean dolateinline;
8065 output BackendDAE.BackendDAE outDAE;
8066 protected
8067 list<BackendDAE.EqSystem> systs;
8068 BackendDAE.Shared shared;
8069 list<Option<BackendDAE.StructurallySingularSystemHandlerArg>> args;
8070 Boolean causalized;
8071 algorithm
8072 49351 BackendDAE.DAE(systs,shared) := inDAE;
8073 // reduce index
8074 49351 (systs,shared,args,causalized) := mapCausalizeDAE(systs,shared,inMatchingOptions,matchingAlgorithm,stateDeselection,{},{},false);
8075 // do late inline
8076
2/2
✓ Branch 0 taken 9278 times.
✓ Branch 1 taken 40072 times.
49350 outDAE := if dolateinline then BackendInline.lateInlineFunction(BackendDAE.DAE(systs,shared)) else BackendDAE.DAE(systs,shared);
8077 //print("The StructurallySingularSystemHandlerArgs\n");
8078 //List.map_0(args,BackendDump.SSSHandlerArgString);
8079
8080 // do state selection
8081
2/2
✓ Branch 0 taken 12075 times.
✓ Branch 1 taken 37275 times.
49350 if causalized then
8082 12075 BackendDAE.DAE(systs,shared) := stateDeselectionDAE(outDAE, args, stateDeselection);
8083 end if;
8084
8085 // sort assigned equations to blt form
8086 49350 systs := mapSortEqnsDAE(systs, shared);
8087 49350 outDAE := BackendDAE.DAE(systs, shared);
8088 end causalizeDAE;
8089
8090 protected function mapCausalizeDAE "
8091 Run the matching Algorithm.
8092 In case of a DAE a DAE handler is used to reduce the index of the DAE."
8093 input list<BackendDAE.EqSystem> isysts;
8094 input BackendDAE.Shared ishared;
8095 input Option<BackendDAE.MatchingOptions> inMatchingOptions;
8096 input tuple<BackendDAEFunc.matchingAlgorithmFunc,String> matchingAlgorithm;
8097 input tuple<BackendDAEFunc.StructurallySingularSystemHandlerFunc,String,BackendDAEFunc.stateDeselectionFunc,String> stateDeselection;
8098 input list<BackendDAE.EqSystem> acc;
8099 input list<Option<BackendDAE.StructurallySingularSystemHandlerArg>> acc1;
8100 input Boolean iCausalized;
8101 output list<BackendDAE.EqSystem> osysts;
8102 output BackendDAE.Shared oshared;
8103 output list<Option<BackendDAE.StructurallySingularSystemHandlerArg>> oargs;
8104 output Boolean oCausalized;
8105 algorithm
8106 (osysts,oshared,oargs,oCausalized) := match isysts
8107 local
8108 BackendDAE.EqSystem syst;
8109 list<BackendDAE.EqSystem> systs;
8110 BackendDAE.Shared shared;
8111 Option<BackendDAE.StructurallySingularSystemHandlerArg> arg;
8112 list<Option<BackendDAE.StructurallySingularSystemHandlerArg>> args;
8113 Boolean causalized;
8114
8115 case {}
8116 49350 then (listReverse(acc),ishared,listReverse(acc1),iCausalized);
8117
8118 case syst::systs algorithm
8119 414933 Error.checkCancel();
8120 414933 (syst,shared,arg,causalized) := causalizeDAEWork(syst,ishared,inMatchingOptions,matchingAlgorithm,stateDeselection,iCausalized);
8121 414932 (systs,shared,args,causalized) := mapCausalizeDAE(systs,shared,inMatchingOptions,matchingAlgorithm,stateDeselection,syst::acc,arg::acc1,causalized);
8122 then (systs,shared,args,causalized);
8123 end match;
8124 end mapCausalizeDAE;
8125
8126 protected function causalizeDAEWork "
8127 Run the matching Algorithm.
8128 In case of an DAE an DAE-Handler is used to reduce
8129 the index of the dae."
8130 input BackendDAE.EqSystem isyst;
8131 input BackendDAE.Shared ishared;
8132 input Option<BackendDAE.MatchingOptions> inMatchingOptions;
8133 input tuple<BackendDAEFunc.matchingAlgorithmFunc,String> matchingAlgorithm;
8134 input tuple<BackendDAEFunc.StructurallySingularSystemHandlerFunc,String,BackendDAEFunc.stateDeselectionFunc,String> stateDeselection;
8135 input Boolean iCausalized;
8136 output BackendDAE.EqSystem osyst;
8137 output BackendDAE.Shared oshared;
8138 output Option<BackendDAE.StructurallySingularSystemHandlerArg> oArg;
8139 output Boolean oCausalized;
8140 algorithm
8141 (osyst,oshared,oArg,oCausalized) := matchcontinue (isyst,matchingAlgorithm,stateDeselection)
8142 local
8143 array<Integer> mapIncRowEqn;
8144 array<list<Integer>> mapEqnIncRow;
8145 BackendDAE.EqSystem syst;
8146 BackendDAE.MatchingOptions match_opts;
8147 BackendDAE.Shared shared;
8148 BackendDAE.StructurallySingularSystemHandlerArg arg;
8149 BackendDAEFunc.matchingAlgorithmFunc matchingAlgorithmfunc;
8150 BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler;
8151 AvlTreePathFunction.Tree funcs;
8152 Integer nvars,neqns;
8153 String str,mAmethodstr,str1;
8154
8155 case (BackendDAE.EQSYSTEM(matching=BackendDAE.MATCHING()), _, _)
8156 then (isyst, ishared,NONE(), iCausalized);
8157
8158 case (BackendDAE.EQSYSTEM(matching=BackendDAE.NO_MATCHING()), (matchingAlgorithmfunc,_), (sssHandler,_,_,_)) algorithm
8159 //BackendDump.dumpEqSystem(isyst, "causalizeDAEWork");
8160 //print("SystemSize: " + intString(systemSize(isyst)));
8161 61588 funcs := getFunctions(ishared);
8162 123176 (syst,_,_,mapEqnIncRow,mapIncRowEqn) := getAdjacencyMatrixScalar(isyst,BackendDAE.SOLVABLE(), SOME(funcs), isInitializationDAE(ishared));
8163 61588 match_opts := Util.getOptionOrDefault(inMatchingOptions,(BackendDAE.INDEX_REDUCTION(), BackendDAE.EXACT()));
8164 61588 arg := IndexReduction.getStructurallySingularSystemHandlerArg(syst,ishared,mapEqnIncRow,mapIncRowEqn);
8165 // check singular system
8166 61588 nvars := BackendVariable.daenumVariables(syst);
8167 61588 neqns := systemSize(syst);
8168 61588 syst := Causalize.singularSystemCheck(nvars,neqns,syst,match_opts,matchingAlgorithm,arg,ishared);
8169 // execStat("transformDAE -> singularSystemCheck " + mAmethodstr);
8170 // match the system and reduce index if neccessary
8171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61587 times.
61587 (syst,shared,arg) := matchingAlgorithmfunc(syst, ishared, false, match_opts, sssHandler, arg);
8172 // execStat("transformDAE -> matchingAlgorithm " + mAmethodstr + " index Reduction Method " + str1);
8173 61587 then (syst, shared,SOME(arg), true);
8174
8175 case (_, (_,mAmethodstr), (_,str1,_,_)) algorithm
8176 // A cancel unwinds through here; do not blame the module for it.
8177 1 Error.checkCancel();
8178 1 str := "Transformation Module " + mAmethodstr + " index Reduction Method " + str1 + " failed!";
8179
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1 if not isInitializationDAE(ishared) then
8180 1 Error.addMessage(Error.INTERNAL_ERROR, {str});
8181 end if;
8182 1 then fail();
8183 end matchcontinue;
8184 end causalizeDAEWork;
8185
8186 protected function stateDeselectionDAE
8187 input BackendDAE.BackendDAE inDAE;
8188 input list<Option<BackendDAE.StructurallySingularSystemHandlerArg>> args;
8189 input tuple<BackendDAEFunc.StructurallySingularSystemHandlerFunc,String,BackendDAEFunc.stateDeselectionFunc,String> stateDeselection;
8190 output BackendDAE.BackendDAE outDAE;
8191 protected
8192 String methodstr;
8193 BackendDAEFunc.stateDeselectionFunc sDfunc;
8194 algorithm
8195 // do state selection
8196 12075 (_, _, sDfunc, methodstr) := stateDeselection;
8197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12075 times.
12075 outDAE := sDfunc(inDAE, args);
8198 //execStat("transformDAE -> state selection " + methodstr);
8199 end stateDeselectionDAE;
8200
8201 protected function mapSortEqnsDAE "Run Tarjan's Algorithm."
8202 input list<BackendDAE.EqSystem> inSystem;
8203 input BackendDAE.Shared inShared;
8204 output list<BackendDAE.EqSystem> outSystem;
8205 algorithm
8206
4/4
✓ Branch 0 taken 414932 times.
✓ Branch 1 taken 49350 times.
✓ Branch 2 taken 414932 times.
✓ Branch 3 taken 49350 times.
464282 outSystem := list(match syst
8207 case BackendDAE.EQSYSTEM(matching=BackendDAE.MATCHING(comps=_::_)) then syst;
8208 else algorithm
8209 61588 Error.checkCancel();
8210 61588 then sortEqnsDAEWork(syst, inShared);
8211 end match for syst in inSystem);
8212 end mapSortEqnsDAE;
8213
8214 protected function sortEqnsDAEWork "Run Tarjans Algorithm."
8215 input BackendDAE.EqSystem inSystem;
8216 input BackendDAE.Shared inShared;
8217 output BackendDAE.EqSystem outSystem;
8218 protected
8219 BackendDAE.EqSystem syst;
8220 array<list<Integer>> mapEqnIncRow;
8221 array<Integer> mapIncRowEqn;
8222 AvlTreePathFunction.Tree funcs;
8223 algorithm
8224 try
8225 // sorting algorithm
8226 61588 funcs := getFunctions(inShared);
8227 123176 (syst, _, _, mapEqnIncRow, mapIncRowEqn) := getAdjacencyMatrixScalar(inSystem, BackendDAE.NORMAL(), SOME(funcs), isInitializationDAE(inShared));
8228 61588 (outSystem, _) := BackendDAETransform.strongComponentsScalar(syst, inShared, mapEqnIncRow, mapIncRowEqn);
8229
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 61588 times.
61588 if Flags.isSet(Flags.DUMP_SCC_GRAPHML) then
8230 ✗ dumpStrongComponents(outSystem, inShared);
8231 end if;
8232 else
8233 //BackendDump.dumpEqSystem(inSystem, "Transformation module sort components failed for following system:");
8234 ✗ Error.addInternalError("Transformation module sort components failed", sourceInfo());
8235 ✗ fail();
8236 end try;
8237 end sortEqnsDAEWork;
8238
8239 function dumpStrongComponents
8240 "dump the strongly connected components on a flag"
8241 input BackendDAE.EqSystem isyst;
8242 input BackendDAE.Shared ishared;
8243 algorithm
8244 () := match ishared
8245 local
8246 String fileName, fileNamePrefix;
8247 Integer seqNo;
8248
8249 case BackendDAE.SHARED(info = BackendDAE.EXTRA_INFO(fileNamePrefix = fileNamePrefix))
8250 algorithm
8251 ✗ seqNo := System.tmpTickIndex(Global.backendDAE_fileSequence);
8252 ✗ fileName := fileNamePrefix + "_" + intString(seqNo) + "_Comps" + intString(systemSize(isyst)) + ".graphml";
8253 ✗ DumpGraphML.dumpSystem(isyst, ishared, NONE(), fileName, false);
8254 then ();
8255
8256 end match;
8257 end dumpStrongComponents;
8258
8259 public function postOptimizeDAE
8260 "Run the post-optimization modules."
8261 input BackendDAE.BackendDAE inDAE;
8262 input list<tuple<BackendDAEFunc.optimizationModule, String>> inPostOptModules;
8263 input tuple<BackendDAEFunc.matchingAlgorithmFunc, String> inMatchingAlgorithm;
8264 input tuple<BackendDAEFunc.StructurallySingularSystemHandlerFunc, String, BackendDAEFunc.stateDeselectionFunc, String> inDAEHandler;
8265 output BackendDAE.BackendDAE outDAE = inDAE;
8266 protected
8267 BackendDAEFunc.optimizationModule optModule;
8268 String moduleStr;
8269 BackendDAE.EqSystems systs;
8270 BackendDAE.Shared shared;
8271 constant Boolean debug = false;
8272 algorithm
8273 3959 execStat("prepare postOptimizeDAE");
8274
2/2
✓ Branch 0 taken 40072 times.
✓ Branch 1 taken 3959 times.
44031 for postOptModule in inPostOptModules loop
8275 40072 Error.checkCancel();
8276 40072 (optModule, moduleStr) := postOptModule;
8277 40072 moduleStr := moduleStr + " (" + BackendDump.printBackendDAEType2String(inDAE.shared.backendDAEType) + ")";
8278 try
8279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40072 times.
40072 BackendDAE.DAE(systs, shared) := optModule(outDAE);
8280 40072 (systs, shared) := filterEmptySystems(systs, shared);
8281 40072 outDAE := BackendDAE.DAE(systs, shared);
8282 if debug then execStat("postOpt " + moduleStr); end if;
8283 40072 outDAE := causalizeDAE(outDAE, SOME((BackendDAE.NO_INDEX_REDUCTION(), BackendDAE.EXACT())), inMatchingAlgorithm, inDAEHandler, false);
8284 40072 execStat("postOpt " + (if debug then "causalize " else "") + moduleStr);
8285
2/2
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 40041 times.
40072 if Flags.isSet(Flags.OPT_DAE_DUMP) then
8286 31 BackendDump.dumpBackendDAE(outDAE, "post-optimization module " + moduleStr);
8287 end if;
8288 else
8289 ✗ execStat("<failed> postOpt " + moduleStr);
8290 ✗ Error.addCompilerError("post-optimization module " + moduleStr + " failed.");
8291 ✗ fail();
8292 end try;
8293 end for;
8294
8295
2/2
✓ Branch 1 taken 3955 times.
✓ Branch 2 taken 4 times.
3959 if Flags.isSet(Flags.OPT_DAE_DUMP) then
8296 4 print("post-optimization done.\n");
8297 end if;
8298 end postOptimizeDAE;
8299
8300 public function getSolvedSystemforJacobians "Run the equation system pipeline."
8301 input BackendDAE.BackendDAE inDAE;
8302 input list<String> strPreOptModules;
8303 input Option<String> strMatchingAlgorithm;
8304 input Option<String> strDAEHandler;
8305 input list<String> strPostOptModules;
8306 output BackendDAE.BackendDAE outDAE;
8307 protected
8308 BackendDAE.BackendDAE dae;
8309 list<tuple<BackendDAEFunc.optimizationModule, String>> preOptModules;
8310 list<tuple<BackendDAEFunc.optimizationModule, String>> postOptModules;
8311 tuple<BackendDAEFunc.StructurallySingularSystemHandlerFunc, String, BackendDAEFunc.stateDeselectionFunc, String> daeHandler;
8312 tuple<BackendDAEFunc.matchingAlgorithmFunc, String> matchingAlgorithm;
8313 algorithm
8314 1754 preOptModules := selectOptModules(strPreOptModules, {}, {}, allPreOptimizationModules());
8315 1754 postOptModules := selectOptModules(strPostOptModules, {}, {}, allPostOptimizationModules());
8316 1754 matchingAlgorithm := getMatchingAlgorithm(strMatchingAlgorithm);
8317 1754 daeHandler := getIndexReductionMethod(strDAEHandler);
8318
8319 //fcall2(Flags.DUMP_DAE_LOW, BackendDump.dumpBackendDAE, inDAE, "dumpdaelow");
8320 // pre optimisation phase
8321 1754 dae := preOptimizeDAE(inDAE, preOptModules);
8322
8323 // transformation phase (matching and sorting using a index reduction method
8324 1754 dae := causalizeDAE(dae, SOME((BackendDAE.NO_INDEX_REDUCTION(), BackendDAE.EXACT())), matchingAlgorithm, daeHandler, true);
8325 1754 execStat("causalizeDAE (first run)");
8326 //fcall(Flags.DUMP_DAE_LOW, BackendDump.bltdump, ("bltdump", dae));
8327
8328 // post-optimization phase
8329 1754 outDAE := postOptimizeDAE(dae, postOptModules, matchingAlgorithm, daeHandler);
8330
8331 //fcall2(Flags.DUMP_INDX_DAE, BackendDump.dumpBackendDAE, outDAE, "dumpindxdae");
8332 //bcall(Flags.isSet(Flags.DUMP_BACKENDDAE_INFO) or Flags.isSet(Flags.DUMP_STATESELECTION_INFO) or Flags.isSet(Flags.DUMP_DISCRETEVARS_INFO), BackendDump.dumpCompShort, outDAE);
8333 //fcall2(Flags.DUMP_EQNINORDER, BackendDump.dumpEqnsSolved, outDAE, "system for jacobians");
8334 end getSolvedSystemforJacobians;
8335
8336 public function sortGlobalKnownVarsInDAE "
8337 author: ptaeuber
8338 This function sorts the globalKnownVars"
8339 input output BackendDAE.BackendDAE backendDAE;
8340 protected
8341 BackendDAE.Variables globalKnownVars, globalKnownVars_sorted;
8342 BackendDAE.EquationArray parameterEqns;
8343 BackendDAE.EqSystem paramSystem;
8344 BackendDAE.AdjacencyMatrix m;
8345 BackendDAE.Var var;
8346 array<Integer> ass1, ass2;
8347 list<list<Integer>> comps;
8348 list<Integer> flatComps;
8349 algorithm
8350 1085 globalKnownVars := backendDAE.shared.globalKnownVars;
8351 1085 parameterEqns := BackendEquation.emptyEqnsSized(BackendVariable.varsSize(globalKnownVars));
8352 1085 parameterEqns := BackendVariable.traverseBackendDAEVars(globalKnownVars, createGlobalKnownVarsEquations, parameterEqns);
8353
8354 1085 paramSystem := BackendDAEUtil.createEqSystem(globalKnownVars, parameterEqns);
8355 1085 (m, _) := BackendDAEUtil.adjacencyMatrix(paramSystem, BackendDAE.NORMAL(), NONE(), isInitializationDAE(backendDAE.shared));
8356 1085 (ass1, ass2) := Matching.PerfectMatching(m);
8357 1085 comps := Sorting.Tarjan(m, ass1);
8358
4/4
✓ Branch 0 taken 185937 times.
✓ Branch 1 taken 1085 times.
✓ Branch 2 taken 185937 times.
✓ Branch 3 taken 1085 times.
187022 flatComps := list(Initialization.flattenParamComp(comp, globalKnownVars) for comp in comps);
8359
8360 1085 globalKnownVars_sorted := BackendVariable.emptyVarsSized(BackendVariable.varsSize(globalKnownVars));
8361
2/2
✓ Branch 0 taken 185937 times.
✓ Branch 1 taken 1085 times.
187022 for i in flatComps loop
8362 185937 var := BackendVariable.getVarAt(globalKnownVars, i);
8363 185937 globalKnownVars_sorted := BackendVariable.addVar(var, globalKnownVars_sorted);
8364 end for;
8365
8366 1085 backendDAE := setDAEGlobalKnownVars(backendDAE, globalKnownVars_sorted);
8367 1085 ExecStat.execStat("sorting global known variables");
8368 end sortGlobalKnownVarsInDAE;
8369
8370 protected function createGlobalKnownVarsEquations
8371 input output BackendDAE.Var var;
8372 input output BackendDAE.EquationArray parameterEqns;
8373 protected
8374 DAE.Exp lhs, rhs;
8375 BackendDAE.Equation eqn;
8376 algorithm
8377 185937 lhs := BackendVariable.varExp(var);
8378 185937 rhs := BackendVariable.varBindExpStartValueNoFail(var);
8379 185937 eqn := BackendDAE.EQUATION(lhs, rhs, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_BINDING);
8380 185937 parameterEqns := BackendEquation.add(eqn, parameterEqns);
8381 end createGlobalKnownVarsEquations;
8382
8383 public function getEqnIndexArray
8384 "author: kabdelhak FHB 10-2019
8385 Returns the scalar equation indices for an equation array. REMOVABLE?"
8386 input BackendDAE.EquationArray eqs;
8387 output array<list<Integer>> eqIdxArray;
8388 protected
8389 Integer idx = 1, idx2 = 0, size;
8390 list<Integer> eqIdxLst;
8391 algorithm
8392 ✗ eqIdxArray := arrayCreate(BackendEquation.getNumberOfEquations(eqs), {});
8393 ✗ for eq in BackendEquation.equationList(eqs) loop
8394 ✗ size := BackendEquation.equationSize(BackendEquation.get(eqs, idx));
8395 ✗ eqIdxLst := List.map1(List.intRange(size),intAdd,idx2);
8396 ✗ arrayUpdate(eqIdxArray, idx, eqIdxLst);
8397 ✗ idx := idx+1;
8398 ✗ idx2 := size+idx2;
8399 end for;
8400 end getEqnIndexArray;
8401
8402 public function analyticalToStructuralSingularity
8403 "author: kabdelhak FHB 10-2019
8404 Performs the conversion of analytical to structural singularities by
8405 using gaussian elimination on the linear integer part of the strong
8406 component jacobian and replacing the zero row equations.
8407 Example:
8408 (f1) der(x) = sin(time);
8409 (f2) der(y) = cos(time) + b;
8410 (f3) a + 2b + x = 3;
8411 (f4) 2a + 4b + 2y = 6;
8412 Jac:
8413 | 1 2 |
8414 | 2 4 | -> linear dependent
8415 (f4) gets replaced by (f4) - 2*(f3) -> 2y - 2x = 0;
8416 "
8417 input list<Integer> comp;
8418 input output array<Integer> ass1;
8419 input output array<Integer> ass2;
8420 input output BackendDAE.EqSystem syst;
8421 input output Boolean changed;
8422 input Boolean init = false;
8423 protected
8424 array<list<Integer>> mapArrayToScalar;
8425 array<Integer> mapScalarToArray;
8426 list<tuple<BackendDAE.Equation, tuple<Integer, Integer>>> loopEqs = {}; /* scalar index needs to be list -- replace lookup with eqnIndexArray*/
8427 list<tuple<BackendDAE.Var, Integer>> loopVars = {};
8428 BackendDAE.Equation tmp_eq;
8429 SymbolicJacobian.LinearJacobian linJac;
8430 algorithm
8431
2/2
✓ Branch 1 taken 1574 times.
✓ Branch 2 taken 36187 times.
37761 if listLength(comp) > 1 then
8432 /* collect eqs and vars from strong component */
8433
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1574 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1574 times.
1574 SOME((mapArrayToScalar, mapScalarToArray, _, _, _)) := syst.mapping;
8434
2/2
✓ Branch 0 taken 15669 times.
✓ Branch 1 taken 1574 times.
17243 for eqnIndex in comp loop
8435 /* ignore multidimensional equations for now */
8436
2/2
✓ Branch 3 taken 8631 times.
✓ Branch 4 taken 7038 times.
15669 if listLength(mapArrayToScalar[mapScalarToArray[eqnIndex]]) == 1 then
8437 8631 tmp_eq := BackendEquation.get(syst.orderedEqs, mapScalarToArray[eqnIndex]);
8438 8631 loopEqs := (tmp_eq, (mapScalarToArray[eqnIndex], eqnIndex)) :: loopEqs;
8439 else
8440 /*
8441 tmp_eq := BackendEquation.get(syst.orderedEqs, mapScalarToArray[eqnIndex]);
8442 BackendDump.dumpEquationList({tmp_eq}, "ignored array eqs index: " + intString(eqnIndex));
8443 */
8444 end if;
8445 15669 loopVars := (BackendVariable.getVarAt(syst.orderedVars, ass1[eqnIndex]), ass1[eqnIndex]) :: loopVars;
8446 end for;
8447
8448
4/4
✓ Branch 0 taken 662 times.
✓ Branch 1 taken 912 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 908 times.
1574 if not listEmpty(loopEqs) and (listLength(loopEqs) <= Flags.getConfigInt(Flags.MAX_SIZE_ASSC)) then
8449 try
8450 /* generate linear integer sub jacobian from system */
8451 908 linJac := SymbolicJacobian.LinearJacobian.generate(loopEqs, loopVars, ass1);
8452
8453
2/2
✓ Branch 1 taken 333 times.
✓ Branch 2 taken 565 times.
898 if not SymbolicJacobian.LinearJacobian.emptyOrSingle(linJac) then
8454
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 332 times.
333 if Flags.isSet(Flags.DUMP_ASSC) then
8455
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
2 print(SymbolicJacobian.LinearJacobian.toString(linJac, "Original (initial: " + boolString(init) + ")"));
8456 end if;
8457
8458 /* solve jacobian with gaussian elimination */
8459 333 linJac := SymbolicJacobian.LinearJacobian.solve(linJac);
8460
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 332 times.
333 if Flags.isSet(Flags.DUMP_ASSC) then
8461
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
2 print(SymbolicJacobian.LinearJacobian.toString(linJac, "Solved (initial: " + boolString(init) + ")"));
8462 end if;
8463
8464 /* set changed to true if it was true before, or any row changed in the jacobian */
8465
4/4
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 158 times.
✓ Branch 3 taken 108 times.
✓ Branch 4 taken 67 times.
333 changed := changed or SymbolicJacobian.LinearJacobian.anyChanges(linJac);
8466
8467 /* resolve zero rows to new equations and update assignments / adjacency matrix */
8468 333 (ass1, ass2, syst) := SymbolicJacobian.LinearJacobian.resolveASSC(linJac, ass1, ass2, syst, init);
8469 end if;
8470 else
8471 /* possibly fails if jacobian is empty --- nothing to do */
8472 end try;
8473 end if;
8474 end if;
8475 end analyticalToStructuralSingularity;
8476
8477
8478 /*************************************************
8479 * index reduction method Selection
8480 ************************************************/
8481
8482 public function getIndexReductionMethodString
8483 " function: getIndexReductionMethodString"
8484 output String strIndexReductionMethod;
8485 algorithm
8486 10401 strIndexReductionMethod := Config.getIndexReductionMethod();
8487 end getIndexReductionMethodString;
8488
8489 public function getIndexReductionMethod
8490 " function: getIndexReductionMethod"
8491 input Option<String> ostrIndexReductionMethod;
8492 output tuple<BackendDAEFunc.StructurallySingularSystemHandlerFunc,String,BackendDAEFunc.stateDeselectionFunc,String> IndexReductionMethod;
8493 protected
8494 list<tuple<BackendDAEFunc.StructurallySingularSystemHandlerFunc,String,BackendDAEFunc.stateDeselectionFunc,String>> allIndexReductionMethods;
8495 String strIndexReductionMethod;
8496 algorithm
8497 10401 allIndexReductionMethods := {(IndexReduction.failIfIndexReduction, "none", IndexReduction.noStateDeselection, "none"),
8498 (IndexReduction.pantelidesIndexReduction, "Pantelides", IndexReduction.noStateDeselection, "uode"),
8499 (IndexReduction.pantelidesIndexReduction, "Pantelides", IndexReduction.dynamicStateSelection, "dynamicStateSelection"),
8500 (IndexReduction.pantelidesIndexReduction, "Pantelides", IndexReduction.dynamicStateSelection, "dummyDerivatives")};
8501 10401 strIndexReductionMethod := getIndexReductionMethodString();
8502 10401 strIndexReductionMethod := Util.getOptionOrDefault(ostrIndexReductionMethod,strIndexReductionMethod);
8503 10401 IndexReductionMethod := selectIndexReductionMethod(strIndexReductionMethod,allIndexReductionMethods);
8504 end getIndexReductionMethod;
8505
8506 protected function selectIndexReductionMethod
8507 " function: selectIndexReductionMethod"
8508 input String strIndexReductionMethod;
8509 input list<tuple<Type_a,String,Type_b,String>> inIndexReductionMethods;
8510 output tuple<Type_a,String,Type_b,String> outIndexReductionMethod;
8511 replaceable type Type_a subtypeof Any;
8512 replaceable type Type_b subtypeof Any;
8513 algorithm
8514 outIndexReductionMethod:=
8515 matchcontinue inIndexReductionMethods
8516 local
8517 String name,str;
8518 tuple<Type_a,String,Type_b,String> method;
8519 list<tuple<Type_a,String,Type_b,String>> methods;
8520 case (method as (_,_,_,name))::_
8521 guard
8522 stringEqual(strIndexReductionMethod,name)
8523 then
8524 method;
8525 case _::methods
8526 algorithm
8527 18802 method := selectIndexReductionMethod(strIndexReductionMethod,methods);
8528 then
8529 method;
8530 else
8531 algorithm
8532 ✗ str := stringAppendList({"Selection of Index Reduction Method ",strIndexReductionMethod," failed."});
8533 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
8534 ✗ then
8535 fail();
8536 end matchcontinue;
8537 end selectIndexReductionMethod;
8538
8539 /*************************************************
8540 * matching Algorithm Selection
8541 ************************************************/
8542
8543 public function getMatchingAlgorithmString
8544 " function: getMatchingAlgorithmString"
8545 output String strMatchingAlgorithm;
8546 algorithm
8547 10401 strMatchingAlgorithm := Config.getMatchingAlgorithm();
8548 end getMatchingAlgorithmString;
8549
8550 public function getMatchingAlgorithm
8551 " function: getIndexReductionMethod"
8552 input Option<String> ostrMatchingAlgorithm;
8553 output tuple<BackendDAEFunc.matchingAlgorithmFunc,String> matchingAlgorithm;
8554 protected
8555 list<tuple<BackendDAEFunc.matchingAlgorithmFunc,String>> allMatchingAlgorithms;
8556 String strMatchingAlgorithm;
8557 algorithm
8558 10401 allMatchingAlgorithms := {(Matching.BFSB,"BFSB"),
8559 (Matching.DFSB,"DFSB"),
8560 (Matching.MC21A,"MC21A"),
8561 (Matching.PF,"PF"),
8562 (Matching.PFPlus,"PFPlus"),
8563 (Matching.HK,"HK"),
8564 (Matching.HKDW,"HKDW"),
8565 (Matching.ABMP,"ABMP"),
8566 (Matching.PR_FIFO_FAIR,"PR"),
8567 (Matching.DFSBExternal,"DFSBExt"),
8568 (Matching.BFSBExternal,"BFSBExt"),
8569 (Matching.MC21AExternal,"MC21AExt"),
8570 (Matching.PFExternal,"PFExt"),
8571 (Matching.PFPlusExternal,"PFPlusExt"),
8572 (Matching.HKExternal,"HKExt"),
8573 (Matching.HKDWExternal,"HKDWExt"),
8574 (Matching.ABMPExternal,"ABMPExt"),
8575 (Matching.PR_FIFO_FAIRExternal,"PRExt"),
8576 (Matching.BBMatching,"BB")};
8577 10401 strMatchingAlgorithm := getMatchingAlgorithmString();
8578 10401 strMatchingAlgorithm := Util.getOptionOrDefault(ostrMatchingAlgorithm,strMatchingAlgorithm);
8579 10401 matchingAlgorithm := selectMatchingAlgorithm(strMatchingAlgorithm,allMatchingAlgorithms);
8580 end getMatchingAlgorithm;
8581
8582 protected function selectMatchingAlgorithm
8583 " function: selectMatchingAlgorithm"
8584 input String strMatchingAlgorithm;
8585 input list<tuple<Type_a,String>> inMatchingAlgorithms;
8586 output tuple<Type_a,String> outMatchingAlgorithm;
8587 replaceable type Type_a subtypeof Any;
8588 algorithm
8589 outMatchingAlgorithm:=
8590 matchcontinue inMatchingAlgorithms
8591 local
8592 String name,str;
8593 tuple<Type_a,String> method;
8594 list<tuple<Type_a,String>> methods;
8595 case (method as (_,name))::_
8596 guard
8597 stringEqual(strMatchingAlgorithm,name)
8598 then
8599 method;
8600 case _::methods
8601 algorithm
8602 134799 method := selectMatchingAlgorithm(strMatchingAlgorithm,methods);
8603 then
8604 method;
8605 else
8606 algorithm
8607 ✗ str := stringAppendList({"Selection of Matching Algorithm ",strMatchingAlgorithm," failed."});
8608 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
8609 ✗ then
8610 fail();
8611 end matchcontinue;
8612 end selectMatchingAlgorithm;
8613
8614
8615 // =============================================================================
8616 // Optimization module selection
8617 //
8618 // =============================================================================
8619
8620 public function allPreOptimizationModules
8621 "This list contains all back end pre-optimization modules."
8622 output list<tuple<BackendDAEFunc.optimizationModule, String>> allPreOptimizationModules = {
8623 (BackendDAEUtil.introduceOutputRealDerivatives, "introduceOutputRealDerivatives"),
8624 (BackendDAEUtil.introduceOutputAliases, "introduceOutputAliases"),
8625 (DataReconciliation.newExtractionAlgorithm, "dataReconciliation"),
8626 (DataReconciliation.extractBoundaryCondition, "dataReconciliationBoundaryConditions"),
8627 (DataReconciliation.stateEstimation, "dataReconciliationStateEstimation"),
8628 (DynamicOptimization.createDynamicOptimization,"createDynamicOptimization"),
8629 (BackendInline.normalInlineFunction, "normalInlineFunction"),
8630 (EvaluateParameter.evaluateParameters, "evaluateParameters"),
8631 (RemoveSimpleEquations.removeVerySimpleEquations, "removeVerySimpleEquations"),
8632 (BackendDAEOptimize.simplifyIfEquations, "simplifyIfEquations"),
8633 (BackendDAEOptimize.expandDerOperator, "expandDerOperator"),
8634 (BackendDAEOptimize.removeLocalKnownVars, "removeLocalKnownVars"),
8635 (CommonSubExpression.wrapFunctionCalls, "wrapFunctionCalls"),
8636 (SynchronousFeatures.clockPartitioning, "clockPartitioning"),
8637 (IndexReduction.findStateOrder, "findStateOrder"),
8638 (BackendDAEOptimize.introduceDerAlias, "introduceDerAlias"),
8639 (DynamicOptimization.inputDerivativesForDynOpt, "inputDerivativesForDynOpt"), // only for dyn. opt.
8640 (BackendDAEOptimize.replaceEdgeChange, "replaceEdgeChange"),
8641 (InlineArrayEquations.inlineArrayEqn, "inlineArrayEqn"),
8642 (BackendDAEOptimize.sortEqnsVars, "sortEqnsVars"),
8643 (BackendDAEOptimize.removeEqualRHS, "removeEqualRHS"),
8644 (RemoveSimpleEquations.removeSimpleEquations, "removeSimpleEquations"),
8645 (CommonSubExpression.commonSubExpressionReplacement, "comSubExp"),
8646 (ResolveLoops.resolveLoops, "resolveLoops"),
8647 (EvaluateFunctions.evalFunctions, "evalFunc"),
8648 (FindZeroCrossings.encapsulateWhenConditions, "encapsulateWhenConditions"),
8649 // TODO: move the following modules to the correct position
8650 (BackendDAEOptimize.removeProtectedParameters, "removeProtectedParameters"),
8651 (BackendDAEOptimize.removeUnusedParameter, "removeUnusedParameter"),
8652 (BackendDAEOptimize.removeUnusedVariables, "removeUnusedVariables"),
8653 (BackendDAEOptimize.residualForm, "residualForm"),
8654 (BackendDAEOptimize.simplifyAllExpressions, "simplifyAllExpressions"),
8655 (BackendDAEOptimize.simplifyInStream, "simplifyInStream"),
8656 (BackendDump.dumpDAE, "dumpDAE"),
8657 (XMLDump.dumpDAEXML, "dumpDAEXML"),
8658 // This should indeed be at the end
8659 (BackendDAETransform.collapseArrayExpressions, "collapseArrayExpressions")
8660 };
8661 end allPreOptimizationModules;
8662
8663 public function allPostOptimizationModules
8664 "This list contains all back end sim-optimization modules."
8665 output list<tuple<BackendDAEFunc.optimizationModule, String>> allPostOptimizationModules = {
8666 (BackendInline.lateInlineFunction, "lateInlineFunction"),
8667 (DynamicOptimization.simplifyConstraints, "simplifyConstraints"),
8668 (CommonSubExpression.wrapFunctionCalls, "wrapFunctionCalls"),
8669 (CommonSubExpression.cseBinary, "cseBinary"),
8670 (BackendDAEOptimize.replaceDerCalls, "replaceDerCalls"),
8671 (OnRelaxation.relaxSystem, "relaxSystem"),
8672 (InlineArrayEquations.inlineArrayEqn, "inlineArrayEqn"),
8673 (SymbolicJacobian.constantLinearSystem, "constantLinearSystem"),
8674 (BackendDAEOptimize.simplifysemiLinear, "simplifysemiLinear"),
8675 (ResolveLoops.solveLinearSystem, "solveLinearSystem"),
8676 (BackendDAEOptimize.addedScaledVars_states, "addScaledVars_states"),
8677 (BackendDAEOptimize.addedScaledVars_inputs, "addScaledVars_inputs"),
8678 (RemoveSimpleEquations.removeSimpleEquations, "removeSimpleEquations"),
8679 (BackendDAEOptimize.inlineFunctionInLoops, "forceInlineFunctionInLoops"), // before simplifyComplexFunction
8680 (BackendDAEOptimize.simplifyComplexFunction, "simplifyComplexFunction"),
8681 (ExpressionSolve.solveSimpleEquations, "solveSimpleEquations"),
8682 (ResolveLoops.reshuffling_post, "reshufflePost"),
8683 (DynamicOptimization.reduceDynamicOptimization, "reduceDynamicOptimization"), // before tearing
8684 (Tearing.tearingSystem, "tearingSystem"),
8685 (BackendDAEOptimize.simplifyLoops, "simplifyLoops"),
8686 (Tearing.recursiveTearing, "recursiveTearing"),
8687 (HpcOmEqSystems.partitionLinearTornSystem, "partlintornsystem"),
8688 (BackendDAEOptimize.countOperations, "countOperations"),
8689 (SymbolicJacobian.inputDerivativesUsed, "inputDerivativesUsed"),
8690 (DynamicOptimization.removeLoops, "extendDynamicOptimization"),
8691 (BackendDAEOptimize.addTimeAsState, "addTimeAsState"),
8692 (SymbolicJacobian.calculateStrongComponentJacobians, "calculateStrongComponentJacobians"),
8693 (SymbolicJacobian.calculateStateSetsJacobians, "calculateStateSetsJacobians"),
8694 (SymbolicJacobian.symbolicJacobian, "symbolicJacobian"),
8695 (SymbolicJacobian.generateSymbolicSensitivities, "generateSymbolicSensitivities"),
8696 (SymbolicJacobian.generateSymbolicLinearizationPast, "generateSymbolicLinearization"),
8697 (BackendDAEOptimize.removeConstants, "removeConstants"),
8698 (BackendDAEOptimize.simplifyTimeIndepFuncCalls, "simplifyTimeIndepFuncCalls"),
8699 (BackendDAEOptimize.simplifyAllExpressions, "simplifyAllExpressions"),
8700 (BackendDAEOptimize.hets, "hets"),
8701 (FindZeroCrossings.findZeroCrossings, "findZeroCrossings"),
8702 // TODO: move the following modules to the correct position
8703 (BackendDump.dumpComponentsGraphStr, "dumpComponentsGraphStr"),
8704 (BackendDump.dumpDAE, "dumpDAE"),
8705 (XMLDump.dumpDAEXML, "dumpDAEXML"),
8706 // This should indeed be at the end
8707 (BackendDAETransform.collapseArrayExpressions, "collapseArrayExpressions"),
8708 // DAEmode modules
8709 (DAEMode.createDAEmodeBDAE, "createDAEmodeBDAE"),
8710 (SymbolicJacobian.symbolicJacobianDAE, "symbolicJacobianDAE"),
8711 (BackendDAEUtil.setEvaluationStage, "setEvaluationStage")
8712 };
8713 end allPostOptimizationModules;
8714
8715 protected function allInitOptimizationModules
8716 "This list contains all back end init-optimization modules."
8717 output list<tuple<BackendDAEFunc.optimizationModule, String>> allInitOptimizationModules = {
8718 (Initialization.replaceHomotopyWithSimplified, "replaceHomotopyWithSimplified"),
8719 (InlineArrayEquations.inlineArrayEqn, "inlineArrayEqn"),
8720 (SymbolicJacobian.constantLinearSystem, "constantLinearSystem"),
8721 (BackendDAEOptimize.inlineHomotopy, "inlineHomotopy"),
8722 (BackendDAEOptimize.inlineFunctionInLoops, "forceInlineFunctionInLoops"), // before simplifyComplexFunction
8723 (BackendDAEOptimize.simplifyComplexFunction, "simplifyComplexFunction"),
8724 (CommonSubExpression.wrapFunctionCalls, "wrapFunctionCalls"),
8725 (DynamicOptimization.reduceDynamicOptimization, "reduceDynamicOptimization"), // before tearing
8726 (Tearing.tearingSystem, "tearingSystem"),
8727 (BackendDAEOptimize.simplifyLoops, "simplifyLoops"),
8728 (Tearing.recursiveTearing, "recursiveTearing"),
8729 (ExpressionSolve.solveSimpleEquations, "solveSimpleEquations"),
8730 (BackendDAEOptimize.generateHomotopyComponents, "generateHomotopyComponents"), // after tearing, after solveSimpleEquations, before calculateStrongComponentJacobians
8731 (SymbolicJacobian.calculateStrongComponentJacobians, "calculateStrongComponentJacobians"),
8732 (BackendDAEOptimize.simplifyAllExpressions, "simplifyAllExpressions"),
8733 (SymbolicJacobian.inputDerivativesUsed, "inputDerivativesUsed"),
8734 (DynamicOptimization.removeLoops, "extendDynamicOptimization"),
8735 // This should indeed be at the end
8736 (BackendDAETransform.collapseArrayExpressions, "collapseArrayExpressions")
8737 };
8738 end allInitOptimizationModules;
8739
8740 public function getPreOptModulesString
8741 output list<String> strPreOptModules;
8742 algorithm
8743 1176 strPreOptModules := Config.getPreOptModules();
8744 end getPreOptModulesString;
8745
8746 public function isDataReconciliationEnabled
8747 "Returns true if one of the data reconciliation pre-optimization modules is
8748 enabled or the uncertainty extraction (modelEquationsUC) is running. The
8749 uncertain attribute is only meaningful for these and must not influence a
8750 plain simulation."
8751 output Boolean enabled;
8752 protected
8753 constant list<String> drModules = {"dataReconciliation", "dataReconciliationBoundaryConditions", "dataReconciliationStateEstimation"};
8754 algorithm
8755
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 78 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 76 times.
78 if isSome(getGlobalRoot(Global.uncertaintyExtraction)) then
8756 enabled := true;
8757 76 return;
8758 end if;
8759
2/2
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 2 times.
30 for m in listAppend(Flags.getConfigStringList(Flags.PRE_OPT_MODULES_ADD), getPreOptModulesString()) loop
8760
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 if listMember(m, drModules) then
8761 enabled := true;
8762 ✗ return;
8763 end if;
8764 end for;
8765 enabled := false;
8766 end isDataReconciliationEnabled;
8767
8768 protected function deprecatedDebugFlag
8769 input Flags.DebugFlag inFlag;
8770 input list<String> inModuleList;
8771 input String inModule;
8772 input String inPhase;
8773 output list<String> outModuleList = inModuleList;
8774 algorithm
8775
1/2
✓ Branch 1 taken 1077 times.
✗ Branch 2 not taken.
1077 if Flags.isSet(inFlag) then
8776 outModuleList := inModule::inModuleList;
8777 ✗ Error.addCompilerWarning("Deprecated debug flag -d=" + FlagsUtil.debugFlagName(inFlag) + " detected. Use --" + inPhase + "=" + inModule + " instead.");
8778 end if;
8779 end deprecatedDebugFlag;
8780
8781 protected function deprecatedConfigFlag
8782 input Flags.ConfigFlag inFlag;
8783 input list<String> inModuleList;
8784 input String inModule;
8785 input String inPhase;
8786 output list<String> outModuleList = inModuleList;
8787 algorithm
8788 ✗ if Flags.getConfigBool(inFlag) then
8789 outModuleList := inModule::inModuleList;
8790 ✗ Error.addCompilerWarning("Deprecated flag --" + FlagsUtil.configFlagName(inFlag) + " detected. Use --" + inPhase + "=" + inModule + " instead.");
8791 end if;
8792 end deprecatedConfigFlag;
8793
8794 public function getPreOptModules
8795 input Option<list<String>> inPreOptModules;
8796 output list<tuple<BackendDAEFunc.optimizationModule, String>> outPreOptModules;
8797 protected
8798 list<String> preOptModules;
8799 list<String> enabledModules = Flags.getConfigStringList(Flags.PRE_OPT_MODULES_ADD);
8800 list<String> disabledModules = Flags.getConfigStringList(Flags.PRE_OPT_MODULES_SUB);
8801 algorithm
8802 1091 preOptModules := getPreOptModulesString();
8803 1091 preOptModules := Util.getOptionOrDefault(inPreOptModules, preOptModules);
8804
8805
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1091 times.
✓ Branch 5 taken 16 times.
✓ Branch 6 taken 1075 times.
1091 if isSome(getGlobalRoot(Global.isInStream)) then
8806 enabledModules := "simplifyInStream"::enabledModules;
8807 end if;
8808
8809
2/2
✓ Branch 1 taken 1077 times.
✓ Branch 2 taken 14 times.
1091 if Flags.getConfigBool(Flags.DEFAULT_OPT_MODULES_ORDERING) then
8810 // handle special flags, which enable modules
8811 1077 enabledModules := deprecatedDebugFlag(Flags.SORT_EQNS_AND_VARS, enabledModules, "sortEqnsVars", "preOptModules+");
8812
8813
3/4
✓ Branch 1 taken 1043 times.
✓ Branch 2 taken 34 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1043 times.
1077 if Config.acceptOptimicaGrammar() or Flags.getConfigBool(Flags.GENERATE_DYN_OPTIMIZATION_PROBLEM) then
8814 enabledModules := "inputDerivativesForDynOpt"::enabledModules;
8815 enabledModules := "createDynamicOptimization"::enabledModules;
8816 end if;
8817
8818 // handle special flags, which disable modules
8819
2/8
✗ Branch 1 not taken.
✓ Branch 2 taken 1077 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1077 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1077 if Flags.getConfigString(Flags.REMOVE_SIMPLE_EQUATIONS) == "causal" or
8820 Flags.getConfigString(Flags.REMOVE_SIMPLE_EQUATIONS) == "none" then
8821 disabledModules := "removeSimpleEquations"::disabledModules;
8822 end if;
8823
8824
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1074 times.
1077 if not Flags.isSet(Flags.NF_SCALARIZE) then
8825 disabledModules := "inlineArrayEqn"::disabledModules;
8826 end if;
8827 end if;
8828
8829
3/4
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1077 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
1091 if not Flags.getConfigBool(Flags.DEFAULT_OPT_MODULES_ORDERING) and not listEmpty(enabledModules) then
8830 ✗ Error.addCompilerError("It's not possible to combine following flags: --preOptModules+=... and --" + FlagsUtil.configFlagName(Flags.DEFAULT_OPT_MODULES_ORDERING) + "=false");
8831 ✗ fail();
8832 end if;
8833
8834
3/4
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1077 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
1091 if not Flags.getConfigBool(Flags.DEFAULT_OPT_MODULES_ORDERING) and not listEmpty(disabledModules) then
8835 ✗ Error.addCompilerError("It's not possible to combine following flags: --postOptModules-=... and --" + FlagsUtil.configFlagName(Flags.DEFAULT_OPT_MODULES_ORDERING) + "=false");
8836 ✗ fail();
8837 end if;
8838
8839 1091 outPreOptModules := selectOptModules(preOptModules, enabledModules, disabledModules, allPreOptimizationModules());
8840 end getPreOptModules;
8841
8842 public function getPostOptModulesString
8843 output list<String> strpostOptModules;
8844 algorithm
8845 1089 strpostOptModules := Config.getPostOptModules();
8846 end getPostOptModulesString;
8847
8848 public function getPostOptModules
8849 input Option<list<String>> inPostOptModules;
8850 output list<tuple<BackendDAEFunc.optimizationModule, String>> outPostOptModules;
8851 protected
8852 list<String> postOptModules;
8853 list<String> enabledModules = Flags.getConfigStringList(Flags.POST_OPT_MODULES_ADD);
8854 list<String> disabledModules = Flags.getConfigStringList(Flags.POST_OPT_MODULES_SUB);
8855 algorithm
8856 1089 postOptModules := getPostOptModulesString();
8857 1089 postOptModules := Util.getOptionOrDefault(inPostOptModules, postOptModules);
8858
8859
2/2
✓ Branch 1 taken 1075 times.
✓ Branch 2 taken 14 times.
1089 if Flags.getConfigBool(Flags.DEFAULT_OPT_MODULES_ORDERING) then
8860 // handle special flags, which enable modules
8861
2/2
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 1041 times.
1075 if Flags.getConfigBool(Flags.GENERATE_DYN_OPTIMIZATION_PROBLEM) then
8862 enabledModules := "simplifyConstraints"::enabledModules;
8863 end if;
8864
8865
3/4
✓ Branch 1 taken 1068 times.
✓ Branch 2 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1068 times.
1075 if not Flags.getConfigString(Flags.LOOP2CON) == "none" then
8866 enabledModules := "extendDynamicOptimization"::enabledModules;
8867 end if;
8868
8869
4/6
✓ Branch 1 taken 1024 times.
✓ Branch 2 taken 51 times.
✓ Branch 4 taken 1024 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1024 times.
1075 if Flags.getConfigBool(Flags.GENERATE_SYMBOLIC_LINEARIZATION) or Config.acceptOptimicaGrammar() or Flags.getConfigBool(Flags.GENERATE_DYN_OPTIMIZATION_PROBLEM) then
8870 enabledModules := "generateSymbolicLinearization"::enabledModules;
8871 end if;
8872
8873
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1071 times.
1075 if Flags.getConfigInt(Flags.SIMPLIFY_LOOPS) > 0 then
8874 enabledModules := "simplifyLoops"::enabledModules;
8875 end if;
8876
8877
2/4
✓ Branch 1 taken 1075 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1075 times.
1075 if Flags.getConfigString(Flags.HETS) <> "none" then
8878 enabledModules := "hets"::enabledModules;
8879 end if;
8880
8881
8882
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1075 times.
1075 if Flags.isSet(Flags.COUNT_OPERATIONS) then
8883 enabledModules := "countOperations"::enabledModules;
8884 end if;
8885
8886
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1073 times.
1075 if 1 < Flags.getConfigInt(Flags.MAX_SIZE_FOR_SOLVE_LINIEAR_SYSTEM) then
8887 enabledModules := "solveLinearSystem"::enabledModules;
8888 end if;
8889
8890
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1074 times.
1075 if Flags.isSet(Flags.RESHUFFLE_POST) then
8891 enabledModules := "reshufflePost"::enabledModules;
8892 end if;
8893
8894
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 1067 times.
1075 if Flags.getConfigInt(Flags.RTEARING) > 0 then
8895 enabledModules := "recursiveTearing"::enabledModules;
8896 end if;
8897
8898
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1074 times.
1075 if Flags.getConfigInt(Flags.PARTLINTORN) > 0 then
8899 enabledModules := "partlintornsystem"::enabledModules;
8900 end if;
8901
8902
3/12
✗ Branch 1 not taken.
✓ Branch 2 taken 1075 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1075 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 1075 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
1075 if Flags.getConfigString(Flags.REMOVE_SIMPLE_EQUATIONS) == "none" or
8903 Flags.getConfigString(Flags.REMOVE_SIMPLE_EQUATIONS) == "fastAcausal" or
8904 Flags.getConfigString(Flags.REMOVE_SIMPLE_EQUATIONS) == "allAcausal" then
8905 disabledModules := "removeSimpleEquations"::disabledModules;
8906 end if;
8907
8908
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1072 times.
1075 if not Flags.isSet(Flags.NF_SCALARIZE) then
8909 disabledModules := "inlineArrayEqn"::disabledModules;
8910 end if;
8911 end if;
8912
8913
3/4
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1075 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
1089 if not Flags.getConfigBool(Flags.DEFAULT_OPT_MODULES_ORDERING) and not listEmpty(enabledModules) then
8914 ✗ Error.addCompilerError("It's not possible to combine following flags: --postOptModules+=... and --" + FlagsUtil.configFlagName(Flags.DEFAULT_OPT_MODULES_ORDERING) + "=false");
8915 ✗ fail();
8916 end if;
8917
8918
3/4
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1075 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
1089 if not Flags.getConfigBool(Flags.DEFAULT_OPT_MODULES_ORDERING) and not listEmpty(disabledModules) then
8919 ✗ Error.addCompilerError("It's not possible to combine following flags: --postOptModules-=... and --" + FlagsUtil.configFlagName(Flags.DEFAULT_OPT_MODULES_ORDERING) + "=false");
8920 ✗ fail();
8921 end if;
8922
8923 1089 outPostOptModules := selectOptModules(postOptModules, enabledModules, disabledModules, allPostOptimizationModules());
8924 end getPostOptModules;
8925
8926 public function getInitOptModules
8927 input Option<list<String>> inInitOptModules;
8928 input list<String> inEnabledModules = {};
8929 input list<String> inDisabledModules = {};
8930 output list<tuple<BackendDAEFunc.optimizationModule, String>> outInitOptModules;
8931 protected
8932 list<String> initOptModules;
8933 list<String> enabledModules = Flags.getConfigStringList(Flags.INIT_OPT_MODULES_ADD);
8934 list<String> disabledModules = Flags.getConfigStringList(Flags.INIT_OPT_MODULES_SUB);
8935 algorithm
8936 1120 initOptModules := Config.getInitOptModules();
8937 1120 initOptModules := Util.getOptionOrDefault(inInitOptModules, initOptModules);
8938
8939
2/2
✓ Branch 1 taken 1106 times.
✓ Branch 2 taken 14 times.
1120 if Flags.getConfigBool(Flags.DEFAULT_OPT_MODULES_ORDERING) then
8940 // handle special flags, which enable modules
8941
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1102 times.
1106 if Flags.getConfigInt(Flags.SIMPLIFY_LOOPS) > 0 then
8942 enabledModules := "simplifyLoops"::enabledModules;
8943 end if;
8944
8945
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 1097 times.
1106 if Flags.getConfigInt(Flags.RTEARING) > 0 then
8946 enabledModules := "recursiveTearing"::enabledModules;
8947 end if;
8948
8949 // handle special flags, which disable modules
8950 end if;
8951
8952
3/4
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1106 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
1120 if not Flags.getConfigBool(Flags.DEFAULT_OPT_MODULES_ORDERING) and not listEmpty(enabledModules) then
8953 ✗ Error.addCompilerError("It's not possible to combine following flags: --initOptModules+=... and --" + FlagsUtil.configFlagName(Flags.DEFAULT_OPT_MODULES_ORDERING) + "=false");
8954 ✗ fail();
8955 end if;
8956
8957
3/4
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1106 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
1120 if not Flags.getConfigBool(Flags.DEFAULT_OPT_MODULES_ORDERING) and not listEmpty(disabledModules) then
8958 ✗ Error.addCompilerError("It's not possible to combine following flags: --initOptModules-=... and --" + FlagsUtil.configFlagName(Flags.DEFAULT_OPT_MODULES_ORDERING) + "=false");
8959 ✗ fail();
8960 end if;
8961
8962 1120 outInitOptModules := selectOptModules(initOptModules, enabledModules, disabledModules, allInitOptimizationModules());
8963 1120 initOptModules := List.map(outInitOptModules, Util.tuple22);
8964 1120 outInitOptModules := selectOptModules(initOptModules, inEnabledModules, inDisabledModules, allInitOptimizationModules());
8965 end getInitOptModules;
8966
8967 protected function selectOptModules
8968 input list<String> inStrOptModules;
8969 input list<String> inEnabledModules = {};
8970 input list<String> inDisabledModules = {};
8971 input list<tuple<BackendDAEFunc.optimizationModule, String>> inOptModules;
8972 output list<tuple<BackendDAEFunc.optimizationModule, String>> outOptModules = {};
8973 protected
8974 Boolean forceOrdering = Flags.getConfigBool(Flags.DEFAULT_OPT_MODULES_ORDERING);
8975 String name;
8976 Integer numModules = listLength(inOptModules);
8977 array<Boolean> activeModules = arrayCreate(numModules, false);
8978 Integer index;
8979 Integer maxIndex = -1;
8980 algorithm
8981
2/2
✓ Branch 0 taken 7866 times.
✓ Branch 1 taken 62 times.
7928 if forceOrdering then
8982
2/2
✓ Branch 0 taken 66962 times.
✓ Branch 1 taken 7866 times.
74828 for name in inStrOptModules loop
8983
2/2
✓ Branch 1 taken 66962 times.
✓ Branch 2 taken 66962 times.
133924 for index in getModuleIndexes(name, inOptModules) loop
8984
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66962 times.
66962 if index < maxIndex then
8985 ✗ Error.addCompilerWarning("Specified ordering will be ignored. Use --" + FlagsUtil.configFlagName(Flags.DEFAULT_OPT_MODULES_ORDERING) + "=false to override module ordering.");
8986 maxIndex := numModules;
8987 else
8988 maxIndex := intMax(maxIndex, index);
8989 end if;
8990
8991 66962 activeModules[index] := true;
8992 end for;
8993 end for;
8994
8995
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 7866 times.
8138 for name in inEnabledModules loop
8996
2/2
✓ Branch 2 taken 272 times.
✓ Branch 3 taken 272 times.
544 for index in getModuleIndexes(name, inOptModules) loop
8997 272 activeModules[index] := true;
8998 end for;
8999 end for;
9000
9001
2/2
✓ Branch 0 taken 2164 times.
✓ Branch 1 taken 7866 times.
10030 for name in inDisabledModules loop
9002
2/2
✓ Branch 2 taken 2164 times.
✓ Branch 3 taken 2164 times.
4328 for index in getModuleIndexes(name, inOptModules) loop
9003 2164 activeModules[index] := false;
9004 end for;
9005 end for;
9006
9007
1/2
✓ Branch 0 taken 7866 times.
✗ Branch 1 not taken.
268180 for i in 1:numModules loop
9008
2/2
✓ Branch 1 taken 67189 times.
✓ Branch 2 taken 193125 times.
260314 if activeModules[i] then
9009 67189 outOptModules := listGet(inOptModules, i)::outOptModules;
9010 end if;
9011 end for;
9012 else
9013
2/2
✓ Branch 0 taken 257 times.
✓ Branch 1 taken 62 times.
319 for name in inStrOptModules loop
9014 257 outOptModules := selectOptModules1(name, inOptModules)::outOptModules;
9015 end for;
9016 end if;
9017 7928 outOptModules := listReverse(outOptModules);
9018 end selectOptModules;
9019
9020 protected function getModuleIndexes
9021 input String inModuleName;
9022 input list<tuple<BackendDAEFunc.optimizationModule, String>> inModuleList;
9023 output list<Integer> outIndexes = {};
9024 protected
9025 String name;
9026 Integer index=1;
9027 algorithm
9028
2/2
✓ Branch 0 taken 2433662 times.
✓ Branch 1 taken 69398 times.
2503060 for module in inModuleList loop
9029 2433662 (_, name) := module;
9030
4/4
✓ Branch 0 taken 181735 times.
✓ Branch 1 taken 2251927 times.
✓ Branch 3 taken 69398 times.
✓ Branch 4 taken 112337 times.
2433662 if stringEqual(inModuleName, name) then
9031 outIndexes := index::outIndexes;
9032 end if;
9033 2433662 index := index+1;
9034 end for;
9035
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69398 times.
69398 if listEmpty(outIndexes) then
9036 ✗ Error.addCompilerError("'" + inModuleName + "' is not a valid optimization module. Please check the flags carefully.");
9037 ✗ fail();
9038 end if;
9039 end getModuleIndexes;
9040
9041 protected function selectOptModules1
9042 input String strOptModule;
9043 input list<tuple<BackendDAEFunc.optimizationModule, String>> inOptModules;
9044 output tuple<BackendDAEFunc.optimizationModule, String> outOptModule;
9045 algorithm
9046 outOptModule := match inOptModules
9047 local
9048 String name;
9049 tuple<BackendDAEFunc.optimizationModule, String> module;
9050 list<tuple<BackendDAEFunc.optimizationModule, String>> rest;
9051
9052 case (module as (_, name))::_ guard(stringEqual(name, strOptModule))
9053 then module;
9054
9055 case (_, name)::rest guard(not stringEqual(name, strOptModule))
9056 3616 then selectOptModules1(strOptModule, rest);
9057
9058 else algorithm
9059 ✗ Error.addInternalError("Selection of optimization module " + strOptModule + " failed.", sourceInfo());
9060 ✗ then fail();
9061 end match;
9062 end selectOptModules1;
9063
9064 public function isInitOptModuleActivated " returns true if given initOptModule is activated
9065 author: ptaeuber"
9066 input String initOptModule;
9067 input list<tuple<BackendDAEFunc.optimizationModule, String>> activatedInitOptModules = {};
9068 output Boolean isActivated = false;
9069 protected
9070 list<tuple<BackendDAEFunc.optimizationModule, String>> modules = activatedInitOptModules;
9071 String s;
9072 algorithm
9073 ✗ if listEmpty(modules) then
9074 ✗ modules := getInitOptModules(NONE());
9075 end if;
9076 ✗ for module in modules loop
9077 ✗ (_, s) := module;
9078 ✗ if stringEqual(s, initOptModule) then
9079 isActivated := true;
9080 ✗ return;
9081 end if;
9082 end for;
9083 end isInitOptModuleActivated;
9084
9085 /*************************************************
9086 * traverse BackendDAE equation systems
9087 ************************************************/
9088
9089 public function mapEqSystem1<A>
9090 "Helper to map a preopt module over each equation system"
9091 input BackendDAE.BackendDAE dae;
9092 input Function func;
9093 input A a;
9094 output BackendDAE.BackendDAE odae;
9095
9096 partial function Function
9097 input BackendDAE.EqSystem syst;
9098 input A a;
9099 input BackendDAE.Shared shared;
9100 output BackendDAE.EqSystem osyst;
9101 output BackendDAE.Shared oshared;
9102 end Function;
9103 protected
9104 list<BackendDAE.EqSystem> systs;
9105 BackendDAE.Shared shared;
9106 algorithm
9107 2233 BackendDAE.DAE(systs, shared) := dae;
9108 2233 (systs, shared) := List.map1Fold(systs, func, a, shared);
9109 // Filter out empty systems
9110 2233 (systs, shared) := filterEmptySystems(systs, shared);
9111 2233 odae := BackendDAE.DAE(systs, shared);
9112 end mapEqSystem1;
9113
9114 public function mapEqSystemAndFold<B>
9115 "Helper to map a preopt module over each equation system"
9116 input BackendDAE.BackendDAE inDAE;
9117 input Function inFunc;
9118 input B initialExtra;
9119 output BackendDAE.BackendDAE outDAE;
9120 output B outExtra;
9121
9122 partial function Function
9123 input BackendDAE.EqSystem inSyst;
9124 input BackendDAE.Shared inShared;
9125 input B inExtra;
9126 output BackendDAE.EqSystem outSyst;
9127 output BackendDAE.Shared outShared;
9128 output B outExtra;
9129 end Function;
9130 protected
9131 list<BackendDAE.EqSystem> systs;
9132 BackendDAE.Shared shared;
9133 algorithm
9134 21777 BackendDAE.DAE(systs, shared) := inDAE;
9135 21777 (systs, shared, outExtra) := List.mapFold2(systs, inFunc, shared, initialExtra);
9136 // Filter out empty systems
9137 21777 (systs, shared) := filterEmptySystems(systs, shared);
9138 21777 outDAE := BackendDAE.DAE(systs, shared);
9139 end mapEqSystemAndFold;
9140
9141 public function foldEqSystem
9142 "Helper to map a preopt module over each equation system"
9143 input BackendDAE.BackendDAE dae;
9144 input Function func;
9145 input B initialExtra;
9146 output B extra;
9147 partial function Function
9148 input BackendDAE.EqSystem syst;
9149 input BackendDAE.Shared shared;
9150 input B fold;
9151 output B ofold;
9152 end Function;
9153 replaceable type B subtypeof Any;
9154 protected
9155 list<BackendDAE.EqSystem> systs;
9156 BackendDAE.Shared shared;
9157 algorithm
9158 10483 BackendDAE.DAE(systs, shared) := dae;
9159 10483 extra := List.fold1(systs,func,shared,initialExtra);
9160 // Filter out empty systems
9161 10483 (_, shared) := filterEmptySystems(systs, shared);
9162 end foldEqSystem;
9163
9164 public function mapEqSystem
9165 "Helper to map a preopt module over each equation system"
9166 input BackendDAE.BackendDAE inDAE;
9167 input Function inFunc;
9168 output BackendDAE.BackendDAE outDAE;
9169 partial function Function
9170 input BackendDAE.EqSystem syst;
9171 input BackendDAE.Shared shared;
9172 output BackendDAE.EqSystem osyst;
9173 output BackendDAE.Shared oshared;
9174 end Function;
9175 protected
9176 list<BackendDAE.EqSystem> systs;
9177 BackendDAE.Shared shared;
9178 algorithm
9179 20344 BackendDAE.DAE(systs, shared) := inDAE;
9180 20344 (systs, shared) := List.mapFold(systs, inFunc, shared);
9181 // Filter out empty systems
9182 20343 (systs, shared) := filterEmptySystems(systs, shared);
9183 20343 outDAE := BackendDAE.DAE(systs, shared);
9184 end mapEqSystem;
9185
9186 public function nonEmptySystem
9187 input BackendDAE.EqSystem syst;
9188 output Boolean nonEmpty;
9189 algorithm
9190
4/4
✓ Branch 1 taken 852 times.
✓ Branch 2 taken 47540 times.
✓ Branch 4 taken 829 times.
✓ Branch 5 taken 23 times.
48392 nonEmpty := BackendVariable.varsSize(syst.orderedVars) <> 0 or BackendEquation.getNumberOfEquations(syst.removedEqs) <> 0;
9191 end nonEmptySystem;
9192
9193 protected function filterEmptySystems
9194 "Filter out equation systems leaving at least one behind"
9195 input BackendDAE.EqSystems inSysts;
9196 input BackendDAE.Shared inShared;
9197 output BackendDAE.EqSystems outSysts = {};
9198 output BackendDAE.Shared outShared = inShared;
9199 protected
9200 list<BackendDAE.Equation> reqns = {};
9201 algorithm
9202
2/2
✓ Branch 0 taken 898767 times.
✓ Branch 1 taken 115450 times.
1014217 for e in inSysts loop
9203 898767 (reqns, outSysts) := filterEmptySystem(e, reqns, outSysts);
9204 end for;
9205
9206
2/2
✓ Branch 0 taken 4724 times.
✓ Branch 1 taken 110726 times.
115450 if listEmpty(outSysts) then
9207 9448 outSysts := {BackendDAEUtil.createEqSystem(BackendVariable.emptyVars(), BackendEquation.emptyEqns())};
9208 else
9209 110726 outSysts := Dangerous.listReverseInPlace(outSysts);
9210 end if;
9211
9212
1/2
✓ Branch 1 taken 115450 times.
✗ Branch 2 not taken.
115450 outShared.removedEqs := BackendEquation.addList(reqns, outShared.removedEqs);
9213 end filterEmptySystems;
9214
9215 protected function filterEmptySystem
9216 input BackendDAE.EqSystem inSyst;
9217 input output list<BackendDAE.Equation> reqs;
9218 input output BackendDAE.EqSystems systs;
9219 algorithm
9220
3/6
✓ Branch 1 taken 23961 times.
✓ Branch 2 taken 874806 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 23961 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
898767 if BackendVariable.varsSize(inSyst.orderedVars) <> 0 or
9221 (isClockedSyst(inSyst) and BackendEquation.getNumberOfEquations(inSyst.removedEqs) <> 0) then
9222 874806 systs := inSyst::systs;
9223 else
9224 23961 reqs := listAppend(BackendEquation.equationList(inSyst.removedEqs), reqs);
9225 end if;
9226 end filterEmptySystem;
9227
9228 public function getAllVarLst "retrieve all variables of the dae by collecting them from each equation system and combining with known vars"
9229 input BackendDAE.BackendDAE dae;
9230 output list<BackendDAE.Var> varLst;
9231 protected
9232 BackendDAE.EqSystems eqs;
9233 BackendDAE.Variables globalKnownVars;
9234 algorithm
9235 ✗ BackendDAE.DAE(eqs=eqs,shared = BackendDAE.SHARED(globalKnownVars=globalKnownVars)) := dae;
9236 ✗ varLst := List.flatten(List.map(globalKnownVars::List.map(eqs, BackendVariable.daeVars), BackendVariable.varList));
9237 end getAllVarLst;
9238
9239 public function isClockedSyst
9240 input BackendDAE.EqSystem inSyst;
9241 output Boolean out;
9242 algorithm
9243 out := match inSyst
9244 case BackendDAE.EQSYSTEM(partitionKind=BackendDAE.CLOCKED_PARTITION()) then true;
9245 else false;
9246 end match;
9247 end isClockedSyst;
9248
9249 public function getAlgorithms
9250 input BackendDAE.BackendDAE dae;
9251 output array<DAE.Algorithm> algs;
9252 protected
9253 BackendDAE.EqSystems systs;
9254 list<DAE.Algorithm> alglst;
9255 algorithm
9256 ✗ BackendDAE.DAE(eqs=systs) := dae;
9257 ✗ alglst := List.fold(systs,collectAlgorithmsFromEqSystem,{});
9258 ✗ algs := listArray(alglst);
9259 end getAlgorithms;
9260
9261 protected function collectAlgorithmsFromEqSystem
9262 input BackendDAE.EqSystem syst;
9263 input list<DAE.Algorithm> alglst;
9264 output list<DAE.Algorithm> oalglst;
9265 protected
9266 BackendDAE.EquationArray eqns;
9267 algorithm
9268 ✗ BackendDAE.EQSYSTEM(orderedEqs=eqns) := syst;
9269 ✗ oalglst := BackendEquation.traverseEquationArray(eqns,collectAlgorithms,alglst);
9270 end collectAlgorithmsFromEqSystem;
9271
9272 protected function collectAlgorithms
9273 input BackendDAE.Equation inEq;
9274 input list<DAE.Algorithm> inAlgs;
9275 output BackendDAE.Equation outEq;
9276 output list<DAE.Algorithm> algs;
9277 algorithm
9278 (outEq,algs) := match (inEq,inAlgs)
9279 local
9280 DAE.Algorithm alg;
9281 case (BackendDAE.ALGORITHM(alg=alg),algs)
9282 then (inEq,alg::algs);
9283 else (inEq,inAlgs);
9284 end match;
9285 end collectAlgorithms;
9286
9287 // =============================================================================
9288 // section for getConditionList
9289 //
9290 // =============================================================================
9291
9292 public function getConditionList "author: lochel
9293 This function extracts all when-conditions. A when-condition can only be a
9294 ComponentRef or initial()-call. If one condition is equal to >initial()<, the
9295 second output becomes true."
9296 input DAE.Exp inCondition;
9297 output list<DAE.ComponentRef> outConditionVarList;
9298 output Boolean outInitialCall;
9299 algorithm
9300 (outConditionVarList, outInitialCall) := match inCondition
9301 local
9302 list<DAE.Exp> conditionList;
9303 list<DAE.ComponentRef> conditionVarList;
9304 Boolean initialCall;
9305
9306 case DAE.ARRAY(array=conditionList)
9307 algorithm
9308 197 (conditionVarList, initialCall) := getConditionList1(conditionList, {}, false);
9309 then (conditionVarList, initialCall);
9310
9311 else
9312 algorithm
9313 515 (conditionVarList, initialCall) := getConditionList1({inCondition}, {}, false);
9314 then (conditionVarList, initialCall);
9315 end match;
9316 end getConditionList;
9317
9318 protected function getConditionList1 "author: lochel"
9319 input list<DAE.Exp> inConditionList;
9320 input list<DAE.ComponentRef> inConditionVarList;
9321 input Boolean inInitialCall;
9322 output list<DAE.ComponentRef> outConditionVarList;
9323 output Boolean outInitialCall;
9324 algorithm
9325 (outConditionVarList, outInitialCall) := match inConditionList
9326 local
9327 list<DAE.Exp> conditionList;
9328 list<DAE.ComponentRef> conditionVarList;
9329 Boolean initialCall;
9330 DAE.ComponentRef componentRef;
9331 DAE.Exp exp;
9332
9333 case {}
9334 then (inConditionVarList, inInitialCall);
9335
9336 // filter constant conditions
9337 case exp::conditionList guard(Expression.isConst(exp)) algorithm
9338 83 (conditionVarList, initialCall) := getConditionList1(conditionList, inConditionVarList, inInitialCall);
9339 then (conditionVarList, initialCall);
9340
9341 case DAE.CALL(path=Absyn.IDENT(name="initial"))::conditionList algorithm
9342 29 (conditionVarList, initialCall) := getConditionList1(conditionList, inConditionVarList, true);
9343 then (conditionVarList, initialCall);
9344
9345 case DAE.CREF(componentRef=componentRef)::conditionList algorithm
9346 826 (conditionVarList, initialCall) := getConditionList1(conditionList, componentRef::inConditionVarList, inInitialCall);
9347 then (conditionVarList, initialCall);
9348
9349 case exp::_ algorithm
9350 ✗ Error.addInternalError("function getConditionList1 failed for " + ExpressionBasics.printExpStr(exp), sourceInfo());
9351 ✗ then fail();
9352 end match;
9353 end getConditionList1;
9354
9355 public function isArrayComp"outputs true if the strongComponent is an arrayEquation"
9356 input BackendDAE.StrongComponent comp;
9357 output Boolean isArray;
9358 algorithm
9359 isArray := match comp
9360 case BackendDAE.SINGLEARRAY()
9361 then true;
9362 else false;
9363 end match;
9364 end isArrayComp;
9365
9366 public function isWhenComp"outputs true if the strongComponent is a whenEquation"
9367 input BackendDAE.StrongComponent comp;
9368 output Boolean isWhen;
9369 algorithm
9370 isWhen := match comp
9371 case BackendDAE.SINGLEWHENEQUATION()
9372 then true;
9373 else false;
9374 end match;
9375 end isWhenComp;
9376
9377 public function isSingleEquationComp "outputs true if the strongComponent is a singleEquation"
9378 input BackendDAE.StrongComponent comp;
9379 output Boolean isWhen;
9380 algorithm
9381 isWhen := match comp
9382 case BackendDAE.SINGLEEQUATION()
9383 then true;
9384 else false;
9385 end match;
9386 end isSingleEquationComp;
9387
9388 public function isLinearEqSystemComp "outputs true if the strongComponent is a linear equationsystem"
9389 input BackendDAE.StrongComponent comp;
9390 output Boolean isWhen;
9391 algorithm
9392 isWhen := match comp
9393 case BackendDAE.EQUATIONSYSTEM(jacType = BackendDAE.JAC_LINEAR())
9394 then true;
9395 else false;
9396 end match;
9397 end isLinearEqSystemComp;
9398
9399 public function isNonLinearEqSystemComp "outputs true if the strongComponent is a nonlinear equationsystem"
9400 input BackendDAE.StrongComponent comp;
9401 output Boolean isWhen;
9402 algorithm
9403 isWhen := match comp
9404 case BackendDAE.EQUATIONSYSTEM(jacType = BackendDAE.JAC_NONLINEAR())
9405 then true;
9406 else false;
9407 end match;
9408 end isNonLinearEqSystemComp;
9409
9410 public function isLinearTornSystemComp "outputs true if the strongComponent is a linear torn system"
9411 input BackendDAE.StrongComponent comp;
9412 output Boolean isWhen;
9413 algorithm
9414 isWhen := match comp
9415 case BackendDAE.TORNSYSTEM(linear=true)
9416 then true;
9417 else false;
9418 end match;
9419 end isLinearTornSystemComp;
9420
9421 public function isNonLinearTornSystemComp "outputs true if the strongComponent is a nonlinear torn system"
9422 input BackendDAE.StrongComponent comp;
9423 output Boolean isWhen;
9424 algorithm
9425 isWhen := match comp
9426 case BackendDAE.TORNSYSTEM(linear=false)
9427 then true;
9428 else false;
9429 end match;
9430 end isNonLinearTornSystemComp;
9431
9432 public function extendRange
9433 input DAE.Exp inRangeExp;
9434 input BackendDAE.Variables inKnVariables;
9435 output list<DAE.Exp> outExpLst = {};
9436 protected
9437 DAE.Exp start, step, stop;
9438 Option<DAE.Exp> ostep;
9439 DAE.Type ty;
9440 algorithm
9441 try
9442
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 106 times.
107 DAE.RANGE(ty = ty, start = start, step = ostep, stop = stop) := inRangeExp;
9443
9444 106 start := evalExp(start, inKnVariables);
9445 106 stop := evalExp(stop, inKnVariables);
9446
9447
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 101 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 101 times.
101 if isSome(ostep) then
9448 ✗ SOME(step) := ostep;
9449 ✗ ostep := SOME(evalExp(step, inKnVariables));
9450 end if;
9451
9452 101 outExpLst := Expression.expandRange(DAE.RANGE(ty, start, ostep, stop));
9453 else
9454
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if Flags.isSet(Flags.FAILTRACE) then
9455 ✗ Debug.trace("BackendDAECreate.extendRange failed. Maybe some ZeroCrossing are not supported\n");
9456 end if;
9457 end try;
9458 end extendRange;
9459
9460 public function evalExp
9461 input DAE.Exp inExp;
9462 input BackendDAE.Variables inKnVariables;
9463 output DAE.Exp outExp;
9464 algorithm
9465 outExp := match inExp
9466 local
9467 DAE.Exp e, e1, e2;
9468
9469 case DAE.CREF()
9470 algorithm
9471
0/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
5 ((BackendDAE.VAR(bindExp = SOME(e)) :: _), _) :=
9472 BackendVariable.getVar(inExp.componentRef, inKnVariables);
9473 then
9474 e;
9475
9476 case DAE.BINARY(operator = DAE.ADD(DAE.T_INTEGER()))
9477 algorithm
9478 ✗ e1 := evalExp(inExp.exp1, inKnVariables);
9479 ✗ e2 := evalExp(inExp.exp2, inKnVariables);
9480 ✗ then
9481 DAE.ICONST(Expression.expInt(e1) + Expression.expInt(e2));
9482
9483 case DAE.BINARY(operator = DAE.SUB(DAE.T_INTEGER()))
9484 algorithm
9485 ✗ e1 := evalExp(inExp.exp1, inKnVariables);
9486 ✗ e2 := evalExp(inExp.exp2, inKnVariables);
9487 ✗ then
9488 DAE.ICONST(Expression.expInt(e1) - Expression.expInt(e2));
9489
9490 else inExp;
9491 end match;
9492 end evalExp;
9493
9494 public function expInt "returns the int value of an expression"
9495 input DAE.Exp inExp;
9496 input BackendDAE.Variables inKnVariables;
9497 output Integer i;
9498 algorithm
9499 i := match inExp
9500 local
9501 Integer i1, i2;
9502 DAE.ComponentRef cr;
9503 DAE.Exp e, e1, e2;
9504
9505 case DAE.ICONST(integer=i2)
9506 then i2;
9507
9508 case DAE.ENUM_LITERAL(index=i2)
9509 then i2;
9510
9511 case DAE.CREF(componentRef=cr) algorithm
9512 ✗ ((BackendDAE.VAR(bindExp=SOME(e)):: _), _) := BackendVariable.getVar(cr, inKnVariables);
9513 ✗ i2 := expInt(e, inKnVariables);
9514 then i2;
9515
9516 case DAE.BINARY(exp1=e1, operator=DAE.ADD(DAE.T_INTEGER()), exp2=e2) algorithm
9517 ✗ i1 := expInt(e1, inKnVariables);
9518 i2 := expInt(e2, inKnVariables);
9519 i := i1 + i2;
9520 then i;
9521
9522 case DAE.BINARY(exp1=e1, operator=DAE.SUB(DAE.T_INTEGER()), exp2=e2) algorithm
9523 ✗ i1 := expInt(e1, inKnVariables);
9524 i2 := expInt(e2, inKnVariables);
9525 i := i1 - i2;
9526 then i;
9527 end match;
9528 end expInt;
9529
9530 public function createEqSystem
9531 input BackendDAE.Variables inVars;
9532 input BackendDAE.EquationArray inEqs = BackendEquation.emptyEqns();
9533 input BackendDAE.StateSets inStateSets = {};
9534 input BackendDAE.BaseClockPartitionKind inPartitionKind = BackendDAE.UNKNOWN_PARTITION();
9535 input BackendDAE.EquationArray removedEqs = BackendEquation.emptyEqns();
9536 output BackendDAE.EqSystem outSyst;
9537 algorithm
9538 155690 outSyst := BackendDAE.EQSYSTEM( inVars, inEqs, NONE(), NONE(), NONE(), BackendDAE.NO_MATCHING(),
9539 inStateSets, inPartitionKind, removedEqs );
9540 end createEqSystem;
9541
9542 public function createEmptyShared
9543 input BackendDAE.BackendDAEType backendDAEType;
9544 input BackendDAE.ExtraInfo ei;
9545 input FCore.Cache cache;
9546 input FCore.Graph graph;
9547 output BackendDAE.Shared shared;
9548 algorithm
9549 5322 shared := BackendDAE.SHARED(BackendVariable.emptyVars(),
9550 BackendVariable.emptyVars(),
9551 BackendVariable.emptyVars(),
9552 BackendVariable.emptyVars(),
9553 BackendEquation.emptyEqns(),
9554 BackendEquation.emptyEqns(),
9555 {},
9556 {},
9557 cache,
9558 graph,
9559 AvlTreePathFunction.new(),
9560 emptyEventInfo(),
9561 {},
9562 backendDAEType,
9563 {},
9564 ei,
9565 emptyPartitionsInfo(),
9566 BackendDAE.emptyDAEModeData,
9567 NONE(),
9568 NONE(),
9569 {}
9570 );
9571 end createEmptyShared;
9572
9573 public function emptyPartitionsInfo
9574 output BackendDAE.PartitionsInfo partitionsInfo;
9575 protected
9576 array<BackendDAE.BasePartition> basePartitions;
9577 array<BackendDAE.SubPartition> subPartitions;
9578 algorithm
9579 6417 basePartitions := arrayCreate(0, BackendDAE.BASE_PARTITION(DAE.INFERRED_CLOCK(), 0));
9580 6417 subPartitions := arrayCreate(0, BackendDAE.SUB_PARTITION(BackendDAE.DEFAULT_SUBCLOCK, false, {}));
9581 6417 partitionsInfo := BackendDAE.PARTITIONS_INFO(basePartitions, subPartitions);
9582 end emptyPartitionsInfo;
9583
9584 public function makeSingleEquationComp
9585 input Integer eqIdx;
9586 input Integer varIdx;
9587 output BackendDAE.StrongComponent comp;
9588 algorithm
9589 12 comp := BackendDAE.SINGLEEQUATION(eqIdx,varIdx);
9590 end makeSingleEquationComp;
9591
9592 public function getAliasVars "author: lochel"
9593 input BackendDAE.BackendDAE inDAE;
9594 output BackendDAE.Variables outAliasVars;
9595 algorithm
9596 6240 BackendDAE.DAE(shared=BackendDAE.SHARED(aliasVars=outAliasVars)) := inDAE;
9597 end getAliasVars;
9598
9599 public function getGlobalKnownVarsFromDAE "author: lochel"
9600 input BackendDAE.BackendDAE inDAE;
9601 output BackendDAE.Variables globalKnownVars;
9602 algorithm
9603 2228 BackendDAE.DAE(shared=BackendDAE.SHARED(globalKnownVars=globalKnownVars)) := inDAE;
9604 end getGlobalKnownVarsFromDAE;
9605
9606
9607 public function setVars
9608 input BackendDAE.BackendDAE inDAE;
9609 input BackendDAE.Variables inVars;
9610 output BackendDAE.BackendDAE outDAE;
9611 protected
9612 BackendDAE.EqSystems systs;
9613 BackendDAE.EqSystem syst;
9614 BackendDAE.Shared shared;
9615 algorithm
9616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 BackendDAE.DAE(syst::systs, shared) := inDAE;
9617 28 syst := setEqSystVars(syst, inVars);
9618 28 outDAE := BackendDAE.DAE(syst::systs, shared);
9619 end setVars;
9620
9621 public function setEqs
9622 input BackendDAE.BackendDAE inDAE;
9623 input BackendDAE.EquationArray inEqs;
9624 output BackendDAE.BackendDAE outDAE;
9625 protected
9626 BackendDAE.EqSystems systs;
9627 BackendDAE.EqSystem syst;
9628 BackendDAE.Shared shared;
9629 algorithm
9630 ✗ BackendDAE.DAE(syst::systs, shared) := inDAE;
9631 ✗ syst := setEqSystEqs(syst, inEqs);
9632 ✗ outDAE := BackendDAE.DAE(syst::systs, shared);
9633 end setEqs;
9634
9635 public function setAliasVars "author: lochel"
9636 input BackendDAE.BackendDAE inDAE;
9637 input BackendDAE.Variables inAliasVars;
9638 output BackendDAE.BackendDAE outDAE;
9639 protected
9640 BackendDAE.EqSystems systs;
9641 BackendDAE.Shared shared;
9642 algorithm
9643 1387 BackendDAE.DAE(systs, shared) := inDAE;
9644 1387 shared := setSharedAliasVars(shared, inAliasVars);
9645 1387 outDAE := BackendDAE.DAE(systs, shared);
9646 end setAliasVars;
9647
9648 public function setDAEGlobalKnownVars "author: lochel"
9649 input BackendDAE.BackendDAE inDAE;
9650 input BackendDAE.Variables inGlobalKnownVars;
9651 output BackendDAE.BackendDAE outDAE;
9652 protected
9653 BackendDAE.EqSystems systs;
9654 BackendDAE.Shared shared;
9655 algorithm
9656 6650 BackendDAE.DAE(systs, shared) := inDAE;
9657 6650 shared := setSharedGlobalKnownVars(shared, inGlobalKnownVars);
9658 6650 outDAE := BackendDAE.DAE(systs, shared);
9659 end setDAEGlobalKnownVars;
9660
9661 public function setFunctionTree "author: lochel"
9662 input BackendDAE.BackendDAE inDAE;
9663 input AvlTreePathFunction.Tree inFunctionTree;
9664 output BackendDAE.BackendDAE outDAE;
9665 protected
9666 BackendDAE.EqSystems systs;
9667 BackendDAE.Shared shared;
9668 algorithm
9669 4522 BackendDAE.DAE(systs, shared) := inDAE;
9670 4522 shared := setSharedFunctionTree(shared, inFunctionTree);
9671 4522 outDAE := BackendDAE.DAE(systs, shared);
9672 end setFunctionTree;
9673
9674 public function setEqSystEqs
9675 "Set ordered equations of input equation system to given equations."
9676 input BackendDAE.EqSystem inSyst;
9677 input BackendDAE.EquationArray inEqs;
9678 output BackendDAE.EqSystem syst = inSyst;
9679 algorithm
9680 15882 syst.orderedEqs := inEqs;
9681 end setEqSystEqs;
9682
9683 public function setEqSystVars
9684 input BackendDAE.EqSystem inSyst;
9685 input BackendDAE.Variables inVars;
9686 output BackendDAE.EqSystem outSyst;
9687 algorithm
9688 outSyst := match inSyst
9689 local
9690 BackendDAE.EqSystem syst;
9691 case syst as BackendDAE.EQSYSTEM()
9692 17494 algorithm syst.orderedVars := inVars;
9693 then syst;
9694 end match;
9695 end setEqSystVars;
9696
9697 public function setEqSystMatrices
9698 input BackendDAE.EqSystem inSyst;
9699 input Option<BackendDAE.AdjacencyMatrix> m = NONE();
9700 input Option<BackendDAE.AdjacencyMatrix> mT = NONE();
9701 input Option<BackendDAE.AdjacencyMatrixMapping> mapping = NONE();
9702 output BackendDAE.EqSystem outSyst;
9703 algorithm
9704 outSyst := match inSyst
9705 local
9706 BackendDAE.EqSystem syst;
9707 case syst as BackendDAE.EQSYSTEM()
9708 algorithm
9709 395445 syst.m := m;
9710 395445 syst.mT := mT;
9711 395445 syst.mapping := mapping;
9712 then syst;
9713 end match;
9714 end setEqSystMatrices;
9715
9716 public function clearEqSyst
9717 input BackendDAE.EqSystem inSyst;
9718 output BackendDAE.EqSystem outSyst;
9719 protected
9720 BackendDAE.Variables vars;
9721 BackendDAE.EquationArray eqs, removedEqs;
9722 BackendDAE.StateSets stateSets;
9723 BackendDAE.BaseClockPartitionKind partitionKind;
9724 algorithm
9725 52747 BackendDAE.EQSYSTEM( orderedVars=vars, orderedEqs=eqs, stateSets=stateSets, partitionKind=partitionKind,
9726 removedEqs=removedEqs ) := inSyst;
9727 52747 outSyst := BackendDAE.EQSYSTEM( orderedVars=vars, orderedEqs=eqs, m=NONE(), mT=NONE(), mapping=NONE(), removedEqs=removedEqs,
9728 matching=BackendDAE.NO_MATCHING(), stateSets=stateSets, partitionKind=partitionKind );
9729 end clearEqSyst;
9730
9731 public function setEqSystMatching
9732 input BackendDAE.EqSystem inSyst;
9733 input BackendDAE.Matching matching;
9734 output BackendDAE.EqSystem outSyst;
9735 algorithm
9736 outSyst := match inSyst
9737 local
9738 BackendDAE.EqSystem syst;
9739 case syst as BackendDAE.EQSYSTEM()
9740 124358 algorithm syst.matching := matching;
9741 then syst;
9742 end match;
9743 end setEqSystMatching;
9744
9745 public function setEqSystStateSets
9746 input BackendDAE.EqSystem inSyst;
9747 input BackendDAE.StateSets stateSets;
9748 output BackendDAE.EqSystem outSyst;
9749 algorithm
9750 outSyst := match inSyst
9751 local
9752 BackendDAE.EqSystem syst;
9753 case syst as BackendDAE.EQSYSTEM()
9754 ✗ algorithm syst.stateSets := stateSets;
9755 then syst;
9756 end match;
9757 end setEqSystStateSets;
9758
9759 public function setEqSystRemovedEqns
9760 input BackendDAE.EqSystem inSyst;
9761 input BackendDAE.EquationArray removedEqs;
9762 output BackendDAE.EqSystem outSyst = inSyst;
9763 algorithm
9764 1104 outSyst.removedEqs := removedEqs;
9765 end setEqSystRemovedEqns;
9766
9767 public function setSharedRemovedEqns
9768 input BackendDAE.Shared inShared;
9769 input BackendDAE.EquationArray inRemovedEqs;
9770 output BackendDAE.Shared outShared;
9771 algorithm
9772 outShared := match inShared
9773 local
9774 BackendDAE.Shared shared;
9775 case shared as BackendDAE.SHARED() algorithm
9776 2171 shared.removedEqs := inRemovedEqs;
9777 then shared;
9778 end match;
9779 end setSharedRemovedEqns;
9780
9781 public function setSharedInitialEqns
9782 input BackendDAE.Shared inShared;
9783 input BackendDAE.EquationArray initialEqs;
9784 output BackendDAE.Shared outShared;
9785 algorithm
9786 outShared := match inShared
9787 local
9788 BackendDAE.Shared shared;
9789 case shared as BackendDAE.SHARED()
9790 ✗ algorithm shared.initialEqs := initialEqs;
9791 then shared;
9792 end match;
9793 end setSharedInitialEqns;
9794
9795 public function setSharedSymJacs
9796 input BackendDAE.Shared inShared;
9797 input BackendDAE.SymbolicJacobians symjacs;
9798 output BackendDAE.Shared outShared;
9799 algorithm
9800 outShared := match inShared
9801 local
9802 BackendDAE.Shared shared;
9803 case shared as BackendDAE.SHARED()
9804 1121 algorithm shared.symjacs := symjacs;
9805 then shared;
9806 end match;
9807 end setSharedSymJacs;
9808
9809 public function getSharedSymJacs
9810 input BackendDAE.Shared inShared;
9811 output BackendDAE.SymbolicJacobians outSymjacs;
9812 algorithm
9813 outSymjacs := match inShared
9814 local
9815 BackendDAE.Shared shared;
9816 ✗ case shared as BackendDAE.SHARED() then shared.symjacs;
9817 end match;
9818 end getSharedSymJacs;
9819
9820 public function setSharedFunctionTree
9821 input BackendDAE.Shared inShared;
9822 input AvlTreePathFunction.Tree inFunctionTree;
9823 output BackendDAE.Shared outShared;
9824 algorithm
9825 outShared := match inShared
9826 local
9827 BackendDAE.Shared shared;
9828 case shared as BackendDAE.SHARED()
9829 168737 algorithm shared.functionTree := inFunctionTree;
9830 then shared;
9831 end match;
9832 end setSharedFunctionTree;
9833
9834 public function setSharedEventInfo
9835 input BackendDAE.Shared inShared;
9836 input BackendDAE.EventInfo eventInfo;
9837 output BackendDAE.Shared outShared = inShared;
9838 algorithm
9839 3876 outShared.eventInfo := eventInfo;
9840 end setSharedEventInfo;
9841
9842 public function setSharedGlobalKnownVars
9843 input BackendDAE.Shared inShared;
9844 input BackendDAE.Variables globalKnownVars;
9845 output BackendDAE.Shared outShared = inShared;
9846 algorithm
9847 58080 outShared.globalKnownVars := globalKnownVars;
9848 end setSharedGlobalKnownVars;
9849
9850 public function setSharedAliasVars
9851 input BackendDAE.Shared inShared;
9852 input BackendDAE.Variables aliasVars;
9853 output BackendDAE.Shared outShared;
9854 algorithm
9855 outShared := match inShared
9856 local
9857 BackendDAE.Shared shared;
9858 case shared as BackendDAE.SHARED()
9859 118249 algorithm shared.aliasVars := aliasVars;
9860 then shared;
9861 end match;
9862 end setSharedAliasVars;
9863
9864 public function setSharedOptimica
9865 input BackendDAE.Shared inShared;
9866 input list<DAE.Constraint> constraints;
9867 input list<DAE.ClassAttributes> classAttrs;
9868 output BackendDAE.Shared outShared;
9869 algorithm
9870 outShared := match inShared
9871 local
9872 BackendDAE.Shared shared;
9873 case shared as BackendDAE.SHARED()
9874 algorithm
9875 1085 shared.constraints := constraints;
9876 1085 shared.classAttrs := classAttrs;
9877 then shared;
9878 end match;
9879 end setSharedOptimica;
9880
9881 public function collapseOrderedEqs
9882 input BackendDAE.BackendDAE inDAE;
9883 output BackendDAE.EquationArray outEqns;
9884 protected
9885 list<BackendDAE.Equation> eqsLst;
9886 algorithm
9887 ✗ eqsLst := List.fold(inDAE.eqs, collapseRemovedEqs1, {});
9888 ✗ outEqns := BackendEquation.listEquation(listAppend(eqsLst, BackendEquation.equationList(inDAE.shared.removedEqs)));
9889 end collapseOrderedEqs;
9890
9891 public function collapseRemovedEqs
9892 input BackendDAE.BackendDAE inDAE;
9893 output BackendDAE.EquationArray outEqns;
9894 protected
9895 list<BackendDAE.Equation> eqsLst;
9896 algorithm
9897 2257 eqsLst := List.fold(inDAE.eqs, collapseRemovedEqs1, {});
9898 2257 outEqns := BackendEquation.listEquation(listAppend(eqsLst, BackendEquation.equationList(inDAE.shared.removedEqs)));
9899 end collapseRemovedEqs;
9900
9901 protected function collapseRemovedEqs1
9902 input BackendDAE.EqSystem inSyst;
9903 input list<BackendDAE.Equation> inEqns;
9904 output list<BackendDAE.Equation> outEqns;
9905 algorithm
9906
2/2
✓ Branch 1 taken 55067 times.
✓ Branch 2 taken 61 times.
55128 outEqns := if BackendDAEUtil.isClockedSyst(inSyst) then inEqns
9907 else listAppend(BackendEquation.equationList(inSyst.removedEqs), inEqns);
9908 end collapseRemovedEqs1;
9909
9910 public function emptyEventInfo
9911 output BackendDAE.EventInfo info;
9912 algorithm
9913 5322 info := BackendDAE.EVENT_INFO({}, ZeroCrossings.new(), ZeroCrossings.new(), ZeroCrossings.new(), 0);
9914 end emptyEventInfo;
9915
9916 public function getSubClock
9917 input BackendDAE.EqSystem inSyst;
9918 input BackendDAE.Shared inShared;
9919 output Option<BackendDAE.SubClock> outSubClock;
9920 algorithm
9921 outSubClock := match inSyst.partitionKind
9922 local
9923 Integer idx;
9924 case BackendDAE.CLOCKED_PARTITION(idx)
9925 61 then SOME(inShared.partitionsInfo.subPartitions[idx].clock);
9926 else NONE();
9927 end match;
9928 end getSubClock;
9929
9930 public function componentsEqual"outputs true if 1 strongly connected components are equal"
9931 input BackendDAE.StrongComponent comp1;
9932 input BackendDAE.StrongComponent comp2;
9933 output Boolean isEqual;
9934 algorithm
9935 isEqual := match(comp1,comp2)
9936 local
9937 Integer i1,i2, j1,j2;
9938 list<Integer> l1,l2,k1,k2;
9939 BackendDAE.InnerEquations l3,k3;
9940 case(BackendDAE.SINGLEEQUATION(eqn=i1,var=i2),BackendDAE.SINGLEEQUATION(eqn=j1,var=j2))
9941 ✗ then intEq(i1,j1) and intEq(i2,j2);
9942
9943 case(BackendDAE.EQUATIONSYSTEM(eqns=l1,vars=l2),BackendDAE.EQUATIONSYSTEM(eqns=k1,vars=k2))
9944 ✗ then List.isEqualOnTrue(l1,k1,intEq) and List.isEqualOnTrue(l2,k2,intEq);
9945
9946 case(BackendDAE.SINGLEARRAY(eqn=i1,vars=l1),BackendDAE.SINGLEARRAY(eqn=j1,vars=k1))
9947 ✗ then intEq(i1,j1) and List.isEqualOnTrue(l1,k1,intEq);
9948
9949 case(BackendDAE.SINGLEALGORITHM(eqn=i1,vars=l1),BackendDAE.SINGLEALGORITHM(eqn=j1,vars=k1))
9950 ✗ then intEq(i1,j1) and List.isEqualOnTrue(l1,k1,intEq);
9951
9952 case(BackendDAE.SINGLECOMPLEXEQUATION(eqn=i1,vars=l1),BackendDAE.SINGLECOMPLEXEQUATION(eqn=j1,vars=k1))
9953 ✗ then intEq(i1,j1) and List.isEqualOnTrue(l1,k1,intEq);
9954
9955 case(BackendDAE.SINGLEWHENEQUATION(eqn=i1,vars=l1),BackendDAE.SINGLEWHENEQUATION(eqn=j1,vars=k1))
9956 ✗ then intEq(i1,j1) and List.isEqualOnTrue(l1,k1,intEq);
9957
9958 case(BackendDAE.SINGLEIFEQUATION(eqn=i1,vars=l1),BackendDAE.SINGLEIFEQUATION(eqn=j1,vars=k1))
9959 ✗ then intEq(i1,j1) and List.isEqualOnTrue(l1,k1,intEq);
9960
9961 case(BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(tearingvars=l1,residualequations=l2,innerEquations=l3)),BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(tearingvars=k1,residualequations=k2,innerEquations=k3)))
9962 ✗ then List.isEqualOnTrue(l1,k1,intEq) and List.isEqualOnTrue(l2,k2,intEq) and List.isEqualOnTrue(l3,k3,innerEquationsEqual);
9963 else false;
9964 end match;
9965 end componentsEqual;
9966
9967 protected function innerEquationsEqual"compares 2 innerEquations from innerEquations in TearingSets"
9968 input BackendDAE.InnerEquation innerEquation1;
9969 input BackendDAE.InnerEquation innerEquation2;
9970 output Boolean isEqual;
9971 algorithm
9972 isEqual := match(innerEquation1,innerEquation2)
9973 local
9974 Integer i1,i2;
9975 list<Integer> l1,l2;
9976 case(BackendDAE.INNEREQUATION(eqn=i1,vars=l1),BackendDAE.INNEREQUATION(eqn=i2,vars=l2))
9977 ✗ then intEq(i1,i2) and List.isEqualOnTrue(l1,l2,intEq);
9978 case(BackendDAE.INNEREQUATIONCONSTRAINTS(eqn=i1,vars=l1),BackendDAE.INNEREQUATIONCONSTRAINTS(eqn=i2,vars=l2))
9979 ✗ then intEq(i1,i2) and List.isEqualOnTrue(l1,l2,intEq);
9980 else
9981 false;
9982 end match;
9983 end innerEquationsEqual;
9984
9985
9986 public function causalizeVarBindSystem"causalizes a system of variables and their binding-equations.
9987 author: waurich TUD 08.2015"
9988 input list<BackendDAE.Var> varLstIn;
9989 input Boolean isInitial;
9990 output list<list<Integer>> comps;
9991 output array<Integer> ass1;
9992 output array<Integer> ass2;
9993 protected
9994 Integer nVars,nEqs;
9995 BackendDAE.AdjacencyMatrix m, mT;
9996 list<DAE.Exp> bindExps;
9997 list<BackendDAE.Equation> eqs;
9998 algorithm
9999 1069 bindExps := List.map(varLstIn,BackendVariable.varBindExp);
10000 1069 eqs := List.threadMap2(List.map(varLstIn,BackendVariable.varExp), bindExps, BackendEquation.generateEquation, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
10001 1069 (m, mT) := BackendDAEUtil.adjacencyMatrixDispatch(BackendVariable.listVar1(varLstIn), BackendEquation.listEquation(eqs), BackendDAE.ABSOLUTE(), NONE(), isInitial);
10002 1069 nVars := listLength(varLstIn);
10003 1069 nEqs := listLength(eqs);
10004 1069 ass1 := arrayCreate(nVars, -1);
10005 1069 ass2 := arrayCreate(nEqs, -1);
10006 1069 Matching.matchingExternalsetAdjacencyMatrix(nVars, nEqs, m);
10007 1069 BackendDAEEXT.matching(nVars, nEqs, 5, -1, 0.0, 1);
10008 1069 BackendDAEEXT.getAssignment(ass2, ass1);
10009 1069 comps := Sorting.TarjanTransposed(mT, ass2);
10010 end causalizeVarBindSystem;
10011
10012 public function traverseEqSystemStrongComponents
10013 "This function goes through the strong components of a EqSystem and pass
10014 the variables and equation with their indexes to the traversing function.
10015 It fail if the EqSytem does not have the matching and strong components are
10016 empty. It does not change the input EqSystem."
10017 replaceable type Type_a subtypeof Any;
10018 input BackendDAE.EqSystem syst;
10019 input FuncExpType func;
10020 input Type_a inTypeA;
10021 output Type_a outTypeA = inTypeA;
10022 partial function FuncExpType
10023 input list<BackendDAE.Equation> inEqns;
10024 input list<BackendDAE.Var> inVars;
10025 input list<Integer> varIdxs;
10026 input list<Integer> eqnIdxs;
10027 input Type_a inA;
10028 output Type_a outA;
10029 end FuncExpType;
10030 protected
10031 BackendDAE.StrongComponents comps;
10032 BackendDAE.Variables varArr;
10033 BackendDAE.EquationArray eqnArr;
10034 list<BackendDAE.Var> vars;
10035 list<BackendDAE.Equation> eqns;
10036 list<Integer> varIdxs, eqnIdxs;
10037 String name;
10038 algorithm
10039 try
10040
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 BackendDAE.EQSYSTEM(matching = BackendDAE.MATCHING(comps=comps),
10041 orderedVars = varArr,
10042 orderedEqs = eqnArr) := syst;
10043
10044
2/2
✓ Branch 0 taken 9833 times.
✓ Branch 1 taken 26 times.
9859 for component in comps loop
10045 9833 (vars, varIdxs, eqns, eqnIdxs) := getStrongComponentVarsAndEquations(component, varArr, eqnArr);
10046
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9833 times.
9833 outTypeA := func(eqns, vars, varIdxs, eqnIdxs, outTypeA);
10047 end for;
10048 else
10049 ✗ (_, _, name) := System.dladdr(func);
10050 ✗ Error.addInternalError("BackendDAEUtil.traverseEqSystemStrongComponents failed " +
10051 "with function:\n" + name + "\n", sourceInfo());
10052 ✗ fail();
10053 end try;
10054 end traverseEqSystemStrongComponents;
10055
10056 public function getStrongComponentsVarsAndEquations"gets the variables and and the equations from all sccs.
10057 author: Waurich TUD 09-2015"
10058 input BackendDAE.StrongComponents comps;
10059 input BackendDAE.Variables varArr;
10060 input BackendDAE.EquationArray eqArr;
10061 output list<BackendDAE.Var> varsOut = {};
10062 output list<Integer> varIdxsOut = {};
10063 output list<BackendDAE.Equation> eqsOut = {};
10064 output list<Integer> eqIdxsOut = {};
10065 protected
10066 BackendDAE.StrongComponent comp;
10067 list<BackendDAE.Equation> eqs;
10068 list<BackendDAE.Var> vars;
10069 list<Integer> vIdxs,eIdxs;
10070 algorithm
10071 ✗ for comp in comps loop
10072 ✗ (vars,vIdxs,eqs,eIdxs) := BackendDAEUtil.getStrongComponentVarsAndEquations(comp, varArr, eqArr);
10073 ✗ varsOut := listAppend(vars,varsOut);
10074 ✗ varIdxsOut := listAppend(vIdxs,varIdxsOut);
10075 ✗ eqsOut := listAppend(eqs,eqsOut);
10076 ✗ eqIdxsOut := listAppend(eIdxs,eqIdxsOut);
10077 end for;
10078 ✗ varsOut := listReverse(varsOut);
10079 ✗ varIdxsOut := listReverse(varIdxsOut);
10080 ✗ eqsOut := listReverse(eqsOut);
10081 ✗ eqIdxsOut := listReverse(eqIdxsOut);
10082 end getStrongComponentsVarsAndEquations;
10083
10084 public function getStrongComponentVarsAndEquations"gets the variables and and the equations from the scc.
10085 author: Waurich TUD 09-2015"
10086 input BackendDAE.StrongComponent comp;
10087 input BackendDAE.Variables varArr;
10088 input BackendDAE.EquationArray eqArr;
10089 output list<BackendDAE.Var> varsOut;
10090 output list<Integer> varIdxs;
10091 output list<BackendDAE.Equation> eqsOut;
10092 output list<Integer> eqIdcxs;
10093 algorithm
10094 (varsOut,varIdxs,eqsOut,eqIdcxs) := match comp
10095 local
10096 Integer vidx,eidx;
10097 list<Integer> vidxs,eidxs, otherEqns, otherVars;
10098 list<list<Integer>> otherVarsLst;
10099 BackendDAE.Equation eq;
10100 BackendDAE.Var var;
10101 list<BackendDAE.Equation> eqs;
10102 list<BackendDAE.Var> vars;
10103 BackendDAE.InnerEquations innerEquations;
10104 case BackendDAE.SINGLEEQUATION(eqn=eidx,var=vidx)
10105 algorithm
10106 149389 var := BackendVariable.getVarAt(varArr,vidx);
10107 149389 eq := BackendEquation.get(eqArr,eidx);
10108 then ({var},{vidx},{eq},{eidx});
10109 case BackendDAE.EQUATIONSYSTEM(eqns=eidxs,vars=vidxs)
10110 algorithm
10111 560 vars := List.map1(vidxs,BackendVariable.getVarAtIndexFirst,varArr);
10112 560 eqs := BackendEquation.getList(eidxs,eqArr);
10113 then (vars,vidxs,eqs,eidxs);
10114 case BackendDAE.SINGLEARRAY(eqn=eidx,vars=vidxs)
10115 algorithm
10116 529 vars := List.map1(vidxs,BackendVariable.getVarAtIndexFirst,varArr);
10117 529 eq := BackendEquation.get(eqArr,eidx);
10118 then (vars,vidxs,{eq},{eidx});
10119 case BackendDAE.SINGLEALGORITHM(eqn=eidx,vars=vidxs)
10120 algorithm
10121 480 vars := List.map1(vidxs,BackendVariable.getVarAtIndexFirst,varArr);
10122 480 eq := BackendEquation.get(eqArr,eidx);
10123 then (vars,vidxs,{eq},{eidx});
10124 case BackendDAE.SINGLECOMPLEXEQUATION(eqn=eidx,vars=vidxs)
10125 algorithm
10126 791 vars := List.map1(vidxs,BackendVariable.getVarAtIndexFirst,varArr);
10127 791 eq := BackendEquation.get(eqArr,eidx);
10128 then (vars,vidxs,{eq},{eidx});
10129 case BackendDAE.SINGLEWHENEQUATION(eqn=eidx,vars=vidxs)
10130 algorithm
10131 424 vars := List.map1(vidxs,BackendVariable.getVarAtIndexFirst,varArr);
10132 424 eq := BackendEquation.get(eqArr,eidx);
10133 then (vars,vidxs,{eq},{eidx});
10134 case BackendDAE.SINGLEIFEQUATION(eqn=eidx,vars=vidxs)
10135 algorithm
10136 ✗ vars := List.map1(vidxs,BackendVariable.getVarAtIndexFirst,varArr);
10137 ✗ eq := BackendEquation.get(eqArr,eidx);
10138 then (vars,vidxs,{eq},{eidx});
10139 case BackendDAE.TORNSYSTEM(strictTearingSet = BackendDAE.TEARINGSET(residualequations=eidxs,tearingvars=vidxs, innerEquations=innerEquations))
10140 algorithm
10141 1792 (otherEqns,otherVarsLst,_) := List.map_3(innerEquations, BackendDAEUtil.getEqnAndVarsFromInnerEquation);
10142 1792 otherVars := List.flatten(otherVarsLst);
10143 1792 eidxs := listAppend(otherEqns,eidxs);
10144 1792 vidxs := listAppend(otherVars,vidxs);
10145 1792 vars := List.map1(vidxs,BackendVariable.getVarAtIndexFirst,varArr);
10146 1792 eqs := BackendEquation.getList(eidxs,eqArr);
10147 then (vars,vidxs,eqs,eidxs);
10148 end match;
10149 end getStrongComponentVarsAndEquations;
10150
10151 public function getStrongComponentEquations"gets all equations from a component"
10152 input list<BackendDAE.StrongComponent> comps;
10153 input BackendDAE.EquationArray eqs;
10154 input BackendDAE.Variables vars;
10155 output list<BackendDAE.Equation> eqsOut;
10156 protected
10157 BackendDAE.StrongComponent comp;
10158 list<BackendDAE.Equation> eqLst;
10159 algorithm
10160 eqsOut := {};
10161
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 3 times.
69 for comp in comps loop
10162 66 (_,_,eqLst,_) := BackendDAEUtil.getStrongComponentVarsAndEquations(comp,vars,eqs);
10163 66 eqsOut := listAppend(eqLst,eqsOut);
10164 end for;
10165 end getStrongComponentEquations;
10166
10167 public function isFuncCallWithNoDerAnnotation"checks if the equation is a function call which has a noDerivative annotation.
10168 Outputs the noDerivative binding crefs as well.
10169 author: waurich TUD 10-2015"
10170 input BackendDAE.Equation eq;
10171 input AvlTreePathFunction.Tree functionTree;
10172 output Boolean isFuncCallWithNoDerAnno;
10173 output list<DAE.ComponentRef> noDerivativeInputs;
10174 algorithm
10175 53096 (_,(_,noDerivativeInputs)) := BackendEquation.traverseExpsOfEquation(eq,function Expression.traverseExpTopDown(func=isFuncCallWithNoDerAnnotation1),(functionTree,{}));
10176
1/2
✓ Branch 0 taken 53096 times.
✗ Branch 1 not taken.
53096 isFuncCallWithNoDerAnno := not listEmpty(noDerivativeInputs);
10177 end isFuncCallWithNoDerAnnotation;
10178
10179 public function isFuncCallWithNoDerAnnotation1 "checks if the exp is a function call which has a noDerivative annotation.
10180 Collects all crefs which dont need a derivative.
10181 author: waurich TUD 10-2015"
10182 input DAE.Exp expIn;
10183 input tuple<AvlTreePathFunction.Tree, list<DAE.ComponentRef>> tplIn; // <functionTree, foldList to collect noDer-input-vars>
10184 output DAE.Exp expOut;
10185 output Boolean cont;
10186 output tuple<AvlTreePathFunction.Tree, list<DAE.ComponentRef>> tplOut;
10187 algorithm
10188 (expOut, cont, tplOut) := matchcontinue(expIn, tplIn)
10189 local
10190 list<Integer> inputPos;
10191 Absyn.Path path;
10192 DAE.FunctionDefinition mapper;
10193 AvlTreePathFunction.Tree functionTree;
10194 list<DAE.ComponentRef> crefsIn, noDerivativeInputs;
10195 list<DAE.Exp> expLst;
10196 list<tuple<Integer,DAE.derivativeCond>> conditionRefs;
10197 case(DAE.CALL(path=path,expLst=expLst),(functionTree,crefsIn))
10198 algorithm
10199 53420 (mapper, _) := Differentiate.getFunctionMapper(path, functionTree);
10200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12635 times.
12635 DAE.FUNCTION_DER_MAPPER(conditionRefs=conditionRefs) := mapper;
10201 12635 inputPos := getNoDerivativeInputPosition(conditionRefs);
10202 12635 expLst := List.map1(inputPos,List.getIndexFirst,expLst);
10203 12635 expLst := List.filter1OnTrue(expLst,isNotFunctionCall,functionTree);
10204 12635 noDerivativeInputs := List.flatten(List.map(expLst,Expression.getAllCrefs));
10205 //print("crefs: "+stringDelimitList(List.map(noDerivativeInputs,ComponentReference.crefStr),", ")+"\n");
10206 12635 then (expIn,true,(functionTree,listAppend(noDerivativeInputs,crefsIn)));
10207 else
10208 then (expIn,true,tplIn);
10209 end matchcontinue;
10210 end isFuncCallWithNoDerAnnotation1;
10211
10212 public function isNotFunctionCall
10213 "Returns true if the given expression is something different than a function call.
10214 author: waurich TUD 10-2015"
10215 input DAE.Exp inExp;
10216 input AvlTreePathFunction.Tree funcsIn;
10217 output Boolean outIsNoCall;
10218 algorithm
10219 outIsNoCall := matchcontinue inExp
10220 local
10221 Absyn.Path path;
10222 DAE.Function func;
10223 case DAE.CALL(path=path)
10224 algorithm
10225
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 502 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 502 times.
508 SOME(func) := AvlTreePathFunction.get(funcsIn,path);
10226 502 then listEmpty(DAEUtil.getFunctionElements(func));
10227 else true;
10228 end matchcontinue;
10229 end isNotFunctionCall;
10230
10231 protected function getNoDerivativeInputPosition"get the position idx for the input-var which does not need a derivation from the NoDerivative annotations"
10232 input list<tuple<Integer,DAE.derivativeCond>> conds;
10233 output list<Integer> IdxsOut = {};
10234 algorithm
10235
2/2
✓ Branch 0 taken 12465 times.
✓ Branch 1 taken 12635 times.
25100 for c in conds loop
10236 IdxsOut := match c
10237 local
10238 Integer idx;
10239 case (idx,DAE.NO_DERIVATIVE(_))
10240 then idx::IdxsOut;
10241 else IdxsOut;
10242 end match;
10243 end for;
10244 end getNoDerivativeInputPosition;
10245
10246 public function checkAdjacencyMatrixSolvability "Performs a limited matching algorithm to sometimes figure out which equations are superfluous or which variables are never solved for."
10247 input BackendDAE.EqSystem syst;
10248 input AvlTreePathFunction.Tree functionTree;
10249 input Boolean isInitial;
10250 protected
10251 Integer varSize, eqnSize, v, eq, count;
10252 BackendDAE.AdjacencyMatrix m, mT, mOrig, mTOrig;
10253 list<Integer> vars, eqs;
10254 array<Integer> solvedVars;
10255 array<list<tuple<DAE.ComponentRef,Integer>>> solvedEqs;
10256 list<tuple<DAE.ComponentRef,Integer>> names;
10257 Integer errors = 0, numSolved = 0, eqSize, lenInfos, lenVars;
10258 Boolean cont = true;
10259 BackendDAE.Variables varsArray;
10260 BackendDAE.Var var;
10261 BackendDAE.EquationArray eqsArray;
10262 BackendDAE.Equation _equation;
10263 constant Boolean debug=false;
10264 constant Boolean alwaysCheck=false;
10265 SourceInfo info;
10266 String str;
10267 algorithm
10268 1095 varsArray := syst.orderedVars;
10269 1095 eqsArray := syst.orderedEqs;
10270 1095 varSize := BackendVariable.varsSize(varsArray);
10271 1095 eqnSize := BackendEquation.equationArraySize(eqsArray);
10272
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1091 times.
1095 if varSize <> eqnSize then
10273
2/2
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 3 times.
9 Error.addMessage(if varSize > eqnSize then Error.UNDERDET_EQN_SYSTEM else Error.OVERDET_EQN_SYSTEM, {String(eqnSize), String(varSize)});
10274 elseif not alwaysCheck then
10275 1091 return;
10276 end if;
10277 4 (_, mOrig, mTOrig) := BackendDAEUtil.getAdjacencyMatrixfromOption(syst, BackendDAE.ABSOLUTE(), SOME(functionTree), isInitial);
10278
10279 4 m := arrayCopy(mOrig);
10280 4 mT := arrayCopy(mTOrig);
10281
10282 4 solvedVars := arrayCreate(arrayLength(mT), 0);
10283 4 solvedEqs := arrayCreate(arrayLength(m), {});
10284
10285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
10 for i in 1:arrayLength(m) /* Not eqnSize; that is the size including arrays */ loop
10286 6 _equation := BackendEquation.get(eqsArray, i);
10287 6 info := BackendEquation.equationInfo(_equation);
10288 6 eqSize := BackendEquation.equationSize(_equation);
10289 6 count := listLength(arrayGet(m, i));
10290
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if eqSize > count then
10291 ✗ str := stringDelimitList(list(ComponentReferenceBasics.printComponentRefStr(BackendVariable.varCref(BackendVariable.getVarAt(varsArray, j))) for j in arrayGet(m, i)), ", ");
10292 ✗ Error.addSourceMessage(Error.EQUATION_NOT_SOLVABLE_DIFFERENT_COUNT, {BackendDump.equationString(_equation), String(eqSize), String(count), str}, info);
10293 ✗ fail();
10294 end if;
10295 end for;
10296
10297 if debug then
10298 print("Got adjacency matrix "+String(varSize)+" "+String(arrayLength(m))+" "+String(eqnSize)+" "+String(arrayLength(mT))+"...\n");
10299 end if;
10300 count := 0;
10301
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 while cont and count < 1000 loop
10302 cont := false;
10303
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 count := count+1;
10304
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
20 for i in 1:arrayLength(m) /* Not eqnSize; that is the size including arrays */ loop
10305
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
12 if not listEmpty(arrayGet(solvedEqs, i)) then
10306 6 continue;
10307 end if;
10308 6 _equation := BackendEquation.get(eqsArray, i);
10309 6 info := BackendEquation.equationInfo(_equation);
10310 6 eqSize := BackendEquation.equationSize(_equation);
10311 6 vars := arrayGet(m, i);
10312 6 lenVars := listLength(vars);
10313
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 5 times.
6 if eqSize == 0 then
10314 1 arrayUpdate(solvedEqs, i, {(DAE.emptyCref,0)});
10315 1 continue;
10316 end if;
10317
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 if lenVars <= eqSize then
10318
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 2 times.
3 if lenVars < eqSize then
10319 1 variableDoesNotFitInEquation(i, vars, mOrig, eqsArray, varsArray, solvedVars);
10320 1 errors := errors+1;
10321
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if lenVars == 0 then
10322 2 arrayUpdate(solvedEqs, i, (DAE.emptyCref,0)::arrayGet(solvedEqs,i));
10323 end if;
10324 end if;
10325
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 for v in vars loop
10326 2 var := BackendVariable.getVarAt(varsArray, v);
10327 4 arrayUpdate(solvedEqs, i, (var.varName,v)::arrayGet(solvedEqs,i));
10328 2 arrayUpdate(solvedVars, v, i);
10329 2 eqs := arrayGet(mT, v);
10330
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for eq in eqs loop
10331 // Remove references to the variable in other equations since we can't solve it there
10332 4 arrayUpdate(m, eq, List.setDifference(arrayGet(m, eq), vars));
10333 end for;
10334 numSolved := numSolved+1;
10335 end for;
10336 cont := true;
10337 end if;
10338 end for;
10339
10340 if debug then
10341 print("Number of equations solved: " + String(numSolved-errors) + "\n");
10342 print("Number of errors: " + String(errors) + "\n");
10343 end if;
10344
10345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
24 for i in 1:arrayLength(mT) /* = varSize */ loop
10346
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 6 times.
16 if 0 <> arrayGet(solvedVars, i) then
10347 10 continue;
10348 end if;
10349 6 eqs := arrayGet(mT, i);
10350 6 var := BackendVariable.getVarAt(varsArray, i);
10351 6 info := var.source.info;
10352
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if listEmpty(eqs) then
10353
8/8
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 13 taken 4 times.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 3 times.
16 Error.addSourceMessage(Error.VAR_NO_REMAINING_EQN, {
10354 ComponentReferenceBasics.printComponentRefStr(var.varName),
10355 stringAppendList(list("\n Equation " + String(eq) + ": " + BackendDump.equationString(BackendEquation.get(eqsArray, eq)) + ", which needs to solve for " + stringDelimitList(list(ComponentReferenceBasics.printComponentRefStr(Util.tuple21(tpl)) for tpl in arrayGet(solvedEqs, eq)), ", ") for eq in arrayGet(mTOrig, i)))
10356 }, info);
10357 3 arrayUpdate(solvedVars, i, -1);
10358 elseif listLength(eqs) == 1 then
10359
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
3 {eq} := eqs;
10360 3 eqSize := BackendEquation.equationSize(BackendEquation.get(eqsArray, eq));
10361 3 names := arrayGet(solvedEqs, eq);
10362 3 lenInfos := listLength(names);
10363 3 arrayUpdate(solvedVars, i, eq);
10364 6 arrayUpdate(solvedEqs, eq, (var.varName,i)::names);
10365
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 2 times.
3 if lenInfos >= eqSize then
10366 1 variableDoesNotFitInEquation(eq, {i}, mOrig, eqsArray, varsArray, solvedVars);
10367 1 errors := errors+1;
10368 end if;
10369 3 vars := arrayGet(m, eq);
10370
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if lenInfos+1 >= eqSize then // TODO: FIXME
10371
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 for v in vars loop
10372 // Remove references to the equation in other variables since we can't solve it there
10373 6 arrayUpdate(mT, v, List.setDifference(arrayGet(mT, v), eqs));
10374 end for;
10375 end if;
10376 numSolved := numSolved+1;
10377 cont := true;
10378 end if;
10379 end for;
10380
10381 if debug then
10382 print("Number of equations solved: " + String(numSolved-errors) + "\n");
10383 print("Number of errors: " + String(errors) + "\n");
10384 end if;
10385 end while;
10386
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 true := 0 == errors;
10387 if alwaysCheck and varSize == eqnSize then
10388 return;
10389 end if;
10390 if debug then
10391 for i in 1:arrayLength(mT) /* = varSize */ loop
10392 var := BackendVariable.getVarAt(varsArray, i);
10393 if 0 == arrayGet(solvedVars, i) then
10394 print("Remaining unsolved variable:" + ComponentReferenceBasics.printComponentRefStr(var.varName) + "\n");
10395 end if;
10396 end for;
10397 for i in 1:arrayLength(m) /* = varSize */ loop
10398 _equation := BackendEquation.get(eqsArray, i);
10399 eqnSize := BackendEquation.equationSize(_equation);
10400 count := listLength(arrayGet(solvedEqs, i));
10401 if eqnSize <> count then
10402 vars := arrayGet(m, i);
10403 print("Remaining vars: " + stringDelimitList(list(String(j) for j in vars), ", ") + "\n");
10404 if count > 0 then
10405 str := stringDelimitList(list(ComponentReferenceBasics.printComponentRefStr(Util.tuple21(e)) for e in arrayGet(solvedEqs, i)), ", ");
10406 print("Remaining equation (already solved "+str+"): " + BackendDump.equationString(_equation) + "\n");
10407 else
10408 print("Remaining equation: " + BackendDump.equationString(_equation) + "\n");
10409 end if;
10410 end if;
10411 end for;
10412 end if;
10413 2 fail();
10414 end checkAdjacencyMatrixSolvability;
10415
10416 protected function variableDoesNotFitInEquation
10417 input Integer eq;
10418 input list<Integer> vars;
10419 input BackendDAE.AdjacencyMatrix m;
10420 input BackendDAE.EquationArray eqsArray;
10421 input BackendDAE.Variables varsArray;
10422 input array<Integer> solvedVars;
10423 protected
10424 BackendDAE.Equation _equation;
10425 list<Integer> varsInOrig, eqsInOrig;
10426 String eqsString;
10427 SourceInfo info;
10428 Integer eqSize;
10429 algorithm
10430 2 _equation := BackendEquation.get(eqsArray, eq);
10431 2 info := BackendEquation.equationInfo(_equation);
10432 2 eqSize := BackendEquation.equationSize(_equation);
10433
10434 2 varsInOrig := List.setDifference(arrayGet(m, eq), vars);
10435
6/6
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 2 times.
4 eqsInOrig := List.sortedUnique(List.sort(list(arrayGet(solvedVars,myVar) for myVar guard arrayGet(solvedVars,myVar)>0 in varsInOrig), intGt), intEq);
10436
4/4
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 2 times.
3 eqsString := stringAppendList(list("\n Equation " + String(eqNum) + " (size: "+String(BackendEquation.equationSize(BackendEquation.get(eqsArray, eqNum)))+"): " + BackendDump.equationString(BackendEquation.get(eqsArray, eqNum)) for eqNum in eqsInOrig));
10437 10 Error.addSourceMessage(Error.EQN_NO_SPACE_TO_SOLVE, {
10438 String(eq),
10439 String(eqSize),
10440 BackendDump.equationString(_equation),
10441 getVariableNamesForErrorMessage(varsArray, vars),
10442 getVariableNamesForErrorMessage(varsArray, varsInOrig),
10443 eqsString
10444 }, info);
10445 end variableDoesNotFitInEquation;
10446
10447 protected function getVariableNamesForErrorMessage
10448 input BackendDAE.Variables varsArray;
10449 input list<Integer> vars;
10450 output String names;
10451 algorithm
10452
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 time.
4 if listEmpty(vars) then
10453 names := "";
10454 else
10455
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
6 names := " " + stringDelimitList(list(ComponentReferenceBasics.printComponentRefStr(BackendVariable.varCref(BackendVariable.getVarAt(varsArray, v))) for v in vars), ", ");
10456 end if;
10457 end getVariableNamesForErrorMessage;
10458
10459 // =============================================================================
10460 // warn about iteration variables with no nominal attribute
10461 //
10462 // =============================================================================
10463
10464 protected function warnAboutIterationVariablesWithNoNominal
10465 " author: ptaeuber"
10466 input BackendDAE.BackendDAE inDAE;
10467 protected
10468 BackendDAE.StrongComponents comps;
10469 String daeTypeStr, compKind;
10470 list<Integer> vlst = {};
10471 list<BackendDAE.Var> vars;
10472 algorithm
10473 ✗ daeTypeStr := BackendDump.printBackendDAEType2String(inDAE.shared.backendDAEType);
10474 ✗ for syst in inDAE.eqs loop
10475 ✗ BackendDAE.EQSYSTEM(matching=BackendDAE.MATCHING(comps=comps)) := syst;
10476
10477 // Go through all the strongly connected components.
10478 ✗ for comp in comps loop
10479 // Get the component's variables.
10480 (compKind, vlst) := match comp
10481 case BackendDAE.EQUATIONSYSTEM(vars = vlst, jacType = BackendDAE.JAC_NONLINEAR())
10482 ✗ then ("nonlinear equation system in the " + daeTypeStr + " DAE:", vlst);
10483 case BackendDAE.EQUATIONSYSTEM(vars = vlst, jacType = BackendDAE.JAC_GENERIC())
10484 ✗ then ("equation system with analytic Jacobian in the " + daeTypeStr + " DAE:", vlst);
10485 case BackendDAE.EQUATIONSYSTEM(vars = vlst, jacType = BackendDAE.JAC_NO_ANALYTIC())
10486 ✗ then ("equation system without analytic Jacobian in the " + daeTypeStr + " DAE:", vlst);
10487 case BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(tearingvars = vlst), linear = false)
10488 ✗ then ("torn nonlinear equation system in the " + daeTypeStr + " DAE:", vlst);
10489 // If the component is none of these types, do nothing.
10490 else ("", {});
10491 end match;
10492
10493 ✗ if not listEmpty(vlst) then
10494 // Filter out the variables that are missing start values.
10495 ✗ vars := List.map1r(vlst, BackendVariable.getVarAt, syst.orderedVars);
10496 ✗ vars := list(v for v guard(not BackendVariable.varHasNominalValue(v)) in vars);
10497
10498 // Print a warning if we found any variables with missing start values.
10499 ✗ if not listEmpty(vars) then
10500 ✗ Error.addCompilerWarning(BackendDump.varListStringIndented(vars, "Iteration variables with no nominal value in " + compKind));
10501 end if;
10502 end if;
10503 end for;
10504 end for;
10505 end warnAboutIterationVariablesWithNoNominal;
10506
10507 public function getLinearfromJacType " author: Frenkel TUD 2012-09"
10508 input BackendDAE.JacobianType jacType;
10509 output Boolean linear;
10510 algorithm
10511 linear := match jacType
10512 case BackendDAE.JAC_CONSTANT() then true;
10513 case BackendDAE.JAC_LINEAR() then true;
10514 case BackendDAE.JAC_NONLINEAR() then false;
10515 case BackendDAE.JAC_NO_ANALYTIC() then false;
10516 end match;
10517 end getLinearfromJacType;
10518
10519 public function containsHomotopyCall
10520 input DAE.Exp inExp;
10521 input Boolean inHomotopy;
10522 output DAE.Exp outExp;
10523 output Boolean outHomotopy;
10524 algorithm
10525
3/4
✓ Branch 0 taken 54648 times.
✓ Branch 1 taken 528 times.
✓ Branch 3 taken 55176 times.
✗ Branch 4 not taken.
109824 (outExp, outHomotopy) := Expression.traverseExpTopDown(inExp, containsHomotopyCall2, inHomotopy);
10526 end containsHomotopyCall;
10527
10528 protected function containsHomotopyCall2
10529 input DAE.Exp inExp;
10530 input Boolean inHomotopy;
10531 output DAE.Exp outExp = inExp;
10532 output Boolean cont;
10533 output Boolean outHomotopy;
10534 algorithm
10535 (outExp, outHomotopy, cont) := match(inExp, inHomotopy)
10536 case (_, true)
10537 then (inExp, true, false);
10538
10539 case (DAE.CALL(path=Absyn.IDENT(name="homotopy")), _)
10540 then (inExp, true, false);
10541
10542 case (DAE.CREF(componentRef=DAE.CREF_IDENT(ident=BackendDAE.homotopyLambda)), _)
10543 then (inExp, true, false);
10544
10545 else (inExp, inHomotopy, true);
10546 end match;
10547 end containsHomotopyCall2;
10548
10549 public function doIndexReduction
10550 input BackendDAE.MatchingOptions opt;
10551 output Boolean b;
10552 algorithm
10553 b := match opt
10554 case (BackendDAE.INDEX_REDUCTION(), _) then true;
10555 else false;
10556 end match;
10557 end doIndexReduction;
10558
10559 public function markNonlinearIterationVariables
10560 input output BackendDAE.BackendDAE dae;
10561 algorithm
10562
4/4
✓ Branch 0 taken 3918 times.
✓ Branch 1 taken 1060 times.
✓ Branch 2 taken 3918 times.
✓ Branch 3 taken 1060 times.
4978 dae.eqs := list(markNonlinearIterationVariablesEqSystem(syst) for syst in dae.eqs);
10563 end markNonlinearIterationVariables;
10564
10565 protected function markNonlinearIterationVariablesEqSystem
10566 input output BackendDAE.EqSystem syst;
10567 algorithm
10568 syst := match syst
10569 local
10570 BackendDAE.StrongComponents comps;
10571 UnorderedSet<DAE.ComponentRef> set = UnorderedSet.new(ComponentReferenceBasics.hashComponentRef, ComponentReferenceBasics.crefEqual);
10572 case BackendDAE.EQSYSTEM(matching = BackendDAE.MATCHING(comps = comps)) algorithm
10573
2/2
✓ Branch 0 taken 41587 times.
✓ Branch 1 taken 3918 times.
45505 for comp in comps loop
10574 41587 markNonlinearIterationVariablesStrongComponent(comp, set);
10575 end for;
10576 3918 (syst.orderedVars, _) := BackendVariable.traverseBackendDAEVarsWithUpdate(syst.orderedVars, markNonlinearIterationVariable, set);
10577 then syst;
10578 else syst;
10579 end match;
10580 end markNonlinearIterationVariablesEqSystem;
10581
10582 protected function markNonlinearIterationVariablesStrongComponent
10583 input BackendDAE.StrongComponent comp;
10584 input UnorderedSet<DAE.ComponentRef> set;
10585 protected
10586 list<BackendDAE.Var> nonlinear_iteration_vars;
10587 algorithm
10588 nonlinear_iteration_vars := match comp
10589 local
10590 BackendDAE.Jacobian jac;
10591 425 case BackendDAE.TORNSYSTEM(strictTearingSet=BackendDAE.TEARINGSET(jac=jac), linear=false) then SymbolicJacobian.getNonLinearVariables(jac);
10592 227 case BackendDAE.EQUATIONSYSTEM(jac=jac, jacType=BackendDAE.JAC_GENERIC()) then SymbolicJacobian.getNonLinearVariables(jac);
10593 else {};
10594 end match;
10595
2/2
✓ Branch 0 taken 387 times.
✓ Branch 1 taken 41587 times.
41974 for var in nonlinear_iteration_vars loop
10596 387 UnorderedSet.add(var.varName, set);
10597 end for;
10598 end markNonlinearIterationVariablesStrongComponent;
10599
10600 protected function markNonlinearIterationVariable
10601 input output BackendDAE.Var var;
10602 input output UnorderedSet<DAE.ComponentRef> set;
10603 algorithm
10604
2/2
✓ Branch 1 taken 61703 times.
✓ Branch 2 taken 386 times.
62089 if UnorderedSet.contains(var.varName, set) then
10605 386 var := BackendVariable.setVarInitNonlinear(var, true);
10606 end if;
10607 end markNonlinearIterationVariable;
10608
10609 annotation(__OpenModelica_Interface="backend");
10610 end BackendDAEUtil;
10611